> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getversive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create asset upload

> Start uploading an image, video, or PDF to show beside a question

Creates an upload ticket for a question's stimulus asset. Files never go through this endpoint: when `mime_type` is sent the response carries `upload_url`, a signed URL that accepts one `PUT` of the raw file within two hours. Upload the file, call [Complete asset upload](https://docs.getversive.com/api-reference/asset-uploads/complete-asset-upload.md) while its `status` is `pending` (stop at `ready`; `rejected` and `expired` are final, so create a new ticket), then reference the ticket as `asset.upload_id` when you [create](https://docs.getversive.com/api-reference/questions/batch-questions.md) or [update](https://docs.getversive.com/api-reference/questions/update-question.md) a question. Returns `201`.

> [!NOTE]
>
> MCP sessions get the same ticket through the `create_asset_upload` tool, plus a hosted page for uploading in the browser. Organization API keys use the direct upload only.

**file\_name** `string`

Original file name with extension, for example `concept-a.png`. Shown on the hosted upload page; the stored object's extension comes from `mime_type` (the file name's extension is used only when the type is unknown).

**mime\_type** `string`

One of `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/bmp`, `image/x-ms-bmp`, `video/mp4`, `video/webm`, `video/quicktime`, `application/pdf`. Both BMP media types accept `.bmp` images. Excel spreadsheets (`.xls`, `.xlsx`) are not supported.

**size\_bytes** `integer`

Size of the file when known. Anything above 50 MB is refused before a ticket is created.

### Response

**upload\_id** `string`

The ticket id.

**status** `string`

`pending` on creation.

**upload\_url** `string`

Signed URL for one `PUT` of the raw file, only present when `mime_type` was sent. Send the `Content-Type` header from `headers`. The URL is a credential: do not log or share it.

**method** `string`

`PUT`.

**headers** `object`

Headers to send with the upload (`Content-Type`).

**expires\_at** `string`

When the ticket and the signed URL stop working (two hours).

**max\_bytes** `integer`

The size limit, 52428800.

**allowed\_mime\_types** `string[]`

The accepted media types.

### Limits

* At most 30 tickets per API key per hour.
* 50 MB per file. The bucket also enforces the type list on the upload itself.
* Tickets that never receive a file expire after two hours.

```bash cURL theme={null}
curl -X POST "https://api.getversive.com/api/v1/asset-uploads" \
  -H "Authorization: Bearer $VERSIVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_name": "concept-a.png", "mime_type": "image/png", "size_bytes": 184320}'

# then upload the file to the returned upload_url
curl -X PUT -H "Content-Type: image/png" --data-binary @concept-a.png "$UPLOAD_URL"
```

```json Response theme={null}
{
  "upload_id": "5c8e2f1a-7d4b-4e9c-a1f3-6b2d8c4e0a9f",
  "status": "pending",
  "file_name": "concept-a.png",
  "mime_type": "image/png",
  "size_bytes": null,
  "asset_type": null,
  "asset_url": null,
  "error": null,
  "expires_at": "2026-09-23T14:05:00.118Z",
  "created_at": "2026-09-23T12:05:00.118Z",
  "completed_at": null,
  "max_bytes": 52428800,
  "allowed_mime_types": ["application/pdf", "image/bmp", "image/gif", "image/jpeg", "image/png", "image/webp", "image/x-ms-bmp", "video/mp4", "video/quicktime", "video/webm"],
  "upload_url": "https://xyz.supabase.co/storage/v1/object/upload/sign/interview_media/questions/…?token=…",
  "method": "PUT",
  "headers": { "Content-Type": "image/png" }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.