Production API
Document Processing API
Upload documents, receive structured business data asynchronously, and recover results by document ID.
What the service provides
- Secure document intake and validation
- Asynchronous processing and status tracking
- Structured line-item extraction
- Per-upload callback URLs
- Caller metadata returned with results
- Result recovery when a callback is missed
- Tenant-scoped API keys and permissions
- A stable integration contract independent of the underlying processing engine
Authentication
Keep API keys in server-side secrets and send them as Bearer tokens.
Authorization: Bearer ds_live_your_secret_key
Upload a document
POST https://datascribe.app/api/client/upload
| Field | Required | Description |
|---|---|---|
| file | Yes | PDF or supported image, up to 50 MB. |
| webhook_url | Recommended | Public HTTP(S) callback URL for this upload. Query parameters are preserved. |
| metadata | Recommended | A valid JSON string returned with processing events and results. |
curl --fail-with-body -sS \
-X POST 'https://datascribe.app/api/client/upload' \
-H "Authorization: Bearer ${DATASCRIBE_API_KEY}" \
-F "file=@${PDF_FILE};type=application/pdf" \
-F "webhook_url=${CALLBACK_URL}" \
-F 'metadata={"v":1,"import_id":"YOUR-IMPORT-ID","flow":"standard","source":"pdf"}'Immediate response
{
"success": true,
"documentId": "DOCUMENT-UUID",
"status": "pending",
"message": "Document uploaded successfully. Processing has been queued."
}This acknowledges the upload. It is not the final extraction result. Store the documentId immediately.
Callback events
The exact callback URL supplied with the upload is used for all events, including its query parameters.
document.receivedThe document was accepted.
document.processingExtraction is in progress.
document.completedThe final structured result is available.
document.failedProcessing ended with an error.
{
"event": "document.completed",
"documentId": "DOCUMENT-UUID",
"status": "completed",
"timestamp": "2026-08-27T12:00:10.000Z",
"metadata": { "v": 1, "import_id": "YOUR-IMPORT-ID", "flow": "standard", "source": "pdf" },
"result": {
"extraction": {
"totalHT": 42.50,
"items": [
{ "rank": 1, "sku": "ITEM-001", "description": "Product description", "quantity": 10, "unitPrice": 4.25, "amount": 42.50 }
]
},
"processingTime": 8.4,
"totalItems": 1,
"rankSource": "printed",
"pageCount": 5,
"confidence": 1,
"checks": {
"lineArithmetic": { "checked": 1, "matching": 1, "mismatchedRanks": [] },
"documentTotal": { "printedTotalHT": 42.50, "sumOfLineAmounts": 42.50, "matches": true },
"lineCount": { "returned": 1, "expectedFromPrintedRanks": 1, "missing": 0 }
},
"reread": null
}
}rank is the line number printed on the source document, copied as-is: gaps are possible and meaningful. When the document prints no line numbers, rank falls back to a 1..N reading order and result.rankSource is "sequential" instead of "printed". amount is the line total printed on the document excluding VAT, and totalHT the document's printed pre-VAT total; total remains the VAT-inclusive total.
checks reports what is arithmetically verifiable in the result: which lines satisfy quantity × unitPrice == amount (mismatchedRanks lists those that do not), whether the line amounts add up to totalHT, and whether any printed line is missing. confidence is derived from those checks only, and is null when nothing is verifiable — no line amounts, no printed total, no line numbers. pageCount is the real page count of the document.
Lines flagged by checks are read a second time before the result is sent. reread reports what that pass changed: corrected lists each field it replaced, rejected lists lines whose re-read did not add up and was therefore discarded. It is null when no line needed a second look.
Extraction is probabilistic. Values may be null or require human validation when source documents are incomplete or difficult to read.
Recover a result
GET https://datascribe.app/api/client/documents/{documentId}
Use this endpoint whenever a final callback is missing. Callback delivery alone must not be the only recovery mechanism.
curl --fail-with-body -sS \
"https://datascribe.app/api/client/documents/${DATASCRIBE_DOCUMENT_ID}" \
-H "Authorization: Bearer ${DATASCRIBE_API_KEY}"pendingprocessingcompletedfailedError handling
| Status | Meaning | Recommended action |
|---|---|---|
| 400 | Invalid request or metadata | Correct the request. |
| 401 | Invalid or expired key | Verify the server-side secret. |
| 403 | Insufficient scope | Verify key permissions. |
| 404 | Unknown document for this tenant | Verify the documentId. |
| 413 | File too large | Reduce or split the file. |
| 422 | Unsupported format | Use a supported file type. |
| 429 | Rate limit reached | Retry with exponential backoff. |
| 500 | Temporary service error | Retry with backoff, then contact support. |
Need help with an integration?
Contact us for custom extraction fields, workflow review, and production onboarding.
Contact support