assets.sunra.ai URL that you can pass straight into any model endpoint.
Uploading takes two requests:
- Initiate —
POST /v1/storage/upload/initiatewith 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. - Upload —
PUTthe bytes to that pre-signed URL.
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 onapi.sunra.ai:
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 are400 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:
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:
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_namethat survives intofile_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.mp3will reach the model mislabelled. upload_urlexpires after one hour. It is a signed URL, not a reservation: if it expires before you finish, call/upload/initiateagain. Each call mints a fresh object, so the retry gets a newfile_urltoo.- Content type must match on both requests. The value in
content_typeand theContent-Typeheader of thePUThave to be identical. - Uploaded files are publicly readable.
file_urlis 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_urlcan be reused across as many predictions as you like; it is not consumed by the first model that reads it.