---
title: "Start an upload"
method: POST
path: "/videos/upload"
tags: ["Videos"]
---

# Start an upload

`POST /videos/upload`

## Request

- Base URL: `https://api.cut.pro/api/v1`
- URL: `https://api.cut.pro/api/v1/videos/upload`
- Auth: API key in header `X-Api-Key`

Returns the generated `video_id` plus whatever the file's size requires to upload it directly to storage, then call `POST /videos/upload/complete` to register the upload and get the credit cost.

When `mode` is `single`, PUT the bytes to `upload_url` with the same `Content-Type` you declared here.

When `mode` is `multipart` the file is past the storage provider's single-PUT ceiling: split it into `part_size`-byte chunks and PUT each one to the matching entry of `part_urls` (index 0 is part 1, the last part may be shorter). Collect each response's `ETag` header and post them to `POST /videos/upload/multipart/complete`.

Max file size comes from your plan — a `FILE_TOO_LARGE` response reports the effective ceiling in `max_size`. Extensions: `.mp4`, `.mov`, `.webm`, `.mkv`.

## Request body

- object
  - `file_name` string, required: Original file name. Used to detect the extension and as a fallback title.
  - `file_size` number, required: Size of the file in bytes. The ceiling comes from your plan.
  - `content_type` string: MIME type — defaults to `video/mp4`. Must match the bytes you PUT.

## Response `200`

Response for status 200

- union
  - object
    - `mode` 'single', required
    - `video_id` string, required: Generated video ID. Pass it to `POST /videos/upload/complete` after the PUT.
    - `upload_url` string, required: Presigned PUT URL — upload the raw bytes here.
    - `expires_in` number, required: Seconds until `upload_url` expires.
  - object
    - `mode` 'multipart', required
    - `video_id` string, required: Generated video ID. Pass it to the multipart complete call and then to `POST /videos/upload/complete`.
    - `upload_id` string, required: Multipart upload ID — echo it back when completing or aborting.
    - `part_urls` string[], required: One presigned PUT URL per part, in order. Index 0 is part number 1.
    - `part_size` number, required: Bytes per part. Every part but the last must be exactly this size.
    - `expires_in` number, required: Seconds until the part URLs expire.

## Other responses

- `400`: Response for status 400
- `500`: Response for status 500

---

[API](https://skmtc.dev/cut/apis/cutpro-api.md) · [All operations](https://skmtc.dev/cut/apis/cutpro-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cut/apis/cutpro-api/revisions/89d0bafe529c?raw)
