Issue document
POST /api/v1/facturas
Issues an electronic tax document (comprobante electrónico) (FE, TE, NC, or ND) and queues it for submission to Hacienda. The response is immediate, with status procesando; the final status arrives later via webhook or by polling GET /facturas/{clave}.
Authentication and permissions
| Attribute | Value |
|---|---|
| Scheme | API key (X-Api-Key) |
| Required scope | facturas:write for tipo FE/TE — notas:write for tipo NC/ND. See Scopes. |
| Idempotent | Yes (with the Idempotency-Key header) |
| Rate limit | 120 req/min per API key |
Headers
POST /api/v1/facturas HTTP/1.1
Host: api.pos.lxsyscr.com
X-Api-Key: lxs_live_a1b2c3d4_001122...
Content-Type: application/json
Idempotency-Key: 4f1c8a8a-2c4f-4b5e-9c2a-1234567890ab
Accept: application/jsonRequest body
See FacturaApiRequestDto for the complete schema.
Minimal example (FE):
{
"tipo": "FacturaElectronica",
"idUsuario": 7,
"cliente": { "idCliente": 42 },
"condicionVenta": "01",
"medioPago": "01",
"moneda": "CRC",
"lineas": [
{ "idProducto": 100, "cantidad": 2 }
]
}Complete example (FE with discount, tax exemption, USD):
{
"tipo": "FacturaElectronica",
"idUsuario": 7,
"cliente": { "idCliente": 42 },
"condicionVenta": "02",
"plazoCredito": 30,
"medioPago": "04",
"moneda": "USD",
"tipoCambio": 670.50,
"codigoActividad": "722002",
"comentario": "Pedido #1234 — Cliente VIP",
"lineas": [
{
"idProducto": 100,
"cantidad": 3,
"precioUnitario": 50.00,
"montoDescuento": 5.00,
"naturalezaDescuento": "Volumen >= 3 unidades"
},
{
"idProducto": 101,
"cantidad": 1,
"idExoneracion": 7
}
],
"referencias": []
}The line with
idExoneracionsends no amount at all: the server calculates how much to exempt from the customer’s exemption and the product’s VAT rate. The7comes from theexoneracionesarray ofGET /clientes/{identificacion}. ThemontoExoneracionfield still exists in the contract but is ignored — see Tax exemptions.
Responses
201 Created
HTTP/1.1 201 Created
Location: /api/v1/facturas/50615012600310112345600100001010000000123456789012
Content-Type: application/json{
"clave": "50615012600310112345600100001010000000123456789012",
"numeroConsecutivo": "00100001010000000123",
"tipoDocumento": "01",
"estadoHacienda": "procesando",
"totalComprobante": 169.50,
"moneda": "USD",
"fechaEmision": "2026-05-15T15:32:11Z"
}400 Bad Request
Validation failed. Examples:
{ "error": "Debe incluir al menos una línea." }{ "error": "Producto 999 no encontrado." }{ "error": "Cliente 42 no encontrado." }{ "error": "Factura electrónica requiere cliente." }If a line sends idExoneracion and the exemption isn’t valid for that customer, issuance is rejected instead of silently invoicing with full VAT — see Tax exemptions:
{ "error": "Línea 1: la exoneración 7 no existe o no pertenece al cliente 42." }{ "error": "Línea 1: la exoneración 7 está inactiva." }{ "error": "Línea 1: la exoneración 7 venció el 10/01/2026." }{ "error": "Línea 1: se indicó 'idExoneracion' 7 pero el documento no tiene cliente. La exoneración pertenece a un cliente registrado; envíe 'cliente.idCliente' o 'cliente.identificacion'." }When issuing an NC or ND, the reason for the reference must be a code from the catalog, sent in referencias[0].codigo or referencias[0].razon. Free text alone won’t issue it:
{ "error": "La razón de la referencia no es un código válido (razon='Cargo por interés moratorio'). Envíe el código de 2 dígitos en 'codigo' o en 'razon', tomado del catálogo: 01 (Anula documento de referencia), 02 (Corrige texto de documento de referencia), 04 (Referencia a otro documento), … " }401 Unauthorized
Missing, malformed, or revoked API key.
{ "error": "API key ausente, inválida o revocada." }403 Forbidden
Valid API key but without the scope required for the issued tipo.
{ "error": "La API key no tiene el scope 'facturas:write', requerido para emitir este tipo de comprobante." }{ "error": "La API key no tiene el scope 'notas:write', requerido para emitir este tipo de comprobante." }Important: A key with
facturas:writebut withoutnotas:writecan issue FE and TE, but gets403when attemptingtipo: "NotaCredito"or"NotaDebito". See Scopes.
409 Conflict
Idempotency-Key reused with a different body. See Idempotency.
{ "error": "Idempotency-Key reutilizada con body distinto." }413 Payload Too Large
Body exceeds 256 KB.
429 Too Many Requests
HTTP/1.1 429 Too Many Requests
Retry-After: 38{ "error": "Rate limit excedido. Reintenta en 38 segundos." }500 Internal Server Error
{ "error": "Error interno emitiendo el comprobante." }501 Not Implemented
Document type not yet supported (historical case, no longer applies).
{ "error": "Funcionalidad no disponible en esta versión." }Operational notes
- Issuance is asynchronous with respect to submission to Hacienda. A
201means “queued for submission,” not “accepted by Hacienda.” - The PDF and the XML become available right after local issuance, without waiting for Hacienda’s response.
- If no webhook was configured, you must poll
GET /facturas/{clave}to learn the final status.