Uploading
Get a URL to upload a file to
For a file too big to send inline — a whole pack — or one you have on disk and would rather not base64. Ask with the file's exact length, PUT the bytes to url with the Content-Length it names (curl -T pack.zip "<url>" does both), then pass {"upload": "<upload>"} as the file of the call that wants it.
The URL takes exactly size bytes and expires after fifteen minutes. An upload is used once: the call that consumes it deletes it.
/uploadsBody
sizeintegerrequired1–536870912The file's length in bytes.
Response · 201
A presigned URL.
uploadstringrequiredPass this as file.upload.
urlstringrequiredPUT the bytes here.
methodstringrequiredAlways PUT.
headersobjectrequiredHeaders the PUT must carry.
maxBytesintegerrequiredThe exact length the URL accepts.
expiresAtstringrequiredISO 8601. Upload before this.
Error codes
Branch on error.code, never on the message.
invalid_request400Something in the body or query is wrong. message says what.
invalid_api_key401The key isn't one of ours, or it has been revoked.
missing_api_key401No Authorization: Bearer header was sent.
wrong_key_kind401An MCP key sent to the REST API, or an API key sent to the MCP server. Each only opens its own.
plan_required403The key is valid, but its account is on Starter. The API needs a paid plan.
not_found404No such pack, asset or job.