Docs / API Reference / Facturas
API Reference

Facturas

Crear y gestionar comprobantes electrónicos. El endpoint principal (POST /api/v1/facturas) es asíncrono: responde con la factura en PENDIENTE y la autoriza en background.

Crear un comprobante

POST /api/v1/facturas — Crea un comprobante (async)

Body

Parámetro Tipo Descripción
tipo_identificacion required string Tipo de identificación del comprador (tabla SRI): '04' RUC, '05' cédula, '06' pasaporte, '07' consumidor final, '08' id. del exterior.
identificacion required string RUC (13 dígitos), cédula (10) o documento según el tipo.
razon_social required string Nombre o razón social del comprador. Máx 300 caracteres.
direccion optional string Dirección del comprador (se imprime en el RIDE).
email optional string Email del comprador; se usa al enviar el RIDE por correo.
detalles required array Líneas del comprobante. Mínimo 1.
sucursal_id optional integer Sucursal emisora (estab/punto de emisión). Si se omite, se infiere del usuario o de la matriz.
es_borrador optional boolean Si true, se guarda como BORRADOR y no se envía al SRI. Default: false.
idempotency_key optional string Idempotencia (también vía header Idempotency-Key): reintentar con la misma key devuelve la MISMA factura (200) en vez de crear otra.
pagos optional array Formas de pago (split). Si se omite, se registra un único pago '01' (efectivo) por el total. Cada elemento tiene 'forma_pago' (código Tabla 24 SRI), 'total', y opcionalmente 'plazo'+'unidadTiempo' ('dias') para crédito.
condicion_pago optional string 'contado' (default) o 'credito'. Si 'credito', se exige 'fecha_vencimiento'.
fecha_vencimiento optional date Solo si 'condicion_pago'='credito' (YYYY-MM-DD).
propina optional number Propina / 10% de servicio en USD (≥ 0). Solo para empresas marcadas como restaurante, bar u hotel. Suma al total y no grava IVA. Default: 0. Ver propina.

Forma de pagos[] (Tabla 24 SRI)

Parámetro Tipo Descripción
forma_pago required string Código de la Tabla 24 SRI: '01' efectivo, '15' compensación, '16' T. débito, '17' dinero electrónico, '18' T. prepago, '19' T. crédito, '20' otros, '21' endoso.
total required number Monto del pago en USD. La Σ de todos los pagos debe cuadrar (tolerancia ±0.01) con el total de la factura (incluida la propina, si la hay).
plazo optional integer Plazo del pago a crédito (entero ≥ 1). Solo si aplica.
unidad_tiempo optional string Unidad del plazo. Únicamente 'dias' está soportado por el SRI.

Forma de detalles[]

Parámetro Tipo Descripción
codigo_principal required string Código del producto/servicio (codigoPrincipal del SRI). Máx 25 caracteres.
descripcion required string Texto que aparece en el RIDE. Máx 300 caracteres.
cantidad required number Cantidad, mayor a 0. Hasta 6 decimales.
precio_unitario required number Precio sin impuestos, en USD. Hasta 6 decimales.
descuento optional number Descuento por línea en valor absoluto (no porcentaje). Default: 0.
tarifa_iva optional integer Tarifa de IVA (%): 0, 5 ó 15. Default: 15.
iva_codigo optional string codigoPorcentaje del SRI si necesitas distinguir 0% ('0') de exento ('7') o no objeto ('6'). Si se omite, se deriva de tarifa_iva.

Respuesta (201 Created)

{
  "id": 177,
  "numero_comprobante": "001-001-000000177",
  "fecha_emision": "2026-07-03T10:12:34",
  "tipo_identificacion": "04",
  "identificacion": "0991234567001",
  "razon_social": "ACME S.A.",
  "direccion": null,
  "email": "facturacion@acme.example",
  "subtotal_0": 0.0,
  "subtotal_15": 75.0,
  "iva": 11.25,
  "total": 86.25,
  "propina": 0.0,
  "estado": "PENDIENTE",
  "clave_acceso": null,
  "numero_autorizacion": null,
  "fecha_autorizacion": null,
  "estado_sri": null,
  "detalles": [ { "...": "..." } ],
  "pagos": [ { "forma_pago": "01", "total": 86.25 } ]
}
import { Emitoo } from "emitoo";

const client = new Emitoo(); // lee la API key de EMITOO_API_KEY

const factura = await client.facturas.crear(
  {
    tipo_identificacion: "04",
    identificacion: "0991234567001",
    razon_social: "ACME S.A.",
    email: "facturacion@acme.example",
    detalles: [
      { codigo_principal: "LIC-1", descripcion: "Licencia mensual",
        cantidad: 1, precio_unitario: 75.0, tarifa_iva: 15 },
    ],
  },
  { idempotencyKey: "order-90210" },
);

¿Cuándo se considera autorizada?

El POST responde en milisegundos con PENDIENTE. La firma, envío y respuesta del SRI ocurren en segundo plano. Te avisamos por webhook (factura.autorizada) cuando el comprobante queda firme, o puedes hacer polling a /status.

