Webhooks and Events
This guide covers handling async document flows, retrying failed documents, and understanding SUNAT error responses.
Async document flow
Section titled “Async document flow”Most SUIT document types use SUNAT’s synchronous sendBill method — you send the request and receive the result immediately. However, Comunicaciones de Baja (voided documents) use the asynchronous sendSummary method.
Sync vs async
Section titled “Sync vs async”| SUNAT Method | Documents | Flow |
|---|---|---|
| sendBill (sync) | Facturas, Boletas, NC, ND, Guias, Retenciones, Percepciones | Request -> immediate response |
| sendSummary (async) | Comunicacion de Baja | Request -> ticket -> poll for result |
Handling async documents
Section titled “Handling async documents”When emitting a voided document, the response includes a ticket number:
{ "id": "cm3vwx234", "ticket": "1708123456789", "status": "SENT"}Poll for the result using the check-ticket endpoint:
curl -X POST https://api.suit.pe/api/documents/cm3vwx234/check-ticket \ -H "Authorization: Bearer sk_live_YOUR_API_KEY"See the Voided Documents reference for the complete polling implementation.
Retrying failed documents
Section titled “Retrying failed documents”If a document fails with status SUNAT_ERROR (SUNAT server was down or returned a temporary error), you can retry the submission:
curl -X POST https://api.suit.pe/api/documents/:id/retry \ -H "Authorization: Bearer sk_live_YOUR_API_KEY"The retry endpoint re-sends the already-signed XML to SUNAT. It does not re-generate or re-sign the document.
Retryable statuses
Section titled “Retryable statuses”| Status | Retryable | Action |
|---|---|---|
SUNAT_ERROR | Yes | POST /api/documents/:id/retry |
SIGN_ERROR | No | Fix certificate configuration, re-emit |
REJECTED | No | Fix data issues, emit a new document |
ERROR | No | Contact support |
Error handling
Section titled “Error handling”HTTP status codes
Section titled “HTTP status codes”| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (document emitted successfully) |
| 204 | No Content (delete successful) |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized (invalid/missing auth) |
| 404 | Not Found |
| 409 | Conflict (duplicate document) |
| 429 | Rate Limited |
| 500 | Server Error |
Error response format
Section titled “Error response format”{ "statusCode": 400, "error": "Bad Request", "message": "Validation error: series must match pattern F\\d{3}"}SUNAT rejection codes
Section titled “SUNAT rejection codes”When SUNAT rejects a document, the response includes the CDR response code and description:
{ "id": "cm3abc123", "status": "REJECTED", "cdrResponseCode": "2329", "cdrDescription": "El tipo de documento de identidad del receptor no es valido"}Common rejection codes:
| Code | Description | How to fix |
|---|---|---|
| 2017 | RUC del receptor no existe | Verify the customer RUC number |
| 2329 | Tipo de doc. identidad no valido | Use the correct identityType code |
| 2370 | Serie no valida | Use F prefix for facturas, B for boletas |
| 3105 | Monto total no coincide | Check IGV calculations (SUIT calculates automatically) |
Rate limits
Section titled “Rate limits”| Scope | Limit | Window |
|---|---|---|
/api/* (API Key/JWT) | 60 requests | 1 minute |
/admin/* (Master Key) | 20 requests | 1 minute |
| General | 100 requests | 1 minute |
When rate limited, the API returns HTTP 429 with a Retry-After header indicating how many seconds to wait.
{ "statusCode": 429, "error": "Too Many Requests", "message": "Rate limit exceeded. Retry after 30 seconds."}