Complete API endpoint documentation with cURL and Postman examples
Base URL: https://apiocr.dexaitech.com
Replace with your production URL in production environments.
/auth/loginAuth: None (Public)Authenticate a user and receive a JWT access token. The token should be stored and used for subsequent authenticated requests.
| Header | Value | Required |
|---|---|---|
| Content-Type | text/plain (TOON format) | Required |
| Accept | text/plain | Required |
| Field | Type | Required | Description |
|---|---|---|---|
| string | Required | User's email address | |
| password | string | Required | User's password |
Example:
email:"user@example.com"
password:"yourpassword123"curl -X POST "https://apiocr.dexaitech.com/auth/login" \
-H "Content-Type: text/plain" \
-H "Accept: text/plain" \
-d 'email:"user@example.com"
password:"yourpassword123"'| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | Content-Type | text/plain (TOON format) |
| ✓ | Accept | text/plain |
email:"user@example.com" password:"yourpassword123"
access_token:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
token_type:"bearer"
user_type:"standard"
roles:["user"]/users/registerAuth: None (Public)Create a new user account. After registration, the user can login to receive an access token.
| Header | Value | Required |
|---|---|---|
| Content-Type | text/plain (TOON format) | Required |
| Accept | text/plain | Required |
| Field | Type | Required | Description |
|---|---|---|---|
| first_name | string | Required | User's first name |
| last_name | string | Required | User's last name |
| string | Required | User's email address | |
| password | string | Required | Password (min 8 characters) |
Example:
first_name:"John"
last_name:"Doe"
email:"john.doe@example.com"
password:"securepassword123"curl -X POST "https://apiocr.dexaitech.com/users/register" \
-H "Content-Type: text/plain" \
-H "Accept: text/plain" \
-d 'first_name:"John"
last_name:"Doe"
email:"john.doe@example.com"
password:"securepassword123"'| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | Content-Type | text/plain (TOON format) |
| ✓ | Accept | text/plain |
first_name:"John" last_name:"Doe" email:"john.doe@example.com" password:"securepassword123"
message:"User registered successfully"
user:{
id:"uuid-xxx-xxx"
email:"john.doe@example.com"
first_name:"John"
last_name:"Doe"
api_key:"ak_xxxxxxxxxxxxxx"
}/auth/logoutAuth: JWT Bearer TokenInvalidate the current user session. The JWT token will be blacklisted.
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer YOUR_JWT_TOKEN | Required |
curl -X POST "https://apiocr.dexaitech.com/auth/logout" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | Authorization | Bearer YOUR_JWT_TOKEN |
message:"Logged out successfully"/users/profileAuth: JWT Bearer TokenRetrieve the current authenticated user's profile information including their API key.
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer YOUR_JWT_TOKEN | Required |
| Content-Type | text/plain | Optional |
| Accept | text/plain | Optional |
curl -X GET "https://apiocr.dexaitech.com/users/profile" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Accept: text/plain"| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | Authorization | Bearer YOUR_JWT_TOKEN |
| ✓ | Content-Type | text/plain |
| ✓ | Accept | text/plain |
id:"uuid-xxx-xxx"
email:"john.doe@example.com"
first_name:"John"
last_name:"Doe"
api_key:"ak_xxxxxxxxxxxxxxxxxxxxxx"
user_type:"standard"
roles:["user"]
created_at:"2025-01-20T10:30:00Z"Submit a document once and retrieve its result whenever you want. The document is classified (Qwen 2.5-VL primary, OCR + keyword fallback) and brokered through RabbitMQ to a worker. The endpoint is hit-and-run (asynchronous): you get a request_id back immediately, and the result is persisted and retained so you can fetch it later — whether processing takes seconds or hours.
POST /v1/documents/process-async (file upload or S3/URL). It is classified, stored, and queued on RabbitMQ.202 Accepted immediately with request_id, status: processing, a status_url, a document_url preview, and a poll_interval_seconds hint. (A document classified as other is rejected up front with 422 not_processed.)GET /v1/requests/{request_id} until status: completed (or failed). The result is retained — there is no deadline, so you can retrieve it minutes or hours later without re-uploading.formatted_result. Shape depends on the classified type — see the receipt/invoice/bank-statement schemas below.wait=true to block for the result and receive it inline (200 OK) when it finishes in time; otherwise you get the same 202 and fall back to polling.https://apiocr.dexaitech.com/v1/documentsEvery request requires the external-user API key in the request header.
All responses are TOON-encoded with Content-Type: text/plain (not JSON). Snippets below show the decoded TOON.
Classify a document, broker it through RabbitMQ, process it, and return the extracted result in the same call. Accepts a direct file upload (multipart).
/v1/documents/process-asyncAuth: X-API-KeyA caller-supplied document_type is treated only as a hint — it shapes the description field on the response but does not override the classifier. Documents classified as other are not stored and not queued (HTTP 422).
| Mode | Field | Type | Required | Description |
|---|---|---|---|---|
| Form | file | file | Yes* | The document file (PDF or image). *Or send a JSON body with s3_url/url instead. |
| Form | document_type | string | No | Hint, e.g. InvoicePDF. Only affects the description field. |
| Query / Form / JSON | wait | boolean | No | Default false (hit-and-run → 202). Set true to block for the result and receive it inline (200) when ready in time. Can be passed as a query string (?wait=true, works for both upload modes), a multipart form field, or a JSON body field — the query string wins if more than one is set. |
| JSON | s3_url / url / public_url | string | No | Process a document by URL instead of uploading: private S3, presigned, public-read S3, or any public http(s) URL. |
Upload the file directly. The document_type field is optional and only used as a hint.
curl -X POST "https://apiocr.dexaitech.com/v1/documents/process-async" \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@/path/to/receipt_scan.jpg" \
-F "document_type=InvoiceImage"Response — 202 Accepted (default, hit-and-run). The document is accepted and queued; use status_url to fetch the result later:
request_id: req_77aa11bb22
status: processing
status_url: /v1/requests/req_77aa11bb22
document_url: "https://bucket.s3.eu-west-2.amazonaws.com/uploads/12/abc.pdf?X-Amz-..."
filename: receipt_scan.pdf
document_type: ReceiptPDF
confidence: 0.98
submitted_at: "2026-06-08T10:17:44.882210"
poll_interval_seconds: 5
retry_after: 5
result_retained: true
message: "Document accepted and queued for processing. Retrieve the result anytime via GET status_url by polling until status is 'completed' (or 'failed'). The result is retained and remains available, even hours later."Fetch the result — GET /v1/requests/{request_id}. Poll until status: completed; the extracted data is under formatted_result (shape depends on the classified type), with a fresh document_url:
request_id: req_77aa11bb22
status: completed
filename: receipt_scan.pdf
submitted_at: "2026-06-08T10:17:44.882210"
completed_at: "2026-06-08T10:18:12.553001"
processing_time_ms: 27671
validation: true
document_url: "https://bucket.s3.eu-west-2.amazonaws.com/uploads/12/abc.pdf?X-Amz-..."
formatted_result:
multiple_receipts[1]:
- tableItems[1]{quantity,description,totalAmount,unitPrice,taxAmount,netAmount,discountAmount}:
1,SAUSAGE AND MASH,12.9,12.9,0.0,12.9,0.0
documentId: "268472"
supplierName: THE PLUME OF FEATHERS
customerName: HANNAH
date: 15/08/2025
totalAmount: 12.9
taxAmount: 0.0
netAmount: 12.9
currencyCode: GBPResponse — 200 OK. Only when you submit with wait=true and the worker finishes before the broker timeout; the extracted data is returned inline:
request_id: req_9f8e7d6c5b
status: completed
validation: true
document_type: ReceiptPDF
confidence: 0.98
document_url: "https://bucket.s3.eu-west-2.amazonaws.com/uploads/12/abc.pdf?X-Amz-..."
message: Document processed with status completed.
formatted_result:
multiple_receipts[1]:
- tableItems[1]{quantity,description,totalAmount,unitPrice,taxAmount,netAmount,discountAmount}:
1,SAUSAGE AND MASH,12.9,12.9,0.0,12.9,0.0
documentId: "268472"
supplierName: THE PLUME OF FEATHERS
totalAmount: 12.9
currencyCode: GBP| Field | Type | Description |
|---|---|---|
| request_id | string | Unique id for the request. Use it to fetch the result (GET /v1/requests/{request_id}) and to bind a transaction id. |
| status | string | processing while queued/running; completed when the result is ready; failed on error; not_processed for unsupported docs. |
| status_url | string | (202) Path to poll for the result: /v1/requests/{request_id}. |
| document_url | string | Presigned URL to preview/download the stored document. Regenerated on each status fetch so it never expires. |
| poll_interval_seconds | int | (202) Suggested polling cadence; also sent as the Retry-After header. |
| result_retained | bool | (202) Always true — the result is persisted and stays retrievable after completion. |
| submitted_at / completed_at | datetime | When the request was accepted and when processing finished. |
| processing_time_ms | int | Total processing duration once completed. |
| document_type | string | The classified type the document was processed as. |
| confidence | float | Classifier confidence (0.0–1.0). |
| validation | bool | Mandatory-field validation outcome of the extracted result: true = all mandatory fields present, false = one or more missing. null while still processing / not yet validated. See “Mandatory-field validation” below. |
| formatted_result | object | The extracted data. Shape depends on the classified type (receipt / invoice / bank-statement). Receipts are wrapped in multiple_receipts[]. |
When the classifier cannot identify the document as an invoice, receipt, or bank statement it is not processed — nothing is stored or queued. The classifier's reason (from the Qwen model) is returned.
filename: random_photo.jpg
status: not_processed
document_type: other
confidence: 0.88
message: "Document was not processed because it could not be identified as an invoice, receipt, or bank statement. Reason: Qwen2.5-VL: The image shows a landscape photograph with no financial content."| Status | Body (TOON) | Cause |
|---|---|---|
| 400 | error: "Content-Type must be multipart/form-data" | Unsupported content type. |
| 400 | error: "file is required" | Form mode without a file. |
| 422 | status: not_processed | Document classified as other (see above). |
| 500 | error: "<message>" | Unexpected server error. |
Form mode: Headers → X-API-Key only (Postman sets the multipart boundary automatically). Body → form-data → key file (type: File) and optional key document_type (type: Text).
Toggle wait: add it to the URL as a query string — …/process-async?wait=true to block for the result, or omit it (or ?wait=false) for hit-and-run. This works for both form-data and JSON requests.
The extracted data is returned inline under formatted_result. Keep the request_id to correlate the request or to bind a transaction id (see below).
Retrieve the status and final extracted result for a request. This is the endpoint you poll after a hit-and-run submit. The result is retained, so it can be fetched minutes or hours later without re-uploading.
/v1/requests/{request_id}Auth: X-API-KeyPass the request_id returned by POST /v1/documents/process-async as a path parameter. The request is scoped to the authenticated user — a request_id belonging to another user returns 404.
| Field | Type | Required | Description |
|---|---|---|---|
| request_id | string | Yes | The id returned at submit time, e.g. req_77aa11bb22. |
curl -X GET "https://apiocr.dexaitech.com/v1/requests/req_77aa11bb22" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: text/plain"Response — still processing. Keep polling at poll_interval_seconds until status: completed (or failed). validation stays null until the result is ready:
request_id: req_77aa11bb22
status: processing
filename: receipt_scan.pdf
submitted_at: "2026-06-08T10:17:44.882210"
completed_at: null
processing_time_ms: null
error_message: null
validation: null
document_url: "https://bucket.s3.eu-west-2.amazonaws.com/uploads/12/abc.pdf?X-Amz-..."Response — completed. The extracted data is under formatted_result (shape depends on the classified type), and validation reports whether all mandatory fields are present:
request_id: req_77aa11bb22
status: completed
filename: receipt_scan.pdf
submitted_at: "2026-06-08T10:17:44.882210"
completed_at: "2026-06-08T10:18:12.553001"
processing_time_ms: 27671
error_message: null
validation: true
document_url: "https://bucket.s3.eu-west-2.amazonaws.com/uploads/12/abc.pdf?X-Amz-..."
formatted_result:
multiple_receipts[1]:
- tableItems[1]{quantity,description,totalAmount,unitPrice,taxAmount,netAmount,discountAmount}:
1,SAUSAGE AND MASH,12.9,12.9,0.0,12.9,0.0
documentId: "268472"
supplierName: THE PLUME OF FEATHERS
date: 15/08/2025
totalAmount: 12.9
taxAmount: 0.0
netAmount: 12.9
currencyCode: GBPResponse — failed. error_message carries the reason; validation is false when the result lacks mandatory fields:
request_id: req_77aa11bb22
status: failed
filename: receipt_scan.pdf
submitted_at: "2026-06-08T10:17:44.882210"
completed_at: "2026-06-08T10:18:05.110200"
processing_time_ms: 20228
error_message: "Extraction failed: unreadable document"
validation: false
document_url: "https://bucket.s3.eu-west-2.amazonaws.com/uploads/12/abc.pdf?X-Amz-..."| Status | Detail | Cause |
|---|---|---|
| 404 | Request not found | Unknown request_id, or it belongs to another user. |
| 401 | API key required / Invalid API key | Missing or invalid X-API-Key. |
Every completed document is checked for the mandatory fields of its type. The boolean outcome is surfaced as the validation field on both the wait=true response and the fetch-by-id response. It never alters the extracted data.
validation: true — all mandatory fields for the document type are present.
validation: false — one or more mandatory fields are missing or empty.
validation: null — not yet validated (still processing).
A mandatory field fails validation when it is absent, null, the string "null", an empty string, whitespace-only, an empty list [], or an empty object {}. Numeric fields may be 0 (valid) but never null.
| Type | Top-level fields | Each tableItems entry |
|---|---|---|
| Invoice | supplierName, documentId, date, dueDate, currencyCode, totalAmount, taxAmount, netAmount, discountAmount, tableItems (≥ 1 item) | description, quantity, unitPrice, netAmount, taxAmount, discountAmount, totalAmount |
| Receipt | documentId, supplierName, date, totalAmount, taxAmount, netAmount, discountAmount, currencyCode, tableItems (≥ 1 item) | description, quantity, unitPrice, netAmount, taxAmount, discountAmount, totalAmount |
| Bank statement | bankName, accountHolderName, accountNumber, currencyCode, openingDate, closingDate, openingBalance, closingBalance, tableItems (≥ 1 item) | date, description, creditAmount, debitAmount, balanceAmount |
Receipts wrapped in multiple_receipts[] validate every receipt — validation is true only if all of them pass. Fields outside the lists above (e.g. invoice orderNumber, receipt paymentMethod) are ignored by validation.
/v1/documents/update-transaction-idAuth: X-API-KeyAttach (or overwrite) a caller-supplied transaction_id on an existing processing request. Since the document upload endpoints no longer accept transaction_id as an input, call this endpoint after upload with the returned request_id to correlate the request with your own external transaction. The call is idempotent and scoped to the requests owned by the authenticated user.
| Header | Value | Required |
|---|---|---|
| X-API-Key | YOUR_API_KEY | Required |
| Content-Type | application/json | Required |
| Accept | text/plain | Optional |
| Field | Type | Required | Description |
|---|---|---|---|
| request_id | string | Required | Identifier returned by one of the upload endpoints (e.g. req_abc123def456). |
| transaction_id | string | Required | Caller-supplied identifier to bind to the request. Re-sending the same value is a no-op; sending a different value overwrites the previous one. |
Example:
{
"request_id": "req_abc123def456",
"transaction_id": "tx_abc123def456"
}curl -X POST "https://apiocr.dexaitech.com/v1/documents/update-transaction-id" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"request_id": "req_abc123def456",
"transaction_id": "tx_abc123def456"
}'| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | X-API-Key | YOUR_API_KEY |
| ✓ | Content-Type | application/json |
| ✓ | Accept | text/plain |
{
"request_id": "req_abc123def456",
"transaction_id": "tx_abc123def456"
}success: true
request_id: "req_abc123def456"
transaction_id: "tx_abc123def456"
# Error responses (text/plain, TOON-encoded):
# 400 error: "request_id and transaction_id are required"
# 400 error: "Invalid JSON body"
# 404 error: "Request req_abc123def456 not found"
# 401 error: "API key required" / "Invalid API key"
#
# Notes:
# - Idempotent: re-sending the same payload is safe.
# - Sending a different transaction_id overwrites the previous value.
# - Requests belonging to another user return 404 (not 403) to avoid
# leaking existence./v1/ws/statusAuth: X-API-KeyThe /v1/ws/status WebSocket endpoint provides real-time status updates for document processing requests. Unlike REST polling, this endpoint maintains a persistent connection and pushes updates to your client whenever request status changes, eliminating the need for repeated queries.
When to use: Use WebSocket for interactive user dashboards, progress tracking, or real-time notifications. Use REST polling for batch processing or stateless API integrations.
URL:
wss://apiocr.dexaitech.com/v1/ws/statusAuthentication:
Pass your API key via the X-API-Key header before connection:
X-API-Key: <your_api_key>Connection Lifecycle:
action: connection acknowledgmentClients send JSON messages to control subscriptions and health checks:
Subscribe to Request Updates
Start tracking status updates for a specific request ID.
{
"action": "subscribe",
"request_id": "req_32e69baba8054d018cb5c31f034eca52"
}Unsubscribe from Request Updates
Stop tracking a request (server auto-unsubscribes on terminal status).
{
"action": "unsubscribe",
"request_id": "req_32e69baba8054d018cb5c31f034eca52"
}Keepalive Check (Ping)
Send periodically to prevent inactivity timeout. Server responds with pong.
{
"action": "ping"
}| Action | Required Fields | Purpose |
|---|---|---|
| subscribe | request_id | Start receiving updates for a request |
| unsubscribe | request_id | Stop tracking a request |
| ping | — | Keepalive; server responds with pong |
The server sends control messages and status events to connected clients:
Connection Acknowledgment
Sent immediately after successful authentication.
{
"action": "connection",
"status": "connected",
"message": "Authentication successful. Ready to subscribe."
}Snapshot Event
Current request state sent immediately upon subscription.
{
"event": "snapshot",
"request_id": "req_32e69baba8054d018cb5c31f034eca52",
"status": "PROCESSING",
"message": "processing",
"submitted_at": "2026-03-16T10:00:00Z",
"completed_at": null,
"processing_time_ms": null,
"result_data": null,
"formatted_result": null,
"error_message": null,
"is_terminal": false
}Update Event
Sent whenever request status or result changes.
{
"event": "update",
"request_id": "req_32e69baba8054d018cb5c31f034eca52",
"status": "COMPLETED",
"message": "completed",
"submitted_at": "2026-03-16T10:00:00Z",
"completed_at": "2026-03-16T10:01:23Z",
"processing_time_ms": 83420,
"result_data": {
"document_type": "invoice",
"fields": {
"invoice_number": "INV-1009",
"amount": "1200.00",
"vendor": "Acme Corp"
}
},
"formatted_result": {
"summary": "Invoice INV-1009 from Acme Corp",
"amount": "$1,200.00"
},
"error_message": null,
"is_terminal": true
}Heartbeat Event
Sent every ~5 seconds when no state changes have occurred. Confirms connection is alive.
{
"event": "heartbeat",
"request_id": "req_32e69baba8054d018cb5c31f034eca52",
"status": "PROCESSING",
"message": "processing",
"submitted_at": "2026-03-16T10:00:00Z",
"completed_at": null,
"processing_time_ms": null,
"result_data": null,
"formatted_result": null,
"error_message": null,
"is_terminal": false
}Subscribe Acknowledgment
Confirms subscription success or failure before snapshot is sent.
{
"action": "ack",
"request_id": "req_32e69baba8054d018cb5c31f034eca52",
"success": true,
"message": "Subscription created"
}Pong Response
Server response to client ping, includes server timestamp.
{
"action": "pong",
"timestamp": 1710581325.123
}Per-Request Error Event
Sent when a request operation fails (e.g., permission denied, not found).
{
"action": "error",
"request_id": "req_32e69baba8054d018cb5c31f034eca52",
"error": "Request not found or access denied"
}Unknown Action Error
Sent when client sends unrecognized action.
{
"action": "error",
"error": "Unknown action: invalid_action"
}| Message Type | When Sent | Purpose |
|---|---|---|
| connection | After successful auth | Confirms connection ready |
| snapshot | Immediately on subscribe | Current request state |
| update | When status/result changes | Live status updates |
| heartbeat | Every ~5s (idle) | Confirms socket is active |
| ack | After subscribe/unsubscribe | Operation confirmation |
| pong | In response to ping | Keepalive response |
| error | On request or action failure | Error details |
Every RequestStatusEvent (snapshot, update, heartbeat) contains these fields:
| Field | Type | Always Present | Description |
|---|---|---|---|
| event | string | Yes | One of: "snapshot" | "update" | "heartbeat" |
| request_id | string | Yes | Unique identifier for the request being tracked |
| status | string | Yes | Processing status (see Status Values section) |
| message | string | Yes | Human-readable lowercase status label (e.g., "processing", "completed"). Use for UI display. |
| submitted_at | ISO 8601 | Yes | When the request was submitted (e.g., "2026-03-16T10:00:00Z") |
| completed_at | ISO 8601 | null | Yes | When processing completed (null if still processing) |
| processing_time_ms | integer | null | Yes | Wall-clock milliseconds from submission to completion (null while processing) |
| result_data | object | null | Yes | Raw unprocessed result output (available only when status === "COMPLETED") |
| formatted_result | object | null | Yes | Post-processed, display-ready result (available only when status === "COMPLETED"). Prefer this over result_data for UI rendering. |
| error_message | string | null | Yes | Error details (populated only when status === "FAILED") |
| is_terminal | boolean | Yes | True if status is terminal (COMPLETED, FAILED, CANCELLED, TIMEOUT). After a terminal event, the server auto-unsubscribes. |
The server follows strict timing intervals for polling and keepalive:
Poll Interval: 1.5 seconds
Server checks request status every 1.5 seconds. If status has changed since the last check, an update event is sent.
Heartbeat Interval: 5.0 seconds
If no status change occurs within ~5 seconds, a heartbeat event is sent (with current state). This confirms the connection is alive without broadcasting false updates.
Event Type Selection
update: Sent when status or result changed (detected on poll interval)heartbeat: Sent when nothing changed for 5 seconds (keepalive signal)WebSocket Close Codes
1008 — Policy Violation
JWT authentication failed or expired. Reconnect with a valid token.
1011 — Internal Error
Unexpected server error. Check server logs and retry with exponential backoff.
1000 — Normal Closure
Expected disconnect after all subscriptions completed, or client-initiated close.
Per-Request Errors
If a subscribe/unsubscribe fails, server sends an error event instead of an ack:
{
"action": "error",
"request_id": "req_32e69baba8054d018cb5c31f034eca52",
"error": "Request not found or access denied"
}Distinguishing Errors
action: error JSON message → subscribe/unsubscribe failed for that request IDBest practices for handling disconnections and recovering active subscriptions:
1. Track Active Subscriptions
Maintain a set of currently active request IDs on the client side.
2. Exponential Backoff on Reconnect
Start with 1 second, then 2s, 4s, 8s, etc., up to 60s. Prevents thundering herd on server restart.
3. Re-subscribe After Reconnect
Once the new WebSocket is open, re-issue subscribe messages for all active request IDs. The server will send fresh snapshots.
4. Deduplicate Snapshots
If a snapshot arrives after you've already received updates for that request, ignore the snapshot (compare timestamps or version numbers).
5. Heartbeat Timeout
If no message arrives for 15+ seconds, close and reconnect. Don't wait forever.
| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | X-API-Key | your_api_key |
Step 1: Paste your API key in the X-API-Key header
Step 2: Click Connect to establish WebSocket connection
Step 3: Send subscription message in Message tab:
{
"action": "subscribe",
"request_id": "req_example_id"
}Step 4: Observe snapshot, update, and heartbeat events
/healthAuth: None (Public)Check if the API server is running and healthy. This endpoint is public and requires no authentication.
| Header | Value | Required |
|---|---|---|
| Accept | application/json | Optional |
curl -X GET "https://apiocr.dexaitech.com/health"| ✓ | KEY | VALUE |
|---|---|---|
| ✓ | Accept | application/json |
status:"healthy"
timestamp:"2025-01-27T12:00:00Z"
version:"1.0.0"
uptime_seconds:86400| Status Code | Meaning | Common Causes |
|---|---|---|
200 | Success | Request completed successfully |
201 | Created | Resource created successfully |
400 | Bad Request | Missing required fields, invalid format |
401 | Unauthorized | Missing or invalid token/API key |
403 | Forbidden | Valid auth but insufficient permissions |
404 | Not Found | Resource doesn't exist |
409 | Conflict | Resource already exists (e.g., email taken) |
429 | Rate Limited | Too many requests |
500 | Server Error | Internal server error |
503 | Unavailable | Service temporarily unavailable |
504 | Timeout | Request timed out during processing |
If you have questions or run into issues, check our support resources.