Create Upload

Request a presigned URL to upload a file to object storage (step 1 of 2). The two-step upload flow: 1. `POST /uploads` — register the file and receive a short-lived `upload_url`. PUT your file bytes directly to that URL (do not send them to this API). 2. `POST /uploads/{id}` — confirm the upload completed and bind the file to a resource (e.g. a workflow). The file is moved to its final location and the upload record transitions from `pending` to `uploaded`. `category` controls which file formats are accepted: - `script` — text-based formats (txt, srt, csv, json, xliff, docx) - `dictionary` — audio formats (mp3, wav, m4a, ogg, webm) The presigned URL expires within a short window (see `upload_url` TTL in the response). If the URL expires before the PUT completes, discard this upload record and start over with a fresh `POST /uploads` call. `X-Workspace-Id` is optional but recommended for workspace-scoped storage quota tracking. API keys with a bound workspace attach automatically. Dual-auth: Bearer JWT or API key (scope `uploads:write`).

Authentication

AuthorizationBearer
Clerk JWT token
OR
AuthorizationBearer

Onepin live API key (op_live_...). Test and public keys are reserved in Phase 1.

Headers

X-Workspace-Idstring or nullOptional

Request

This endpoint expects an object.
filenamestringRequired1-255 characters

Original filename including extension (e.g. script.txt). Must include a file extension.

categoryenumRequired

File category. Determines which formats are accepted: script for text formats (txt, srt, csv, json, xliff, docx); dictionary for audio formats (mp3, wav, m4a, ogg, webm).

Response

Successful Response
dataobject
metaobject

Errors

422
Unprocessable Entity Error