Guides

Browser uploads

Let end users upload from the browser without exposing your Reupload API key. Your backend creates the session; the browser PUTs to the signed CDN URL; your backend completes the upload.

Recommended flow

  1. Browser calls your API (e.g. POST /api/uploads/prepare) with filename, type, and size.
  2. Your server calls Reupload POST /uploads/session with the API key and returns uploadUrl, uploadId, and fileId to the browser.
  3. Browser sends PUT with fetch (or XMLHttpRequest) to uploadUrl.
  4. Browser notifies your server; your server calls POST /uploads/complete with uploadId.
  5. Poll GET /uploads/session/:uploadId or use a file.uploaded webhook to know when the file is ready.

CORS on the CDN PUT

Signed upload URLs embed allowed browser origins. For API-created sessions, only origins configured on the project in the dashboard are allowed (up to 20 full origins like https://app.example.com — no path, query, or wildcards).

Dashboard uploads also include server-configured default origins; API sessions use project origins only. If the browser origin is not allowed, the CDN PUT fails with a CORS error before bytes reach storage.

Configure origins

In the dashboard, open your project settings and add every origin that will run the upload UI (production, staging,http://localhost:5173 for local dev, etc.).

Example: browser PUT

upload.js
async function uploadToCdn(uploadUrl, file) {
  const res = await fetch(uploadUrl, {
    method: "PUT",
    headers: { "Content-Type": file.type },
    body: file,
  });
  if (!res.ok) {
    throw new Error(`CDN upload failed: ${res.status}`);
  }
}

The declared size and contentType in the session must match the file exactly. Do not send extra headers unless your CDN token requires them.

Security

  • Never put ru_... API keys in front-end bundles or mobile apps.
  • Treat uploadUrl as a short-lived secret (default 300s). Issue a new session per upload attempt.
  • Validate file type and size on your server before calling Reupload.
  • Rate-limit your own /prepare endpoint to prevent abuse of your API key indirectly.

Mobile and desktop apps

Native apps can PUT to uploadUrl without CORS. The same three-step flow applies; only browser clients need project origin configuration.

Full stack example with copy-paste code: React/Next + Node.js guide.