Skip to main content
Sunra models take their file inputs as URLs — the audio you want transcribed, the image you want animated. When the file only exists on your machine or in a private bucket, upload it to Sunra storage first: you get back an assets.sunra.ai URL that you can pass straight into any model endpoint. Uploading takes two requests:
  1. InitiatePOST /v1/storage/upload/initiate with the file name and content type. Sunra replies with a pre-signed URL to upload to, plus the final public URL the file will have.
  2. UploadPUT the bytes to that pre-signed URL.
The file is readable at its public URL as soon as the PUT succeeds — there is no processing step to wait for.

Authentication

Only the first request is authenticated, with the same API key you use everywhere else on api.sunra.ai:
The second request carries its authorization inside the pre-signed URL, so it needs no API key — which is what makes it safe to hand the upload_url to a browser or a mobile client. See Authentication for how to obtain and store the key.

Step 1 — Initiate the upload

Request body

Response

201 Created:
Each call mints a fresh, randomly named object — the name you send is never used as the object name, so uploads can never collide with or overwrite each other. Only the extension survives, lower-cased: Chunk10.MP3 lands at …/<uuid>.mp3.

Rejected file names

Both of these are 400 and create nothing, so correct the name and call again: Multi-part extensions keep only the last segment: archive.tar.gz uploads fine and lands at …/<uuid>.gz.

Step 2 — Upload the file

PUT the raw bytes to upload_url, repeating the content type you declared:
The Content-Type header is part of what was signed. If it differs from the content_type you sent to /upload/initiate — even by case or by a stray charset parameter — the signature no longer matches and the object store rejects the upload. Do not add an Authorization header here.

Step 3 — Use the file URL

file_url is a normal public URL. Pass it to any model endpoint that accepts a file input — here, speech-to-text:
That returns a request_id like any other submission; poll or stream it as described in Queue.

Full example

Upload a local audio file and transcribe it:

Things to know

  • The extension is required, and it is load-bearing. It is the one part of file_name that survives into file_url, and some models — speech-to-text in particular — read the media format off the URL path. Send the real extension for the file’s actual format; a WAV file named .mp3 will reach the model mislabelled.
  • upload_url expires after one hour. It is a signed URL, not a reservation: if it expires before you finish, call /upload/initiate again. Each call mints a fresh object, so the retry gets a new file_url too.
  • Content type must match on both requests. The value in content_type and the Content-Type header of the PUT have to be identical.
  • Uploaded files are publicly readable. file_url is unguessable, but it is not secret and it is not time-limited — anyone who has the URL can fetch the file. Do not upload anything confidential, and treat the URLs themselves as sensitive if the content is.
  • Files are not tied to a request. Once uploaded, a file_url can be reused across as many predictions as you like; it is not consumed by the first model that reads it.