verifyApiUser.
apiwhatsapp. El dueño del trabajo es el id del API user. Un trabajo de Demo no puede leerse
ni descargarse desde Comercial ni desde otro usuario.
Autenticación
| Campo | Tipo | Descripción | |
|---|---|---|---|
ruc | string | requerido | RUC con el que se inicia sesión en el portal del SRI. No se persiste en base. |
clave | string | requerido | Clave del portal del SRI. Solo vive en memoria. No confundir con claveAcceso. |
fechaEmision | string | requerido | Fecha de emisión en YYYY-MM-DD o DD/MM/YYYY. Debe ser anterior a la fecha actual de Ecuador (America/Guayaquil). Hoy o futuro responde 400. |
estadoAutorizacion | string | opcional | Por defecto autorizados. También noAutorizados y porProcesar. |
tipo | string | opcional | Por defecto factura. Valores: factura, liquidacion, credito, debito, guia, retencion. Varios separados por coma. |
establecimiento | string | opcional | Tres dígitos, por ejemplo 001. Solo se envía si el formulario muestra el campo. |
puntoEmision | string | opcional | Tres dígitos. Solo se envía si el formulario muestra el campo. |
claveAcceso | string | opcional | Filtro de 49 dígitos (clave de acceso / número de autorización). No es la clave de login. |
identificacion | string | opcional | RUC, cédula o pasaporte del filtro de consulta, 10–13 dígitos. |
httpHandoff | boolean | opcional | Por defecto true. La descarga HTTP de TXT y XML se resuelve contra la URL absoluta del formulario JSF (recuperarComprobantes.jsf) con javax.faces.ViewState. Con false solo baja la primera página por clic. La API no descarga RIDE/PDF: rideDisponible indica si el portal expuso el enlace. |
soloReporte | boolean | opcional | Por defecto false. En true baja únicamente el TXT y no vuelve a pedir los XML. |
esperar | boolean | opcional | Por defecto true: el POST espera el trabajo real hasta SRI_ESPERA_HTTP_MS (máx. 120 s). Con false responde 202 de inmediato y hay que consultar el GET de estado. Si se agota el tiempo, responde 202 con esperaAgotada: true y el mismo jobId. |
fechaEmision es obligatoria. anio y mes no forman parte del cuerpo de emitidos (si se envían, se ignoran).
curl -X POST "https://apis.davycorp.ec/v2/docs-emitidos/demo" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ruc": "1790000000001",
"clave": "TU_CLAVE_SRI",
"fechaEmision": "2026-09-14",
"estadoAutorizacion": "autorizados",
"tipo": "factura"
}'await fetch("https://apis.davycorp.ec/v2/docs-emitidos/demo", {
method: "POST",
headers: {
Authorization: "Bearer TU_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
ruc: "1790000000001",
clave: "TU_CLAVE_SRI",
fechaEmision: "2026-09-14",
estadoAutorizacion: "autorizados",
tipo: "factura"
})
});import requests
requests.post(
"https://apis.davycorp.ec/v2/docs-emitidos/demo",
headers={"Authorization": "Bearer TU_API_KEY"},
json={
"ruc": "1790000000001",
"clave": "TU_CLAVE_SRI",
"fechaEmision": "2026-09-14",
"estadoAutorizacion": "autorizados",
"tipo": "factura",
},
){
"job_id": "8c1d0c2e-4b1a-4f0e-9c2a-6e5b1a0d4f11",
"estado": "pendiente",
"mensaje": "Descarga iniciada. Consulta el estado con el mismo prefijo de modalidad."
}{
"id": "JOB_ID",
"estado": "completado",
"modalidad": "demo",
"zip_url": "/v2/docs-emitidos/demo/JOB_ID/archivo",
"archivoUrl": "/v2/docs-emitidos/demo/JOB_ID/archivo",
"comprobantesUrl": "/v2/docs-emitidos/demo/JOB_ID/comprobantes",
"resultadoUrl": "/v2/docs-emitidos/demo/JOB_ID",
"error": null,
"creado": "2026-10-26T18:00:00.000Z",
"terminado": "2026-10-26T18:04:12.000Z"
}// 400 — cuerpo incompleto { "error": "ruc y clave son obligatorios" } // 400 — fecha hoy o futura { "error": "La fecha ingresada debe ser menor a la fecha actual" } // 401 — sin header Authorization { "error": "API Key requerida" } // 403 — API key inválida { "success": false, "error": "Api user inválido" } // 404 — job inexistente o de otro dueño { "error": "Job no encontrado" } // 409 — consultar comprobantes/archivo mientras se ejecuta { "error": "El trabajo sigue en ejecución" } // 429 — cupo del API user { "error": "Límite de consultas alcanzado", "status": false } // 500 — fallo interno { "error": "Error interno del servidor", "status": false }
| Método | Endpoint relativo | Función |
|---|---|---|
| GET | /v2/docs-emitidos/demo/:jobId | Consultar estado del trabajo. |
| GET | /v2/docs-emitidos/demo/:jobId/comprobantes | Obtener listado JSON de comprobantes. |
| GET | /v2/docs-emitidos/demo/:jobId/archivo | Descargar ZIP (cuando completado o parcial). |
| POST | /v2/docs-emitidos/demo/:jobId/cancelar | Cancelar trabajo si el estado lo permite. |
Los GET de esta API no incrementan el cupo. El POST que crea el trabajo sí pasa por el conteo existente.
verifyApiUser. No pasa por verifyLicense.
El dueño del trabajo es el id del API user, no el código de licencia. Aislamiento estricto respecto a Demo.
Autenticación
| Campo | Tipo | Descripción | |
|---|---|---|---|
ruc | string | requerido | RUC con el que se inicia sesión en el portal del SRI. |
clave | string | requerido | Clave del portal del SRI. Distinta de claveAcceso. |
fechaEmision | string | requerido | Fecha de emisión en YYYY-MM-DD o DD/MM/YYYY. Debe ser anterior a hoy en America/Guayaquil. |
estadoAutorizacion | string | opcional | Por defecto autorizados. También noAutorizados y porProcesar. |
tipo | string | opcional | Por defecto factura. Valores: factura, liquidacion, credito, debito, guia, retencion. Varios separados por coma. |
establecimiento | string | opcional | Tres dígitos, por ejemplo 001, si el formulario lo muestra. |
puntoEmision | string | opcional | Tres dígitos, si el formulario lo muestra. |
claveAcceso | string | opcional | Filtro de 49 dígitos (clave de acceso / nro. autorización). |
identificacion | string | opcional | RUC, cédula o pasaporte del filtro de consulta, 10–13 dígitos. |
httpHandoff | boolean | opcional | Por defecto true. Igual comportamiento que en Demo: descarga HTTP contra el formulario JSF con javax.faces.ViewState. |
soloReporte | boolean | opcional | Por defecto false. En true baja solo el TXT y no pide XML. |
esperar | boolean | opcional | Por defecto true. Con false responde 202 de inmediato. Si se agota SRI_ESPERA_HTTP_MS, 202 + esperaAgotada: true. |
Restricciones de fecha: fechaEmision es obligatoria, admite YYYY-MM-DD o DD/MM/YYYY y debe ser anterior al día actual en America/Guayaquil. El SRI rechaza la fecha de hoy y no se sustituye por otra.
Diferencias con Demo: el contrato JSON es idéntico. Lo único que cambia es el prefijo de ruta (/comercial) y que los jobs de una modalidad no pueden leerse desde la otra.
curl -X POST "https://apis.davycorp.ec/v2/docs-emitidos/comercial" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ruc": "1790000000001",
"clave": "TU_CLAVE_SRI",
"fechaEmision": "2026-09-14",
"tipo": "factura,retencion"
}'await fetch("https://apis.davycorp.ec/v2/docs-emitidos/comercial", {
method: "POST",
headers: {
Authorization: "Bearer TU_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
ruc: "1790000000001",
clave: "TU_CLAVE_SRI",
fechaEmision: "2026-09-14",
tipo: "factura,retencion"
})
});import requests
requests.post(
"https://apis.davycorp.ec/v2/docs-emitidos/comercial",
headers={"Authorization": "Bearer TU_API_KEY"},
json={
"ruc": "1790000000001",
"clave": "TU_CLAVE_SRI",
"fechaEmision": "2026-09-14",
"tipo": "factura,retencion",
},
){
"job_id": "8c1d0c2e-4b1a-4f0e-9c2a-6e5b1a0d4f11",
"estado": "pendiente",
"mensaje": "Descarga iniciada. Consulta el estado con el mismo prefijo de modalidad."
}{
"id": "JOB_ID",
"estado": "completado",
"modalidad": "comercial",
"zip_url": "/v2/docs-emitidos/comercial/JOB_ID/archivo",
"archivoUrl": "/v2/docs-emitidos/comercial/JOB_ID/archivo",
"comprobantesUrl": "/v2/docs-emitidos/comercial/JOB_ID/comprobantes",
"resultadoUrl": "/v2/docs-emitidos/comercial/JOB_ID",
"error": null,
"creado": "2026-10-26T18:00:00.000Z",
"terminado": "2026-10-26T18:04:12.000Z"
}// 400 — cuerpo incompleto { "error": "ruc y clave son obligatorios" } // 400 — fecha inválida { "error": "La fecha ingresada debe ser menor a la fecha actual" } // 401 — sin header Authorization { "error": "API Key requerida" } // 403 — API key inválida { "success": false, "error": "Api user inválido" } // 404 — job inexistente o de otro dueño/modalidad { "error": "Job no encontrado" } // 409 — consultar comprobantes/archivo en ejecución { "error": "El trabajo sigue en ejecución" } // 429 — cupo del API user { "error": "Límite de consultas alcanzado", "status": false } // 500 — fallo interno { "error": "Error interno del servidor", "status": false }
| Método | Endpoint relativo | Función |
|---|---|---|
| GET | /v2/docs-emitidos/comercial/:jobId | Consultar estado del trabajo. |
| GET | /v2/docs-emitidos/comercial/:jobId/comprobantes | Obtener listado JSON. |
| GET | /v2/docs-emitidos/comercial/:jobId/archivo | Descargar ZIP. |
| POST | /v2/docs-emitidos/comercial/:jobId/cancelar | Cancelar trabajo. |
Estado, archivo y cancelación repiten la cadena de verifyApiUser y la comprobación de dueño. Cruzar modalidad o dueño responde 404 con {"error":"Job no encontrado"} o {"error":"Archivo no disponible"}.
- Enviar el
POSTa la modalidad elegida (/demoo/comercial). - Leer el identificador devuelto en
job_id. - Consultar el estado con el prefijo de la misma modalidad:
GET /v2/docs-emitidos/{modalidad}/:jobId. - Consultar los comprobantes cuando el estado lo permita:
GET .../:jobId/comprobantes. - Descargar el ZIP cuando
archivoUrlesté disponible:GET .../:jobId/archivo. - Cancelar si todavía se puede:
POST .../:jobId/cancelar.
jobId creado con /demo solo se consulta con
/demo; lo mismo para /comercial. Cruzar modalidad o dueño responde 404.
# 1) Crear trabajo curl -X POST "https://apis.davycorp.ec/v2/docs-emitidos/demo" \ -H "Authorization: Bearer TU_API_KEY" \ -H "Content-Type: application/json" \ -d '{"ruc":"1790000000001","clave":"TU_CLAVE_SRI","fechaEmision":"2026-09-14","tipo":"factura"}' # 2) Consultar estado (usa el job_id devuelto) curl "https://apis.davycorp.ec/v2/docs-emitidos/demo/JOB_ID" \ -H "Authorization: Bearer TU_API_KEY" # 3) Listado JSON de comprobantes curl "https://apis.davycorp.ec/v2/docs-emitidos/demo/JOB_ID/comprobantes" \ -H "Authorization: Bearer TU_API_KEY" # 4) Descargar ZIP curl -L "https://apis.davycorp.ec/v2/docs-emitidos/demo/JOB_ID/archivo" \ -H "Authorization: Bearer TU_API_KEY" \ -o comprobantes.zip # 5) Cancelar (si sigue pendiente/procesando) curl -X POST "https://apis.davycorp.ec/v2/docs-emitidos/demo/JOB_ID/cancelar" \ -H "Authorization: Bearer TU_API_KEY"
| Estado | Significado |
|---|---|
pendiente | En cola. La clave está solo en memoria de este proceso. |
procesando | Login y descarga en curso. Hay un solo trabajo a la vez. |
completado | La consulta al SRI terminó. Puede ser período vacío (total 0) o ZIP completo. archivoUrl / zip_url apuntan a GET /{jobId}/archivo si el temporal sigue. |
parcial | Hay listado pero el portal no entregó todos los XML (o ninguno), o quedó paginación sin recorrer. El ZIP, si existe, no se presenta como completo. |
fallido | Error o reinicio del servidor. No se vuelve a intentar el login solo. |
cancelado | El cliente pidió parar. |
Reintentos. INTENTOS vale 6. No se reintenta un rechazo explícito de credenciales ni un Chromium que no arranca. Dentro de una página, SRI_XML_WORKERS vale 2. SRI_JOB_TIMEOUT_MS en 0 no corta el trabajo.
Archivos. XML, TXT y ZIP viven en un directorio temporal por trabajo (os.tmpdir()), no en el repo. El listado JSON se guarda en PostgreSQL (metadatos, no el XML). El ZIP incluye xml/, comprobantes.json y resultado.json. Se borra al terminar la transmisión o al vencer SRI_TMP_TTL_MS (30 min por defecto). El nombre del ZIP es comprobantes_<TIPO>_<anio>_<mes>.zip.
Modo esperar. Si se omite esperar vale true y el POST espera el trabajo real. Con esperar=false responde 202 de inmediato. Si el tiempo HTTP se agota, 202 con esperaAgotada: true y el mismo jobId. Hay que seguir consultando el GET de estado.
Reinicio. Al arrancar, lo que quedó pendiente o procesando pasa a fallido. La clave no está en PostgreSQL, así que el proceso no puede volver a entrar al SRI por su cuenta.
| Modalidad | Crear trabajo | Middlewares | Dueño |
|---|---|---|---|
| Demo | POST /v2/docs-emitidos/demo | verifyApiUser | id del API user |
| Comercial | POST /v2/docs-emitidos/comercial | verifyApiUser | id del API user |
Estado, archivo y cancelación repiten la misma cadena. Cruzar modalidad o dueño responde 404 con {"error":"Job no encontrado"} o {"error":"Archivo no disponible"}.
pages/consultas/menu.jsf y consulta los documentos que el contribuyente emitió. Los recibidos siguen en /v2/docs-recibidos.
| HTTP | Cuándo | Cuerpo |
|---|---|---|
| 200 | Consulta de estado, comprobantes, o cancelación de un pendiente | JSON del trabajo, o estado: cancelado |
| 202 | Trabajo creado (asíncrono), espera HTTP agotada, o cancelación diferida | job_id, estado, mensaje, opcionalmente esperaAgotada |
| 400 | Faltan ruc y clave, tipo desconocido, fecha inválida o filtros incompatibles | error |
| 401 | Sin header Authorization | {"error":"API Key requerida"} |
| 403 | API key inválida | success: false, error |
| 404 | Trabajo de otro dueño o modalidad, o ZIP que ya no está | Job no encontrado o Archivo no disponible |
| 409 | Cancelar un trabajo ya terminado, o consultar comprobantes/ZIP mientras sigue en ejecución | El trabajo ya terminó o El trabajo sigue en ejecución |
| 429 | El API user llegó a usage_limit | {"error":"Límite de consultas alcanzado","status":false} |
| 500 | Fallo interno al crear, consultar o guardar | error y status: false |
No todos los endpoints devuelven todos los códigos. Los GET de estado, comprobantes y archivo no atraviesan verifyLicense; aplican 401, 403, 404, 409 y 500. El POST de creación añade 400 y 429 según el cuerpo y el cupo del API user.
Un fallo del portal queda en error del trabajo y no detiene el proceso de las otras APIs. La descarga masiva contra el SRI no forma parte de esta integración: un trabajo, un período.