Getting started
Quickstart
Add uploads in a few minutes. Use the Try it panel on the right with your real API key and project ID — curl commands update automatically.
1. Create an API key and project
Sign up, open the dashboard, create a project, and generate an API key with files.write (and files.read if you want to poll session status or download files).
Copy these into your server environment:
REUPLOAD_API_KEY— full key (starts withru_, shown once)REUPLOAD_PROJECT_ID— UUID from project settings
2. Verify your key
GET /public/whoami confirms the key and lists projects (id, name, and uploadCorsOrigins when set) your key can use. Run the curl in the Try it panel.
{
"apiKeyId": "uuid",
"workspaceId": "uuid",
"name": "Production",
"permissions": ["files.read", "files.write"],
"allProjects": false,
"projects": [
{
"id": "your-project-uuid",
"name": "Production",
"uploadCorsOrigins": ["https://app.example.com"]
}
]
}3. Upload a file
Pick one path — both end with the same processing and webhooks.
Path A — CDN flow (browser or client uploads)
Your server creates a session; the client PUTs bytes to a signed CDN URL; your server completes. Best when the browser uploads directly to storage.
Create an upload session
POST /uploads/session with projectId, filename, contentType, and exact byte size.
{
"uploadId": "uuid",
"fileId": "uuid",
"uploadUrl": "https://cdn.reupload.dev/v1/upload/eyJ2Ijox...",
"expiresIn": 300
}Return uploadUrl and uploadId to your client. Keep fileId if you need it before processing finishes.
Upload bytes to the CDN
PUT the file to uploadUrl with the same Content-Type and body size you declared. This is not a Reupload API call.
For browser apps, see Browser uploads or the React/Next + Node.js guide (CDN flow).
Complete the upload
POST /uploads/complete with uploadId returns 202:
{ "fileId": "uuid", "status": "processing" }Path B — Server direct (your backend uploads)
One multipart/form-data request from your server. Use when users send files to your API first and you forward them to Reupload — no CDN PUT or upload CORS.
curl -s -X POST 'https://api.reupload.dev/api/v1/uploads/direct' \
-H 'Authorization: Bearer ru_...' \
-F 'projectId=your-project-uuid' \
-F 'filename=docs/report.pdf' \
-F 'file=@./report.pdf;type=application/pdf'{
"uploadId": "uuid",
"fileId": "uuid",
"status": "processing"
}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 →
Full proxy example: Server-side upload guide. Details: Server-side uploads.
4. Wait for processing
The upload HTTP call succeeding does not mean the file is ready to serve. Direct upload already stored your bytes; CDN upload finished the PUT — in both cases Reupload still scans, finalizes, and emits webhooks in the background. Poll GET /uploads/session/:uploadId until session.status is COMPLETED — the response then includes a top-level file object with path, url, and sizeBytes (same shape as webhook data). Or handle a file.uploaded webhook. Applies to both upload paths. Why direct upload returns 202 →
5. Download or delete
GET /files/:fileId/access returns a signed CDN URL. DELETE /files/:fileId requires files.delete.
Endpoint matrix and quotas: API reference.
SDKs
Use official packages instead of hand-rolled fetch: @reupload/sdk (server), @reupload/client (browser), @reupload/react (React uploaders). Packages overview.