Batch Image Processing
Process multiple images in a single request. This endpoint is for images only — for multi-page documents use PDF processing instead.
Only use the batch API when your workload is not latency sensitive. For immediate responses use single image endpoints.
Submit a batch
- cURL
- Python
- TypeScript
- Go
- Java
curl -X POST https://api.mathpix.com/v3/batch \
-H "app_id: APP_ID" \
-H "app_key: APP_KEY" \
-H "Content-Type: application/json" \
--data '{
"urls": {
"inverted": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/inverted.jpg",
"algebra": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/algebra.jpg"
},
"formats": ["latex_simplified"]
}'
import requests
base_url = "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/"
r = requests.post("https://api.mathpix.com/v3/batch",
json={
"urls": {
"algebra": base_url + "algebra.jpg",
"inverted": base_url + "inverted.jpg"
},
"formats": ["latex_simplified"]
},
headers={
"app_id": "APP_ID",
"app_key": "APP_KEY",
"content-type": "application/json"
},
timeout=30
)
reply = r.json()
print(reply) # {"batch_id": 17}
const base = "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/";
const response = await fetch("https://api.mathpix.com/v3/batch", {
method: "POST",
headers: {
app_id: "APP_ID",
app_key: "APP_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
urls: {
inverted: base + "inverted.jpg",
algebra: base + "algebra.jpg",
},
formats: ["latex_simplified"],
}),
});
const { batch_id } = await response.json();
console.log(`Batch ID: ${batch_id}`);
body := bytes.NewBufferString(`{
"urls": {
"inverted": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/inverted.jpg",
"algebra": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/algebra.jpg"
},
"formats": ["latex_simplified"]
}`)
req, _ := http.NewRequest("POST", "https://api.mathpix.com/v3/batch", body)
req.Header.Set("app_id", "APP_ID")
req.Header.Set("app_key", "APP_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
result, _ := io.ReadAll(resp.Body)
fmt.Println(string(result)) // {"batch_id": 17}
HttpClient client = HttpClient.newHttpClient();
String body = """
{
"urls": {
"inverted": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/inverted.jpg",
"algebra": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/algebra.jpg"
},
"formats": ["latex_simplified"]
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mathpix.com/v3/batch"))
.header("app_id", "APP_ID")
.header("app_key", "APP_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response:
{
"batch_id": 17
}
Poll for results
Wait approximately one second per five images, then GET the batch results:
- cURL
- Python
- TypeScript
- Go
- Java
curl https://api.mathpix.com/v3/batch/17 \
-H "app_id: APP_ID" \
-H "app_key: APP_KEY"
import requests, time
headers = {"app_id": "APP_ID", "app_key": "APP_KEY"}
batch_id = "17"
time.sleep(5) # wait for processing
r = requests.get(f"https://api.mathpix.com/v3/batch/{batch_id}", headers=headers)
print(r.json())
const headers = { app_id: "APP_ID", app_key: "APP_KEY" };
const batchId = "17";
await new Promise((r) => setTimeout(r, 5000));
const response = await fetch(`https://api.mathpix.com/v3/batch/${batchId}`, { headers });
console.log(await response.json());
time.Sleep(5 * time.Second)
req, _ := http.NewRequest("GET", "https://api.mathpix.com/v3/batch/17", nil)
req.Header.Set("app_id", "APP_ID")
req.Header.Set("app_key", "APP_KEY")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
result, _ := io.ReadAll(resp.Body)
fmt.Println(string(result))
HttpClient client = HttpClient.newHttpClient();
Thread.sleep(5000);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mathpix.com/v3/batch/17"))
.header("app_id", "APP_ID").header("app_key", "APP_KEY").GET().build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Before completion, results may be empty or partial. When complete:
{
"keys": ["algebra", "inverted"],
"results": {
"algebra": {
"detection_list": [],
"detection_map": {
"contains_chart": 0,
"contains_diagram": 0,
"contains_graph": 0,
"contains_table": 0,
"is_blank": 0,
"is_inverted": 0,
"is_not_math": 0,
"is_printed": 0
},
"latex_simplified": "12 + 5 x - 8 = 12 x - 10",
"latex_confidence": 0.99640350138238,
"position": {
"height": 208,
"top_left_x": 0,
"top_left_y": 0,
"width": 1380
}
},
"inverted": {
"detection_list": ["is_inverted", "is_printed"],
"latex_simplified": "x ^ { 2 } + y ^ { 2 } = 9",
"latex_confidence": 0.99982263230866
}
}
}
Use v3/text behavior
Set ocr_behavior: "text" to process images with v3/text behavior instead of the default v3/latex. Options can be set at the top level or per image:
Top-level options:
{
"urls": {
"inverted": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/inverted.jpg",
"algebra": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/algebra.jpg"
},
"ocr_behavior": "text",
"formats": ["text", "html", "data"],
"data_options": { "include_asciimath": true }
}
Per-image options:
{
"urls": {
"inverted": {
"url": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/inverted.jpg",
"ocr_behavior": "text",
"formats": ["text", "html", "data"],
"data_options": { "include_asciimath": true }
},
"algebra": {
"url": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/algebra.jpg",
"ocr_behavior": "text",
"formats": ["text", "html", "data"],
"data_options": { "include_asciimath": true }
}
}
}
Use callbacks
Receive results automatically when the batch completes:
{
"urls": {
"inverted": "https://raw.githubusercontent.com/Mathpix/api-examples/master/images/inverted.jpg"
},
"formats": ["latex_simplified"],
"callback": {
"post": "https://your-server.com/webhook",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
Even with a callback, there is no guarantee it will succeed (e.g., due to transient network failure). Always poll as a fallback.
Workflow
- Submit a batch of image URLs — returns a
batch_id - Poll results with
GET /v3/batch/{batch_id}(wait ~1 second per 5 images) - Results contain an OCR result object for each image key
Next steps
- POST v3/batch reference — Full request parameters, response schema, and callback object
- Process an Image — For single image processing