---
title: "Initiate a single-PUT file upload"
method: POST
path: "/v2/files/upload"
tags: ["FilesV2"]
---

# Initiate a single-PUT file upload

`POST /v2/files/upload`

## Request

- Base URL: `https://dovetail.com/api`
- URL: `https://dovetail.com/api/v2/files/upload`
- Auth: HTTP bearer

Initiate a single-PUT upload for files **up to 5 GB**. The response includes a pre-signed `upload_url` that the client should `PUT` the full file body to. After the `PUT` succeeds, call **Complete upload** at `POST /v2/files/{file_id}/upload/complete`.

The pre-signed `upload_url` is signed for server-side encryption with AWS KMS, so the `PUT` request **must** include the header `x-amz-server-side-encryption: aws:kms`. Omitting it (or sending a different value) fails the request with a signature mismatch (HTTP `403`).

```bash
curl -X PUT "<upload_url>" \
-H "x-amz-server-side-encryption: aws:kms" \
-H "Content-Type: <type>" \
--data-binary @/path/to/file
```

Files larger than 5 GB must use the large-upload endpoint (`POST /v2/files/large-upload`) instead.

Once finalized, inspect the file with `GET /v1/files/{file_id}` and download it with `GET /v1/files/{file_id}/download` — no v2 read surface exists yet.

Returns `201` with the upload session details. Orphaned uploads that are not completed are eventually cleaned up.

**Required scope:** `data:file_import` or `doc:file_import`

## Request body

- object
  - `name` string, required: The file's original name, including extension. 1-1024 characters.
  - `type` string, required: The file's MIME type (e.g. `image/png`, `video/mp4`). Up to 255 characters.
  - `size` integer, required: Total size of the file in bytes. Must be between 1 and 5000000000 (5 GB). For files larger than 5 GB use the large-upload endpoint instead.

## Response `201`

201

- object
  - `data` object, required
    - `file_id` string, required: Base62-encoded UUID identifying the newly created file record.
    - `upload_url` string, uri, required: Pre-signed URL the client should `PUT` the file body to.
    - `expires_at` string, required: ISO 8601 timestamp at which `upload_url` expires.
    - `max_file_size_bytes` 5000000000, required: Maximum size (bytes) accepted by this endpoint.

## Other responses

- `400`: 400
- `401`: 401
- `403`: 403
- `404`: 404
- `422`: 422
- `429`: 429
- `500`: 500

## Changes

- **2026-11-03** `8abea327e6b9`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/dovetail/apis/dovetail-public-api/changes/v2/files/upload/post.md)

---

[API](https://skmtc.dev/dovetail/apis/dovetail-public-api.md) - [All operations](https://skmtc.dev/dovetail/apis/dovetail-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/dovetail/apis/dovetail-public-api/revisions/8abea327e6b9?raw)
