Upload a file for an import/upload task
The URL comes from result.form.url of the task and already holds the signed parameters. Send the file as multipart/form-data in the field file. No API key needed. Other form fields are ignored. At most 100 MB per request; send larger files with a PUT to result.upload.url.
https://api.switchfile.io/upload/{taskId}Example
curl "https://api.switchfile.io/upload/c1f3a9d2-7e44-4b0a-a1b5-2f0e8c9d6a31?expires=1762538401&max_file_size=1073741824&signature=8d2e4f6a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d1e" \
-F [email protected]import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("report.docx")]), "report.docx");
const res = await fetch("https://api.switchfile.io/upload/c1f3a9d2-7e44-4b0a-a1b5-2f0e8c9d6a31?expires=1762538401&max_file_size=1073741824&signature=8d2e4f6a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d1e", {
method: "POST",
body: form,
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
console.log(await res.json());<?php
$ch = curl_init('https://api.switchfile.io/upload/c1f3a9d2-7e44-4b0a-a1b5-2f0e8c9d6a31?expires=1762538401&max_file_size=1073741824&signature=8d2e4f6a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d1e');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('report.docx'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException("HTTP $status: $response");
}
print_r(json_decode($response, true));import requests
res = requests.post(
"https://api.switchfile.io/upload/c1f3a9d2-7e44-4b0a-a1b5-2f0e8c9d6a31?expires=1762538401&max_file_size=1073741824&signature=8d2e4f6a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d1e",
files={"file": open("report.docx", "rb")},
)
res.raise_for_status()
print(res.json())Parameters
Path parameters
taskIdstring (uuid)requiredID of the import/upload task
Query parameters
expiresnumberrequiredPart of the signed URL
example: 1762538401
max_file_sizenumberrequiredPart of the signed URL
example: 1073741824
signaturestringrequiredPart of the signed URL
at least 1 characters · example: 8d2e4f6a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d1e
max_file_countnumberPart of the signed URL
Request body
expiresintegerfilefilerequiredmax_file_countintegermax_file_sizeintegersignaturestring
Responses
201Stored. The task is finished
dataTaskDetailrequireddata.codestring | nullrequireddata.copy_of_task_idstring (uuid) | nullrequireddata.created_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.creditsstring (integer) | integerrequireddata.depends_on_task_idsstring (uuid)[]requireddata.depends_on_tasksmap of string (uuid)Name and ID of each input task
keys match ^(.*)$
data.ended_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.enginestring | nullrequiredInternal identifier, may change. Do not rely on its value
data.engine_versionstring | nullrequiredInternal identifier, may change. Do not rely on its value
data.host_namestring | nullrequireddata.idstring (uuid)requireddata.jobJobdata.job.created_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.job.ended_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.job.idstring (uuid)requireddata.job.linksobjectrequireddata.job.links.selfstringrequireddata.job.started_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.job.statusstringrequiredone of "waiting", "processing", "finished", "error"
data.job.tagstring | nullrequireddata.job.tasksTask[]data.job.tasks[].codestring | nullrequireddata.job.tasks[].copy_of_task_idstring (uuid) | nullrequireddata.job.tasks[].created_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.job.tasks[].creditsstring (integer) | integerrequireddata.job.tasks[].depends_on_task_idsstring (uuid)[]requireddata.job.tasks[].ended_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.job.tasks[].enginestring | nullrequiredInternal identifier, may change. Do not rely on its value
data.job.tasks[].engine_versionstring | nullrequiredInternal identifier, may change. Do not rely on its value
data.job.tasks[].host_namestring | nullrequireddata.job.tasks[].idstring (uuid)requireddata.job.tasks[].job_idstring (uuid)requireddata.job.tasks[].linksobjectrequireddata.job.tasks[].messagestring | nullrequireddata.job.tasks[].namestringrequireddata.job.tasks[].operationstringrequireddata.job.tasks[].percentstring (integer) | integerrequiredProgress as in CloudConvert: 100 when finished, otherwise 0
0 to 100
data.job.tasks[].prioritystring (integer) | integerrequireddata.job.tasks[].regionstringrequiredRegion the task runs in (eu-central)
data.job.tasks[].resultTaskResultrequireddata.job.tasks[].retry_of_task_idstring (uuid) | nullrequireddata.job.tasks[].started_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.job.tasks[].statusstringrequiredone of "waiting", "processing", "finished", "error"
data.job.tasks[].storagestring | nullrequireddata.job.tasks[].user_idstring | nullrequiredAccount of the job (opaque ID, the same as data.id in /v2/users/me)
data.job.tasks[].waiting_forstringWhat a waiting task waits for, one of "upload", "inputs", "queued". Only set while status is waiting
data.job_idstring (uuid)requireddata.linksobjectrequireddata.links.selfstringrequireddata.messagestring | nullrequireddata.namestringrequireddata.operationstringrequireddata.payloadmap of anykeys match ^(.*)$
data.percentstring (integer) | integerrequiredProgress as in CloudConvert: 100 when finished, otherwise 0
0 to 100
data.prioritystring (integer) | integerrequireddata.regionstringrequiredRegion the task runs in (eu-central)
data.resultTaskResultrequireddata.result.filesResultFile[]data.result.files[].detected_input_formatstringconvert only: the format the input actually had, when it differs from the given format or the file extension (for example a PNG file named .jpg)
data.result.files[].filenamestringrequireddata.result.files[].notesstring[]convert only: notes when the output differs from the request, for example a frame rate the target format does not support that was set to the nearest allowed value
data.result.files[].sizestring (integer) | integerdata.result.files[].urlstringdata.result.formUploadFormdata.result.form.parametersobjectrequireddata.result.form.urlstringrequireddata.result.uploadDirectUploadimport/upload only: a signed URL for large files, without the 100 MB limit of result.form. The task finishes on its own a few seconds after the PUT. Call POST /v2/tasks/{id}/upload-complete to finish it right away.
data.result.upload.expires_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.result.upload.headersmap of stringrequiredHeaders the PUT request must send (usually none)
keys match ^(.*)$
data.result.upload.max_file_sizestring (integer) | integerrequiredLargest allowed file in bytes. A larger upload makes the task fail
data.result.upload.methodstringrequiredone of "PUT"
data.result.upload.urlstringrequiredSigned URL. Send the file as the raw body of a PUT request, not as a form
data.retriesTask[]data.retries[].codestring | nullrequireddata.retries[].copy_of_task_idstring (uuid) | nullrequireddata.retries[].created_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.retries[].creditsstring (integer) | integerrequireddata.retries[].depends_on_task_idsstring (uuid)[]requireddata.retries[].ended_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.retries[].enginestring | nullrequiredInternal identifier, may change. Do not rely on its value
data.retries[].engine_versionstring | nullrequiredInternal identifier, may change. Do not rely on its value
data.retries[].host_namestring | nullrequireddata.retries[].idstring (uuid)requireddata.retries[].job_idstring (uuid)requireddata.retries[].linksobjectrequireddata.retries[].links.selfstringrequireddata.retries[].messagestring | nullrequireddata.retries[].namestringrequireddata.retries[].operationstringrequireddata.retries[].percentstring (integer) | integerrequiredProgress as in CloudConvert: 100 when finished, otherwise 0
0 to 100
data.retries[].prioritystring (integer) | integerrequireddata.retries[].regionstringrequiredRegion the task runs in (eu-central)
data.retries[].resultTaskResultrequireddata.retries[].result.filesResultFile[]data.retries[].result.formUploadFormdata.retries[].result.uploadDirectUploadimport/upload only: a signed URL for large files, without the 100 MB limit of result.form. The task finishes on its own a few seconds after the PUT. Call POST /v2/tasks/{id}/upload-complete to finish it right away.
data.retries[].retry_of_task_idstring (uuid) | nullrequireddata.retries[].started_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.retries[].statusstringrequiredone of "waiting", "processing", "finished", "error"
data.retries[].storagestring | nullrequireddata.retries[].user_idstring | nullrequiredAccount of the job (opaque ID, the same as data.id in /v2/users/me)
data.retries[].waiting_forstringWhat a waiting task waits for, one of "upload", "inputs", "queued". Only set while status is waiting
data.retry_of_task_idstring (uuid) | nullrequireddata.started_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.statusstringrequiredone of "waiting", "processing", "finished", "error"
data.storagestring | nullrequireddata.user_idstring | nullrequiredAccount of the job (opaque ID, the same as data.id in /v2/users/me)
data.waiting_forstringWhat a waiting task waits for, one of "upload", "inputs", "queued". Only set while status is waiting
201 application/json{ "data": { "id": "c1f3a9d2-7e44-4b0a-a1b5-2f0e8c9d6a31", "job_id": "6e2c1b1f-3c1a-4d4e-9a57-0d7b2f6a8e10", "name": "upload-1", "operation": "import/upload", "status": "finished", "message": null, "code": null, "credits": 0, "created_at": "2026-11-06T18:00:00+00:00", "started_at": "2026-11-06T18:00:00+00:00", "ended_at": "2026-11-06T18:00:01+00:00", "depends_on_task_ids": [], "retry_of_task_id": null, "copy_of_task_id": null, "priority": 0, "host_name": null, "storage": null, "engine": null, "engine_version": null, "percent": 100, "region": "eu-central", "user_id": "4f8a2c6e-1b3d-4e5f-8a7c-9d0b2e4f6a18", "result": { "files": [ { "filename": "report.docx", "size": 48213 } ] }, "links": { "self": "https://api.switchfile.io/v2/tasks/c1f3a9d2-7e44-4b0a-a1b5-2f0e8c9d6a31" } } }403The signature is wrong or the form has expired
EXPIRED403 application/json{ "message": "The upload form has expired.", "code": "EXPIRED" }404Does not exist for this account
NOT_FOUND404 application/json{ "message": "Task not found.", "code": "NOT_FOUND" }413The request or the file is too large
FILE_TOO_LARGE413 application/json{ "message": "The file is larger than the allowed maximum.", "code": "FILE_TOO_LARGE" }422A file was already uploaded for this task
INVALID_DATA422 application/json{ "message": "file: A file was already uploaded for this task.", "code": "INVALID_DATA", "errors": { "file": [ "A file was already uploaded for this task." ] } }429Too many requests or a daily quota is used up. See Retry-After
RATE_LIMIT_EXCEEDED429 application/json{ "message": "Too many requests. Try again in 12 seconds.", "code": "RATE_LIMIT_EXCEEDED" }