Asynchronous Processing
Use the async API when you want background processing, webhook delivery, or explicit job tracking.
Endpoint
POST /v1/documents/parse/async
Authentication
x-api-key: your_api_key_here
Request Body
Send multipart/form-data.
| Field | Type | Description | Required |
|---|---|---|---|
file | File | Document to process | Yes, unless fileUrl is provided |
templateId | UUID | Existing template ID | Yes |
language | string | Optional OCR language hint | No |
fileUrl | URL | Public file URL to fetch instead of uploading | No |
Supported Formats
- PNG
- JPG / JPEG
- WEBP
- TIFF
- BMP
One File Per Job
The async API currently supports one document per job. Submit separate jobs for multiple files.
Idempotency
Async submissions are deduplicated by:
- user
- template ID
- file contents
If you submit the exact same file again with the same template, Parselyze returns the existing job instead of creating a new one.
Submit a Job
cURL
curl -X POST https://api.parselyze.com/v1/documents/parse/async \
-H "x-api-key: YOUR_API_KEY" \
-F "file=@invoice.pdf" \
-F "templateId=YOUR_TEMPLATE_ID"
Javascript/NodeJS
import { Parselyze } from "parselyze";
const parselyze = new Parselyze(process.env.PARSELYZE_API_KEY);
const job = await parselyze.documents.parseAsync({
file: "./large_document.pdf",
templateId: "YOUR_TEMPLATE_ID"
});
console.log(`Job submitted: ${job.jobId}`);
Example response:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"message": "Document submitted for processing. You will be notified when complete.",
"createdAt": "2026-03-31T10:30:00Z"
}
Duplicate submission example:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"message": "This document has already been submitted. Returning existing job.",
"createdAt": "2026-03-31T10:28:15Z"
}
Check Job Status
GET /v1/jobs/:jobId
cURL
curl -X GET https://api.parselyze.com/v1/jobs/550e8400-e29b-41d4-a716-446655440000 \
-H "x-api-key: YOUR_API_KEY"
Javascript/NodeJS
import { Parselyze } from "parselyze";
const parselyze = new Parselyze(process.env.PARSELYZE_API_KEY);
// Poll for completion
let result;
while (true) {
result = await parselyze.jobs.get(job.jobId);
if (result.status === "completed") {
console.log("Job completed:", result.result);
break;
} else if (result.status === "failed") {
console.error("Job failed:", result.error);
break;
}
console.log(`Status: ${result.status}, waiting...`);
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5s
}
Example 'Processing Job' response:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"fileName": "invoice.pdf",
"templateId": "YOUR_TEMPLATE_ID",
"result": null,
"error": null,
"pageCount": null,
"attempts": 1,
"createdAt": "2026-03-31T10:30:00Z",
"startedAt": "2026-03-31T10:30:05Z",
"completedAt": null
}
Example 'Completed Job' response:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"fileName": "invoice.pdf",
"templateId": "YOUR_TEMPLATE_ID",
"result": {
"invoice": {
"number": "INV-2025-001",
"date": "2025-05-26",
"total": 1250.75
}
},
"error": null,
"pageCount": 1,
"attempts": 1,
"createdAt": "2026-03-31T10:30:00Z",
"startedAt": "2026-03-31T10:30:05Z",
"completedAt": "2026-03-31T10:30:20Z"
}
Example 'Failed Job' response:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"fileName": "invoice.pdf",
"templateId": "YOUR_TEMPLATE_ID",
"result": null,
"error": "Document could not be read.",
"pageCount": 12,
"attempts": 3,
"createdAt": "2026-03-31T10:30:00Z",
"startedAt": "2026-03-31T10:30:05Z",
"completedAt": "2026-03-31T10:31:45Z"
}
Status Values
pendingprocessingretryingcompletedfailed
Webhooks
If you configure a webhook in the dashboard, Parselyze will push document.completed or document.failed events automatically.
See Webhooks.
Current Limitations
- One file per job
- No ZIP support
- Scanned PDFs over 30 pages are not supported yet
When Async Is a Good Fit
- Background workers
- Automation tools
- Polling from your backend
- Webhook-first integrations