Jobs

GET/v1/jobs/{job_id}Requires an API key
GET/v1/jobsRequires an API key

A job is created when you send mode=async to Convert or Batch convert. Read it to see its status and, when it is done, its result. See the guide to asynchronous jobs.

Request

GET /v1/jobs/{job_id} reads one job.

Parameter In Description
job_id path The job_id (or batch_id) returned when you submitted

GET /v1/jobs lists your latest jobs, newest first.

Parameter In Type Description
limit query integer 1 to 100, default 20

Response

Both return a job (the list returns an array of jobs):

Field Type Description
id string The job identifier
status string pending, processing, completed or failed
file_name string The uploaded file
file_type string Its content type
pages_count integer Pages counted
output_format string json, markdown or html
ocr_applied boolean OCR was used
is_batch boolean true for a batch
total_files, successful_files, failed_files integer Counts for a batch
data object, string or null The result once completed; null otherwise
input_truncated boolean The text was longer than the extractor limit
result_expired boolean true when the result was erased (24 hours after completion)
error_message string or null The reason when failed
webhook_url string or null The webhook you asked for
webhook_status string or null delivered or failed for completion events; empty otherwise
created_at, completed_at datetime When the job was created and when it ended
{
  "id": "3f2b8c1e-5d1c-4a7e-9a0b-0c1d2e3f4a5b",
  "status": "completed",
  "file_name": "invoice.pdf",
  "file_type": "application/pdf",
  "pages_count": 1,
  "output_format": "json",
  "ocr_applied": false,
  "is_batch": false,
  "total_files": 1,
  "successful_files": 0,
  "failed_files": 0,
  "data": {"invoice_number": "INV-2847", "total": 1240.0},
  "input_truncated": false,
  "result_expired": false,
  "error_message": null,
  "webhook_url": null,
  "webhook_status": null,
  "created_at": "2026-10-12T09:29:58",
  "completed_at": "2026-10-12T09:30:00"
}

Errors

Status When
401 Missing, wrong or revoked API key
403 The job belongs to another user
404 No job with that id
422 limit is out of range

Examples

Start a job and wait for the result
JOB=$(curl -s https://api.docslice.app/v1/convert \
  -H "Authorization: Bearer $DOCSLICE_API_KEY" \
  -F "file=@invoice.pdf" \
  -F "mode=async" | grep -o '"job_id":"[^"]*"' | cut -d'"' -f4)

for attempt in $(seq 1 60); do
  RESULT=$(curl -s "https://api.docslice.app/v1/jobs/$JOB" -H "Authorization: Bearer $DOCSLICE_API_KEY")
  case "$RESULT" in
    *'"status":"completed"'* | *'"status":"failed"'*) echo "$RESULT"; break ;;
  esac
  sleep 2
done
import json
import os
import time
import requests

api_key = os.environ["DOCSLICE_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}"}

with open("invoice.pdf", "rb") as handle:
    accepted = requests.post(
        "https://api.docslice.app/v1/convert",
        headers=headers,
        files={"file": ("invoice.pdf", handle, "application/pdf")},
        data={"mode": "async"},
        timeout=120,
    ).json()

for _ in range(60):
    job = requests.get(f"https://api.docslice.app/v1/jobs/{accepted['job_id']}", headers=headers, timeout=30).json()
    if job["status"] in ("completed", "failed"):
        break
    time.sleep(2)

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

const headers = { Authorization: `Bearer ${process.env.DOCSLICE_API_KEY}` };

async function main() {
  const form = new FormData();
  form.append("file", new Blob([fs.readFileSync("invoice.pdf")], { type: "application/pdf" }), "invoice.pdf");
  form.append("mode", "async");
  const accepted = await (await fetch("https://api.docslice.app/v1/convert", { method: "POST", headers, body: form })).json();

  let job;
  for (let attempt = 0; attempt < 60; attempt++) {
    job = await (await fetch(`https://api.docslice.app/v1/jobs/${accepted.job_id}`, { headers })).json();
    if (job.status === "completed" || job.status === "failed") break;
    await new Promise((resolve) => setTimeout(resolve, 2000));
  }
  console.log(JSON.stringify(job, null, 2));
}

main();
<?php
function call($url, $options = []) {
    $curl = curl_init($url);
    curl_setopt_array($curl, $options + [
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('DOCSLICE_API_KEY')],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 120,
    ]);
    $body = curl_exec($curl);
    curl_close($curl);
    return json_decode($body, true);
}

$accepted = call('https://api.docslice.app/v1/convert', [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('invoice.pdf', 'application/pdf', 'invoice.pdf'),
        'mode' => 'async',
    ],
]);

for ($attempt = 0; $attempt < 60; $attempt++) {
    $job = call('https://api.docslice.app/v1/jobs/' . $accepted['job_id']);
    if (in_array($job['status'], ['completed', 'failed'], true)) {
        break;
    }
    sleep(2);
}
echo json_encode($job, JSON_PRETTY_PRINT);
List your latest jobs
curl -s "https://api.docslice.app/v1/jobs?limit=5" \
  -H "Authorization: Bearer $DOCSLICE_API_KEY"
import json
import os
import requests

response = requests.get(
    "https://api.docslice.app/v1/jobs",
    headers={"Authorization": f"Bearer {os.environ['DOCSLICE_API_KEY']}"},
    params={"limit": 5},
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
fetch("https://api.docslice.app/v1/jobs?limit=5", {
  headers: { Authorization: `Bearer ${process.env.DOCSLICE_API_KEY}` },
})
  .then((response) => response.json())
  .then((data) => console.log(JSON.stringify(data, null, 2)));
<?php
$curl = curl_init('https://api.docslice.app/v1/jobs?limit=5');
curl_setopt_array($curl, [
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('DOCSLICE_API_KEY')],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
echo curl_exec($curl);
curl_close($curl);