{
"success": false,
"statusCode": 400,
"path": "/api/master?module=pathology",
"timestamp": "2026-09-07T04:11:45.928Z",
"message": "Unsupported file type \"report.xyz\" for pathology module. Supported types: PDF, HL7, XML, JSON, CSV, Parquet, and Images (PNG, JPEG, HEIC, HEIF, AVIF, WEBP, BMP, TIFF).",
"error": "UNSUPPORTED_FILE_TYPE",
"code": "UNSUPPORTED_FILE_TYPE",
"type": "validation"
}When success is false, the data field is absent. Rejected uploads include a machine-readable code and a type ("validation" for file-type errors, "billing" for subscription/usage errors) so you can branch programmatically without parsing the message string.
If you send multiple files in one request and any file is an unsupported type, the entire request is rejected and no file is processed.
When the upload is rejected for a billing or usage reason, the response is HTTP 402 Payment Required with type: "billing". The code field identifies the specific cause:
code | Meaning |
|---|---|
SUBSCRIPTION_EXPIRED | Your subscription for this module has expired (or you have no active subscription). Renew to resume uploads. |
MODULE_SUBSCRIPTION_MISSING | You have no subscription for the module you're uploading to. |
SUBSCRIPTION_INACTIVE | A subscription exists for this module but is not currently active. |
PAGE_LIMIT_EXCEEDED | You have used all pages in your plan and no overage is available. |
SPEND_CAP_REACHED | Processing another page would exceed your configured spend cap. |
PILOT_QUOTA_EXCEEDED | Your pilot transformation quota is exhausted. |
Example (SUBSCRIPTION_EXPIRED):
{
"success": false,
"statusCode": 402,
"path": "/api/master?module=pathology",
"timestamp": "2026-09-07T04:11:45.928Z",
"message": "Your pathology subscription has expired",
"error": "SUBSCRIPTION_EXPIRED",
"code": "SUBSCRIPTION_EXPIRED",
"type": "billing"
}Example (SPEND_CAP_REACHED):
{
"success": false,
"statusCode": 402,
"path": "/api/master?module=pathology",
"timestamp": "2026-09-07T04:11:45.928Z",
"message": "Spend cap reached. Cannot process more pages.",
"error": "SPEND_CAP_REACHED",
"code": "SPEND_CAP_REACHED",
"type": "billing"
}For every 402, code and message always describe the same cause. Subscriptions are per-module: an active subscription for another module does not permit uploads to a module whose subscription has expired.
{
"success": false,
"statusCode": 401,
"path": "/api/master?module=pathology",
"timestamp": "2026-04-02T08:26:13.716Z",
"message": "Invalid API token format",
"error": "Unauthorized"
}Three distinct message values are possible:
| Message | Cause |
|---|---|
"API token required" | Authorization header is missing entirely |
"Invalid API token format" | Header present but token doesn't match the expected format |
"Invalid API token" | Token is correctly formatted but not found or account is inactive |
Returned when a required parameter is missing or invalid — for example, the module query parameter is absent.
{
"success": false,
"statusCode": 400,
"path": "/api/master",
"timestamp": "2026-09-07T04:11:45.928Z",
"message": "Query parameter 'module' is required. Use: 'pathology', 'wearable', or 'medical'",
"error": "Bad Request"
}Returned when an unexpected error occurs while processing the request. This indicates a problem on our side, not with your request — retry after a short delay, and if it persists, contact support with the timestamp and path.
{
"success": false,
"statusCode": 500,
"path": "/api/master?module=pathology",
"timestamp": "2026-09-07T04:11:45.928Z",
"message": "Internal server error",
"error": "Internal Server Error"
}When processing fails, JondaX POSTs an error payload to your callback endpoint.
| Code | Message |
|---|---|
JX2001 | We couldn't read the text in the image you uploaded. |
JX2002 | The image format you uploaded isn't suitable for text recognition. |
JX2005 | The file isn't a blood test result. |
JX3002 | We do not support transforming data in the language you uploaded yet. |
JX3003 | We had trouble understanding the meaning of the original data. |
| Field | Type | Description |
|---|---|---|
customerId | integer | Your account identifier. Always present. |
uploadId | string | The upload ID of the failed file. Always present. |
fileName | string | Original uploaded filename. Always present. |
errorCode | string | Error code (see table above). |
errorMessage | string | Human-readable error description. |
Results | array | Always present but empty ([]) in error callbacks. |
POST /api/results HTTP/1.1
Host: api.example.com
Content-Type: application/json
[api-header]: [api-key]
{
"customerId": 16,
"uploadId": "a24d4b93-5062-41fb-95b1-b85f5765ae91",
"fileName": "4434.png",
"errorCode": "JX2005",
"errorMessage": "The file isn't a blood test result.",
"Results": []
}The status endpoint (GET /api/v1/status/:uploadId) can return the following errors:
Returned when the uploadId does not exist or the upload has passed the 30-day retention window and been purged.
{
"message": "UploadId not found or expired",
"error": "Not Found",
"statusCode": 404
}{
"message": "Upload has expired and data has been purged",
"error": "Not Found",
"statusCode": 404
}Returned when the uploadId exists but was created by a different customer's API key.
{
"message": "UploadId belongs to a different customer",
"error": "Forbidden",
"statusCode": 403
}Returned when the API key is missing or invalid on the status endpoint.
{
"message": "Missing API key",
"error": "Unauthorized",
"statusCode": 401
}{
"message": "Invalid API key",
"error": "Unauthorized",
"statusCode": 401
}| Symptom | Likely cause | Fix |
|---|---|---|
401 — "API token required" | Authorization header missing | Add Authorization: Bearer <token> to every request |
401 — "Invalid API token format" | Token format wrong | Check for extra spaces, quotes, or missing Bearer prefix |
401 — "Invalid API token" | Token not recognised or account inactive | Verify the token in the Integration page; regenerate if needed |
401 on status polling | API key missing or invalid | Use the same API key from the Integration page in Authorization: Bearer <key> |
403 on status polling | Wrong API key for this upload | Use the API key that was active when the file was uploaded |
404 on status polling | Upload ID doesn't exist or expired | Verify the uploadId value; check if 30-day retention has passed |
400 — "Query parameter 'module' is required..." | Missing/invalid module parameter | Add ?module=pathology (or wearable/medical) to the request URL |
400 — code: "UNSUPPORTED_FILE_TYPE" | File format not accepted | Convert to a supported format and retry |
402 — code: "SUBSCRIPTION_EXPIRED" / "MODULE_SUBSCRIPTION_MISSING" / "SUBSCRIPTION_INACTIVE" | No active subscription for this module | Renew or activate your pathology subscription on the Integration page |
402 — code: "PAGE_LIMIT_EXCEEDED" / "SPEND_CAP_REACHED" / "PILOT_QUOTA_EXCEEDED" | Plan usage exhausted or spend cap reached | Upgrade your plan, raise your spend cap, or wait for the next billing period |
500 — "Internal server error" | Unexpected error on our side | Retry after a short delay; if it persists, contact support with the timestamp and path |
| Upload accepted but no callback received | Callback URL unreachable or misconfigured | Verify endpoint URL, availability, and auth header/key on the Integration page |
Callback delivery exhausted on status | All 3 retry attempts failed | Check your endpoint's availability and response codes; contact support to retrieve the stored result |