docs/api/files

API

Files

Upload a file before a job reads it. Uploads and outputs are deleted after 24 hours.

Upload a file

Send the file as the body of POST /v1/files, with its name in X-File-Name as percent-encoded UTF-8. The body needs a Content-Length and can be up to 32 MiB. The file is ready when the response comes back.

The format comes from the content. X-File-Format names it instead, and replaces detection.

A JSON body without X-File-Name asks for upload instructions or an import, as below. To upload a JSON file itself, send its name in X-File-Name.

Terminal
$ export CV_API_KEY=cv_sk_…

Set your key once. Every cv command reads it.

Terminal
$ curl -X POST https://api.convert.dev/v1/files \  -H "Authorization: Bearer $CV_API_KEY" \  -H "X-File-Name: lease.docx" \  --data-binary @lease.docx
response12 lines
{  "object": "file",  "id": "file_01JC9W3TQ6V8ZK2N5R7M4H1XEB",  "status": "ready",  "name": "lease.docx",  "size": 4007,  "format": {"id": "docx", "mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},  "source": "inline",  "url": "https://…",  "expires_at": "2026-11-04T09:12:31Z",  "created_at": "2026-11-03T09:12:31Z"}

Upload a large file

For a larger file, send JSON with its name and size first. The file starts as uploading, and its upload says how to send the bytes.

  • Up to 64 MiB, method is put: send the whole file to url with the headers given, then call POST /v1/files/{id}/complete.
  • Larger, method is multipart, with part_size of 16 MiB and the number of parts. Ask for part URLs with POST /v1/files/{id}/parts, up to 100 numbers at a time from 1, send each part, and keep the ETag of each answer.
  • Then complete it with the list of parts. The file becomes ready once its format is known.

A file can have up to 10,000 parts, and the plan sets the largest file you can upload. The upload links work for an hour.

Terminal
$ curl -X POST https://api.convert.dev/v1/files \  -H "Authorization: Bearer $CV_API_KEY" \  -H "Content-Type: application/json" \  -d '{"name": "survey.pdf", "size": 48210944}'
response16 lines
{  "object": "file",  "id": "file_01JC9W6A4N9R3K7T2Q8V5M1HXE",  "status": "uploading",  "name": "survey.pdf",  "size": 48210944,  "source": "upload",  "expires_at": "2026-11-04T09:20:05Z",  "created_at": "2026-11-03T09:20:05Z",  "upload": {    "method": "put",    "url": "https://…",    "headers": {"content-length": "48210944", "if-none-match": "*"},    "expires_at": "2026-11-03T10:20:05Z"  }}
Terminal

Complete a multipart upload with every part number and its ETag. A single put completes with no body.

$ curl -X POST https://api.convert.dev/v1/files/file_01JC9W6A4N9R3K7T2Q8V5M1HXE/complete \  -H "Authorization: Bearer $CV_API_KEY" \  -H "Content-Type: application/json" \  -d '{"parts": [{"number": 1, "etag": "\"5d41…\""}, {"number": 2, "etag": "\"7d79…\""}]}'

The file object

Field
idThe file's id, such as file_01JC9W6C8T2M5Q9K3V7N1R4XBF. A job names its inputs by it.
statusuploading, ready or expired. A job takes a ready file.
nameThe file name you gave, or the name of an output.
sizeBytes.
formatThe format id and mime, from the content or from the format you declared.
pagesThe page count of a PDF.
revThe revision of the content, once a job has read the file. An edit names it. An edited output whose refs moved has none, so read it before the next edit.
sourceupload, inline for a file sent as the body, or output for a file a job made.
urlA signed link to download the file. It needs no key and works for an hour.
indexFor an output, its place among the outputs of its job, from 0.
expires_atWhen the file is deleted.
uploadHow to send the bytes, right after you ask for upload instructions.

List, get and delete

GET /v1/files lists files newest first, up to limit (1 to 100) at a time. Pass next_cursor as cursor for the next page, and source to list only some, such as upload,inline.

A limit outside 1 to 100, or a source the API does not know, fails with invalid_request.

GET /v1/files/{id} returns one file with a fresh url. DELETE /v1/files/{id} deletes it now and answers 204.

Terminal
$ curl https://api.convert.dev/v1/files?source=upload,inline&limit=20 \  -H "Authorization: Bearer $CV_API_KEY"

How long files are kept

Uploads and outputs are deleted 24 hours after they are made. ttl_s in the JSON that creates a file keeps it for less, and a job's output.ttl_s does the same for its outputs. Neither keeps a file longer.

Uploads that are still kept count against the organization's storage. See Pricing and limits.

Updated 3 November 2026