API
Uploads
All upload routes require Authorization: Bearer ru_... and the files.write permission (plus files.read to poll sessions). Pick the flow that matches where file bytes are sent.
Choose a flow
Client-side (CDN)
Three steps: create session → PUT to signed uploadUrl → complete. Best when the browser or app uploads directly to storage.
POST /uploads/session · PUT uploadUrl · POST /uploads/complete →
Server-side (direct)
One multipart request from your backend with the file bytes. No CDN PUT and no project upload CORS. Returns 202 while background processing finishes — see why below.
POST /uploads/direct →
Direct upload stores your file before the response returns
202 + processing means background work (scan, finalize, quotas) is still running — not that the upload failed. Use webhooks or poll GET /uploads/session/:uploadId for path, url, and confirmed sizeBytes. Why this design →
Shared behavior
filenamemay include folder paths (e.g.docs/report.pdf) — folders are created under the project- Same supported file types, size limits, quotas, and rate limits for both flows
- Both return
202when processing starts; pollGET /uploads/session/:uploadIduntilsession.statusisCOMPLETED— the response then includes a top-levelfileobject (same fields as webhookdata). Or usefile.uploadedwebhooks. - Do not mix CDN and direct flows for the same file
Every upload needs a filename with a supported extension. The contentType you send must match that extension (for example, report.pdf with application/pdf). See supported file types →
Guides: Browser uploads (CORS for CDN flow), React/Next + Node.js, Server-side upload.