---
title: "Request a file upload URL"
method: POST
path: "/api/v1/files/upload"
tags: ["Files"]
---

# Request a file upload URL

`POST /api/v1/files/upload`

Returns a pre-signed URL for uploading a file via PUT.

## Request body

- FileUploadBody — Request a pre-signed upload URL. After receiving the URL, PUT the raw file bytes to it within the expiration window.
  - `filename` string, required — Original filename including extension (e.g. 'part.step', 'model.obj'). Used for display and format detection.
  - `contentType` string, required — MIME type of the file (e.g. 'application/step', 'model/gltf-binary'). Must match the actual file content.
  - `bytes` integer, required — Exact file size in bytes. Must match the Content-Length of the subsequent PUT to the upload URL. Maximum: 1 GB.
  - `sha256` string — SHA-256 hex digest of the file content. When provided, enables server-side deduplication — if an identical file was previously uploaded under this API key, the existing file is reused and no upload is needed.

## Response `201`

Upload URL and file ID

- UploadResponse — Success envelope containing the pre-signed upload URL and file metadata
  - `ok` true, required
  - `data` UploadResult, required — Response after requesting a file upload. Contains the pre-signed URL to PUT your file to.
    - `fileId` string, uuid, required — Assigned file identifier — use this to reference the file in subsequent API calls
    - `uploadUrl` string, uri, required — Pre-signed URL to PUT the raw file bytes to. Send the file content with Content-Type and Content-Length headers matching the request.
    - `expiresIn` integer, required — Seconds until the upload URL expires. You must complete the PUT within this window.
    - `maxBytes` integer, required — Maximum allowed file size in bytes for this upload. Determined by your plan tier.
    - `status` 'pending', required

## Other responses

- `400` — Validation error
- `500` — Server error

## Changes

- **2026-05-01** `b0777496a5dd` — 1 breaking
  - the `bytes` request property's max was decreased to `1073741824.00`
- **2026-04-30** `bef883f8a334` — 3 breaking, 3 warning, 14 info
  - the `contentType` request property's minLength was increased from `0` to `1`
  - the `filename` request property's minLength was increased from `0` to `1`
  - the `sha256` request property's minLength was increased from `0` to `1`
  - the `bytes` request property's exclusiveMinimum was set to `0.00`
  - …16 more
- **2026-04-17** `5eb4ed0f33c7` — 9 breaking, 3 warning, 6 info
  - the response property `data` became optional for the status `201`
  - the response property `data/expiresIn` became optional for the status `201`
  - the response property `data/fileId` became optional for the status `201`
  - the response property `data/maxBytes` became optional for the status `201`
  - …14 more

[Change history](https://skmtc.dev/bitbybit-dev/apis/bitbybit-cad-cloud-api/changes/api/v1/files/upload/post.md)

---

[API](https://skmtc.dev/bitbybit-dev/apis/bitbybit-cad-cloud-api.md) · [All operations](https://skmtc.dev/bitbybit-dev/apis/bitbybit-cad-cloud-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/bitbybit-dev/bitbybit-cad-cloud-api/revisions/b08f35b461c9/schema)
