---
title: "Start a direct video upload"
method: POST
path: "/v1/videos/uploads"
tags: ["Videos"]
---

# Start a direct video upload

`POST /v1/videos/uploads`

## Request

- Base URL: `https://nanostudiopro.com/api`
- URL: `https://nanostudiopro.com/api/v1/videos/uploads`
- Auth: HTTP bearer

Uploads a video of any size your storage allows: the file goes straight to storage in parts, never through this API. Send the size first; if it does not fit in your space (the file plus room for its 1080p editing copy, estimated at a third of the file) you get 402 `storage_limit_exceeded` before anything is sent. Then PUT each part (in order of `n`, any concurrency) to its URL, keep each response's `ETag` header, and call `/v1/videos/uploads/complete`. Need more part URLs (files above ~3 GB): `/v1/videos/uploads/parts`. Unfinished uploads are discarded after 7 days and never counted.

## Request body

- object
  - `filename` string, required
  - `size` integer, required: Bytes. Checked against your free space now and against the real file at the end.
  - `content_type` string
  - `project_id` string: Defaults to your most recently used project.
  - `name` string
  - `prompt` string: What the clip should be findable by.
  - `density` 'quick' | 'normal' | 'detailed': Index it for search (clips up to 180 s).
  - `metadata` object: A JSON object of your own fields (a quote number, a client, where it came from), at most 4 KB. Returned as `metadata` on every read.
  - `sha256` string: SHA-256 of the file, 64 hex characters. Optional: when this project already holds the same file, the answer is that clip with `duplicate: true` and nothing is uploaded.
  - `keep_original` boolean: Every clip gets a light 1080p H.264 editing copy, made in the background after the upload and counted toward your storage (none when the file already is 1080p H.264). `false` drops the uploaded original once the copy exists: it frees the space, and the clip is 1080p from then on (frames, downloads, exports).

## Response `200`

`upload_token`, `part_size`, `part_count`, `parts: [{ n, url }]`, `expires_at`. Or, when `sha256` matches a clip already in the project: that clip (`id`, `permanent_url`, `metadata`, …) with `duplicate: true` and no `upload_token`.

## Other responses

- `400`: Not a video, or no size
- `401`: Missing or invalid token
- `402`: Does not fit in your free space
- `429`: Rate limit exceeded

---

[API](https://skmtc.dev/nanostudiopro/apis/nano-studio-pro-api.md) · [All operations](https://skmtc.dev/nanostudiopro/apis/nano-studio-pro-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nanostudiopro/apis/nano-studio-pro-api/revisions/b454211e598e?raw)