Propina (10% de servicio)

Restaurantes, bares y hoteles pueden cobrar la propina en la misma factura con el campo propina. Va en el elemento <propina> del XML, se suma a importeTotal (y al total de la factura, que es lo que el cliente debe), no grava IVA y se imprime en el RIDE. Las pagos[] deben cuadrar con el total ya incluida la propina.

  • Solo la aceptan las empresas marcadas como Restaurante, bar u hotel en Configuración; si no, 400.
  • Una factura dividida en partes (POST /api/v1/facturas/lote) no puede llevar propina (400).
  • No se acredita con nota de crédito: el tope de una NC sobre esa factura es su total sin la propina.
{
  "tipo_identificacion": "07",
  "identificacion": "9999999999999",
  "razon_social": "CONSUMIDOR FINAL",
  "detalles": [
    { "codigo_principal": "MENU-1", "descripcion": "Almuerzo ejecutivo",
      "cantidad": 2, "precio_unitario": 10.00, "tarifa_iva": 15 }
  ],
  "propina": 2.00,
  "pagos": [ { "forma_pago": "01", "total": 25.00 } ]
}

Subtotal 20,00 + IVA 3,00 + propina 2,00 = total 25,00.

RUC Proveedor en el XML

Desde el 26 de septiembre de 2026 el SRI exige que todo comprobante electrónico identifique al proveedor del sistema de facturación. Emitoo agrega en infoAdicional de los seis tipos de comprobante (factura, nota de crédito, nota de débito, guía de remisión, retención y liquidación de compra) el campo <campoAdicional nombre="RUC Proveedor">0993411199001</campoAdicional>. Va como primer campo adicional, antes del email y la descripción del comprobante. No tienes que enviarlo ni configurarlo.

Obtener un comprobante

GET /api/v1/facturas/{id} — Detalle completo, con líneas

Consultar el estado

GET /api/v1/facturas/{id}/status — Solo el estado actual (más liviano)

{
  "id": 177,
  "estado": "AUTORIZADO",
  "clave_acceso": "0307202601099336782800110010010000001771234567813",
  "numero_autorizacion": "0307202601099336782800110010010000001771234567813",
  "fecha_autorizacion": "2026-07-03T10:12:48",
  "estado_sri": "[AUTORIZADO]"
}

Estados posibles: BORRADOR, PENDIENTE, PROCESANDO, EN_PROCESO (recibida por el SRI, esperando autorización), AUTORIZADO, RECHAZADO y DEVUELTA (la recepción del SRI no la aceptó). Más detalle en estados de un comprobante.

Reenviar un comprobante

POST /api/v1/facturas/{id}/reenviar — Re-encola la factura para el worker (sin body)

Si la factura fue DEVUELTA o RECHAZADO, se re-emite con clave de acceso nueva (corrige primero la causa, p.ej. la configuración del emisor). Si está colgada (PENDIENTE / EN_PROCESO), conserva la clave y solo se re-consulta la autorización, sin duplicar. Con una factura ya AUTORIZADO responde 409. El motivo del rechazo viene en estado_sri (en GET /facturas/{id} o /status).

Descargar el RIDE en PDF

GET /api/v1/facturas/{id}/ride — Devuelve el PDF binario

Devuelve el PDF del RIDE con Content-Type: application/pdf, generado con el logo y colores configurados en tu empresa.

Enviar el comprobante por email

POST /api/v1/facturas/{id}/email — Envía el RIDE al cliente final (sin body)

Query params

Parámetro Tipo Descripción
to optional string Dirección de destino. Si se omite, usa el email del comprador en la factura (400 si no hay ninguno).

Listar comprobantes

GET /api/v1/facturas?desde=&hasta=&estado=&q=&cliente_id=&con_saldo=&limit=&offset= — Listado compacto (id, número, fecha, cliente, total, estado, ambiente)

Parámetro Tipo Descripción
desde / hasta optional date Fecha de emisión (inclusive).
estado optional string Estado exacto: PENDIENTE, EN_PROCESO, AUTORIZADO, RECHAZADO, DEVUELTA, ANULADO…
q optional string Busca en razón social del cliente, identificación y número de comprobante.
cliente_id optional integer Solo las del cliente del catálogo con ese id.
con_saldo optional boolean true = solo las AUTORIZADO con saldo por cobrar.
limit / offset optional integer Paginación. Sin parámetros devuelve las últimas 100.
format optional string 'csv' = el mismo listado como archivo CSV (UTF-8 con BOM, para que Excel muestre bien las tildes). Sin limit no se trunca a 100 (tope 50 000).

Resumen de ventas

GET /api/v1/facturas/resumen — Tablero: ventas de hoy, la semana y el mes, serie de 30 días, pendientes ante el SRI, cartera y top de clientes

Devuelve hoy, semana, mes, mes_anterior, serie (últimos 30 días), pendientes_sri, por_cobrar, top_clientes del mes, ambiente_sri, tiene_certificado y cert_expira (vencimiento de la firma electrónica). Respeta el mismo alcance que el listado.