OpenAPI reference · Uploads
Mint a presigned S3 PUT URL
/uploadsReturns a single-use presigned PUT URL the customer uploads
bytes to directly. The returned id is an opaque handle
(upl_...) the customer then references via POST /v1/sources
(type: "file") or POST /v1/knowledge (type: "file") to
kick off ingestion.
The URL is bound to the supplied contentType and the
Content-Length cap — the customer cannot reuse the URL for
a different content type or larger payload.
Required scope: sources:write or knowledge:write —
either satisfies, because the same upload feeds both ingest
endpoints. (Only the deprecated 2026-08-01 version accepts
any valid token here.) Caps differ per content type
(audio/video up to 500 MB, image up to 25 MB, application/pdf
up to 100 MB, text/plain up to 25 MB).
Bytes are GC'd by an S3 lifecycle rule after 24 hours if never referenced.
Authorization
AuthorizationstringrequiredBearer token in the Authorization header.
Pass
Authorization: Bearer scripe_sk_live_<...>(orscripe_sk_test_<...>for test keys) on every request. Keys are scoped to a single workspace and can be revoked from the Scripe dashboard.The same header also accepts an OAuth 2.1 access token (
scripe_oat_*); both credentials share one scope vocabulary and every operation below documents the scope it requires. An API key can hold every scope named on this surface exceptwebhooks:manage, which is grantable to OAuth tokens only today — the webhook-endpoint operations answer403 scope_missingto every API key. Operations that name no scope accept any valid token of the workspace.
Header parameters
Scripe-Api-VersionstringPin the API version. Format
YYYY-MM-DD. Omit to receive the currently rolling default. Unknown versions return400 version_unsupported.Idempotency-KeystringOpaque string (1–64 chars,
[A-Za-z0-9_-]) used to dedup retried writes. Within 24h of the first request, the same key- same body returns the original response (
Idempotent-Replayed: true). Same key + different body returns409 idempotency_key_conflict.
Strongly recommended for every write — see
/docs/api/v1/idempotency.- same body returns the original response (
Request bodyapplication/json
contentTypestringrequiredMIME type of the file. Accepted families:
audio/*,video/*,image/*,application/pdf,application/msword(+ Office Open XML variants),text/plain. Other types return422 unprocessable.maxSizeBytesintegerOptional. Max bytes the customer expects to upload. Defaults to the per-content-type cap (500 MB for audio/video, 100 MB for PDF, etc.). Customer-supplied values over the cap return
422 unprocessable.
Responses
- 200
Presigned URL minted (or replayed via Idempotency-Key).
- 400
Malformed request (bad cursor, bad limit, etc.).
- 401
Missing, malformed, expired, or revoked API key.
- 403
Plan not eligible, scope missing, or workspace mismatch.
- 409
Idempotency-Keyreused with a different body within the 24h dedup window. Pick a fresh key or replay the original body verbatim. - 422
Body shape was JSON but failed validation (
unprocessable). - 429
Sliding-window rate limit exceeded.
- 503
Upload subsystem unavailable (AWS creds missing).
Example request
curl --request POST \
--url 'https://api.scripe.io/v1/uploads' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"contentType": "audio/mpeg",
"maxSizeBytes": 0
}'Example response (200)
{
"data": {
"id": "upl_acme_workspace_random_id_xxx",
"uploadUrl": "https://example.com",
"method": "PUT",
"contentType": "audio/mpeg",
"maxSizeBytes": 0,
"expiresAt": "2026-08-10T09:00:00Z"
}
}