Batch convert

POST/v1/convert/batchRequires an API key

Converts many documents with the same options. A failure on one file does not stop the others. See the guide to batch and ZIP.

Request

The body is multipart/form-data.

Field Type Required Description
files file, repeated yes One or more documents, or a .zip archive. Repeat the field once per file
format text no json (default), markdown or html
mode text no sync (default) or async
schema text no A JSON Schema as a JSON string, used only with format=json
webhook_url text no An http(s) URL called when an async batch ends

Limits: up to 100 files and 200 MB in total, 50 MB per file. Files inside a ZIP are converted if their type is supported.

Response

Synchronous (200)

Field Type Description
success boolean true
mode string sync
batch_id string Identifier of the batch
total_files integer Files found in the request (ZIP members included)
successful_files integer Files converted
failed_files integer Files that failed
total_pages_billed integer Pages counted against your quota
output_format string The format used
results array One entry per file, below

Each entry of results:

Field Type Description
file_name string The file
status string success or error
pages integer Pages of the document
ocr_applied boolean OCR was used
schema_applied boolean The schema was applied
input_truncated boolean The text was longer than the extractor limit
data object or string The result (only when success)
error string The reason (only when error)

Asynchronous (202 Accepted)

{
  "batch_id": "5d1c0a7e",
  "status": "pending",
  "total_files": 2,
  "message": "Batch document conversion job accepted and queued for processing.",
  "status_url": "/v1/jobs/5d1c0a7e",
  "webhook_url": null
}

Errors

Status When
400 No files, or invalid format, mode, schema or webhook_url
401 Missing, wrong or revoked API key
402 The monthly page quota is already used up when you send the batch
413 The batch has more than 100 files or exceeds 200 MB, or a file exceeds 50 MB
422 The body is not valid multipart/form-data
429 Rate limit exceeded; see Retry-After

Problems with a single file are reported in its entry of results, not as an HTTP error.

Examples

Convert several files in one request
curl -s https://api.docslice.app/v1/convert/batch \
  -H "Authorization: Bearer $DOCSLICE_API_KEY" \
  -F "files=@notes.txt" \
  -F "files=@contract.txt" \
  -F "format=markdown"
import json
import os
import requests

api_key = os.environ["DOCSLICE_API_KEY"]
names = ["notes.txt", "contract.txt"]

# the same field name ("files") is repeated, once per document
files = [("files", (name, open(name, "rb"), "text/plain")) for name in names]
response = requests.post(
    "https://api.docslice.app/v1/convert/batch",
    headers={"Authorization": f"Bearer {api_key}"},
    files=files,
    data={"format": "markdown"},
    timeout=300,
)

print(json.dumps(response.json(), indent=2))
const fs = require("node:fs");

const form = new FormData();
for (const name of ["notes.txt", "contract.txt"]) {
  // the same field name ("files") is repeated, once per document
  form.append("files", new Blob([fs.readFileSync(name)], { type: "text/plain" }), name);
}
form.append("format", "markdown");

fetch("https://api.docslice.app/v1/convert/batch", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.DOCSLICE_API_KEY}` },
  body: form,
})
  .then((response) => response.json())
  .then((data) => console.log(JSON.stringify(data, null, 2)));
<?php
// PHP's cURL cannot repeat one field name with CURLFile, so the multipart body is written by hand
$boundary = bin2hex(random_bytes(16));
$body = '';
foreach (['notes.txt', 'contract.txt'] as $name) {
    $body .= "--$boundary\r\n"
        . "Content-Disposition: form-data; name=\"files\"; filename=\"$name\"\r\n"
        . "Content-Type: text/plain\r\n\r\n"
        . file_get_contents($name) . "\r\n";
}
$body .= "--$boundary\r\nContent-Disposition: form-data; name=\"format\"\r\n\r\nmarkdown\r\n--$boundary--\r\n";

$curl = curl_init('https://api.docslice.app/v1/convert/batch');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DOCSLICE_API_KEY'),
        "Content-Type: multipart/form-data; boundary=$boundary",
    ],
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 300,
]);
echo curl_exec($curl);
curl_close($curl);
Convert a ZIP archive
curl -s https://api.docslice.app/v1/convert/batch \
  -H "Authorization: Bearer $DOCSLICE_API_KEY" \
  -F "files=@batch.zip" \
  -F "format=markdown"
import json
import os
import requests

api_key = os.environ["DOCSLICE_API_KEY"]

with open("batch.zip", "rb") as handle:
    response = requests.post(
        "https://api.docslice.app/v1/convert/batch",
        headers={"Authorization": f"Bearer {api_key}"},
        files={"files": ("batch.zip", handle, "application/zip")},
        data={"format": "markdown"},
        timeout=300,
    )

print(json.dumps(response.json(), indent=2))
const fs = require("node:fs");

const form = new FormData();
form.append("files", new Blob([fs.readFileSync("batch.zip")], { type: "application/zip" }), "batch.zip");
form.append("format", "markdown");

fetch("https://api.docslice.app/v1/convert/batch", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.DOCSLICE_API_KEY}` },
  body: form,
})
  .then((response) => response.json())
  .then((data) => console.log(JSON.stringify(data, null, 2)));
<?php
$curl = curl_init('https://api.docslice.app/v1/convert/batch');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('DOCSLICE_API_KEY')],
    CURLOPT_POSTFIELDS => [
        'files' => new CURLFile('batch.zip', 'application/zip', 'batch.zip'),
        'format' => 'markdown',
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 300,
]);
echo curl_exec($curl);
curl_close($curl);