---
title: "Get a presigned upload URL (public file → https URL)"
method: POST
path: "/v1/uploads"
tags: ["Assets"]
---

# Get a presigned upload URL (public file → https URL)

`POST /v1/uploads`

## Request

- Base URL: `https://api.vivideo.ai`
- URL: `https://api.vivideo.ai/v1/uploads`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/vivideo/apis/vivideo-api/docs/v1/uploads/post.ts> (a function with typed inputs; its response is checked against the schema)

Returns a presigned S3 `upload_url` and the resulting public `public_url`. PUT your file bytes to `upload_url` with header `Content-Type: <content_type>`, then use `public_url` as `image_url` / `first_frame_url` (manual videos), `file_url` (avatar photos) or `logo_url` (brand logos).

## Request body

- object
  - `filename` string, required
  - `content_type` string, required

## Response `201`

Presigned upload created.

- Upload
  - `object` string
  - `upload_url` string: Presigned S3 PUT url.
  - `public_url` string: The resulting public https url to reference.
  - `expires_in_seconds` integer
  - `method` string

## Other responses

- `400`: Invalid parameters (`invalid_request`, `unknown_model`, `invalid_url`).
- `401`: Missing, malformed or revoked API key (`missing_api_key`, `invalid_api_key`, `api_key_revoked`).
- `429`: Rate limit hit (`rate_limited`). Honor the `Retry-After` header / `retry_after_seconds` field.

---

[API](https://skmtc.dev/vivideo/apis/vivideo-api.md) - [All operations](https://skmtc.dev/vivideo/apis/vivideo-api/llms.txt) - [OpenAPI document](https://skmtc.dev/vivideo/apis/vivideo-api/revisions/6e8a47e72b46?raw)
