Asynchronous Extraction
Purpose
Section titled “Purpose”Use the canonical async job API for create -> poll -> result.
Endpoints
Section titled “Endpoints”POST /api/v1/extraction-jobsGET /api/v1/extraction-jobs/:idGET /api/v1/extraction-jobs/:id/result
Auth Requirements
Section titled “Auth Requirements”Authorization: api-key <environment-api-key>
Job reads are scoped by the caller’s environment. The job id alone is not sufficient.
Create Job
Section titled “Create Job”- Path:
POST /api/v1/extraction-jobs - Method:
POST
Request Schema
Section titled “Request Schema”Send the same top-level extraction fields used by sync extraction, plus async delivery selection:
filerequiredfilenameoptional for JSON base64 uploadstemplateNamerequired unlessfilterNameis usedfilterNameoptionaldocumentSplittingoptional booleanreturnDocumentsoptional booleanreturnTextoptional booleandocumentReviewoptional whole number from1to99schemaChunkingoptional:autoorcombinedpasswordoptional stringdeliveryModeoptional:pollorwebhook
Optional header:
Idempotency-Key
Contract rules:
- If
deliveryModeis omitted, the runtime defaults topoll - Nested
options.*is rejected delivery.modeis accepted as a compatibility alias fordeliveryMode- An idempotent replay returns the existing job instead of creating a second one
returnBoundingBoxesis deprecated and ignored; new clients should omit itdocumentReviewenables a manual review gate when extracted field confidence is below the threshold
Response Schema
Section titled “Response Schema”New job:
{ "success": true, "job": { "id": "uuid", "status": "queued", "statusUrl": "/api/v1/extraction-jobs/uuid", "retryAfterMs": 5000 }}Idempotent replay:
- HTTP
200 OK X-Idempotent-Replay: true- Same response body shape as normal create
Status Codes
Section titled “Status Codes”202 Acceptedjob created200 OKidempotent replay returned an existing job400 Bad Requestinvalid request shape, invalid delivery mode, or unresolved webhook coverage401 Unauthorizedmissing or invalid API key404 Not Foundrequested template/filter-scoped resource not found409 ConflictsameIdempotency-Keyis currently being created and no completed mapping is available yet
Example Request
Section titled “Example Request”curl -X POST "$BASE_URL/api/v1/extraction-jobs" \ -H "Authorization: api-key $API_KEY" \ -H "Idempotency-Key: inv-1001-upload-1" \ -F "file=@invoice.pdf" \ -F "templateName=invoice" \ -F "deliveryMode=poll"Example Response
Section titled “Example Response”{ "success": true, "job": { "id": "2c0d2f0e-1f4e-4c11-a0d6-64cc7b71697d", "status": "queued", "statusUrl": "/api/v1/extraction-jobs/2c0d2f0e-1f4e-4c11-a0d6-64cc7b71697d", "retryAfterMs": 5000 }}Get Job Status
Section titled “Get Job Status”- Path:
GET /api/v1/extraction-jobs/:id - Method:
GET
Response Schema
Section titled “Response Schema”Queued:
{ "success": true, "job": { "id": "uuid", "status": "queued", "createdAt": "2026-03-12T10:00:00.000Z", "updatedAt": "2026-03-12T10:00:00.000Z", "retryAfterMs": 5000 }}Processing:
{ "success": true, "job": { "id": "uuid", "status": "processing", "createdAt": "2026-03-12T10:00:00.000Z", "updatedAt": "2026-03-12T10:00:20.000Z", "progress": 45, "retryAfterMs": 5000 }}Review required:
{ "success": true, "job": { "id": "uuid", "status": "review_required", "createdAt": "2026-03-12T10:00:00.000Z", "updatedAt": "2026-03-12T10:01:00.000Z", "retryAfterMs": 5000, "resultAvailable": false, "reviewRequiredAt": "2026-03-12T10:01:00.000Z", "reviewThreshold": 92, "reviewFlaggedFieldCount": 3 }}Completed:
{ "success": true, "job": { "id": "uuid", "status": "completed", "createdAt": "2026-03-12T10:00:00.000Z", "updatedAt": "2026-03-12T10:01:03.000Z", "completedAt": "2026-03-12T10:01:03.000Z", "resultAvailable": true, "resultUrl": "/api/v1/extraction-jobs/uuid/result" }}Failed:
{ "success": true, "job": { "id": "uuid", "status": "failed", "createdAt": "2026-03-12T10:00:00.000Z", "updatedAt": "2026-03-12T10:00:45.000Z", "failedAt": "2026-03-12T10:00:45.000Z", "error": { "message": "Document processing failed.", "code": "PROCESSING_ERROR" } }}Status Codes
Section titled “Status Codes”200 OKstatus returned401 Unauthorizedmissing or invalid API key404 Not Foundjob missing or outside the caller’s environment scope429 Too Many Requestsper-job status polling limit exceeded
When a job is review_required, the extraction result is intentionally held
back until the configured review process approves it. Poll the status endpoint
again after review, or wait for the completed webhook if webhook delivery is
enabled.
Get Job Result
Section titled “Get Job Result”- Path:
GET /api/v1/extraction-jobs/:id/result - Method:
GET
Response Schema
Section titled “Response Schema”{ "success": true, "job": { "id": "uuid", "status": "completed", "completedAt": "2026-03-12T10:01:03.000Z" }, "data": { "completionTime": 63.2, "originalName": "invoice.pdf", "processedPages": 3, "documents": [] }}The data payload matches the async extraction result and may include:
completionTimeoriginalNameprocessedPagesdocuments[]with the same document fields used by sync extraction
Status Codes
Section titled “Status Codes”200 OKcompleted result returned401 Unauthorizedmissing or invalid API key404 Not Foundjob missing or outside the caller’s environment scope409 Conflictjob exists but result is not ready yet (RESULT_NOT_READY)409 Conflictjob is awaiting manual review (REVIEW_REQUIRED)409 Conflictjob failed (JOB_FAILED)410 Gonejob completed earlier but the stored result is no longer available (RESULT_EXPIRED)
Example Polling Flow
Section titled “Example Polling Flow”1. Create
Section titled “1. Create”curl -X POST "$BASE_URL/api/v1/extraction-jobs" \ -H "Authorization: api-key $API_KEY" \ -F "file=@invoice.pdf" \ -F "templateName=invoice"2. Poll
Section titled “2. Poll”curl -X GET "$BASE_URL/api/v1/extraction-jobs/$JOB_ID" \ -H "Authorization: api-key $API_KEY"3. Fetch Result
Section titled “3. Fetch Result”curl -X GET "$BASE_URL/api/v1/extraction-jobs/$JOB_ID/result" \ -H "Authorization: api-key $API_KEY"