⚡ Inicio Rápido
Para levantar el servidor localmente en PowerShell con la clave de sesión generada:
# 1. Crear entorno y activar dependencias
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
# 2. Generar clave segura y asignarla al portapapeles y entorno
$env:SRI_API_KEY = .\.venv\Scripts\python.exe -c "import secrets; print(secrets.token_urlsafe(32))"
$env:SRI_API_KEY | Set-Clipboard
# 3. Arrancar la API
.\.venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000
/docs)?Una vez levantado Uvicorn, haz clic en el botón "Abrir Swagger UI (/docs)" en la barra lateral. Haz clic en el botón verde Authorize 🔓 en la esquina superior derecha y pega tu
SRI_API_KEY. Todos los endpoints quedarán listos para probar interactivamente con "Try it out".
🔐 Autenticación
Todas las llamadas requieren autenticación mediante encabezado HTTP con la clave definida en SRI_API_KEY. Puedes usar cualquiera de las dos formas:
| Encabezado | Ejemplo de Formato | Descripción |
|---|---|---|
X-API-Key |
X-API-Key: eB2u9f_zX4-k7qR... |
Encabezado estándar recomendado para clientes REST y scripts. |
Authorization |
Authorization: Bearer eB2u9f_zX4-k7qR... |
Formato Bearer Token (ideal para librerías HTTP estándar). |
🔄 Flujo de Emisión: 2 Formas de Usar la API
La API ofrece dos modalidades según tus necesidades de integración:
Ruta /api (Recomendada)
Tú envías los datos de la venta con un Idempotency-Key. La API guarda el emisor, genera el XML, firma, envía al SRI, gestiona los reintentos en segundo plano y produce el RIDE en PDF automáticamente.
Ruta Directa (Paso a Paso)
Para ERPs que desean controlar manualmente cada etapa: POST /invoices (generar) ➔ POST /documents/{access_key}/send (firmar y enviar) ➔ POST /documents/{access_key}/check (consultar estado).
🩺 Estado del Sistema & Monitoreo
Endpoint público para sondas de disponibilidad, monitoreo de la base de datos y métricas de emisores activos:
curl -X GET "http://127.0.0.1:8000/health"
{
"status": "ok",
"database": "conectada",
"ambiente": "PRUEBAS",
"multitenant": true,
"total_tenants": 3,
"tenants_activos": 3,
"certificado_configurado": true,
"emisor_ruc_configurado": true
}
🏢 Gestión Multitenant de Certificados Digitales (.p12)
Permite a una sola instancia de la API firmar comprobantes para múltiples empresas o RUCs de forma aislada.
Los certificados .p12 y sus contraseñas se almacenan cifrados en reposo mediante AES-256-GCM.
| Endpoint | Método | Descripción |
|---|---|---|
/tenants |
POST | Registra un emisor enviando el certificado .p12 codificado en Base64. |
/tenants/upload |
POST | Carga directa del archivo .p12 o .pfx mediante multipart/form-data. |
/tenants |
GET | Lista todos los emisores registrados, estado de vigencia y días restantes de la firma. |
/tenants/{ruc} |
GET | Consulta el detalle, emisor de la firma y metadatos de un RUC específico. |
/tenants/{ruc}/health |
GET | Comprobación de salud de la firma (alerta si faltan menos de 30 días para su vencimiento). |
/tenants/{ruc}/toggle?active=true|false |
PATCH | Activa o inhabilita temporalmente la emisión para ese RUC. |
/tenants/{ruc} |
DELETE | Elimina el emisor y destruye su certificado digital del almacén seguro. |
$form = @{
file = Get-Item "C:\claves\firma_empresa.p12"
ruc = "1790000000001"
business_name = "Mi Empresa Multitenant S.A."
password = "ClaveDelCertificado123"
}
Invoke-RestMethod "http://127.0.0.1:8000/tenants/upload" `
-Method Post `
-Headers @{ 'X-API-Key' = $env:SRI_API_KEY } `
-Form $form
curl -X POST "http://127.0.0.1:8000/tenants/upload" \
-H "X-API-Key: TU_CLAVE_API" \
-F "file=@/ruta/a/firma.p12" \
-F "ruc=1790000000001" \
-F "business_name=Mi Empresa Multitenant S.A." \
-F "password=ClaveDelCertificado123"
curl -X POST "http://127.0.0.1:8000/tenants" \
-H "X-API-Key: TU_CLAVE_API" \
-H "Content-Type: application/json" \
-d '{
"ruc": "1790000000001",
"business_name": "Mi Empresa Multitenant S.A.",
"p12_base64": "MIIKYgIBAzCCCl4GCSqGSIb3DQEHAaCCCK8EggirMII...==",
"password": "ClaveDelCertificado123"
}'
🔢 Control y Configuración de Secuenciales
Los secuenciales del SRI se incrementan de forma automática, atómica y aislada por serie:
{ambiente}-{ruc}-{tipo_doc}-{establecimiento}-{punto_emision}.
Si tu empresa ya venía emitiendo en otro sistema o sucursal y necesitas fijar el siguiente secuencial de arranque, utiliza POST /api/sequential:
# Configurar para que la serie empiece en el secuencial 500
curl -X POST "http://127.0.0.1:8000/api/sequential" \
-H "X-API-Key: TU_CLAVE_API" \
-H "Content-Type: application/json" \
-d '{
"series": "1-1790000000001-01-001-001",
"next_sequential": 500
}'
$config = @{
series = "1-1790000000001-01-001-001"
next_sequential = 500
}
Invoke-RestMethod "http://127.0.0.1:8000/api/sequential" `
-Method Post `
-Headers @{ 'X-API-Key' = $env:SRI_API_KEY } `
-ContentType "application/json" `
-Body ($config | ConvertTo-Json)
# Consultar el secuencial actual emitido para la serie
curl -X GET "http://127.0.0.1:8000/api/sequential/1-1790000000001-01-001-001" \
-H "X-API-Key: TU_CLAVE_API"
🏢 1. Configurar Perfil del Emisor
Configura una sola vez los datos de tu empresa para el ambiente actual (Certificación o Producción).
Guarda el RUC, razón social, serie (establecimiento + punto de emisión) y dirección matriz.
curl -X PUT "http://127.0.0.1:8000/api/issuer" \
-H "X-API-Key: TU_CLAVE_API" \
-H "Content-Type: application/json" \
-d '{
"ruc": "1790000000001",
"razon_social": "ACME SOLUCIONES S.A.S.",
"dir_matriz": "Av. Amazonas y Naciones Unidas, Quito",
"dir_establecimiento": "Av. Amazonas y Naciones Unidas, Quito",
"establecimiento": "001",
"punto_emision": "001",
"obligado_contabilidad": "NO"
}'
$headers = @{ 'X-API-Key' = $env:SRI_API_KEY; 'Content-Type' = 'application/json' }
$emisor = @{
ruc = "1790000000001"
razon_social = "ACME SOLUCIONES S.A.S."
dir_matriz = "Av. Amazonas y Naciones Unidas, Quito"
dir_establecimiento = "Av. Amazonas y Naciones Unidas, Quito"
establecimiento = "001"
punto_emision = "001"
obligado_contabilidad = "NO"
}
Invoke-RestMethod "http://127.0.0.1:8000/api/issuer" -Method Put -Headers $headers -Body ($emisor | ConvertTo-Json)
import requests
headers = {"X-API-Key": "TU_CLAVE_API"}
data = {
"ruc": "1790000000001",
"razon_social": "ACME SOLUCIONES S.A.S.",
"dir_matriz": "Av. Amazonas y Naciones Unidas, Quito",
"dir_establecimiento": "Av. Amazonas y Naciones Unidas, Quito",
"establecimiento": "001",
"punto_emision": "001",
"obligado_contabilidad": "NO"
}
res = requests.put("http://127.0.0.1:8000/api/issuer", json=data, headers=headers)
print(res.json())
{
"ruc": "1790000000001",
"razon_social": "ACME SOLUCIONES S.A.S.",
"dir_matriz": "Av. Amazonas y Naciones Unidas, Quito",
"dir_establecimiento": "Av. Amazonas y Naciones Unidas, Quito",
"establecimiento": "001",
"punto_emision": "001",
"obligado_contabilidad": "NO"
}
🧾 2. Emitir Factura Electrónica (Asíncrona)
Envía la venta usando el encabezado Idempotency-Key. Si la red falla o reintentas, el servidor devuelve el mismo documento sin duplicar la numeración tributaria.
curl -X POST "http://127.0.0.1:8000/api/documents/invoice" \
-H "X-API-Key: TU_CLAVE_API" \
-H "Idempotency-Key: factura-orden-1002" \
-H "Content-Type: application/json" \
-d '{
"fecha": "2026-10-30",
"comprador": {
"tipo": "05",
"identificacion": "1710034065",
"razon_social": "JUAN PEREZ GONZALEZ",
"direccion": "Quito, Ecuador"
},
"forma_pago": "20",
"lineas": [
{
"codigo": "SERV-001",
"descripcion": "Consultoría Técnica en Facturación",
"cantidad": "1",
"precio_unitario": "50.00",
"descuento": "0.00",
"codigo_iva": "4"
},
{
"codigo": "LIB-002",
"descripcion": "Manual Impreso de Normativas",
"cantidad": "2",
"precio_unitario": "15.00",
"descuento": "5.00",
"codigo_iva": "0"
}
]
}'
$headers = @{
'X-API-Key' = $env:SRI_API_KEY
'Idempotency-Key' = "orden-$((Get-Date).Ticks)"
'Content-Type' = 'application/json'
}
$payload = @{
fecha = (Get-Date -Format yyyy-MM-dd)
comprador = @{
tipo = "05"
identificacion = "1710034065"
razon_social = "JUAN PEREZ GONZALEZ"
direccion = "Quito"
}
forma_pago = "20"
lineas = @(
@{ codigo = "SERV-001"; descripcion = "Servicio Profesional"; cantidad = "1"; precio_unitario = "50.00"; descuento = "0.00"; codigo_iva = "4" }
)
}
$res = Invoke-RestMethod "http://127.0.0.1:8000/api/documents/invoice" -Method Post -Headers $headers -Body ($payload | ConvertTo-Json -Depth 6)
Write-Host "Clave generada:" $res.clave
Write-Host "Estado inicial:" $res.estado
import datetime, requests
headers = {
"X-API-Key": "TU_CLAVE_API",
"Idempotency-Key": f"venta-{datetime.datetime.now().timestamp()}"
}
payload = {
"fecha": datetime.date.today().isoformat(),
"comprador": {
"tipo": "05",
"identificacion": "1710034065",
"razon_social": "JUAN PEREZ",
"direccion": "Quito"
},
"forma_pago": "20",
"lineas": [
{"codigo": "ITM-1", "descripcion": "Servicio de Integración", "cantidad": "1", "precio_unitario": "100.00", "codigo_iva": "4"}
]
}
res = requests.post("http://127.0.0.1:8000/api/documents/invoice", json=payload, headers=headers)
print("Respuesta:", res.status_code, res.json())
{
"fecha": "2026-10-30",
"comprador": {
"tipo": "05",
"identificacion": "1710034065",
"razon_social": "JUAN PEREZ",
"direccion": "Quito"
},
"forma_pago": "20",
"lineas": [
{
"codigo": "SERV-001",
"descripcion": "Servicio de desarrollo",
"cantidad": "1",
"precio_unitario": "100.00",
"descuento": "0.00",
"codigo_iva": "4"
}
]
}
↩️ 3. Emitir Nota de Crédito
Acredita una o varias líneas específicas de una factura previamente autorizada. La API previene devoluciones duplicadas de la misma línea.
curl -X POST "http://127.0.0.1:8000/api/documents/credit-note" \
-H "X-API-Key: TU_CLAVE_API" \
-H "Idempotency-Key: devolucion-nota-001" \
-H "Content-Type: application/json" \
-d '{
"fecha": "2026-10-30",
"factura": "3010202601179000000000110010010000000011234567813",
"motivo": "Devolución de ítem por inconformidad de servicio",
"lineas": [1]
}'
📑 4. Consultar Estado, Descargar RIDE (PDF) y XML
Una vez que el documento alcanza el estado AUTORIZADO, puedes obtener el PDF oficial y el XML firmado:
| Endpoint | Método | Retorno | Descripción |
|---|---|---|---|
/api/documents |
GET | JSON (Lista) | Historial ordenado de comprobantes emitidos por el RUC. |
/api/documents/{access_key} |
GET | JSON (Detalle) | Estado tributario actual (RECIBIDA, AUTORIZADO, etc.) y reintentos. |
/api/documents/{access_key}/ride |
GET | application/pdf |
RIDE Oficial en PDF con código de barras, desglose y logotipo. |
/api/documents/{access_key}/xml |
GET | application/xml |
XML con firma digital XAdES-BES y sobre de autorización del SRI. |
# Descargar el PDF RIDE con PowerShell
$clave = "3010202601179000000000110010010000000011234567813"
Invoke-WebRequest "http://127.0.0.1:8000/api/documents/$clave/ride" `
-Headers @{ 'X-API-Key' = $env:SRI_API_KEY } `
-OutFile "factura-$clave.pdf"
⚙️ API Directa: Generación, Firma y Transmisión Paso a Paso
Diseñada para integraciones con ERPs o sistemas comerciales que gestionan individualmente cada fase del comprobante:
| Paso | Endpoint | Método | Descripción |
|---|---|---|---|
| 1. Crear | /invoices o /credit-notes |
POST | Genera la clave de acceso de 49 dígitos, asigna el secuencial por serie y construye el XML 2.1.0 inicial. |
| 2. Firmar y Enviar | /documents/{access_key}/send |
POST | Firma en formato XAdES-BES 1.3.2 usando el certificado del emisor y transmite al servicio SOAP de recepción del SRI. |
| 3. Consultar SRI | /documents/{access_key}/check |
POST | Consulta el resultado de la autorización con el SRI y actualiza el estado a AUTORIZADO o DEVUELTA. |
| 4. Descargar XML | /documents/{access_key}/xml?version=autorizado |
GET | Descarga el XML final con el sobre oficial de autorización del SRI (o ?version=firmado para el XML enviado). |
$headers = @{ 'X-API-Key' = $env:SRI_API_KEY }
$base = "http://127.0.0.1:8000"
# 1. Crear la factura y obtener la clave de acceso
$factura = Invoke-RestMethod "$base/invoices" -Method Post -Headers $headers `
-ContentType 'application/json' -InFile ".\ejemplos\factura.json"
$clave = $factura.clave
Write-Host "Comprobante creado con clave: $clave"
# 2. Firmar con el certificado del emisor y enviar al SRI
$envio = Invoke-RestMethod "$base/documents/$clave/send" -Method Post -Headers $headers
Write-Host "Estado de recepción SRI: $($envio.estado)"
# 3. Consultar autorización
Start-Sleep -Seconds 3
$auth = Invoke-RestMethod "$base/documents/$clave/check" -Method Post -Headers $headers
Write-Host "Estado final SRI: $($auth.estado)"
# 4. Descargar XML autorizado
Invoke-RestMethod "$base/documents/$clave/xml?version=autorizado" -Headers $headers -OutFile "$clave-autorizado.xml"
# 1. Crear documento
curl -X POST "http://127.0.0.1:8000/invoices" \
-H "X-API-Key: TU_CLAVE_API" \
-H "Content-Type: application/json" \
-d @factura.json
# 2. Firmar y transmitir
curl -X POST "http://127.0.0.1:8000/documents/CLAVE_DE_ACCESO/send" \
-H "X-API-Key: TU_CLAVE_API"
# 3. Consultar estado
curl -X POST "http://127.0.0.1:8000/documents/CLAVE_DE_ACCESO/check" \
-H "X-API-Key: TU_CLAVE_API"
# 4. Descargar XML autorizado
curl -X GET "http://127.0.0.1:8000/documents/CLAVE_DE_ACCESO/xml?version=autorizado" \
-H "X-API-Key: TU_CLAVE_API" -o factura.xml
{
"id_operacion": "venta-sucursal-002-881",
"fecha": "2026-11-01",
"emisor": {
"ruc": "1790000000001",
"razon_social": "Mi Empresa S.A.",
"dir_matriz": "Quito, Av. Amazonas N21-15",
"dir_establecimiento": "Guayaquil, Av. 9 de Octubre 104",
"establecimiento": "002",
"punto_emision": "001",
"obligado_contabilidad": "SI",
"contribuyente_especial": "5368",
"agente_retencion": "1",
"regimen_rimpe": "CONTRIBUYENTE RÉGIMEN RIMPE"
},
"comprador": {
"tipo": "07",
"identificacion": "9999999999999",
"razon_social": "CONSUMIDOR FINAL",
"direccion": "Ecuador"
},
"pagos": [
{
"medio": "20",
"total": "28.75",
"plazo": 30,
"unidad_tiempo": "dias"
}
],
"campos_adicionales": [
{"nombre": "Email", "valor": "[email protected]"},
{"nombre": "Observacion", "valor": "Entrega a domicilio sin costo"}
],
"lineas": [
{
"codigo": "PROD-01",
"descripcion": "Producto con IVA 15%",
"cantidad": "1",
"precio_unitario": "25.00",
"descuento": "0.00",
"codigo_iva": "4"
}
]
}
📊 Catálogos Oficiales del SRI (Ficha 2.34)
Tabla 17: Códigos de Tarifa del IVA
codigo_iva |
Porcentaje | Detalle |
|---|---|---|
"4" | 15% | Tarifa estándar vigente general (marzo 2024 en adelante) |
"0" | 0% | Bienes o servicios con tarifa 0% |
"5" | 5% | Materiales de construcción y proyectos calificados |
"2" | 12% | Tarifa histórica 12% |
"6" | 0% | No objeto de impuesto |
"7" | 0% | Exento de IVA |
Tipos de Identificación de Comprador
| Código | Tipo | Identificación requerida | Validación |
|---|---|---|---|
"04" | RUC | 13 dígitos (ej: 1790000000001) | Algoritmo Módulo 11 oficial |
"05" | Cédula de Identidad | 10 dígitos (ej: 1710034065) | Algoritmo Módulo 10 oficial |
"06" | Pasaporte | Alfanumérico (hasta 13 caracteres) | Sin caracteres especiales |
"07" | Consumidor Final | 9999999999999 | Hasta USD $50.00 según normativa |
"08" | Identificación del Exterior | Alfanumérico extranjero | Compradores sin residencia en Ecuador |
Tabla 24: Formas de Pago
| Código | Descripción |
|---|---|
"01" | Sin utilización del sistema financiero (Efectivo) |
"16" | Tarjeta de débito |
"19" | Tarjeta de crédito |
"20" | Otros con utilización del sistema financiero (Transferencia bancaria / Cheque) |