Asynchronous jobs
A synchronous request holds the connection until the answer is ready. For long documents, large batches or workflows that should not wait, use asynchronous mode: send mode=async, receive a job_id at once, and fetch the result when it is ready.
The flow
- Submit.
POST /v1/convert(or/v1/convert/batch) withmode=async. The answer is202 Acceptedwith ajob_id,status: "pending"and astatus_url. - Wait. The job moves from
pendingtoprocessingtocompleted(orfailed). - Fetch.
GET /v1/jobs/{job_id}returns the job, with the result indataonce it iscompleted. Or pass awebhook_urlwhen you submit and DocSlice calls you when the job ends (see Webhooks).
curl -s https://api.docslice.app/v1/convert \
-H "Authorization: Bearer $DOCSLICE_API_KEY" \
-F "file=@invoice.pdf" \
-F "format=json" \
-F "mode=async"
import json
import os
import requests
api_key = os.environ["DOCSLICE_API_KEY"]
with open("invoice.pdf", "rb") as handle:
response = requests.post(
"https://api.docslice.app/v1/convert",
headers={"Authorization": f"Bearer {api_key}"},
files={"file": ("invoice.pdf", handle, "application/pdf")},
data={"format": "json", "mode": "async"},
timeout=120,
)
print(response.status_code) # 202: accepted, the work continues in the background
print(json.dumps(response.json(), indent=2))
const fs = require("node:fs");
const form = new FormData();
form.append("file", new Blob([fs.readFileSync("invoice.pdf")], { type: "application/pdf" }), "invoice.pdf");
form.append("format", "json");
form.append("mode", "async");
fetch("https://api.docslice.app/v1/convert", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.DOCSLICE_API_KEY}` },
body: form,
}).then(async (response) => {
console.log(response.status); // 202: accepted, the work continues in the background
console.log(JSON.stringify(await response.json(), null, 2));
});
<?php
$curl = curl_init('https://api.docslice.app/v1/convert');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('DOCSLICE_API_KEY')],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('invoice.pdf', 'application/pdf', 'invoice.pdf'),
'format' => 'json',
'mode' => 'async',
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
echo curl_getinfo($curl, CURLINFO_RESPONSE_CODE) . PHP_EOL; // 202: accepted, the work continues in the background
echo $body;
curl_close($curl);
Poll until it ends
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);
Polling every couple of seconds is plenty. Stop when status is completed or failed, and give up after a sensible number of attempts.
Job statuses
status |
Meaning |
|---|---|
pending |
Accepted, waiting to start |
processing |
Being converted |
completed |
Done: the result is in data |
failed |
It did not finish: the reason is in error_message |
What a job contains
id, status, file_name, file_type, pages_count, output_format, ocr_applied, is_batch with total_files, successful_files and failed_files, data, input_truncated, result_expired, error_message, webhook_url, webhook_status, created_at and completed_at.
Results are kept for 24 hours
The content of a finished job is erased 24 hours after it completed. The job record stays, so you can still see its status and page count, but data becomes null and result_expired is true. Save the result on your side as soon as you receive it.
Listing your jobs
GET /v1/jobs returns your latest jobs, newest first. Use limit (1 to 100, default 20).
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);
You can only read your own jobs: asking for another user's job returns 403, and an unknown id returns 404.