Media Upload

Authenticated endpoints for uploading, listing, and deleting media files programmatically.

Endpoints

GET /api/v1/upload/files
GET /api/v1/upload/files/{id}
POST /api/v1/upload (scope: write)
DELETE /api/v1/upload/files/{id} (scope: delete)

List files

GET /api/v1/upload/files?page=1&per_page=24&filter[folder]=images&filter[mime]=image/*

200 OK
{
  "data": [
    {
      "id":   "01H…",
      "name": "hero.jpg",
      "url":  "https://your-host/storage/media/hero.jpg",
      "mime": "image/jpeg",
      "size": 384217,
      "width":  1920,
      "height": 1080,
      "alt":  "Stage at launch event",
      "folder": "images",
      "created_at": "2026-05-29T09:00:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 24, "total": 152 },
  "error": null
}

Get one file

GET /api/v1/upload/files/01H…

200 OK
{ "data": { …same shape as above… }, "error": null }

Upload a file

Multipart upload. Single field file. Optional folder_id, alt, caption.

POST /api/v1/upload
X-API-Key:    pk_live_…
X-API-Secret: sk_live_…
Content-Type: multipart/form-data; boundary=…

--boundary
Content-Disposition: form-data; name="file"; filename="hero.jpg"
Content-Type: image/jpeg

…binary…
--boundary
Content-Disposition: form-data; name="folder_id"

01H4…
--boundary
Content-Disposition: form-data; name="alt"

Stage at launch event
--boundary--

201 Created
{
  "data": {
    "id":     "01H…",
    "name":   "hero.jpg",
    "url":    "https://your-host/storage/media/hero.jpg",
    "mime":   "image/jpeg",
    "size":   384217,
    "width":  1920,
    "height": 1080,
    "alt":    "Stage at launch event",
    "folder": "images"
  },
  "error": null
}

Validation

Delete a file

DELETE /api/v1/upload/files/01H…

204 No Content

Deletes both the DB row and the underlying storage object. The action is irreversible at the storage layer.

Errors

StatusCodeWhen
404FILE_NOT_FOUNDUUID does not exist
413FILE_TOO_LARGEExceeds the configured size cap
415UNSUPPORTED_MEDIA_TYPEMIME outside the allowlist
422VALIDATION_FAILEDMissing or invalid form fields
Linking media to entriesWhen you upload a file, use the returned id as the value of a media field on a content entry. Listing endpoints can resolve and inline that media via ?include=hero_image.