Document AI API (Total Vision)
REST API for document extraction, classification, splitting, cropping, custom model training, and webhook callbacks.
Document AI API (Total Vision)
Total Vision is the document AI API that powers Total Access document processing. Send a PDF or image, receive structured, validated JSON. This page documents the REST API for extraction, classification, splitting, cropping, custom model training, and webhook callbacks.
Base URL
- Production:
https://api.totalaccess.co.za/api/v1/vision - Sandbox:
https://sandbox-api.totalaccess.co.za/api/v1/vision
Authentication
All endpoints require authentication via one of:
| Method | Header | Use Case |
|---|---|---|
| API Key | Authorization: Bearer <API_KEY> | Server-to-server integration |
| OAuth 2.0 | Authorization: Bearer <ACCESS_TOKEN> | Third-party apps acting on behalf of a user |
API keys can be generated from the Total Integration module. Keys are scoped — create a key
with only vision:extract and vision:classify scopes for least-privilege access.
Never expose your API key in client-side code. All calls must be made from a server.
Credit System
Total Vision uses a credit-based pricing model:
| Bundle | Credits | Price | Per Page |
|---|---|---|---|
| Trial | 30 | Free | — |
| Small | 50 | R175 | R3.50 |
| Medium | 100 | R300 | R3.00 |
| Large | 500 | R1,250 | R2.50 |
| Enterprise | 1,000 | R1,750 | R1.75 |
Credits never expire. Each page processed costs 1 credit. Multi-page documents cost 1 credit per page. Classification-only requests cost 0.25 credits. Splitting costs 0.5 credits per detected document boundary.
Check your credit balance at any time:
curl -X GET https://api.totalaccess.co.za/api/v1/vision/credits \
-H "Authorization: Bearer $API_KEY"{
"success": true,
"credits_remaining": 847,
"credits_used_total": 153,
"bundle": "enterprise"
}Endpoints
| Method | Path | Description |
|---|---|---|
POST | /vision/extract | Extract structured data from a document |
POST | /vision/classify | Classify document type without extraction |
POST | /vision/split | Split a multi-page document into individual documents |
POST | /vision/crop | Detect and crop multiple documents from a single page |
POST | /vision/pipeline | Chain multiple operations in a single API call |
GET | /vision/models | List available pre-trained and custom models |
POST | /vision/models | Create a custom extraction model |
POST | /vision/models/:id/train | Upload training documents for a custom model |
PATCH | /vision/results/:id | Submit corrections for continuous learning |
GET | /vision/credits | Check remaining credit balance |
GET | /vision/usage | Usage statistics and STP metrics |
Extract
Extract structured data from a document. This is the primary endpoint — it handles classification, field extraction, line-item parsing, and validation in a single call.
curl -X POST https://api.totalaccess.co.za/api/v1/vision/extract \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_type": "invoice",
"file_base64": "'$(base64 -w0 invoice.pdf)'",
"extract_line_items": true,
"confidence_threshold": 0.85,
"validation": {
"check_vendor_against_master": true,
"check_tax_rates": true
}
}'Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
file_base64 | string | Yes* | — | Base64-encoded file content (PDF, PNG, JPG, WebP, HEIC, TIFF) |
file_url | string | Yes* | — | Public URL to fetch the document from (alternative to file_base64) |
document_type | string | No | auto | Pre-trained type: invoice, receipt, bank_statement, id_document, passport, drivers_license, proof_of_address, resume, contract, purchase_order, delivery_note, bill, credit_note, supplier_statement, custom:<model_id>. Use auto for automatic classification. |
extract_line_items | boolean | No | true | Extract table/line-item data |
confidence_threshold | float | No | 0.50 | Minimum confidence to include a field in the response (0-1) |
validation | object | No | {} | Validation options (see below) |
webhook_url | string | No | — | URL to receive async results (enables async mode) |
language_hint | string | No | auto | ISO 639-1 code (e.g. en, af, zu, ar). Auto-detected if omitted. |
crop | boolean | No | false | Auto-crop multiple documents from a single image before extraction |
split | boolean | No | false | Split multi-page PDFs into individual documents before extraction |
* Either file_base64 or file_url is required.
Validation Object
| Parameter | Type | Default | Description |
|---|---|---|---|
check_vendor_against_master | boolean | false | Cross-check extracted vendor name against your supplier master |
check_tax_rates | boolean | false | Validate tax rates against SARS tables |
gl_code_suggestion | boolean | false | Suggest GL codes based on vendor and line-item description |
custom_rules | array | [] | Custom validation rules (see Custom Rules below) |
Response
{
"success": true,
"request_id": "vis_req_a1b2c3d4",
"document_type": "invoice",
"document_type_confidence": 0.98,
"fields": {
"invoice_number": {
"value": "INV-2023-0847",
"confidence": 0.99,
"bbox": { "x": 72, "y": 45, "width": 180, "height": 22, "page": 1 }
},
"date": {
"value": "2023-07-01",
"confidence": 0.97,
"bbox": { "x": 72, "y": 75, "width": 90, "height": 20, "page": 1 }
},
"due_date": {
"value": "2023-07-31",
"confidence": 0.95,
"bbox": { "x": 72, "y": 100, "width": 90, "height": 20, "page": 1 }
},
"vendor": {
"value": "Summit Office Supplies",
"confidence": 0.96,
"bbox": { "x": 72, "y": 120, "width": 220, "height": 24, "page": 1 }
},
"total_amount": {
"value": 1448.18,
"confidence": 0.99,
"bbox": { "x": 400, "y": 580, "width": 120, "height": 22, "page": 1 }
},
"currency": { "value": "ZAR", "confidence": 0.92 },
"payment_terms": { "value": "Net 30", "confidence": 0.88 },
"subtotal": { "value": 1334.73, "confidence": 0.98 },
"tax": { "value": 113.45, "confidence": 0.97, "tax_rate": 0.15 }
},
"line_items": [
{
"description": { "value": "A4 Copy Paper (5-ream case)", "confidence": 0.94 },
"quantity": { "value": 12, "confidence": 0.99 },
"unit_price": { "value": 32.99, "confidence": 0.97 },
"total": { "value": 395.88, "confidence": 0.98 }
}
],
"validation": {
"vendor_verified": true,
"tax_rates_valid": true,
"gl_code_suggestions": [
{ "line": 0, "gl_code": "5000", "gl_name": "Office Supplies", "confidence": 0.91 }
]
},
"credits_used": 1,
"processing_time_ms": 1234
}Every field includes a confidence score (0-1) and a bbox (bounding box) with pixel
coordinates and page number. Use these to build human-in-the-loop review for low-confidence
fields only — typically fields below 0.85.
Classify
Identify the document type without performing full extraction. Useful for routing documents to different workflows.
curl -X POST https://api.totalaccess.co.za/api/v1/vision/classify \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "file_base64": "'$(base64 -w0 doc.pdf)'" }'{
"success": true,
"document_type": "invoice",
"confidence": 0.98,
"alternatives": [
{ "type": "bill", "confidence": 0.82 },
{ "type": "receipt", "confidence": 0.15 }
],
"credits_used": 0.25
}Split
Detect document boundaries in a multi-page PDF or batch scan and split into individual documents.
curl -X POST https://api.totalaccess.co.za/api/v1/vision/split \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "file_base64": "'$(base64 -w0 batch.pdf)'" }'{
"success": true,
"documents": [
{ "index": 0, "pages": [1, 2], "type": "invoice", "confidence": 0.96 },
{ "index": 1, "pages": [3], "type": "receipt", "confidence": 0.94 },
{ "index": 2, "pages": [4, 5, 6], "type": "bank_statement", "confidence": 0.99 }
],
"credits_used": 1.5
}Crop
Detect and isolate multiple documents scanned on a single page.
curl -X POST https://api.totalaccess.co.za/api/v1/vision/crop \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "file_base64": "'$(base64 -w0 scan.jpg)'" }'Returns an array of cropped images (base64-encoded), each containing a single document.
Pipeline (Chaining)
Chain multiple operations — classify, split, crop, extract — in a single API call. This is the most efficient way to process complex documents.
curl -X POST https://api.totalaccess.co.za/api/v1/vision/pipeline \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_base64": "'$(base64 -w0 batch.pdf)'",
"steps": [
{ "action": "split" },
{ "action": "classify" },
{ "action": "extract", "options": { "extract_line_items": true } }
]
}'The pipeline executes steps sequentially for each detected document and returns an array of extraction results. Chaining is free — you only pay credits for the extraction step, not for splitting or classification within the pipeline.
Custom Models
Train extraction models on your own document layouts when the pre-trained types don't cover your needs.
Create a Custom Model
curl -X POST https://api.totalaccess.co.za/api/v1/vision/models \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Custom Supplier Invoice — Acme Corp",
"document_type": "custom",
"fields": [
{ "name": "acme_order_number", "type": "string", "required": true },
{ "name": "acme_plant_code", "type": "string", "required": false },
{ "name": "line_items", "type": "table", "columns": ["code", "description", "qty", "price"] }
]
}'Upload Training Documents
curl -X POST https://api.totalaccess.co.za/api/v1/vision/models/vis_model_xxx/train \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"documents": [
{ "file_base64": "'$(base64 -w0 sample1.pdf)'", "annotations": { "acme_order_number": "ORD-001" } },
{ "file_base64": "'$(base64 -w0 sample2.pdf)'", "annotations": { "acme_order_number": "ORD-002" } }
]
}'Upload 5-10 sample documents with annotations to train the model. Training typically completes within 10-30 minutes. You'll receive a webhook notification when the model is ready.
Use a Custom Model
curl -X POST https://api.totalaccess.co.za/api/v1/vision/extract \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_type": "custom:vis_model_xxx",
"file_base64": "'$(base64 -w0 new_invoice.pdf)'"
}'Continuous Learning (RAG)
When you correct an extraction, submit the corrected data to improve future accuracy. The AI uses these corrections to build a retrieval-augmented knowledge base.
curl -X PATCH https://api.totalaccess.co.za/api/v1/vision/results/vis_req_a1b2c3d4 \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"corrections": {
"vendor": "Summit Office Supplies (Pty) Ltd",
"invoice_number": "INV-2023-0847-A"
}
}'Corrections are stored and referenced via RAG when processing similar documents in the future. The more corrections you submit, the more accurate the model becomes for your specific document layouts.
Async Processing & Webhooks
For large documents or batch processing, use async mode with webhook callbacks.
curl -X POST https://api.totalaccess.co.za/api/v1/vision/extract \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_base64": "'$(base64 -w0 large_batch.pdf)'",
"webhook_url": "https://your-app.com/webhooks/vision",
"async": true
}'When extraction completes, we send an HMAC-signed POST request to your webhook URL:
{
"event": "vision.extract.completed",
"request_id": "vis_req_a1b2c3d4",
"document_type": "invoice",
"fields": { "...": "..." },
"line_items": [],
"credits_used": 12,
"processing_time_ms": 4567,
"timestamp": "2026-08-05T10:30:00Z"
}Webhook Signature Verification
Every webhook payload is signed with HMAC-SHA256. Verify the signature using your API key:
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, apiKey) {
const expected = crypto
.createHmac('sha256', apiKey)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Failed deliveries are retried 5 times with exponential backoff (1s, 5s, 30s, 2m, 10m) before going to a dead-letter queue. You can view and replay failed deliveries in the dashboard.
Usage & Metrics
Track your straight-through processing (STP) rate, accuracy trends, and credit consumption.
curl -X GET "https://api.totalaccess.co.za/api/v1/vision/usage?from=2026-07-01&to=2026-08-01" \
-H "Authorization: Bearer $API_KEY"{
"success": true,
"period": { "from": "2026-07-01", "to": "2026-08-01" },
"totals": {
"documents_processed": 1247,
"credits_used": 1583,
"avg_processing_time_ms": 1340,
"stp_rate": 0.73
},
"by_document_type": [
{ "type": "invoice", "count": 450, "avg_confidence": 0.96, "stp_rate": 0.81 },
{ "type": "receipt", "count": 380, "avg_confidence": 0.97, "stp_rate": 0.85 },
{ "type": "bank_statement", "count": 120, "avg_confidence": 0.98, "stp_rate": 0.70 }
],
"accuracy_trend": [
{ "week": "2026-W27", "avg_confidence": 0.94 },
{ "week": "2026-W28", "avg_confidence": 0.95 },
{ "week": "2026-W29", "avg_confidence": 0.96 }
]
}Rate Limits
| Tier | Requests/min | Concurrent async jobs |
|---|---|---|
| Free | 60 | 5 |
| Business | 200 | 20 |
| Professional | 500 | 100 |
| Enterprise | Custom | Custom |
Rate limit headers are included in every response:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Remaining requests in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
SDKs
Node.js
npm install @totalaccess/vision-sdkimport { TotalVision } from '@totalaccess/vision-sdk';
const vision = new TotalVision({ apiKey: process.env.TOTAL_VISION_API_KEY });
const result = await vision.extract({
documentType: 'invoice',
fileBase64: pdfBase64,
extractLineItems: true,
confidenceThreshold: 0.85,
});
console.log(result.fields.invoice_number.value); // "INV-2023-0847"
console.log(result.fields.total_amount.value); // 1448.18
console.log(result.lineItems.length); // 4Python
pip install totalaccess-visionfrom totalaccess_vision import TotalVision
vision = TotalVision(api_key=os.environ['TOTAL_VISION_API_KEY'])
result = vision.extract(
document_type='invoice',
file_base64=pdf_base64,
extract_line_items=True,
confidence_threshold=0.85,
)
print(result.fields['invoice_number'].value) # "INV-2023-0847"
print(result.fields['total_amount'].value) # 1448.18
print(len(result.line_items)) # 4PHP
composer require totalaccess/vision-sdkuse TotalAccess\Vision\TotalVision;
$vision = new TotalVision($_ENV['TOTAL_VISION_API_KEY']);
$result = $vision->extract([
'document_type' => 'invoice',
'file_base64' => $pdfBase64,
'extract_line_items' => true,
]);Error Handling
| Status | Error Code | Description |
|---|---|---|
| 400 | invalid_file | File is corrupt, unsupported, or exceeds 50MB |
| 400 | invalid_document_type | Specified document type is not recognised |
| 401 | unauthorized | Missing or invalid API key |
| 402 | insufficient_credits | Not enough credits to process the request |
| 403 | forbidden | API key lacks required scope |
| 422 | validation_failed | Document failed validation rules |
| 429 | rate_limited | Rate limit exceeded — retry after X-RateLimit-Reset |
| 500 | extraction_failed | Internal error during extraction — request is not charged |
{
"success": false,
"error": "insufficient_credits",
"message": "You have 0 credits remaining. Purchase credits at https://totalaccess.co.za/products/total-vision",
"credits_remaining": 0
}Extraction failures are not charged. If the API returns a 5xx error, no credits are deducted from your account. You are only charged for successful processing.
Next Steps
- Public Data API — Integrate extracted data into Total Access work items
- Outbound Webhooks — Configure webhook delivery and retry policies
- AI Agent Bridge — Expose document extraction to AI agents via MCP
- Authentication — API keys, OAuth 2.0, and scopes