API v1
Documentos
Consulta documentos, previsualiza descargas y reportes, y obtén links firmados para descargar archivos.
Qué son los documentos en Zettana
En Zettana, los documentos son los comprobantes electrónicos recuperados desde el SRI para un RUC.
Con estos endpoints puedes:
- listar documentos de un período específico
- consultar de forma incremental los documentos recién recuperados
- obtener el contenido XML de documentos específicos
- previsualizar cuántos documentos hay para una descarga masiva
- obtener un link firmado para descargar un ZIP con los archivos de ese período
- previsualizar un reporte en hoja de cálculo por período
- obtener un link firmado para descargar ese reporte
- obtener un link firmado para un documento individual
Endpoints
GET /v1/rucs/:rucId/documentsGET /v1/documents/incrementalPOST /v1/documents/xml-contentsGET /v1/rucs/:rucId/documents/mass-download-previewGET /v1/rucs/:rucId/documents/mass-downloadGET /v1/rucs/:rucId/documents/spreadsheet-report-previewGET /v1/rucs/:rucId/documents/spreadsheet-reportGET /v1/documents/:documentId/signedLink
Filtros requeridos
Los endpoints de listado y descarga masiva por RUC usan estos filtros:
documentTypedocumentFormatmonthyear
Los endpoints de reporte en hoja de cálculo usan:
documentTypemonthyear
Los valores admitidos para documentType están detallados en
Tipos de documento.
Valores de documentFormat
XMLPDF
Valores de período
month: entero entre1y12year: entero
Objeto documento
Las respuestas de listado usan un objeto con esta estructura:
id: identificador del documentorucId: identificador del RUC consultadodocumentType: tipo de documento. Consulta Tipos de documentodocumentFormat: formato del documentoretrievedAt: fecha y hora en la que Zettana recuperó ese documentoestado: estado del documentonumeroAutorizacion: número de autorizaciónnumeroDocumento: número del documentofechaAutorizacion: fecha de autorizaciónambiente: ambiente del documentofechaEmision: fecha de emisiónrazonSocialEmisor: razón social del emisorrucEmisor: RUC del emisor
Listar documentos
GET /v1/rucs/:rucId/documents
Devuelve los documentos disponibles para un RUC y un conjunto de filtros.
Parámetros de ruta
rucId: identificador del RUC
Parámetros de consulta
documentTypedocumentFormatmonthyearpage: número de página. Por defecto1pageSize: cantidad de elementos por página. Por defecto10numeroAutorizacion: filtro opcional por número de autorización
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
RUC_ID = "REEMPLAZA_CON_EL_ID_DEL_RUC"
params = {
"documentType": "FACTURA",
"documentFormat": "XML",
"month": 10,
"year": 2025,
"page": 1,
"pageSize": 10,
}
response = requests.get(
f"{BASE_URL}/rucs/{RUC_ID}/documents",
headers={"x-api-key": API_KEY},
params=params,
timeout=30,
)
response.raise_for_status()
print(response.json())Campos de salida
documents: arreglo de objetos documentopagination: metadata de paginación de la respuesta
pagination contiene:
page: página actualpageSize: tamaño de página aplicadototal: cantidad total de documentos que cumplen el filtrototalPages: cantidad total de páginas disponibles
El detalle de cada elemento está descrito en la sección Objeto documento.
Ejemplo de salida
{
"documents": [
{
"id": "84d22af7-d0f0-4f53-a634-f66ec772ef90",
"rucId": "3b2781b9-8d95-4b02-a6b7-4d5d66e0b8b6",
"documentType": "FACTURA",
"documentFormat": "XML",
"retrievedAt": "2026-04-11T10:30:00.000Z",
"estado": "AUTORIZADO",
"numeroAutorizacion": "XXXXXXXXXXXXXXXXXXXXXXXX",
"numeroDocumento": "XXXXXXXXXXXXXXXXX",
"fechaAutorizacion": "2025-10-14T12:00:00",
"ambiente": "PRODUCCION",
"fechaEmision": "2025-10-14",
"razonSocialEmisor": "EMPRESA DE EJEMPLO S.A.",
"rucEmisor": "XXXXXXXXXXXXX"
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"total": 1,
"totalPages": 1
}
}Consultar documentos de forma incremental
GET /v1/documents/incremental
Devuelve documentos ordenados por retrievedAt, lo que permite construir
polling periódico para recuperar únicamente los documentos que Zettana obtuvo
desde un punto en el tiempo.
Parámetros de consulta
since: fecha inicial para la primera consulta. Usa formato ISO 8601.cursor: cursor devuelto por una respuesta anterior. Se usa a partir de la segunda consulta.limit: cantidad máxima de documentos a devolver. Máximo200.documentFormat: filtra por formato.documentType: filtra por tipo de documento.rucId: filtra por un RUC específico.
No envíes since y cursor al mismo tiempo.
Flujo recomendado
- Haz la primera consulta con
since. - Guarda el valor de
nextCursor. - En la siguiente consulta, envía ese valor en
cursor.
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
params = {
"since": "2026-04-11T00:00:00.000Z",
"documentFormat": "XML",
"limit": 50,
}
response = requests.get(
f"{BASE_URL}/documents/incremental",
headers={"x-api-key": API_KEY},
params=params,
timeout=30,
)
response.raise_for_status()
print(response.json())Campos de salida
documents: arreglo de objetos documento ordenado porretrievedAtnextCursor: cursor a usar en la siguiente consulta, onullsi no hay más resultadoshasMore: indica si existe una siguiente página
Cada elemento usa los campos descritos en la sección Objeto documento, y
además incluye:
month: mes al que pertenece el documentoyear: año al que pertenece el documento
Ejemplo de salida
{
"documents": [
{
"id": "84d22af7-d0f0-4f53-a634-f66ec772ef90",
"rucId": "3b2781b9-8d95-4b02-a6b7-4d5d66e0b8b6",
"documentType": "FACTURA",
"documentFormat": "XML",
"retrievedAt": "2026-04-11T10:30:00.000Z",
"estado": "AUTORIZADO",
"numeroAutorizacion": "XXXXXXXXXXXXXXXXXXXXXXXX",
"numeroDocumento": "XXXXXXXXXXXXXXXXX",
"fechaAutorizacion": "2025-10-14T12:00:00",
"ambiente": "PRODUCCION",
"fechaEmision": "2025-10-14",
"razonSocialEmisor": "EMPRESA DE EJEMPLO S.A.",
"rucEmisor": "XXXXXXXXXXXXX",
"month": 10,
"year": 2025
}
],
"nextCursor": "eyJyZXRyaWV2ZWRBdCI6IjIwMjYtMDQtMTFUMTA6MzA6MDAuMDAwWiIsImlkIjoiODRkMjJhZjctZDBmMC00ZjUzLWE2MzQtZjY2ZWM3NzJlZjkwIn0",
"hasMore": true
}Obtener contenidos XML
POST /v1/documents/xml-contents
Devuelve el contenido XML de un conjunto de documentos.
Este endpoint está pensado para usarse después de una consulta incremental o después de obtener IDs desde un listado de documentos.
Campos de entrada
documentIds: arreglo de IDs de documentos XML. Debe contener entre1y100elementos
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
payload = {
"documentIds": [
"84d22af7-d0f0-4f53-a634-f66ec772ef90",
"b88fe76f-98b9-40f0-896b-6d8e014e7d73",
]
}
response = requests.post(
f"{BASE_URL}/documents/xml-contents",
headers={"x-api-key": API_KEY},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())Campos de salida
documents: arreglo con el contenido XML de cada documento solicitadodocuments[].id: identificador del documentodocuments[].xmlContent: contenido XML completo del documento
Ejemplo de salida
{
"documents": [
{
"id": "84d22af7-d0f0-4f53-a634-f66ec772ef90",
"xmlContent": "<?xml ...................."
}
]
}Previsualizar una descarga masiva
GET /v1/rucs/:rucId/documents/mass-download-preview
Devuelve un resumen previo de la descarga masiva para un período y conjunto de filtros, indicando cuántos documentos serían descargados y cuándo ocurrió la última sincronización del período consultado.
Parámetros de ruta
rucId: identificador del RUC
Parámetros de consulta
documentTypedocumentFormatmonthyear
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
RUC_ID = "REEMPLAZA_CON_EL_ID_DEL_RUC"
params = {
"documentType": "FACTURA",
"documentFormat": "PDF",
"month": 10,
"year": 2025,
}
response = requests.get(
f"{BASE_URL}/rucs/{RUC_ID}/documents/mass-download-preview",
headers={"x-api-key": API_KEY},
params=params,
timeout=30,
)
response.raise_for_status()
print(response.json())Campos de salida
documentCount: cantidad de documentos disponibles para esos filtroslastSyncDate: fecha de la última sincronización registrada para ese período y tipo de documento, onullsi no existe.
Ejemplo de salida
{
"documentCount": 12,
"lastSyncDate": "2026-04-11T10:30:00.000Z"
}Consideraciones
Se recomienda que lastSyncDate sea lo mas reciente posible para asegurar que la información esté actualizada.
Descargar un documento
GET /v1/documents/:documentId/signedLink
Devuelve un link firmado para acceder a un documento específico.
El valor de signedLink es una URL temporal. Al acceder a esa URL, se descarga
ese documento en particular.
Actualmente, el link firmado expira a los 300 segundos, es decir, después de
5 minutos. Si expira, debes solicitar uno nuevo.
Parámetros de ruta
documentId: identificador del documento
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
DOCUMENT_ID = "REEMPLAZA_CON_EL_ID_DEL_DOCUMENTO"
response = requests.get(
f"{BASE_URL}/documents/{DOCUMENT_ID}/signedLink",
headers={"x-api-key": API_KEY},
timeout=30,
)
response.raise_for_status()
print(response.json())Campos de salida
signedLink: URL temporal para descargar ese documento específico
Ejemplo de salida
{
"signedLink": "https://documents.zettana.com/9f3b2c41-6d8a-4e7f-9c12-5b7a1d3e4f90/download?signature=8f4c2a9b7d6e1c3f5a"
}Descarga masiva
GET /v1/rucs/:rucId/documents/mass-download
Devuelve un objeto JSON con un signedLink temporal para descargar el archivo
ZIP del período solicitado.
Parámetros de ruta
rucId: identificador del RUC
Parámetros de consulta
documentTypedocumentFormatmonthyear
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
RUC_ID = "REEMPLAZA_CON_EL_ID_DEL_RUC"
params = {
"documentType": "FACTURA",
"documentFormat": "PDF",
"month": 10,
"year": 2025,
}
response = requests.get(
f"{BASE_URL}/rucs/{RUC_ID}/documents/mass-download",
headers={"x-api-key": API_KEY},
params=params,
timeout=30,
)
response.raise_for_status()
signed_link = response.json()["signedLink"]
with requests.get(signed_link, stream=True, timeout=60) as archive_response:
archive_response.raise_for_status()
with open("documentos.zip", "wb") as file:
for chunk in archive_response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)Campos de salida
signedLink: URL temporal para descargar el ZIP correspondiente a esos filtros
El link firmado expira a los 300 segundos, es decir, después de 5 minutos.
Si expira, debes solicitar uno nuevo.
Ejemplo de salida
{
"signedLink": "https://documents.zettana.com/archives/factura-pdf-2025-10.zip?signature=8f4c2a9b7d6e1c3f5a"
}Previsualizar un reporte en hoja de cálculo
GET /v1/rucs/:rucId/documents/spreadsheet-report-preview
Devuelve un resumen previo del reporte disponible para un período y tipo de documento.
Parámetros de ruta
rucId: identificador del RUC
Parámetros de consulta
documentTypemonthyear
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
RUC_ID = "REEMPLAZA_CON_EL_ID_DEL_RUC"
params = {
"documentType": "FACTURA",
"month": 10,
"year": 2025,
}
response = requests.get(
f"{BASE_URL}/rucs/{RUC_ID}/documents/spreadsheet-report-preview",
headers={"x-api-key": API_KEY},
params=params,
timeout=30,
)
response.raise_for_status()
print(response.json())Campos de salida
documentCount: cantidad de documentos incluidos en el reportelastSyncDate: fecha de la última sincronización usada para construir el reporte, onullsi no existe
Ejemplo de salida
{
"documentCount": 12,
"lastSyncDate": "2026-04-11T10:30:00.000Z"
}Descargar un reporte en hoja de cálculo
GET /v1/rucs/:rucId/documents/spreadsheet-report
Devuelve un objeto JSON con un signedLink temporal para descargar el reporte
del período solicitado.
Parámetros de ruta
rucId: identificador del RUC
Parámetros de consulta
documentTypemonthyear
Ejemplo
import requests
BASE_URL = "https://backend.zettana.com/v1"
API_KEY = "REEMPLAZA_CON_TU_API_KEY"
RUC_ID = "REEMPLAZA_CON_EL_ID_DEL_RUC"
params = {
"documentType": "FACTURA",
"month": 10,
"year": 2025,
}
response = requests.get(
f"{BASE_URL}/rucs/{RUC_ID}/documents/spreadsheet-report",
headers={"x-api-key": API_KEY},
params=params,
timeout=30,
)
response.raise_for_status()
signed_link = response.json()["signedLink"]
with requests.get(signed_link, stream=True, timeout=60) as report_response:
report_response.raise_for_status()
with open("reporte.xlsx", "wb") as file:
for chunk in report_response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)Campos de salida
signedLink: URL temporal para descargar el reporte en hoja de cálculo
El link firmado expira a los 300 segundos, es decir, después de 5 minutos.
Si expira, debes solicitar uno nuevo.
Ejemplo de salida
{
"signedLink": "https://documents.zettana.com/reports/factura-2025-10.xlsx?signature=8f4c2a9b7d6e1c3f5a"
}Relación con sincronizaciones
Las sincronizaciones y los documentos son pasos distintos.
Primero solicitas una sincronización para el período y tipo de documento que te interesa. Después consultas o descargas los documentos ya disponibles con los endpoints de esta sección.