Tiquete electrónico
Endpoint
POST /api/2.0/documentos-electronicos/emision/tiquete
Crea y envía a Hacienda un tiquete electrónico con la disposición 4.4. A diferencia de la factura electrónica, el tiquete no exige identificar al receptor: los datos del cliente son opcionales y se envían como un bloque completo cuando se desean incluir.
El campo tipo_documento con valor "04" es obligatorio en este endpoint. Una petición que lo omita se rechaza con 422 antes de llegar a Hacienda.
Autenticación
Todas las peticiones requieren los cuatro encabezados siguientes.
| Encabezado | Descripción |
|---|---|
api-token | Token de API de la cuenta. |
access-token | Token de acceso asociado al api-token. |
Content-Type | application/json |
Accept | application/json. Obligatorio. Si se omite, una petición no autenticada responde con una redirección al formulario de inicio de sesión en lugar de un error JSON. |
La emisión por API requiere un plan con acceso a API activo y documentos disponibles en el ciclo vigente.
Ejemplo mínimo
Los siguientes datos son los mínimos para emitir un tiquete de contado sin receptor identificado.
curl --location 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/emision/tiquete' \
--header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \
--header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
"tipo_documento": "04",
"actividad": "014002",
"condicion_venta": "01",
"moneda": "CRC",
"tipo_cambio": 1,
"medio_pago": {
"01": {
"codigo": "01",
"total": 1130
}
},
"comentarios": "Tiquete de prueba por medio del API",
"lineas": [
{
"codigo": "00001",
"codigoCabys": "0196109000000",
"descripcion": "Entrada a CRFW22",
"cantidad": "1",
"unidad": "Unid",
"descuento": 0,
"naturalezaDescuento": "",
"precioUnitario": 1000,
"impuestos": {
"01": {
"tarifa": "08"
}
}
}
]
}'
Campos del documento
Obligatorios
| Campo | Tipo | Descripción |
|---|---|---|
tipo_documento | string | Debe ser exactamente "04", el código de tiquete electrónico. Cualquier otro valor se rechaza. |
actividad | string | Código de la actividad económica del emisor. Debe estar registrada en la cuenta. |
condicion_venta | string | Código de condición de venta. Ver la tabla más abajo. |
moneda | string | Código de moneda, por ejemplo CRC o USD. |
medio_pago | object | De 1 a 4 medios de pago. Ver la tabla más abajo. Se ignora cuando la condición de venta es a crédito. |
lineas | array | Al menos una línea de detalle. Ver la sección correspondiente. |
Opcionales
| Campo | Tipo | Descripción |
|---|---|---|
sucursal | string | Código de sucursal, por ejemplo 004. Si se omite, se usa el valor configurado en las preferencias de facturación. |
punto | string | Punto de emisión, por ejemplo 00001. Si se omite, se usa el valor configurado en las preferencias de facturación. |
tipo_cambio | number | Tipo de cambio, mayor que cero. Si se omite se asume 1; cuando moneda es USD y no se envía, el sistema aplica automáticamente el tipo de cambio de referencia del día. |
comentarios | string | Notas del comprobante. Si el texto contiene un patrón #codigo, ese valor se registra además como número de orden. |
orden | string u object | Número de orden asociado. Acepta un string con el código, o un objeto {"codigo": "...", "estado": "...", "proveedor": "..."}. |
devolucion | number | Monto de devolución de IVA, mayor que cero. |
cargos | array | Otros cargos del comprobante. Ver la sección correspondiente. |
correo-copia | string | Se acepta y se valida como dirección de correo, pero actualmente no tiene efecto en la emisión por API: no se registran destinatarios en copia. Para enviar copias, configure las preferencias de correo de la cuenta. |
Campos condicionales
| Campo | Se vuelve obligatorio cuando… | Reglas |
|---|---|---|
plazo_credito | condicion_venta es 02 o 10 | Entero entre 1 y 99999, expresado en días. |
condicion_venta_otros | condicion_venta es 99 | Texto entre 5 y 100 caracteres. |
medio_pago.<codigo>.detalle | El código del medio de pago es 99 | Texto entre 3 y 100 caracteres. |
cedula, nombre, correo | Se envía tipo_cedula | Ver la sección «Receptor». |
Receptor
El receptor es opcional en el tiquete electrónico. Para incluirlo se envía el siguiente bloque:
"tipo_cedula": "01",
"cedula": "701750946",
"nombre": "Prueba",
"correo": "prueba@prueba.com",
"telefono": "88888888",
"codigo_actividad_receptor": "851207"
Los campos cedula, nombre y correo se vuelven obligatorios en cuanto se envía tipo_cedula. Si desea omitir el receptor, omita los cinco campos en conjunto; enviar el bloque a medias produce un error 422.
| Campo | Descripción |
|---|---|
tipo_cedula | Tipo de identificación. Valores aceptados: 01 física, 02 jurídica, 03 DIMEX, 04 NITE. |
cedula | Identificación del receptor, máximo 20 caracteres. Los guiones se eliminan automáticamente. |
nombre | Nombre del receptor, máximo 80 caracteres. |
correo | Correo electrónico del receptor. Debe ser una dirección válida; a él se envía el comprobante. |
telefono | Teléfono del receptor. Opcional. Se conservan únicamente los dígitos. |
codigo_actividad_receptor | Código de actividad económica del receptor. Opcional. |
nombre_comercial | Nombre comercial del receptor. Opcional; si se envía, entre 3 y 80 caracteres. |
Condición de venta
| Código | Descripción |
|---|---|
01 | Contado |
02 | Crédito |
03 | Consignación |
04 | Apartado |
05 | Arrendamiento con opción de compra |
06 | Arrendamiento en función financiera |
07 | Cobro a favor de un tercero |
08 | Servicios prestados al Estado |
09 | Pago de servicios prestados al Estado |
10 | Venta a crédito en IVA hasta 90 días |
11 | Pago de venta a crédito en IVA hasta 90 días |
12 | Venta de mercancía no nacionalizada |
13 | Venta de bienes usados no contribuyente |
14 | Arrendamiento operativo |
15 | Arrendamiento financiero |
99 | Otros. Requiere condicion_venta_otros. |
Con las condiciones de venta 02, 08 y 10 el comprobante se emite a crédito y los medios de pago enviados se descartan: el XML no incluye el nodo de medio de pago.
Medios de pago
medio_pago es un objeto donde la clave y el campo codigo coinciden. total es el monto cubierto por ese medio y debe ser mayor que cero.
"medio_pago": {
"01": { "codigo": "01", "total": 130 },
"02": { "codigo": "02", "total": 400 },
"03": { "codigo": "03", "total": 600 }
}
Se admiten entre uno y cuatro medios de pago.
| Código | Descripción |
|---|---|
01 | Efectivo |
02 | Tarjeta |
03 | Cheque |
04 | Transferencia o depósito bancario |
05 | Recaudado por terceros |
06 | SINPE Móvil |
07 | Plataforma digital |
99 | Otros. Requiere detalle. |
Por compatibilidad con la versión 4.3 también se acepta un arreglo simple de códigos, en cuyo caso el total del comprobante se asigna íntegro al primer medio: "medio_pago": ["01"].
Líneas de detalle
Campos obligatorios de la línea
| Campo | Tipo | Descripción |
|---|---|---|
codigo | string | Código del producto o servicio, máximo 20 caracteres. |
descripcion | string | Detalle de la línea, entre 3 y 200 caracteres. |
cantidad | number | Cantidad, mayor que cero. Se redondea a 3 decimales. |
unidad | string | Código de unidad de medida del catálogo de Hacienda. Debe coincidir exactamente con un código del catálogo, por ejemplo Unid, Sp, Os, kg, L, Al, Alc. La categoría del código determina si la línea se registra como mercancía o como servicio. |
precioUnitario | number | Precio unitario, mayor o igual a cero. |
descuento | number | Monto del descuento. Envíe 0 si no aplica. |
naturalezaDescuento | string | Naturaleza del descuento. Envíe cadena vacía si no aplica; si se envía texto, debe tener entre 3 y 80 caracteres. |
codigoCabys no es rechazado por la validación, pero Hacienda exige el código CABYS en todos los comprobantes. Omitirlo produce un rechazo del lado de Hacienda, no del API.
Campos opcionales de la línea
| Campo | Tipo | Descripción |
|---|---|---|
codigoCabys | string | Código CABYS de 13 dígitos. |
codigoInternoFV | string | Código del producto en el catálogo de Facturador Virtual. Permite vincular la línea con el producto registrado. |
id_producto | integer | Identificador del producto en Facturador Virtual, como alternativa a codigoInternoFV. |
unidadMedidaComercial | string | Unidad de medida comercial, máximo 20 caracteres. |
partidaArancelaria | string | Partida arancelaria de la mercancía. |
tipoTransaccion | string | Código de tipo de transacción de la versión 4.4. |
tipoDescuento | string | Código del tipo de descuento. Si se omite se asume 08. Con los códigos 01 y 03 el impuesto de la línea se registra como asumido por el emisor. |
tipoDescuentoOtro | string | Descripción cuando tipoDescuento corresponde a «otros». |
ivaCobradoFabrica | number | IVA cobrado en fábrica. |
vinSerie | string | Número VIN o serie, para vehículos. |
esCabysMedicamento | boolean | Marca la línea como medicamento. Al activarse se toman registroMedicamento (máximo 100 caracteres) y formaFarmaceutica (3 caracteres). |
es_combo | boolean | Marca la línea como combo. Los componentes se envían en componentes, un arreglo con la misma estructura de una línea de detalle. |
impuestos | object | Impuestos aplicados a la línea. Ver la siguiente sección. |
Impuestos
impuestos es un objeto cuya clave es el código del impuesto. El campo tarifa recibe el código de tarifa, no el porcentaje: el porcentaje se resuelve a partir de ese código.
"impuestos": {
"01": {
"tarifa": "08"
}
}
| Código de impuesto | Descripción |
|---|---|
01 | Impuesto al Valor Agregado |
02 | Impuesto Selectivo de Consumo |
03 | Impuesto Único a los Combustibles |
04 | Impuesto específico de Bebidas Alcohólicas |
05 | Impuesto Específico sobre las bebidas envasadas sin contenido alcohólico y jabones de tocador |
06 | Impuesto a los Productos de Tabaco |
07 | IVA (cálculo especial) |
08 | IVA Régimen de Bienes Usados (Factor) |
12 | Impuesto Específico al Cemento |
99 | Otros. Se describe en descripcionOtro. |
| Código de tarifa | Descripción | Porcentaje aplicado |
|---|---|---|
01 | Tarifa 0% (Artículo 32, num 1, RLIVA) | 0 |
02 | Tarifa reducida 1% | 1 |
03 | Tarifa reducida 2% | 2 |
04 | Tarifa reducida 4% | 4 |
05 | Transitorio 0% | 0 |
06 | Transitorio 4% | 4 |
07 | Tarifa transitoria 8% | 8 |
08 | Tarifa general 13% | 13 |
09 | Tarifa reducida 0.5% | 0.5 |
10 | Tarifa exenta | 0 |
11 | Tarifa 0% sin derecho a crédito | 0 |
Para el impuesto 08 se envía además factor. Para los impuestos 03, 04, 05 y 06 pueden enviarse los datos específicos cantidadUnidadMedida, porcentaje, proporcion, volumenUnidadConsumo e impuestoUnidad.
Exoneración
La exoneración se declara dentro del impuesto 01 de la línea.
"impuestos": {
"01": {
"tarifa": "08",
"exoneracionTipo": "02",
"exoneracionNumero": "12345",
"exoneracionInstitucion": "01",
"exoneracionFecha": "15/01/2026",
"exoneracionTarifa": 13,
"exoneracionArticulo": 5,
"exoneracionInciso": 2
}
}
| Campo | Descripción |
|---|---|
exoneracionTipo | Tipo de documento de exoneración. |
exoneracionNumero | Número del documento de exoneración. |
exoneracionInstitucion | Código de la institución que emite el documento. |
exoneracionFecha | Fecha de emisión en formato dd/mm/aaaa. |
exoneracionTarifa | Porcentaje de exoneración. Su presencia es la que activa el bloque de exoneración. |
exoneracionTipoOtro | Obligatorio cuando exoneracionTipo es 99. |
exoneracionArticulo, exoneracionInciso | Obligatorios cuando exoneracionTipo es 02, 03, 06, 07 u 08. |
exoneracionInstitucionOtros | Obligatorio cuando exoneracionInstitucion es 99. |
Otros cargos
"cargos": [
{
"tipo": "04",
"detalle": "Comisión de servicio",
"monto": 500,
"tipoIdentidadTercero": "01",
"numeroIdentidadTercero": "701750946",
"nombreTercero": "Tercero S.A.",
"porcentajeTercero": 10
}
]
Los campos tipo, detalle y monto aplican a todos los cargos. Los cuatro campos de tercero solo se envían cuando tipo es 04.
Respuesta
Una emisión procesada devuelve HTTP 200. El campo codigo del cuerpo indica el resultado de la recepción en Hacienda y es independiente del código HTTP.
{
"codigo": 200,
"contenidoXml": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iV…",
"contenidoXmlFirmado": "Nfdsfffadeec2lvbj0iMS4wIiBlbmNvZGluZz0iV…",
"documento": {
"clave": "50622032000070175094601000001040000000006118491223",
"consecutivo": "00400001040000000006",
"recepcion": "recibido",
"comprobacion": "por_comprobar"
},
"errores": []
}
| Campo | Descripción |
|---|---|
codigo | Resultado de la recepción en Hacienda. 200 si el documento fue recibido; 500 si no se pudo entregar. |
contenidoXml | XML generado, codificado en base64. |
contenidoXmlFirmado | XML firmado, codificado en base64. Es null cuando la firma o el envío no se completaron. |
documento.clave | Clave numérica de 50 dígitos del comprobante. |
documento.consecutivo | Consecutivo de 20 dígitos del comprobante. |
documento.recepcion | Estado de la recepción: recibido o por_enviar. |
documento.comprobacion | Estado de la comprobación: por_comprobar, aceptado o rechazado. |
errores | Arreglo de objetos {"tipo": "...", "mensaje": "..."} devueltos por Hacienda. |
Cuando el documento se genera pero Hacienda no lo recibe, el comprobante queda registrado y el sistema reintenta el envío automáticamente:
{
"codigo": 500,
"contenidoXml": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iV…",
"contenidoXmlFirmado": null,
"documento": {
"clave": "50622032000070175094601000001040000000006118491223",
"consecutivo": "00400001040000000006",
"recepcion": "por_enviar",
"comprobacion": "por_comprobar"
},
"errores": [
{
"tipo": "error",
"mensaje": "No se ha podido enviar el documento a Hacienda porque su servicio de recepción presenta inconsistencias. El sistema intentará automáticamente en unos minutos"
}
]
}
Errores
| HTTP | Cuerpo | Causa |
|---|---|---|
| 302 | Redirección al inicio de sesión | Falta el encabezado Accept: application/json en una petición no autenticada. |
| 401 | {"message": "Unauthenticated."} | api-token o access-token inválidos o ausentes. |
| 403 | {"error": "No posee un Plan Api activo"} | El plan de la cuenta no incluye acceso a API. |
| 403 | {"error": "Ha llegado al límite de facturas del Plan Api contratado"} | Se agotaron los documentos del ciclo vigente. |
| 422 | {"errors": {"campo": ["mensaje"]}} | Uno o más campos no cumplen las reglas de validación. Las causas más frecuentes son omitir tipo_documento y enviar tipo_cedula sin el resto del bloque del receptor. |
| 500 | {"error": "...", "pila": [...]} | Error no controlado durante el procesamiento. |
Existe además un caso en el que la respuesta es HTTP 200 con "codigo": 500, "documento": null y "errores": []. Ocurre cuando el comprobante no llegó a construirse; la causa más frecuente es un código de unidad que no existe en el catálogo de unidades de medida. Verifique ese campo antes de reintentar.
Comprobación
La recepción es el primer paso: significa que Hacienda recibió el documento, no que lo aprobó. La comprobación se realiza automáticamente, por lo general en uno o dos minutos, y el estado pasa de por_comprobar a aceptado o rechazado.