API FE 4.4 Inicio Documentación del API de comprobantes electrónicos de Facturador Virtual , versión 4.4 de la disposición del Ministerio de Hacienda de Costa Rica. Quiénes somos Facturador Virtual es una plataforma costarricense de facturación electrónica. Genera los comprobantes con la estructura que exige el Ministerio de Hacienda, los firma con el certificado del contribuyente, los envía al servicio de recepción y da seguimiento a su comprobación, sin que quien integra tenga que construir el XML ni resolver la firma digital. El API expone esas mismas capacidades para que un sistema externo —un punto de venta, un comercio electrónico, un ERP— emita comprobantes de forma programática. En todo comprobante emitido por la plataforma, el campo ProveedorSistema del XML lleva la cédula jurídica 3-101-660528 , que identifica a Facturador Virtual como proveedor del sistema ante Hacienda. Qué encontrará aquí Esta documentación cubre la emisión de comprobantes electrónicos por API : cómo autenticarse y cómo construir cada tipo de documento, campo por campo, con sus catálogos, reglas de validación y respuestas de error. Cada página de documento sigue la misma estructura: endpoint, autenticación, ejemplo mínimo funcional, campos obligatorios, opcionales y condicionales, catálogos aplicables, formato de la respuesta y tabla de errores. Por dónde empezar Obtenga sus credenciales. Necesita un plan con acceso a API activo y el par de tokens que se genera desde el perfil de la cuenta. Empiece por Credenciales de acceso al API . Verifique que funcionan. En esa misma página hay una llamada de solo lectura que confirma las credenciales sin consumir documentos de su plan. Emita su primer documento. Vaya a Factura electrónica y adapte el ejemplo mínimo. Es el documento más común y el que sirve de referencia para los demás. Si su caso no es una factura ordinaria, la tabla siguiente le indica qué página leer. Documentos disponibles Documento Cuándo se usa Método y ruta Tipo Factura electrónica Venta a un receptor identificado. POST /emision/factura 01 Tiquete electrónico Venta en la que no se identifica al receptor. POST /emision/tiquete 04 Nota de crédito Anular o disminuir el monto de un documento ya emitido. PUT /emision/nota-credito/{clave} 03 Nota de débito Incrementar el monto de un documento ya emitido. PUT /emision/nota-debito/{clave} 02 Factura de exportación Venta a un receptor en el extranjero. POST /emision/exportacion 09 Factura de compra Respaldar una compra a quien no puede emitir comprobante electrónico. POST /emision/compra 08 Todas las rutas cuelgan de https://app.facturadorvirtual.com/api/2.0/documentos-electronicos . Convenciones comunes Estas reglas aplican a todos los documentos, y no se repiten en cada página. Autenticación Cuatro encabezados en cada petición: api-token , access-token , Content-Type: application/json y Accept: application/json . El último no es opcional; sin él, una petición no autenticada responde con una redirección al formulario de inicio de sesión en vez de un error JSON. El código HTTP y el código del cuerpo son cosas distintas Una emisión procesada devuelve HTTP 200 aunque Hacienda no haya recibido el documento. El campo codigo del cuerpo es el que informa del resultado de la recepción: 200 si fue recibido, 500 si no se pudo entregar. En este segundo caso el comprobante queda registrado y el sistema reintenta el envío automáticamente. { "codigo": 200, "contenidoXml": "…", "contenidoXmlFirmado": "…", "documento": { "clave": "50622032000070175094601000001010000000006118491223", "consecutivo": "00400001010000000006", "recepcion": "recibido", "comprobacion": "por_comprobar" }, "errores": [] } contenidoXml y contenidoXmlFirmado vienen codificados en base64 y corresponden al XML antes y después de la firma. Recepción y comprobación son dos etapas Que Hacienda reciba el documento no significa que lo apruebe . La comprobación ocurre después, normalmente en uno o dos minutos, y el estado pasa de por_comprobar a aceptado o rechazado . Una integración correcta no asume que un codigo: 200 equivale a un comprobante aceptado. Errores HTTP Significado 302 Falta el encabezado Accept: application/json . 401 Credenciales inválidas. 403 Credenciales correctas, pero el plan no incluye acceso a API o se agotaron los documentos del ciclo. 422 Algún campo no cumple las reglas de validación. El cuerpo indica cuál. 500 Error no controlado durante el procesamiento. Catálogos compartidos Condición de venta, medios de pago, impuestos, códigos de tarifa y unidades de medida son los mismos en todos los documentos. Cada página incluye las tablas que le aplican, de modo que no es necesario saltar entre páginas para construir una petición. Dos detalles que causan la mayoría de los rechazos: el campo tarifa de un impuesto recibe el código de tarifa y no el porcentaje — "08" significa 13 %—, y el campo unidad de una línea debe ser un código del catálogo de unidades de Hacienda, como Unid o Kg , no un texto libre. Soporte Para consultas sobre la integración, escriba a soporte@facturadorvirtual.com . Si su consulta es sobre un comprobante concreto, incluya la clave de 50 dígitos : es el identificador que permite rastrearlo tanto en la plataforma como ante Hacienda. Credenciales de acceso al API Todas las llamadas al API se autentican con un par de credenciales: el API Token y el Access Token . Ambos se generan desde el perfil de la cuenta y se envían en cada petición como encabezados HTTP. Requisito previo La generación y el uso de credenciales requieren un plan con acceso a API activo . Si el plan de la cuenta no lo incluye, la pestaña «API» no aparece en el perfil y las llamadas responden 403 con el mensaje No posee un Plan Api activo . Generar las credenciales Inicie sesión en app.facturadorvirtual.com . Vaya a Perfil y abra la pestaña API , en /perfil/api/detalles . La primera vez verá el aviso «Generación de credenciales». Pulse Generar accesos . La pantalla muestra los dos valores en los campos API Token y Access Token . Cópielos y guárdelos en un lugar seguro. Si la cuenta ya tiene credenciales, la misma pantalla las muestra junto a un botón Regenerar accesos . Credencial Encabezado Formato API Token api-token 48 caracteres alfanuméricos Access Token access-token 52 caracteres alfanuméricos Usar las credenciales Las dos credenciales viajan como encabezados en cada petición. Junto con ellas debe enviarse siempre Accept: application/json . --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' El encabezado Accept: application/json no es opcional. Sin él, una petición cuyas credenciales sean inválidas responde con una redirección al formulario de inicio de sesión en lugar de un error JSON, lo que suele confundirse con un problema de red. Comprobar que funcionan La forma más simple de validar un par de credenciales es consultar el tipo de cambio de referencia. Es una llamada de solo lectura que no consume documentos del plan. curl --location 'https://app.facturadorvirtual.com/api/2.0/indicadores-economicos/tipo-cambio' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Accept: application/json' Con credenciales válidas y un plan API activo, la respuesta es: { "USD": { "compra": 512.45 } } Regenerar las credenciales Regenerar elimina de inmediato el par anterior . Cada cuenta tiene un único juego de credenciales vigente, de modo que toda integración que siga usando los valores antiguos empezará a recibir 401 en la siguiente llamada. Planifique la sustitución antes de pulsar el botón. Regenere las credenciales cuando: Sospeche que fueron expuestas o compartidas por error. Cambie el plan de la cuenta. Las credenciales quedan asociadas al plan vigente en el momento en que se generaron ; tras un cambio de plan conviene regenerarlas para que apunten al plan actual. Rote credenciales como parte de su política de seguridad. Vigencia Las credenciales no tienen fecha de expiración : permanecen válidas hasta que se regeneren. Tampoco es posible mantener varios pares simultáneos por cuenta, por lo que no existe un mecanismo de rotación solapada: la sustitución es instantánea. Errores relacionados con las credenciales HTTP Cuerpo Causa 302 Redirección al inicio de sesión Falta el encabezado Accept: application/json . 401 {"message": "Unauthenticated."} El api-token no existe, o el access-token no corresponde a ese api-token . Ocurre también cuando se siguen usando credenciales ya regeneradas. 403 {"error": "No posee un Plan Api activo"} Las credenciales son válidas, pero el plan asociado no incluye acceso a API. 403 {"error": "Ha llegado al límite de facturas del Plan Api contratado"} Las credenciales son válidas, pero se agotaron los documentos del ciclo vigente. Los dos errores 403 confirman que la autenticación fue correcta: el problema está en el plan, no en las credenciales. Recomendaciones de seguridad Trate ambos valores como contraseñas: quien los posea puede emitir comprobantes electrónicos a nombre de su empresa. Guárdelos en variables de entorno o en un gestor de secretos, nunca en el código fuente ni en repositorios. No los incluya en capturas de pantalla, tiquetes de soporte ni registros de aplicación. Úselos solo desde su servidor. No los incruste en aplicaciones móviles ni en código JavaScript que se ejecute en el navegador, donde quedarían a la vista de cualquiera. Si sospecha una filtración, regenérelos de inmediato. Emisión de documentos elecrónicos Ejemplos de cómo emitir un documento electrónico: Factura electrónicaNota de créditoNota de débitoTiquete electrónico 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 . 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..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 . Nota de crédito electrónica Endpoint PUT /api/2.0/documentos-electronicos/emision/nota-credito/{clave} Emite una nota de crédito electrónica con la disposición 4.4 sobre un documento ya emitido. A diferencia de la factura y el tiquete, este endpoint usa el método PUT y la clave del documento de referencia viaja en la URL, no en el cuerpo. La nota de crédito hereda al receptor, la moneda y el tipo de cambio del documento de referencia . Esos campos se ignoran si se envían en el cuerpo. Ver la sección «Datos heredados». 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. Documento de referencia El segmento {clave} de la URL es la clave numérica de 50 dígitos del documento que se desea corregir o anular. El documento debe pertenecer a la misma cuenta que emite la nota; no es posible referenciar comprobantes de otro contribuyente. PUT /api/2.0/documentos-electronicos/emision/nota-credito/50622032000070175094601000001010000000006118491223 Ejemplo mínimo curl --location --request PUT 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/emision/nota-credito/50622032000070175094601000001010000000006118491223' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data-raw '{ "actividad": "014002", "razon": "01", "condicion_venta": "01", "medio_pago": { "01": { "codigo": "01", "total": 1130 } }, "comentarios": "Anulación de la factura de referencia", "lineas": [ { "codigo": "00001", "codigoCabys": "0196109000000", "descripcion": "Entrada a CRFW22", "cantidad": "1", "unidad": "Unid", "descuento": 0, "naturalezaDescuento": "", "precioUnitario": 1000, "impuestos": { "01": { "tarifa": "08" } } } ] }' Datos heredados del documento de referencia Los siguientes datos se toman del documento referenciado y no se leen del cuerpo de la petición . Enviarlos no produce error, pero tampoco tiene efecto. Dato Origen Identificación, tipo de identificación, nombre, nombre comercial, teléfono y correo del receptor Documento de referencia Ubicación del receptor (provincia, cantón, distrito, barrio, otras señas) Documento de referencia, si lo tenía registrado moneda Resumen del documento de referencia tipo_cambio Resumen del documento de referencia Por esa razón los campos cedula , tipo_cedula , nombre , correo , telefono , moneda y tipo_cambio no aparecen entre los campos aceptados de este endpoint. 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. razon string Código de la razón de la nota. Ver la tabla más abajo. medio_pago object De 1 a 4 medios de pago. 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 condicion_venta string Código de condición de venta de la nota. Ver la tabla más abajo. razon_referencia string Descripción de la razón. Si se omite, se usa el texto correspondiente al código enviado en razon . sin_receptor boolean Exclusivo de la nota de crédito. Con valor verdadero, la nota se emite sin datos del receptor , aunque el documento de referencia los tuviera. codigo_actividad_receptor string Código de actividad económica del receptor. 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. 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. 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. Razón de la nota Código Descripción 01 Para anular documento de referencia 02 Por corrección de texto 03 Por corrección de monto Para anular por completo una factura sin reconstruir el detalle, conviene usar el endpoint de anulación descrito al final de esta página, que arma la nota a partir del documento original. 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 . 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 . 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. id_producto integer Identificador del producto en Facturador Virtual. 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, máximo 2 caracteres. 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». Entre 5 y 100 caracteres. 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 . La exoneración se declara dentro del impuesto 01 con los campos exoneracionTipo , exoneracionNumero , exoneracionInstitucion , exoneracionFecha en formato dd/mm/aaaa y exoneracionTarifa . 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": "50622032000070175094601000001030000000007118491223", "consecutivo": "00400001030000000007", "recepcion": "recibido", "comprobacion": "por_comprobar" }, "errores": [] } La clave y el consecutivo devueltos corresponden a la nota de crédito recién emitida , no al documento de referencia. El tipo de documento 03 en la posición correspondiente identifica la nota de crédito. 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 de la nota de crédito. documento.consecutivo Consecutivo de 20 dígitos de la nota de crédito. 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. 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. 403 {"error": "Factura no encontrada"} La clave del documento de referencia no existe o pertenece a otra cuenta. 500 {"0": "Ha ocurrido un error", "error": "...", "stack": [...]} Error no controlado durante el procesamiento. Los tres códigos 403 confirman que la autenticación fue correcta: el problema está en el plan o en la clave de referencia, no en las credenciales. Anulación completa de un documento Cuando el objetivo es anular por completo una factura, existe un endpoint que construye la nota de crédito a partir del documento original —líneas, impuestos, medios de pago y resumen— sin necesidad de reenviar el detalle. Endpoint POST /api/2.0/documentos-electronicos/anular/factura/{clave} curl --location --request POST 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/anular/factura/50622032000070175094601000001010000000006118491223' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Accept: application/json' La petición no lleva cuerpo . La respuesta tiene el mismo formato que la de la nota de crédito y corresponde a la nota generada. Si la clave no existe o pertenece a otra cuenta, responde 403 con {"error": "Factura no encontrada"} ; si la anulación no puede completarse, responde 500 con el mensaje No fue posible anular la factura . 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 . Nota de débito electrónica Endpoint PUT /api/2.0/documentos-electronicos/emision/nota-debito/{clave} Emite una nota de débito electrónica con la disposición 4.4 sobre un documento ya emitido, para incrementar el monto de una operación previamente facturada. Al igual que la nota de crédito, este endpoint usa el método PUT y la clave del documento de referencia viaja en la URL, no en el cuerpo. La nota de débito hereda al receptor, la moneda y el tipo de cambio del documento de referencia . Esos campos se ignoran si se envían en el cuerpo. Ver la sección «Datos heredados». 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. Documento de referencia El segmento {clave} de la URL es la clave numérica de 50 dígitos del documento sobre el que se emite la nota. El documento debe pertenecer a la misma cuenta que emite la nota; no es posible referenciar comprobantes de otro contribuyente. PUT /api/2.0/documentos-electronicos/emision/nota-debito/50622032000070175094601000001010000000006118491223 Ejemplo mínimo curl --location --request PUT 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/emision/nota-debito/50622032000070175094601000001010000000006118491223' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data-raw '{ "actividad": "014002", "razon": "03", "razon_referencia": "Por corrección de monto", "condicion_venta": "01", "medio_pago": { "01": { "codigo": "01", "total": 565 } }, "comentarios": "Ajuste al alza sobre la factura de referencia", "lineas": [ { "codigo": "00001", "codigoCabys": "0196109000000", "descripcion": "Diferencia de precio Entrada a CRFW22", "cantidad": "1", "unidad": "Unid", "descuento": 0, "naturalezaDescuento": "", "precioUnitario": 500, "impuestos": { "01": { "tarifa": "08" } } } ] }' Datos heredados del documento de referencia Los siguientes datos se toman del documento referenciado y no se leen del cuerpo de la petición . Enviarlos no produce error, pero tampoco tiene efecto. Dato Origen Identificación, tipo de identificación, nombre, nombre comercial, teléfono y correo del receptor Documento de referencia Ubicación del receptor (provincia, cantón, distrito, barrio, otras señas) Documento de referencia, si lo tenía registrado moneda Resumen del documento de referencia tipo_cambio Resumen del documento de referencia Por esa razón los campos cedula , tipo_cedula , nombre , correo , telefono , moneda y tipo_cambio no aparecen entre los campos aceptados de este endpoint. 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. razon string Código de la razón de la nota. Ver la tabla y la advertencia más abajo. medio_pago object De 1 a 4 medios de pago. 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 condicion_venta string Código de condición de venta de la nota. Ver la tabla más abajo. razon_referencia string Descripción de la razón. Si se omite, se usa el texto correspondiente al código enviado en razon . sin_receptor boolean Con valor verdadero, la nota se emite sin datos del receptor , aunque el documento de referencia los tuviera. codigo_actividad_receptor string Código de actividad económica del receptor. 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. 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. 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. Razón de la nota Código Descripción 01 Para anular documento de referencia 02 Por corrección de texto 03 Por corrección de monto Solo se aceptan los tres códigos de la tabla; cualquier otro valor se rechaza con 422 . Si se omite razon_referencia , la descripción se toma del catálogo de razones de la nota de débito. 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 . 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 . 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. id_producto integer Identificador del producto en Facturador Virtual. 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, máximo 2 caracteres. 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». Entre 5 y 100 caracteres. 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 . La exoneración se declara dentro del impuesto 01 con los campos exoneracionTipo , exoneracionNumero , exoneracionInstitucion , exoneracionFecha en formato dd/mm/aaaa y exoneracionTarifa . 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": "50622032000070175094601000001020000000007118491223", "consecutivo": "00400001020000000007", "recepcion": "recibido", "comprobacion": "por_comprobar" }, "errores": [] } La clave y el consecutivo devueltos corresponden a la nota de débito recién emitida , no al documento de referencia. El tipo de documento 02 en la posición correspondiente identifica la nota de débito. 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 de la nota de débito. documento.consecutivo Consecutivo de 20 dígitos de la nota de débito. 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. 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. 403 {"error": "Factura no encontrada"} La clave del documento de referencia no existe o pertenece a otra cuenta. 500 {"0": "Ha ocurrido un error", "error": "...", "stack": [...]} Error no controlado durante el procesamiento. Los tres códigos 403 confirman que la autenticación fue correcta: el problema está en el plan o en la clave de referencia, no en las credenciales. 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 . Factura electrónica de exportación Endpoint POST /api/2.0/documentos-electronicos/emision/exportacion Crea y envía a Hacienda una factura electrónica de exportación con la disposición 4.4. Es el comprobante para ventas a receptores en el extranjero, y se distingue de la factura ordinaria en tres puntos: el receptor es opcional y se identifica como extranjero, cada línea de mercancía puede declarar su partida arancelaria, y normalmente se emite en moneda extranjera. 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 curl --location 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/emision/exportacion' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data-raw '{ "actividad": "014002", "condicion_venta": "01", "moneda": "USD", "tipo_cambio": 512.45, "medio_pago": { "04": { "codigo": "04", "total": 1000 } }, "incliuir_receptor": 1, "tipo_cedula": "05", "cedula": "US-8891234", "nombre": "Costa Rica Coffee Imports LLC", "correo": "purchasing@crcoffee.example", "comentarios": "Exportación de prueba por medio del API", "lineas": [ { "codigo": "00001", "codigoCabys": "0161010100000", "descripcion": "Café oro en sacos de 69 kg", "cantidad": "10", "unidad": "Kg", "partidaArancelaria": "090111000000", "descuento": 0, "naturalezaDescuento": "", "precioUnitario": 100, "impuestos": { "01": { "tarifa": "01" } } } ] }' 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. En una exportación es habitual USD o EUR . 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 tipo_cambio number Tipo de cambio respecto al colón, 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. Para otras monedas debe enviarse explícitamente. 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. nombre_comercial string Nombre comercial del receptor, entre 3 y 80 caracteres. codigo_actividad_receptor string Código de actividad económica del receptor. 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. 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. cedula , nombre , correo Se envía incliuir_receptor Ver la sección «Receptor». Receptor En la factura de exportación el receptor es opcional. Para incluirlo se envía el indicador incliuir_receptor junto con los datos del cliente: "incliuir_receptor": 1, "tipo_cedula": "05", "cedula": "US-8891234", "nombre": "Costa Rica Coffee Imports LLC", "correo": "purchasing@crcoffee.example", "telefono": "18005550123", "nombre_comercial": "CR Coffee" El indicador se llama incliuir_receptor , con esa grafía exacta. Es el nombre del campo tal como lo espera el sistema en todas sus interfaces; escrito de otra forma, el indicador no se reconoce y los datos del receptor dejan de ser obligatorios. Al enviar incliuir_receptor , los campos cedula , nombre y correo pasan a ser obligatorios. Si se omite el indicador, esos campos siguen aceptándose y se incorporan al comprobante, pero no se exige ninguno; omitiéndolos todos, el documento se emite sin receptor identificado. Campo Descripción incliuir_receptor Indicador de inclusión del receptor. Envíe 1 . tipo_cedula Tipo de identificación. Para un receptor en el extranjero corresponde 05 , extranjero no domiciliado. El valor 99 se acepta y se normaliza a 05 . cedula Identificación del receptor, máximo 20 caracteres. En receptores extranjeros se conserva tal cual, sin eliminar guiones. 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. nombre_comercial Nombre comercial del receptor, 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. 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": { "04": { "codigo": "04", "total": 1000 } } 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 . 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 , Kg , L , Sp , Os . 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. partidaArancelaria string Partida arancelaria de la mercancía. Si se envía, debe tener exactamente 12 caracteres . Es el campo propio de la factura de exportación. codigoInternoFV string Código del producto en el catálogo de Facturador Virtual. id_producto integer Identificador del producto en Facturador Virtual. unidadMedidaComercial string Unidad de medida comercial, máximo 20 caracteres. tipoTransaccion string Código de tipo de transacción de la versión 4.4. tipoDescuento string Código del tipo de descuento, máximo 2 caracteres. 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». Entre 5 y 100 caracteres. 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. En una exportación lo habitual es aplicar una tarifa de 0 %. "impuestos": { "01": { "tarifa": "01" } } 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 . La exoneración se declara dentro del impuesto 01 con los campos exoneracionTipo , exoneracionNumero , exoneracionInstitucion , exoneracionFecha en formato dd/mm/aaaa y exoneracionTarifa . Otros cargos "cargos": [ { "tipo": "04", "detalle": "Flete internacional", "monto": 150, "tipoIdentidadTercero": "01", "numeroIdentidadTercero": "701750946", "nombreTercero": "Naviera 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": "50622032000070175094600400001090000000008118491223", "consecutivo": "00400001090000000008", "recepcion": "recibido", "comprobacion": "por_comprobar" }, "errores": [] } El tipo de documento 09 dentro del consecutivo identifica la factura de exportación. 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. 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. Una causa frecuente es una partidaArancelaria que no tiene exactamente 12 caracteres. 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 . Factura electrónica de compra Endpoint POST /api/2.0/documentos-electronicos/emision/compra Crea y envía a Hacienda una factura electrónica de compra con la disposición 4.4. Es el comprobante que el comprador se autoemite cuando adquiere bienes o servicios de alguien que no puede emitir un comprobante electrónico —por ejemplo, un productor agrícola no inscrito—, de modo que la compra quede respaldada como gasto deducible. En este documento los papeles están invertidos respecto de los demás comprobantes . Los campos cedula , tipo_cedula , nombre , nombre_comercial y correo que se envían en el cuerpo describen al vendedor , que figura como emisor del XML. El receptor es siempre la cuenta que hace la petición, y sus datos se toman del perfil, no del cuerpo. 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 El siguiente ejemplo documenta la compra de 100 kg de papaya a un productor no inscrito. curl --location 'https://app.facturadorvirtual.com/api/2.0/documentos-electronicos/emision/compra' \ --header 'api-token: iuJPbVCYQY3AmWuVHMflT9ZySlwzxb9ehviLbHNsz6yQnBm4' \ --header 'access-token: IDq4ME4ZUO9YmQ0fOc43AFp7mMO6talIuIALFaUUcs2H2pwLpYN2' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data-raw '{ "actividad": "014002", "codigo_actividad_receptor": "014002", "condicion_venta": "01", "moneda": "CRC", "tipo_cambio": 1, "medio_pago": { "01": { "codigo": "01", "total": 50000 } }, "tipo_cedula": "01", "cedula": "601230456", "nombre": "Juan Rodríguez Mora", "correo": "jrodriguez@example.com", "tipo_documento": "99", "tipo_documento_otro": "Compra a productor no inscrito", "numero_referencia": "PAPAYA-2026-0001", "codigo_referencia": "04", "fecha_emision": "15/01/2026", "razon_referencia": "Compra de producto agrícola a productor no inscrito", "comentarios": "Compra de papaya a productor local", "lineas": [ { "codigo": "PAPAYA", "codigoCabys": "0113101000000", "descripcion": "Papaya fresca", "cantidad": "100", "unidad": "Kg", "descuento": 0, "naturalezaDescuento": "", "precioUnitario": 500, "impuestos": { "01": { "tarifa": "01" } } } ] }' El vendedor Los datos del vendedor son obligatorios : son los que identifican al emisor del comprobante. "tipo_cedula": "01", "cedula": "601230456", "nombre": "Juan Rodríguez Mora", "correo": "jrodriguez@example.com", "nombre_comercial": "Finca La Esperanza" Campo Descripción tipo_cedula Tipo de identificación del vendedor. Valores aceptados: 01 física, 02 jurídica, 03 DIMEX, 04 NITE, 05 extranjero no domiciliado, 06 no contribuyente. cedula Identificación del vendedor, máximo 20 caracteres. Los guiones se eliminan automáticamente. nombre Nombre del vendedor, máximo 80 caracteres. correo Correo electrónico del vendedor. Debe ser una dirección válida. nombre_comercial Nombre comercial del vendedor, entre 3 y 80 caracteres. otras_sennas_extranjero Dirección del vendedor. Obligatoria cuando tipo_cedula es 05 , entre 5 y 300 caracteres; en los demás casos se ignora. Nótese la grafía del campo. Información de referencia A diferencia del resto de comprobantes, en la factura de compra el bloque de información de referencia siempre se construye y no depende de ningún indicador. Por eso sus cinco primeros campos son obligatorios. Campo Descripción tipo_documento Obligatorio. Tipo del documento de referencia. Ver la tabla de tipos. numero_referencia Obligatorio. Número o identificador del documento de referencia, máximo 50 caracteres. codigo_referencia Obligatorio. Código que indica el motivo de la referencia. Ver la tabla de códigos. fecha_emision Obligatoria. Fecha del documento de referencia, en formato dd/mm/aaaa . razon_referencia Obligatoria. Descripción del motivo de la referencia, máximo 100 caracteres. tipo_documento_otro Obligatorio cuando tipo_documento es 99 . Entre 5 y 100 caracteres. codigo_referencia_otro Obligatorio cuando codigo_referencia es 99 . Entre 5 y 100 caracteres. Tipos de documento de referencia Código Descripción 01 Factura electrónica 02 Nota de débito electrónica 03 Nota de crédito electrónica 04 Tiquete electrónico 05 Nota de despacho 06 Contrato 07 Procedimiento 08 Comprobante emitido en contingencia 09 Devolución de mercadería 10 Sustituye factura rechazada por el Ministerio de Hacienda 11 Sustituye factura rechazada por el receptor del comprobante 12 Sustituye factura de exportación 13 Factura mes vencido 14 Comprobante aportado por contribuyente del Régimen de Tributación Simplificado 15 Sustituye una factura electrónica de compra 16 Comprobante de proveedor no domiciliado 17 Nota de crédito a factura electrónica de compra 18 Nota de débito a factura electrónica de compra 99 Otros. Requiere tipo_documento_otro . Códigos de referencia Código Descripción 01 Anula documento de referencia 02 Corrige texto de documento de referencia 03 Corrige monto 04 Referencia a otro documento 05 Sustituye comprobante provisional por contingencia 99 Otros. Requiere codigo_referencia_otro . Campos del documento Obligatorios Campo Tipo Descripción actividad string Código de la actividad económica registrada en la cuenta. Cuando se envía, también tiene precedencia sobre codigo_actividad_receptor como actividad registrada para el receptor. codigo_actividad_receptor string Código de actividad económica del receptor. moneda string Código de moneda, por ejemplo CRC . condicion_venta string Código de condición de venta. Ver la tabla más abajo. medio_pago object De 1 a 4 medios de pago. 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. tipo_cedula , cedula , nombre , correo string Datos del vendedor. Ver la sección «El vendedor». tipo_documento , numero_referencia , codigo_referencia , fecha_emision , razon_referencia string Información de referencia. Ver la sección correspondiente. Opcionales Campo Tipo Descripción tipo_cambio number Tipo de cambio, mayor que cero. Si se omite se asume 1 . 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. comentarios string Notas del comprobante. 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. otras_sennas_extranjero tipo_cedula es 05 Texto entre 5 y 300 caracteres. tipo_documento_otro tipo_documento es 99 Texto entre 5 y 100 caracteres. codigo_referencia_otro codigo_referencia es 99 Texto entre 5 y 100 caracteres. Campos que este endpoint no aplica Campo Comportamiento devolucion Se valida como número mayor que cero, pero no se aplica : la devolución de IVA del resumen queda siempre en cero. cargos No se procesa. La factura de compra no admite otros cargos. orden No se procesa. Tampoco se extrae un número de orden desde comentarios , como sí ocurre en la factura. correo-copia No se acepta ni se procesa. provincia , canton , distrito , barrio , direccion No se procesan. Para un vendedor extranjero use otras_sennas_extranjero . 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 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": 50000 } } 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 . 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 con un código del catálogo, por ejemplo Unid , Kg , L , Sp , Os . 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. partidaArancelaria string Partida arancelaria. Si se envía, debe tener exactamente 12 caracteres. codigoInternoFV string Código del producto en el catálogo de Facturador Virtual. id_producto integer Identificador del producto en Facturador Virtual. unidadMedidaComercial string Unidad de medida comercial, máximo 20 caracteres. tipoTransaccion string Código de tipo de transacción de la versión 4.4. tipoDescuento string Código del tipo de descuento, máximo 2 caracteres. Si se omite se asume 08 . tipoDescuentoOtro string Descripción cuando tipoDescuento corresponde a «otros». Entre 5 y 100 caracteres. 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 y formaFarmaceutica . es_combo boolean Marca la línea como combo. Los componentes se envían en componentes . 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. "impuestos": { "01": { "tarifa": "01" } } 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 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": "50622032000070175094600400001080000000009118491223", "consecutivo": "00400001080000000009", "recepcion": "recibido", "comprobacion": "por_comprobar" }, "errores": [] } El tipo de documento 08 dentro del consecutivo identifica la factura electrónica de compra. 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. 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. 500 {"0": "Ha ocurrido un error", "error": "...", "stack": [...]} Error no controlado durante el procesamiento. 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 .