Skip to content
Docs menu
Simple API (v1)

Uploads

Send large files to the switchfile API. Signed upload URLs for the simple API, and upload tasks for jobs.

A file sent inside a multipart/form-data request can be up to 100 MB. For larger files, get a signed upload URL first and send the file there. The server reports the largest file in max_file_size, in bytes, in GET /v1/account and in every upload.

Simple API (v1)#

  1. POST /v1/uploads returns an upload_id and a signed url.
  2. Send the file as the body of a PUT to that url. Start before url_expires_at (15 minutes). If the response lists headers, send them with the PUT.
  3. Convert it: POST /v1/convert with {"upload_id": "...", "to": "..."}.

The same upload_id works for several conversions until expires_at, 24 hours later.

JSON
{
  "upload_id": "7d1f0f7e-0b55-4a8e-8c5b-9d8e3f1a2b3c",
  "method": "PUT",
  "url": "https://...",
  "headers": {},
  "max_file_size": 1073741824,
  "url_expires_at": "2026-11-06T18:15:00+00:00",
  "expires_at": "2026-11-07T18:00:00+00:00"
}
UPLOAD=$(curl -s https://api.switchfile.io/v1/uploads \
  -H "Authorization: Bearer $SWITCHFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "lecture.mov"}')
curl -X PUT --upload-file lecture.mov "$(echo "$UPLOAD" | jq -r .url)"
curl https://api.switchfile.io/v1/convert \
  -H "Authorization: Bearer $SWITCHFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"upload_id\": \"$(echo "$UPLOAD" | jq -r .upload_id)\", \"to\": \"mp4\"}"

For files of several GB, stream the file from disk instead of reading it into memory: in Node.js pass createReadStream(path) as body together with duplex: "half" and a Content-Length header.

DELETE /v1/uploads/{id} deletes an uploaded file right away. Conversions already created from it keep their own copy.

Jobs and tasks (v2)#

In a job, an import/upload task waits for the file. Its result.form describes an upload form:

JSON
"result": {
  "form": {
    "url": "https://api.switchfile.io/upload/c1f3a9d2-...?expires=...&max_file_size=...&signature=...",
    "parameters": { "expires": 1762538401, "max_file_count": 1, "max_file_size": 1073741824, "signature": "..." }
  }
}

Send the file as multipart/form-data in the field file to result.form.url. The URL already holds the signed parameters, so the form fields in parameters are optional. No API key is needed for the upload.

Shell
curl "$FORM_URL" -F [email protected]

Uploads through result.form are limited to 100 MB. For larger files the task also has result.upload with a signed PUT URL, the same as in the simple API. After the PUT, the task finishes on its own within a few seconds; call POST /v2/tasks/{id}/upload-complete to finish it right away.

Shell
curl -X PUT --upload-file lecture.mov "$UPLOAD_URL"
curl -X POST "https://api.switchfile.io/v2/tasks/$TASK_ID/upload-complete" \
  -H "Authorization: Bearer $SWITCHFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "lecture.mov"}'

Small files as base64#

Jobs also take a file inline with the import/base64 task, up to 10 MB after decoding. It saves the extra upload request for small files:

JSON
{
  "tasks": {
    "import-1": { "operation": "import/base64", "file": "JVBERi0xLjQK...", "filename": "page.pdf" },
    "convert-1": { "operation": "convert", "input": "import-1", "output_format": "png" },
    "export-1": { "operation": "export/url", "input": "convert-1" }
  }
}