Factura electrónica Endpoint POST /api/2.0/documentos-electronicos/emision/factura Crea y envía a Hacienda una factura electrónica con la disposición 4.4. La emisión es síncrona: la respuesta incluye el XML generado, el XML firmado y el resultado de la recepción por parte de 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 una factura de contado. curl --location 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/emision/factura' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data-raw '{ "actividad": "014002", "codigo_actividad_receptor": "851207", "condicion_venta": "01", "moneda": "CRC", "tipo_cambio": 1, "medio_pago": { "01": { "codigo": "01", "total": 1130 } }, "tipo_cedula": "01", "cedula": "701750946", "nombre": "Prueba", "correo": "prueba@prueba.com", "telefono": "88888888", "comentarios": "Factura 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 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. tipo_cedula string Tipo de identificación del receptor. Valores aceptados: 01 física, 02 jurídica, 03 DIMEX, 04 NITE. cedula string Identificación del receptor, máximo 20 caracteres. Los guiones se eliminan automáticamente. nombre string Nombre del receptor, máximo 80 caracteres. correo string Correo electrónico del receptor. Debe ser una dirección válida; a él se envía el comprobante. lineas array Al menos una línea de detalle. Ver la sección correspondiente. Opcionales Campo Tipo Descripción codigo_actividad_receptor string Código de actividad económica del receptor. Hacienda lo exige para receptores nacionales, por lo que se recomienda enviarlo siempre. sucursal string Código de sucursal, por ejemplo 004 . Si se omite, se usa el valor configurado en las preferencias de facturación de la cuenta. 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. telefono string Teléfono del receptor. Se conservan únicamente los dígitos. nombre_comercial string Nombre comercial del receptor, entre 3 y 80 caracteres. 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. 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. provincia , canton , distrito , barrio , direccion mixed Ubicación del receptor. Solo se incorporan al XML si la preferencia de facturación «especificar dirección» está activa en 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..detalle El código del medio de pago es 99 Texto entre 3 y 100 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. Aun así el campo medio_pago debe venir presente en la petición. Medios de pago medio_pago es un objeto con hasta cuatro entradas, 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 } } 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. Obligatorio para activar la 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 . Información de referencia y de proveedor Para incorporar una referencia a otro documento se envía incluir_info_referencia junto con tipo_documento , numero_referencia , codigo_referencia , fecha_emision en formato dd/mm/aaaa y razon_referencia . Cuando el tipo o el código corresponden a «otros», se agregan tipo_documento_otro y codigo_referencia_otro . Para incorporar los datos del proveedor se envía incluir-info-proveedor junto con tipo-identificador , numero-identificador y orden-compra . 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": "50622032000070175094601000001010000000006118491223", "consecutivo": "00400001010000000006", "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": "50622032000070175094601000001010000000006118491223", "consecutivo": "00400001010000000006", "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. La clave de cada error es la ruta del campo, por ejemplo lineas.0.descripcion . 500 {"0": "Ha ocurrido un error", "error": "...", "stack": [...]} 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 .