10. REST API Reference
All operations are available via REST API. Authenticate with X-API-Key header. Interactive docs at /docs (Swagger) and /redoc (ReDoc).
Authentication
# Login (returns session cookie)
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "your-password"}' \
-c cookies.txt
# Or use API key (recommended for automation)
curl http://localhost:8080/api/documents/ \
-H "X-API-Key: ce_your_api_key_here"
Upload & Extract (Single PDF)
# 1. Upload a PDF
curl -X POST http://localhost:8080/api/documents/ \
-H "X-API-Key: ce_xxx" \
-F "[email protected]" \
-F "document_type_id=utility_bill"
# Response:
{ "id": "abc123", "filename": "invoice.pdf", "status": "pending" }
# 2. Run extraction (~$0.04, 30-60 seconds)
curl -X POST http://localhost:8080/api/extractions/run/abc123 \
-H "X-API-Key: ce_xxx"
# Response:
{
"extraction_id": "ext_789",
"success": true,
"steps": [
{"name": "classify", "success": true, "duration_ms": 1200, "cost": {"total_cost": 0.002}},
{"name": "extract", "success": true, "duration_ms": 28000, "cost": {"total_cost": 0.038}},
{"name": "enrich", "success": true, "duration_ms": 15},
{"name": "validate", "success": true, "duration_ms": 3}
],
"extraction_data": { "supplier_name": "SSE", "bills": [...] },
"validation_result": { "errors": [], "warnings": [...] },
"total_cost": { "total_cost": 0.042 },
"total_duration_ms": 29500,
"_confidence": { "overall": 0.87, "low_confidence_fields": [...] }
}
# 3. Reprocess (free — re-run enrichment + validation after editing JSON)
curl -X POST http://localhost:8080/api/extractions/tools/reprocess \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{"extraction_data": {"supplier_name": "SSE", ...}, "document_type_id": "utility_bill"}'
# Response: enriched data + validation + CSV rows (all free)
Direct File Extraction (No Pre-Upload)
# Option A: Multipart file upload (simplest)
curl -X POST http://localhost:8080/api/extractions/tools/extract-file \
-H "X-API-Key: ce_xxx" \
-F "[email protected]" \
-F "document_type_id=utility_bill" \
-F "store_result=true"
# Option B: Base64-encoded bytes (for programmatic use)
curl -X POST http://localhost:8080/api/extractions/tools/extract-bytes \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{
"pdf_base64": "'$(base64 -w0 invoice.pdf)'",
"document_type_id": "utility_bill",
"store_result": false
}'
# Both return the same response format as /run/{doc_id}
# Use store_result=false for stateless extraction (no DB records)
# Use store_result=true to save for later review/comparison
# Python example:
import base64, requests
with open("invoice.pdf", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
resp = requests.post("http://localhost:8080/api/extractions/tools/extract-bytes",
json={"pdf_base64": b64, "document_type_id": "utility_bill"},
headers={"X-API-Key": "ce_xxx"})
data = resp.json()["extraction_data"]
Batch Processing (50% Cost Savings)
# 1. Submit batch job (up to 10,000 PDFs)
curl -X POST http://localhost:8080/api/batch/submit?document_type_id=utility_bill \
-H "X-API-Key: ce_xxx" \
-F "[email protected]" \
-F "[email protected]" \
-F "[email protected]"
# Response:
{
"job_id": "job_abc123",
"batch_api_id": "msgbatch_xxx",
"total_files": 15,
"status": "processing",
"message": "Batch submitted with 15 files. Results may take up to 24 hours."
}
# 2. Check status (poll every few minutes)
curl http://localhost:8080/api/batch/status/job_abc123 \
-H "X-API-Key: ce_xxx"
# Response (processing):
{
"id": "job_abc123",
"status": "processing",
"api_status": "in_progress",
"total_files": 15,
"succeeded": 8,
"failed": 0,
"processing": 7
}
# Response (completed):
{ "id": "job_abc123", "status": "completed", "succeeded": 14, "failed": 1 }
# 3. Retrieve results
curl http://localhost:8080/api/batch/results/job_abc123 \
-H "X-API-Key: ce_xxx"
# Response:
{
"job_id": "job_abc123",
"status": "completed",
"results": [
{ "custom_id": "a1b2c3_0", "filename": "bill1.pdf", "success": true,
"extraction_data": { "supplier_name": "SSE", "bills": [...] } },
{ "custom_id": "d4e5f6_1", "filename": "bill2.pdf", "success": true,
"extraction_data": { ... } },
{ "custom_id": "g7h8i9_2", "filename": "corrupt.pdf", "success": false,
"error": "JSON parse error" }
]
}
# 4. List all batch jobs
curl http://localhost:8080/api/batch/ -H "X-API-Key: ce_xxx"
Webhooks (Event Notifications)
# Create a webhook
curl -X POST http://localhost:8080/api/webhooks/ \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Slack Notification",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"events": "extraction.complete,batch.complete"
}'
# Events: extraction.complete, extraction.failed, batch.complete,
# ground_truth.saved, regression.complete
# Webhook payload (sent as POST to your URL):
{
"event": "extraction.complete",
"timestamp": "2026-03-31T14:30:00",
"data": {
"document_id": "abc123",
"filename": "invoice.pdf",
"document_type": "utility_bill",
"success": true,
"cost": 0.042,
"duration_ms": 29500
}
}
# Test a webhook
curl -X POST http://localhost:8080/api/webhooks/webhook_id/test \
-H "X-API-Key: ce_xxx"
# List / update / delete
curl http://localhost:8080/api/webhooks/ -H "X-API-Key: ce_xxx"
curl -X PUT http://localhost:8080/api/webhooks/id -d '{"is_active": false}'
curl -X DELETE http://localhost:8080/api/webhooks/id
Folder Watcher (Auto-Extraction)
# Start watching a folder (PDFs dropped here are auto-extracted)
curl -X POST http://localhost:8080/api/watcher/start \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{
"watch_dir": "/data/incoming-pdfs",
"document_type_id": "utility_bill",
"poll_interval": 10
}'
# Files are moved to /data/incoming-pdfs/processed/ or /data/incoming-pdfs/failed/
# Check status
curl http://localhost:8080/api/watcher/status -H "X-API-Key: ce_xxx"
# Stop watcher
curl -X POST http://localhost:8080/api/watcher/stop -H "X-API-Key: ce_xxx"
Output Templates & Export
# Create an output template with transforms and aggregations
curl -X POST http://localhost:8080/api/output-templates/ \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{
"document_type_id": "utility_bill",
"name": "BDL Import Format",
"format": "csv",
"field_mappings": [
{"output_name": "Supplier", "source": "supplier_name", "transform": "upper"},
{"output_name": "Bill Date", "source": "bill_date", "transform": "date_format",
"transform_args": {"format": "%d/%m/%Y"}},
{"output_name": "Charge Name", "source": "bills[].charges[].name"},
{"output_name": "Amount", "source": "bills[].charges[].total",
"transform": "round", "transform_args": {"decimals": 2}},
{"output_name": "Calculated", "source": "{quantity} * {rate}"}
],
"aggregations": [
{"column": "Amount", "function": "sum", "label": "Grand Total"},
{"column": "Charge Name", "function": "count", "label": "Row Count"}
]
}'
# Apply template to extraction data
curl -X POST http://localhost:8080/api/output-templates/apply/template_id \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{"extraction_data": {...}, "document_type_id": "utility_bill"}'
# Export as Excel (direct download)
curl -X POST http://localhost:8080/api/output-templates/template_id/export-xlsx \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{"extraction_data": {...}}' -o output.xlsx
# Export as XML
curl -X POST http://localhost:8080/api/output-templates/template_id/export-xml \
-H "X-API-Key: ce_xxx" \
-d '{"extraction_data": {...}}' -o output.xml
# Available transforms
curl http://localhost:8080/api/output-templates/available-transforms
# AI: Generate template from sample CSV
curl -X POST http://localhost:8080/api/output-templates/generate-from-sample \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{
"document_type_id": "utility_bill",
"sample_columns": ["Supplier", "Bill Date", "Amount", "VAT"],
"available_fields": ["supplier_name", "bill_date", "bills[].charges[].total"]
}'
Document Types & Schema
# List all document types
curl http://localhost:8080/api/document-types/ -H "X-API-Key: ce_xxx"
# Create a new type
curl -X POST http://localhost:8080/api/document-types/ \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{
"type_id": "purchase_order",
"display_name": "Purchase Order",
"description": "Standard PO documents",
"schema_fields": [
{"name": "po_number", "type": "string", "required": true},
{"name": "vendor", "type": "string"},
{"name": "line_items", "type": "array", "items": [
{"name": "description", "type": "string"},
{"name": "quantity", "type": "number"},
{"name": "unit_price", "type": "number"}
]}
],
"extraction_prompt": "Extract all data from this purchase order..."
}'
# AI: Generate type from a sample PDF
curl -X POST http://localhost:8080/api/document-types/generate-from-pdf \
-H "X-API-Key: ce_xxx" \
-F "[email protected]" \
-F "description=Hotel invoice with room charges, taxes, and guest details" \
-F "requirements=Extract guest name, dates, room charges, taxes, total"
# Clone a type
curl -X POST http://localhost:8080/api/document-types/utility_bill/clone \
-d '{"new_type_id": "utility_bill_v2", "new_display_name": "Utility Bill v2"}'
# Export/Import config (for sharing between environments)
curl http://localhost:8080/api/document-types/utility_bill/export -o config.json
curl -X POST http://localhost:8080/api/document-types/import \
-H "Content-Type: application/json" -d @config.json
Quality: Ground Truth & Regression
# Save corrected data as ground truth
curl -X POST http://localhost:8080/api/ground-truth/doc_abc123 \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{"corrected_data": {"supplier_name": "SSE Energy", ...}}'
# Response: auto-computed diff against latest extraction
{ "id": "gt_xyz", "correction_count": 3 }
# Run regression test (re-extracts all docs with ground truth)
curl -X POST http://localhost:8080/api/regression/run \
-H "X-API-Key: ce_xxx" \
-H "Content-Type: application/json" \
-d '{"document_type_id": "utility_bill"}'
# Response:
{
"total_documents": 12,
"passed": 11,
"failed": 1,
"summary": { "pass_rate": 0.917, "avg_score": 0.95 },
"results": [
{ "filename": "sse_bill.pdf", "score": 1.0, "status": "pass" },
{ "filename": "edf_bill.pdf", "score": 0.8, "status": "fail",
"comparison": { "mismatch_count": 2, "mismatches": [...] } }
]
}
# AI: Suggest improvements based on corrections
curl -X POST http://localhost:8080/api/ground-truth/doc_abc123/suggest-improvements \
-d '{"document_type_id": "utility_bill"}'
Integration Workflow Example
# Complete automation flow:
# 1. Set up webhook for notifications
curl -X POST /api/webhooks/ -d '{
"name": "Process Complete", "url": "https://your-system.com/webhook",
"events": "extraction.complete"
}'
# 2. Start folder watcher (or submit via API)
curl -X POST /api/watcher/start -d '{
"watch_dir": "/incoming", "document_type_id": "utility_bill"
}'
# 3. Drop PDFs into /incoming/ → auto-extracted → webhook fires
# 4. Your system receives webhook, fetches results:
curl /api/documents/ # list docs
curl /api/extractions/document/doc_id # get extraction
curl -X POST /api/output-templates/apply/template_id \
-d '{"extraction_data": ...}' # format output
curl -X POST /api/output-templates/template_id/export-xlsx \
-d '{"extraction_data": ...}' -o out.xlsx # Excel export