🌎LATAMArtículo

Cómo integrar el API del ATV de Costa Rica: autenticación, flujo asíncrono y manejo de errores

Guía técnica de integración con el ATV de Costa Rica: autenticación por token, flujo asíncrono de envío y consulta, callback de confirmación, modo sin internet y categorías de error del Ministerio de Hacienda.

Ing. Carlos Méndez
Arquitecto de Software · Integraciones Fiscales LATAM
4 min lectura5 de julio de 2026
Cómo integrar el API del ATV de Costa Rica: autenticación, flujo asíncrono y manejo de errores

Integrar el sistema de facturación electrónica de Costa Rica requiere interactuar con el API del ATV (Administración Tributaria Virtual) del Ministerio de Hacienda. Esta integración tiene particularidades que la diferencian de otros sistemas de LATAM: el modelo asíncrono de validación, la autenticación vía token del sistema TRIBU-CR, y el manejo del modo sin internet.

Si usted ya tiene experiencia con sistemas de facturación de otros países, le recomendamos leer esta guía aun así: el modelo asíncrono del ATV requiere ajustes específicos en la arquitectura del sistema que no son evidentes desde la experiencia con sistemas síncronos.

Autenticación con el ATV: token TRIBU-CR

El ATV de Costa Rica usa un sistema de tokens para autenticación. El flujo es: (1) obtener un token de acceso usando las credenciales del contribuyente, (2) usar ese token en el header de autenticación de cada llamada al API del ATV, (3) renovar el token cuando expire. Los tokens del ATV tienen vigencia de 30 minutos.

python
atv_client.py
# Autenticación ATV Costa Rica — pseudocódigo
import requests
from datetime import datetime, timedelta

class ATVClient:
    TOKEN_URL = "https://idp.comprobanteselectronicos.go.cr/auth/realms/rut/protocol/openid-connect/token"
    API_URL = "https://api.comprobanteselectronicos.go.cr/recepcion/v1"

    def __init__(self, usuario, contrasena):
        self.usuario = usuario
        self.contrasena = contrasena
        self._token = None
        self._token_expiry = None

    def get_token(self):
        if self._token and datetime.utcnow() < self._token_expiry - timedelta(minutes=5):
            return self._token
        resp = requests.post(self.TOKEN_URL, data={
            'grant_type': 'password',
            'client_id': 'api-prod',
            'username': self.usuario,
            'password': self.contrasena
        })
        data = resp.json()
        self._token = data['access_token']
        self._token_expiry = datetime.utcnow() + timedelta(seconds=data['expires_in'])
        return self._token

    def enviar_comprobante(self, clave, xml_b64, fecha, emisor_tipo, emisor_id, receptor_tipo, receptor_id):
        payload = {
            "clave": clave,
            "fecha": fecha,
            "emisor": {"tipoIdentificacion": emisor_tipo, "numeroIdentificacion": emisor_id},
            "receptor": {"tipoIdentificacion": receptor_tipo, "numeroIdentificacion": receptor_id},
            "comprobanteXml": xml_b64
        }
        return requests.post(
            f"{self.API_URL}/recepcion",
            json=payload,
            headers={"Authorization": f"Bearer {self.get_token()}"}
        )

El modelo asíncrono del ATV: envío y consulta

A diferencia de otros sistemas de LATAM donde la respuesta de aceptación es síncrona, el ATV de Costa Rica usa un modelo de dos pasos: usted envía el comprobante y recibe inmediatamente un número de recepción y un estado HTTP 202. El procesamiento real ocurre en background, típicamente entre segundos y minutos después del envío.

Para obtener el resultado del procesamiento, usted puede consultar el endpoint de estado usando la Clave Numérica del comprobante. Alternativamente, puede registrar un callbackUrl en el payload de envío — el ATV hará un POST a ese URL cuando el procesamiento termine. El modo callback es preferible para sistemas de alto volumen.

Flujo completo de emisión y confirmación

El flujo completo recomendado es: (1) generar el XML, (2) firmarlo con el certificado BCCR, (3) convertir el XML firmado a Base64, (4) enviar al ATV con el payload de recepción, (5) almacenar el número de recepción y el estado 'enviado', (6) recibir la notificación del ATV vía callback o polling, (7) actualizar el estado a 'aceptado' o 'rechazado', (8) si fue rechazado, analizar los mensajes de error y corregir.

En el ambiente de certificación (CEN), el ATV procesa más lentamente que en producción. No extraer conclusiones sobre tiempos de procesamiento basados solo en pruebas en CEN.

Manejo de errores del ATV por categoría

Los errores del ATV se clasifican en tres categorías: HTTP 400 (error de formato en el payload de envío — problema en el JSON de recepción, no en el XML), HTTP 422 (el XML fue recibido pero tiene errores de validación de esquema o de firma), y HTTP 202 seguido de estado 'Rechazado' en la consulta (el ATV procesó el comprobante pero lo rechazó por reglas de negocio).

No reintentar automáticamente un comprobante rechazado por reglas de negocio sin corregir el error primero. El ATV puede detectar envíos repetidos y limitar la tasa de envíos del contribuyente.

El modo sin internet: contingencia en Costa Rica

Cuando la conectividad con el ATV no está disponible, el sistema puede generar comprobantes en 'modo sin internet' (situación 3 en la Clave Numérica). Estos comprobantes tienen validez provisional y deben transmitirse al ATV dentro de los 2 días hábiles siguientes. La implementación requiere una cola local de comprobantes pendientes de transmisión y un proceso periódico que los envíe cuando la conectividad se restablece.

Preguntas frecuentes

¿Cuál es el tiempo promedio de procesamiento del ATV en producción?

El Ministerio de Hacienda no publica SLA formales de tiempo de procesamiento. En la práctica, los comprobantes se procesan en segundos durante horario normal. En períodos de alta carga (cierres de mes) el tiempo puede aumentar a minutos. Diseñar el sistema para tolerar tiempos de procesamiento de hasta 15 minutos antes de marcar un comprobante como 'posiblemente fallido'.

¿Cómo puedo implementar el callback del ATV de forma segura?

El endpoint de callback debe verificar que la llamada proviene efectivamente del ATV. El ATV incluye en el POST de callback la Clave Numérica y el estado del comprobante. Validar que la Clave Numérica corresponde a un comprobante real del sistema antes de actualizar el estado. Implementar el callback detrás de autenticación por IP de origen o token compartido.

¿Qué diferencia hay entre el ambiente CEN y el ambiente de producción del ATV?

El CEN (Certificación y Pruebas) es el ambiente de pruebas del Ministerio de Hacienda. Usa endpoints distintos, credenciales distintas y los comprobantes generados no tienen validez fiscal. El catálogo de actividades económicas y contribuyentes puede diferir del de producción. Probar con contribuyentes y actividades que existen en ambos ambientes.

¿Es posible emitir comprobantes en nombre de otro contribuyente como proveedor de servicio?

Sí, existe la figura del proveedor de servicio de facturación que emite comprobantes a nombre del contribuyente usando sus propias credenciales ATV. El contribuyente debe autorizar explícitamente al proveedor en el sistema del Ministerio de Hacienda. Esta figura es la que usan los ISV que ofrecen facturación como servicio a sus clientes.