Tax exemptions
Some customers (governments, NGOs, free trade zones) hold a tax exemption resolution for VAT issued by the Ministry of Finance (Hacienda).
Exemption (exoneración) ≠ exempt (exención). The exemption resolution (exoneración) applies to a customer with a valid resolution; the exempt status (exención) applies to the product. This section covers exemption resolutions only.
The real mechanism: idExoneracion, never an amount
To exempt a line you send idExoneracion (the id of an exemption already registered for that customer), and nothing else. The exempted amount is never sent: the server calculates it from the product’s real VAT rate and the percentage authorized on the exemption, capping the result so a line never exempts more tax than it actually carries.
montoExoneracionexists in the contract but is IGNORED. It’s a field left over from an earlier version of the API: it’s still accepted in the JSON so integrators who already send it don’t get a validation error, but its value is never used for anything — it isn’t added, subtracted, or reflected on the document. IfmontoExoneracionis sent withoutidExoneracion, the line comes out fully taxed, with no error and no warning. SeeFacturaApiLineaDtofor the field’s full detail.
{
"idProducto": 101,
"cantidad": 1,
"idExoneracion": 7
}Where idExoneracion comes from
The integrator gets it from GET /api/v1/clientes/{identificacion}, in the response’s exoneraciones array (ClienteApiResponseDto). Each item carries its idExoneracion, the authorized percentage, issue/expiration dates, and a vigente boolean already resolved by the server:
{
"idCliente": 46,
"identificacion": "117890123",
"...": "...",
"exoneraciones": [
{
"idExoneracion": 7,
"tipoDocumento": "03",
"tipoDocumentoNombre": "Exoneración compras autorizadas de Zona Franca",
"numeroDocumento": "EX-2026-00412",
"nombreInstitucion": "PROCOMER",
"fechaEmision": "2026-01-10T00:00:00Z",
"fechaExpiracion": "2027-01-10T00:00:00Z",
"porcentajeExoneracion": 100,
"estado": true,
"vigente": true
}
]
}Exemptions themselves (creation, editing, validity) are not managed through the API — they’re registered from the POS. GET /clientes/{identificacion} only exposes them so the integrator knows which id to send.
Validation when issuing
The id is validated against the document’s customer and the exemption’s validity; one that doesn’t pass doesn’t silently issue with full VAT — it returns 400:
| Cause | When it happens |
|---|---|
idExoneracion was sent without a cliente on the document | The exemption belongs to a registered customer; it doesn’t apply to a Tiquete Electrónico with no recipient. |
| The id doesn’t exist or doesn’t belong to the document’s customer | The idExoneracion belongs to another customer, or doesn’t exist in the tenant. |
The exemption is inactive (estado: false) | It was deactivated in the POS. |
The exemption is expired (fechaExpiracion in the past) | Same condition as vigente: false in the GET /clientes/{identificacion} response. |
Rejection example:
{ "error": "Línea 1: la exoneración 7 venció el 10/01/2026." }Calculation behavior
The percentage authorized on the exemption is applied to the line’s real VAT, capped at the product’s rate: a 100% exemption on a product taxed at 2% exempts 2 points, not 13. With a partial exemption (for example 50%):
- 50% of the VAT is charged normally.
- 50% of the VAT is exempted (not charged).
LX CloudPos automatically splits the amount between “taxed base” and “exempted base”. See totals calculation.
See also: VAT.