The Spanish version is the authoritative reference. View in Spanish
📬 Response and error handling
Regardless of the channel (REST or WebSocket), xPOS Core returns a JSON object with two parts: a common core that always appears and an optional subset that depends on the country. Each country's sheet indicates which fields appear and how to interpret them.
This page describes the standard xPOS response, which is JSON and has a fixed structure. If your system needs to receive the response with a different structure — your own XML, a different JSON — that is solved with the custom response, which is a separate mechanism and does not alter anything described here.
Full response example
This is the full shape of the response: it includes all possible fields. Values appear as null when the country or the operation does not apply them.
{
"transactionId": null,
"message": null,
"custom_response": null,
"error_description": null,
"stage": null,
"number": null,
"docNumber": null,
"output": null,
"signedXml": null,
"input": null,
"barcodeText": null,
"barcodeBase64": null,
"countryIdentificationCode": null,
"statusCode": null,
"statusDescription": null,
"statusMessage": null,
"applicationResponse": null,
"timeGeneration": null,
"timeValidation": null,
"contingencyCode": null
}Core fields (all countries)
When message is Operation Error (or Operation Successful with an observation in code 200), the stage and error_description fields indicate exactly what happened. See the Error handling section for the integration contract and the full code catalog for the recommended action per stage.
Optional fields by country
Visual code (QR / PDF417)
Chile uses PDF417 and only returns
barcodeBase64. The rest of the countries use QR and return both fields.
Tax identification
Tax authority echo
These fields appear when the tax authority responds synchronously to the submission. Countries with an asynchronous response (Chile, Paraguay) do not return them in the initial response — they are queried later via /api/v1/status.
Contingency
Each country has its own values. An automatic contingency is activated by xPOS when it cannot communicate with the tax authority; a manual one is declared by the issuer according to the tax authority's rules, for example when regularizing a paper receipt. The dashboard's manual contingency is not one of the latter: it emulates an internet outage, so it answers the automatic internet-outage or issuer-contingency code. The details are in each country's sheet:
| Country | Automatic | Manual |
|---|---|---|
| Colombia | 03 and 07 (issuer contingency); 04 and 08 (DIAN contingency). They match the document type generated | — |
| Costa Rica | 03 (no internet) | 02 (contingency: replaces the paper receipt) |
| El Salvador | 1 (Ministry of Finance system unavailable); 3 (issuer internet failure) | 2 (issuer system unavailable); 4 (power supply failure); 5 (other, declared by the POS) |
| Guatemala | 01 (issuer contingency) | — |
| Panama | 01 (issuer contingency) | — |
| Peru | 1, with the reason ContingencyTypeCode 01 (issuer internet outage) | 3 (regularized paper receipt), with a reason from 02 to 07 |
| Dominican Republic | 1 (internet outage) | 2 (documents with series B) |
| Chile and Paraguay | Not used | Not used |
contingencyCodeA document in contingency answers 200, just like an accepted one. To tell them apart, use contingencyCode: the message text is descriptive only.
Presence matrix by country
| Field | CL | CO | CR | SV | GT | PA | PE | PY | DO |
|---|---|---|---|---|---|---|---|---|---|
barcodeText | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓² | ✓ | ✓ |
barcodeBase64 | ✓¹ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓² | ✓ | ✓ |
countryIdentificationCode | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
statusCode / statusDescription / statusMessage | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓³ | – | ✓ |
applicationResponse | – | ✓ | ✓ | ✓ | – | ✓ | ✓ | – | ✓ |
timeGeneration | – | ✓ | ✓ | ✓ | – | ✓ | ✓ | – | ✓ |
timeValidation | – | ✓ | ✓ | ✓ | – | ✓ | – | – | – |
contingencyCode | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | ✓ |
¹ Chile returns barcodeBase64 in PDF417 format (not QR).
² Since version 2.7.1, Peru returns the SUNAT QR (Annex B) and adds its own field valorResumen (hash of the signed XML); in dispatch guides, also gre.qrUrl and gre.transportEnabled. Up to 2.7.0, barcodeText was not returned and barcodeBase64 arrived as the string "null". See the Peru sheet.
³ Peru emits statusCode and statusMessage (read from the SUNAT/OSE CDR), but not statusDescription. It also returns the Peru-specific field series — see the Peru sheet.
Each country sheet includes a response mock with illustrative values. See Communication by country.
🚦 Error handling
xPOS-Core expresses any anomalous result — validation error, tax authority rejection, contingency fallback or scheduled retry — through three core fields of the response: message, stage and error_description. The full catalog of stages lives in xPOS-Core error codes; this section describes the integration contract that the POS must respect to react to each case.
Response contract
When document processing does not end in success, xPOS populates the three fields like this (errors before processing have another shape: see Errors before processing):
Example of an error response: see the Response — Error tab at the top of this page.
Stage code vs. HTTP status
The stage is a body field and is not the HTTP status, but the HTTP status of POST /api/v1/process-documents is derived from it: TIMEOUT_ERROR_503 → 503, COMPLIANCE_ERROR_510 → 510 and any other processing error → 400. That is why the code of each row in the error catalog is the HTTP status the POS receives.
| HTTP | When | Countries |
|---|---|---|
200 | Document processed: accepted by the tax authority, in contingency or queued for deferred submission | All |
400 | Error in the request or the document, in foliation or signing, or rejection by the tax authority | All |
403 | xPOS blocked: technical or financial block, or expired version | All |
404 | The origin does not correspond to an installed issuer, or the onboarding's transformation sheets are missing | All |
409 | Signing certificate expired or without an expiry date, or internal failure resolving the issuer | All (the certificate is not validated this way in Chile) |
422 | The body is not valid JSON | All |
500 | Internal failure building the error response (SERVER_PROCESS_REQUEST_STAGE) | All |
503 | TIMEOUT_ERROR_503: the tax authority did not respond in time and the document may have arrived | Colombia, Costa Rica, El Salvador, Guatemala, Dominican Republic and Peru |
510 | COMPLIANCE_ERROR_510: the tax authority answered something that is not a valid response, or received the document and did not process it | Colombia and Peru |
A document in contingency also answers 200: it is distinguished by contingencyCode in the body. In Chile and Paraguay the 200 means the document was queued and the tax authority's verdict arrives later. A rejection by the tax authority answers 400, with the authority response stage (DIAN_RESPONSE_STAGE, ET_RESPONSE_STAGE, MEGAPRINT_RESPONSE_STAGE, …).
Peru classifies every response from its tax authority as 200, 503, 510 or 400, so the HTTP status already tells the POS what to do. The WebSocket channel has no HTTP status: it returns the same JSON with its stage.
Errors before processing
Before processing the document, xPOS validates the request, the issuer, the device status and the certificate. These errors do not go through the stage catalog and, except for the issuer ones, carry no stage or transactionId. The order is that of the validations:
| HTTP | Cause | Body |
|---|---|---|
422 | The body is not valid JSON | { error } |
400 | origin is missing and the device has more than one issuer installed | { error, message, error_description, stage } with stage = SET_CONTEXT_STAGE |
404 | The origin does not correspond to any installed issuer | Same |
409 | Internal failure resolving the issuer | Same |
403 | xPOS blocked: technical or financial block, or expired version | { errors: [] } |
400 | country, operation, typeDoc, env or inputType invalid for the country, or the body is empty or does not match the inputType | { errors: [] } or { message } |
404 | The onboarding's transformation sheets are missing | { errors: [] } |
409 | Signing certificate expired —even after reloading the configuration— or without an expiry date (does not apply to Chile) | { message } |
What the POS has to do
Each row of the catalog carries a suggested action that the POS should adopt as a contract (in Peru, the action is given directly by the HTTP code):
| Action | POS decision |
|---|---|
| Correct and retry | The input is responsible. Correct the data indicated by error_description and resend POST /api/v1/process-documents. |
| Retry | Transient error (network, token, temporary validation). Resend as is. |
| Reload and retry | The xPOS local state is not healthy (folios, certificates, templates). Call PUT /api/v1/reobtain-config and resend. |
| Correct | Review the case without resending automatically (the tax authority already responded and leaves the action to the operator). |
| End of process | No POS action required (duplicate document, automatic retry scheduled in xPOS, or manual escalation to Gosocket). |
When the POS loses the response
If the network was cut or the POS restarted before processing the response, there is no need to resend the document: the GET /api/v1/status endpoint retrieves the original response from the transactionId or the docNumber — see Status re-retrieval. For deeper diagnosis (audit, escalation), the operational logs at GET /api/v1/db-data/logs are filtered by uuid or free metadata.