Flow

Uploading reference media takes three steps:

  1. POST /api/v1/upload/presign to get upload credentials.
  2. PUT the file to R2 using the returned put_url.
  3. POST /api/v1/upload/{media_id}/complete to confirm.

Presign

POST /api/v1/upload/presign

Headers: X-API-Key: h3k_...

Body:

{
  "kind": "image",
  "filename": "ref.png",
  "content_type": "image/png",
  "size_bytes": 204800,
  "width": 1024,
  "height": 768
}
  • kind: image / video / audio
  • Images: png/jpg/jpeg/webp; videos: mp4/webm/mov; audio: mp3/wav/flac/ogg/m4a
  • size_bytes must match the actual file size; it is checked after upload

Response:

{
  "media_id": "uuid",
  "object_key": "refs/uuid.png",
  "put_url": "https://r2.example.com/..."
}

Upload

Send a PUT request to put_url with the file bytes. The URL is valid for about 600 seconds; if it expires, presign again.

Complete

POST /api/v1/upload/{media_id}/complete

Headers: X-API-Key: h3k_...

After confirmation the media becomes active and can be used in ref_media_ids.

If browser direct upload fails due to CORS or network issues, use POST /api/v1/upload/{media_id}/put to proxy through the tower, then call complete.