eScanX API Reference
Everything you need to integrate our intelligent document OCR API into your applications.
Authentication
Authenticate your API requests using the X-API-Key header. Get your API key from the dashboard after signing up.
Include your API key in every request:
API Playground
Try the extraction endpoint live. Pick a document type, paste your API key, upload a file, and run a real request.
Drag & drop a file or click to browse
JPEG, PNG, WebP, HEIC, or PDF · max 5 MB
Document Extraction
Extract structured data from documents (receipts, invoices, etc.) via our intelligent OCR engine.
/api/v1/extract/{document_type}Request
Send one document as multipart/form-data. Optionally send an Idempotency-Key header so a retry collects the same extraction instead of billing twice.
Strict typing: the path names the document type you expect. A document of a different type is rejected with 422 — it is never reshaped. Use async jobs if you want a best-effort reshape instead.
Response
The extraction object is nested and document-type-specific — switch the document type above to see each shape.
{
"success": true,
"request_id": "req_abc123def456",
"extraction_id": "ext_9f3c1a7b2d84",
"processing_time_ms": 1250,
"document_type": "receipt",
"extraction": {
"merchant": {
"name": "Helsinki Market",
"address": {
"city": "Helsinki",
"country_code": "FI"
},
"business_id": "1234567-8"
},
"buyer": {
"name": "Aurora Digital Oy",
"business_id": "7788990-1"
},
"transaction": {
"date": "2025-01-15",
"time": "14:30",
"receipt_number": "A-4471"
},
"items": [
{
"line_number": 1,
"description": "Coffee 250g",
"quantity": 1,
"unit_price": 4.9,
"item_total": 4.9
}
],
"financial": {
"subtotal": 43.1,
"tax": [
{
"rate": 25.5,
"amount": 4.75
}
],
"tax_total": 4.75,
"total": 47.85,
"currency": "EUR"
},
"payments": [
{
"method": "card",
"card_type": "Visa",
"card_last4": "4242",
"amount": 47.85
}
],
"loyalty": {
"card_number": "9012345678",
"points_earned": 12,
"points_balance": 340
},
"metadata": {
"sub_type": "grocery",
"confidence": {
"overall": 0.97
}
}
},
"error": null,
"credit_cost": 1,
"item_count": 1
}Errors on this endpoint
Extraction History
Every synchronous extraction is recorded. Use these endpoints to fetch a result again later, to recover after a 504, and to review what you have run.
List Extractions
/api/v1/extractionsList your sync extractions. Same filters and response envelope as GET /jobs.
Item fields
Get an Extraction
/api/v1/extractions/{extraction_id}One extraction with its result, retrievable for your whole retention window. This is how you collect a result after a 504 from POST /extract. A still-running extraction is settled opportunistically on read; non-terminal responses carry Retry-After: 3 as a poll-cadence hint.
Extraction Statistics
/api/v1/extractions/statsAggregate counts of your sync extractions. Mirrors GET /jobs/stats.
Cancel an Extraction
/api/v1/extractions/{extraction_id}/cancelCancel only while the extraction is still queued at the engine. Closing the connection is not a cancel — the run completes into history and is billed normally.
Retention
Results and uploaded files are kept for your API retention window, editable in your organization settings and capped by your plan. expires_at is computed when you read it, so changing the setting applies to existing records immediately in both directions. Purged resources answer 404.
Async Jobs
Submit documents for asynchronous extraction. Ideal for large files or batch workflows where you don't need immediate results.
Submit a Job
/api/v1/jobs/{document_type}Submit 1-20 documents for background processing in one request. Returns 202 with one queued job per file.
All-or-nothing: every file is validated and the queue capacity for the whole batch is checked before anything is created. Any violation rejects the entire request and names the file at fault.
Jobs always reshape: document_type is the output shape you asked for, and a differently-typed document is read as what it is and returned in that shape. Strict type matching applies only to synchronous /extract.
202 response
Errors on submit
Check Job Status
/api/v1/jobs/{job_id}Poll the job status until it reaches a terminal state.
Terminal responses include expires_at. After that timestamp the record and the stored file are purged and this endpoint returns 404. The window is your API retention setting, editable in your organization settings.
Webhooks
Instead of polling, provide a webhook_url when submitting a job. Your endpoint will receive a POST request when the job completes or fails. The response includes a webhook_secret for verifying request signatures.
Store the webhook_secret returned in the job submission response. Use it to verify that incoming webhook requests are from eScanX.
List Jobs
/api/v1/jobsList your extraction jobs with optional filters.
Cancel a Job
/api/v1/jobs/{job_id}/cancelCancel a job while it is still queued. Once processing starts the job runs to completion, and a late cancel returns 400 JOB_CANCELLATION_FAILED.
Retry a Job
/api/v1/jobs/{job_id}/retryRetry a failed job. Bumps the extraction attempt and re-queues it. Wrong status or exhausted attempts returns 400 JOB_RETRY_FAILED.
Job Statistics
/api/v1/jobs/statsAggregate counts of your jobs and your remaining queued-job capacity.
Usage Statistics
Check your API usage, quota, and remaining calls for the current billing period.
/api/v1/usageResponse
Health Checks
Monitor the API status with liveness and readiness endpoints. No authentication required.
Liveness Check
/healthReturns OK if the API server is running.
Readiness Check
/health/readyReturns OK if the API and all dependencies (database) are ready to serve requests.
Error Handling
The API uses standard HTTP status codes. Error responses follow the RFC 7807 problem+json format with flat fields.
Error Response Format
Validation Errors (422)
Validation failures return a 422 with a detail array — one entry per invalid field, each with its location, message, and type.
HTTP Status Codes
Rate Limits
API requests are rate-limited per API key to ensure fair usage and platform stability.
How it works
Rate limits are applied per API key. When you exceed the limit, requests return HTTP 429.
Handling Rate Limits
Implement exponential backoff when you receive a 429 response.
SDKs & Libraries
Official SDKs for popular programming languages are coming soon. For now, use our REST API directly with any HTTP client.