Skip to main content

Files API Quickstart

Submit a real batch in five minutes. By the end of this guide you will have submitted a single document, polled its status, downloaded its converted result, and submitted a two-item batch, using only your API key. Every step shows cURL, Python, JavaScript / TypeScript, Go, and Java.

Prerequisites

  • An API key. Get one from the Mathpix Console and export it as APP_KEY in your shell.
  • For s3://, gs://, or Azure Blob URLs, a registered data source for the bucket. Public https:// URLs work without any setup.
export APP_KEY="your-app-key"

1. Submit a single document

Use POST /files/v1/uri to submit one document by URL. The request below submits a public PDF and asks for DOCX and Markdown outputs in addition to the default Mathpix Markdown.

curl -X POST https://api.mathpix.com/files/v1/uri \
-H "app_key: $APP_KEY" \
-H 'Content-Type: application/json' \
--data '{
"source_uri": "https://cdn.mathpix.com/examples/cs229-notes1.pdf",
"conversion_formats": { "docx": true, "md": true }
}'
Example response
{
"file_id": "b1c9c3a8-55e4-4a09-b7d0-218ba5de4c4d"
}

Keep the returned file_id; it is how you check status and download results.

2. Check status

Poll GET /files/v1/{file_id} until status is "completed" (or "error"). A typical document moves through pending (just submitted), then split (pages extracted, OCR in progress, with percent_done rising), then completed. The loops below poll every two seconds and stop at a terminal status.

curl -H "app_key: $APP_KEY" \
"https://api.mathpix.com/files/v1/$FILE_ID"

3. Download the result

Once status is completed, request results by extension via GET /files/v1/{file_id}.{ext}. The examples below download the Mathpix Markdown output and the DOCX output requested at submission.

  • Always produced (download without pre-requesting): mmd, lines.json, lines.mmd.json.
  • On request (set in conversion_formats on submission): docx, xlsx, html, tex.zip, md, and others; see the availability table in Supported Formats.
curl -H "app_key: $APP_KEY" \
"https://api.mathpix.com/files/v1/$FILE_ID.mmd" \
-o result.mmd

curl -H "app_key: $APP_KEY" \
"https://api.mathpix.com/files/v1/$FILE_ID.docx" \
-o result.docx

4. Submit many at once

For batches, use POST /files/v1/jobs: up to 200,000 files in a single request. Pass an array of source URIs plus job-wide conversion and OCR options applied to every file. Each file can carry an optional custom_id for your own correlation. job_id is optional (the server generates one if you omit it), but you must supply your own when you use custom_id, as the example below does.

The batch below submits two documents. The second one references a URL that does not exist, which lets step 5 show how failures surface.

curl -X POST https://api.mathpix.com/files/v1/jobs \
-H "app_key: $APP_KEY" \
-H 'Content-Type: application/json' \
--data '{
"job_id": "quickstart-batch",
"files": [
{ "source_uri": "https://cdn.mathpix.com/examples/cs229-notes1.pdf", "custom_id": "cs229" },
{ "source_uri": "https://example.com/manual.pdf", "custom_id": "manual" }
],
"conversion_formats": { "docx": true, "md": true }
}'
Example response
{
"file_count": 2,
"job_id": "quickstart-batch"
}

5. Track the job

Poll GET /files/v1/jobs/{job_id} for status and counters, then list the failed files via GET /files/v1/jobs/{job_id}/files?status=error. In this batch the manual file fails (its URL does not exist), so the counters show one completed and one errored file, and the error listing identifies which one by your custom_id.

curl -H "app_key: $APP_KEY" \
"https://api.mathpix.com/files/v1/jobs/quickstart-batch"

curl -H "app_key: $APP_KEY" \
"https://api.mathpix.com/files/v1/jobs/quickstart-batch/files?status=error"

The job status once every file reaches a terminal state:

Example response (job status)
{
"job_id": "quickstart-batch",
"status": "completed",
"file_count": 2,
"files_completed": 1,
"files_errored": 1,
"created_at": "2026-07-21T18:05:20.519Z",
"modified_at": "2026-07-21T18:06:28.267Z"
}

The error listing identifies the failed file by its custom_id:

Example response (errored files)
{
"files": [
{
"file_id": "f7d3a210-6c4e-49f3-bd5e-8e1c2f4d6b9a",
"filename": "f7d3a210-6c4e-49f3-bd5e-8e1c2f4d6b9a.pdf",
"status": "error",
"custom_id": "manual"
}
],
"next_page_token": null
}

Once the job is completed, download per-file outputs the same way as step 3: GET /files/v1/{file_id}.{ext} for each file_id returned by the listing.

Where to go next