Overview
Many models accept media (images, video, audio) as input. To use your own files, upload them with this endpoint and pass the returned public_url to Create Prediction.
Uploads happen in two steps:
Request a presigned URL
POST /v1/upload/presign with file metadata. The response contains a short-lived URL to upload to and a stable public_url.
Upload the file
PUT the raw file bytes to presigned_url, applying any required_headers exactly as returned.
Step 1 — Request a presigned URL
Endpoint
Request Body
| Field | Type | Required | Description |
|---|
content_type | string | Yes | MIME type of the file (e.g., image/png, video/mp4, audio/mpeg). |
file_type | string | No | High-level category. One of image, video, audio, other. |
expires_in_seconds | integer | No | How long the stored file is retained before it’s automatically deleted, in seconds. Sets the expires_at in the response. Defaults to 180 days when omitted; clamped to a minimum of 60 seconds and a maximum of 365 days (31536000). Does not affect the 15-minute upload-URL lifetime. |
Code Examples
Response
Response Fields
| Field | Type | Description |
|---|
id | string | Internal upload identifier. |
presigned_url | string | Short-lived URL to PUT the file to. |
public_url | string | Stable URL to pass as a model input once the upload succeeds. |
expires_at | string | ISO-8601 timestamp when the stored file is automatically deleted (its retention deadline). Defaults to 180 days out; set a custom window with expires_in_seconds. This is not the upload-URL deadline — presigned_url itself only accepts uploads for 15 minutes after issuance (see Limits). |
required_headers | object | Headers that must be sent verbatim on the PUT request. The presigned URL is signed for these exact values — missing or modified headers will fail with a signature mismatch. May be empty. |
Step 2 — Upload the file
PUT the raw file bytes to presigned_url. Include every header from required_headers exactly as returned, plus a Content-Type matching the value sent in step 1.
A 200 OK from the PUT means the file is live. Use public_url as the input value when you create a prediction.
Limits
| Limit | Value | Notes |
|---|
| Max file size | 100 MB per upload | |
| Presigned URL lifetime | 15 minutes | How long presigned_url accepts the PUT, measured from issuance. This is not returned in the response; request a new presign if it lapses. |
| Stored file retention | 180 days (default) | How long the uploaded file is kept before automatic deletion — the value reported by expires_at. Override per upload with expires_in_seconds (min 60 seconds, max 365 days). |
Error Responses
| Status | Body | Description |
|---|
400 | {"error": "content_type is required"} | Missing required field. |
401 | {"error": "Invalid or missing API key"} | Authentication failure. |
500 | {"error": "Failed to generate presigned URL"} | Server error. |
The presigned URL expires 15 minutes after it’s issued — this is separate from expires_at, which reports when the stored file is deleted (default 180 days), not the upload deadline. Upload soon after requesting; if the URL lapses, just request a new one.