ATM Cassette Settlement OCR API
Automate the auditing of ATM and cash-recycler terminals. Our engine reads "CASSETTE TOTAL" slips from major vendors (NCR, Diebold, Wincor, Genmega, etc.), differentiating between denomination structures and remaining values. It natively computes mathematical validation (remaining count × denomination = total value) to ensure strict financial accuracy. Beyond printed text, the API effectively transcribes handwritten technician annotations, allowing for seamless reconciliation workflows without manual data entry.
Endpoint
POSThttps://api.structocr.com/v1/atm-cassetteRequest Parameters
Important: This endpoint requires application/json Content-Type. Images must be sent as Base64 strings.
| Parameter | In | Required | Description |
|---|---|---|---|
| x-api-key | Header | Required | Your unique API key generated from the dashboard. |
| Content-Type | Header | Required | Must be set to application/json. |
| img | Body | Required | The Base64 encoded string of the settlement receipt image.
|
Response Schema
The following attributes are extracted into the data object. The engine automatically rejects retail POS formats and executes mathematical verifications on cassette capacities.
| Field | Type | Description |
|---|---|---|
| is_cassette_report | boolean | Returns true if recognized as an audit slip. False if it is a retail receipt. |
| terminal_id | string | null | The printed TERMINAL # or specific device ID. |
| vendor | enum | Guessed machine vendor (e.g., ncr, diebold, wincor, genmega, triton, grg, other, unknown). |
| vendor_confidence | enum | Certainty level (High, Medium, Low). |
| vendor_evidence | string | null | Clues used to infer the vendor, such as specific handwritten notes or layout structures. |
| audit_period | object | Contains start_datetime and end_datetime as ISO 8601 strings. |
| currency | string | null | Guessed ISO currency code, inferred from symbols. |
| cassettes | array of objects | Detailed breakdown for each physical note cassette inside the machine. |
| ↳ cassette_id | string | Identifier for the cassette (e.g., CST1, Type 2). |
| ↳ denomination | number | null | Unit face value of notes loaded in this cassette. |
| ↳ loaded_count | number | Total physical notes loaded into the cassette. |
| ↳ dispensed_count | number | Total physical notes dispensed from the cassette. |
| ↳ rejected_count | number | Total physical notes rejected by the machine. |
| ↳ remaining_count | number | Total physical notes left inside the cassette. |
| ↳ remaining_value | number | null | The printed total financial value remaining in the cassette. |
| ↳ value_check_passed | boolean | null | System-calculated verification: Returns true if (remaining_count * denomination) exactly matches remaining_value. |
| operator_annotations | array of objects | Transcribed handwritten notes (e.g., machine numbers, technician initials) with individual confidence scores. |
| confidence | enum | Overall extraction reliability (High, Medium, Low). |
Code Examples
Request Implementation
curl -X POST https://api.structocr.com/v1/atm-cassette \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"img": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
}'Success Response (200 OK)
{
"success": true,
"data": {
"is_cassette_report": true,
"terminal_id": "T-99824",
"vendor": "ncr",
"vendor_confidence": "High",
"vendor_evidence": "handwritten note reads 'NCR 6622'",
"audit_period": {
"start_datetime": "2025-08-19T10:00:00",
"end_datetime": "2025-08-20T09:34:51"
},
"currency": "USD",
"cassettes": [
{
"cassette_id": "CST1",
"denomination": 20,
"loaded_count": 438,
"dispensed_count": 40,
"rejected_count": 0,
"tested_count": 0,
"remaining_count": 398,
"remaining_value": 7960,
"value_check_passed": true
}
],
"operator_annotations": [
{
"text": "NCR 6622",
"confidence": "Medium"
}
],
"confidence": "High"
}
}Live API Test
Live Demo: ATM Cassette OCR
No registration required. Upload a file to test the extraction.
Drop files here or click to browse
JPG · PNG · WebP · up to 500 files · max 4.5 MB each
Error Responses
400 Bad Request - Invalid Input
{
"status": 400,
"code": "INVALID_REQUEST_FORMAT",
"message":"The image data in 'img' field is malformed. Please check for illegal characters or incorrect Base64 encoding."
}402 Payment Required - Insufficient Credits
{
"status": 402,
"code": "INSUFFICIENT_CREDITS",
"message": "Your account balance is insufficient to complete this operation."
}413 Payload Too Large
The Base64 decoded image size exceeds 4.5MB.
{
"error": "FILE_TOO_LARGE"
}415 Unsupported Media Type
{
"error": "INVALID_CONTENT_TYPE_USE_JSON"
}422 Unprocessable Entity - Policy Violation
{
"status": 422,
"code": "CONTENT_POLICY_VIOLATION",
"message": "The document content could not be processed due to safety policies."
}500 Internal Server Error
{
"status": 500,
"code": "PROCESSING_ERROR",
"message": "An internal error occurred while processing the document..."
}503 Service Unavailable - System Busy
{
"status": 503,
"code": "SYSTEM_BUSY",
"message": "StructOCR is currently processing a high volume of requests..."
}Status Code Definitions
| Code | Error Code | Description |
|---|---|---|
| 200 | SUCCESS | Recognition success |
| 400 | INVALID_REQUEST_FORMAT | Invalid payload or corrupted Base64 structure. |
| 402 | INSUFFICIENT_CREDITS | Account balance too low |
| 413 | FILE_TOO_LARGE | Decoded image exceeds 4.5MB |
| 415 | INVALID_CONTENT_TYPE | Not using application/json |
| 422 | CONTENT_POLICY_VIOLATION | AI safety/policy block |
| 500 | PROCESSING_ERROR | Downstream processing fault |
| 503 | SYSTEM_BUSY | API Rate limit reached |