SDK Python

Cliente oficial de la API para Python. Cubre autenticacion, idempotencia, reintentos y firma de webhook.

  • Paquete: ecuafact.
  • Dependencias: httpx y pydantic (v2).

Como se instala#

pip install ecuafact

Configuracion#

import os
from ecuafact import EcuafactClient, EcuafactClientOptions

client = EcuafactClient(EcuafactClientOptions(
    base_address="https://staging-api.mynexusapi.com/",
    api_key=os.environ["ECUAFACT_API_KEY"],
    identificacion="1790012345001",  # solo integraciones de un RUC
))
Opcion Default Descripcion
base_address - Direccion base del API (obligatoria; define el ambiente)
api_key - API Key (obligatoria)
identificacion None RUC por defecto (opcional)
timeout 100.0 Tiempo maximo por intento (segundos)
user_agent Ecuafact.Sdk/1.0 User-Agent
retry_transient_failures True Reintenta 408/425/429/5xx
max_attempts 3 Intentos por solicitud
respect_retry_after True Respeta Retry-After en 429/503
max_retry_delay_ms 60000 Espera maxima entre reintentos

Metodos#

Metodo Que hace Devuelve
emitir(comprobante) Emite para el RUC por defecto EmisionResultado
emitir_en(ruc, comprobante) Emite para un RUC explicito EmisionResultado
para(ruc) Fija un contribuyente EcuafactContribuyente
get_operacion(id) Consulta el seguimiento de la operacion Operation
get_contexto() Contexto de tu API Key Contexto
get_consumo() Cupo disponible QuotaBucket
listar_emitidos(...) Listan comprobantes PaginaComprobantes
consultar_contribuyente(id) Consulta un contribuyente en el SRI ContribuyenteConsulta
buscar_contribuyentes(...) Busca por nombre list[BusquedaContribuyente]
listar_establecimientos(ruc) Establecimientos de un RUC EstablecimientosContribuyente
validar_identificacion(numero) Valida el formato (sin red) ValidacionIdentificacion
decodificar_clave_acceso(clave) Descompone una clave de acceso ClaveAccesoDecodificada
verify(...) Verifica la firma de un webhook bool

Emision#

from ecuafact import ComprobanteRequest, InfoTributaria

resultado = client.emitir(ComprobanteRequest(
    origen_referencia="MiERP",
    referencia_externa="FACTURA-2026-0001",
    info_tributaria=InfoTributaria(
        ruc="1790012345001", cod_doc="01", estab="002", pto_emi="001", secuencial="000000123"
    ),
    info={
        "fechaEmision": "01/01/2026",
        "tipoIdentificacionComprador": "04",
        "identificacionComprador": "1790012345001",
        "razonSocialComprador": "Cliente Ejemplo",
        "totalSinImpuestos": 100.0,
        "totalDescuento": 0.0,
        "totalConImpuestos": [
            {"codigo": "2", "codigoPorcentaje": "4", "baseImponible": 100.0, "valor": 15.0}
        ],
        "importeTotal": 115.0,
        "moneda": "DOLAR",
        "pagos": [{"formaPago": "01", "total": 115.0}],
    },
    detalles=[{
        "codigoPrincipal": "SERV-001",
        "descripcion": "Servicio de ejemplo",
        "cantidad": 1,
        "precioUnitario": 100.0,
        "descuento": 0.0,
        "precioTotalSinImpuesto": 100.0,
        "impuestos": [
            {"codigo": "2", "codigoPorcentaje": "4", "tarifa": 15.0, "baseImponible": 100.0, "valor": 15.0}
        ],
    }],
))
print(resultado.admission.id_operacion, resultado.admission.codigo)

Emision con RUC explicito: client.emitir_en("1790012345001", comprobante).

Multi-RUC#

ruc = client.para("1790099987001")
pagina = ruc.listar_emitidos()

Estado y consultas#

operacion = client.get_operacion("3f1c8c1e-6f2a-4b7e-9c3d-2a1b0c9d8e7f")
contexto = client.get_contexto()
cupo = client.get_consumo()

Consultas SRI#

Consultas al SRI (contribuyentes, establecimientos, identificaciones y claves de acceso). Son de solo lectura, no consumen cupo y usan la misma API Key.

contribuyente = client.consultar_contribuyente("1760013210001")
encontrados = client.buscar_contribuyentes("PEREZ LOPEZ", "JUAN", "PersonaNatural", 10)
establecimientos = client.listar_establecimientos("1760013210001", "SoloActivos")
validacion = client.validar_identificacion("1760013210001")
clave = client.decodificar_clave_acceso(clave_acceso)

Idempotencia#

idempotency_key es opcional: si no se envia, el SDK la genera, la reutiliza en los reintentos y la devuelve en resultado.idempotency_key (y en el error, como EcuafactApiException.idempotency_key). Al reintentar, reutiliza la clave devuelta. La correlacion de la respuesta queda en resultado.correlation_id (o EcuafactApiException.id_seguimiento en error). Los fallos transitorios (408/425/429/5xx) se reintentan respetando Retry-After; el resto de los 4xx no.

Webhooks#

from ecuafact import verify

valido = verify(secreto, cabecera, cuerpo_crudo, tolerance_seconds=300)

Ve Verificacion de firma y Webhooks.

Errores#

from ecuafact import EcuafactApiException

try:
    client.emitir(comprobante)
except EcuafactApiException as error:
    print(error.codigo, error.mensaje, error.errores, error.id_seguimiento)

EcuafactApiException trae codigo, mensaje, estado_http, id_seguimiento, errores e idempotency_key. Los errores locales son EcuafactSdkException.

Siguientes pasos#

No se pudo completar la operacion. Recargar ✕