POST /v1/batches
Referencia de POST /v1/batches: analiza hasta 100 documentos en una llamada asíncrona, con opciones comunes o por documento y export combinado.
Un lote agrupa hasta 100 documentos en una sola petición. Es siempre asíncrono: la API responde 202 al momento, cada documento se convierte en un análisis normal (an_…) con batch_id, y cuando terminan todos recibes un único webhook batch.completed. Opcionalmente, un fichero combinado (por ejemplo, un Excel con una fila por documento).
Úsalo para cargas masivas: las facturas del mes, los justificantes de una inscripción, los certificados de una plantilla. Para un documento suelto usa POST /v1/analyze. Guía práctica en Lotes masivos.
| Método y ruta | Qué hace |
|---|---|
POST /v1/batches | Crea un lote. Siempre 202. |
GET /v1/batches/{id} | Recupera el lote con sus contadores y exportaciones. |
Crear un lote
Hay dos formas de enviarlo.
multipart/form-data: ficheros
| Campo | Descripción |
|---|---|
files[] | Un fichero por campo; repite el campo para cada documento. También se acepta files. |
options | JSON con las opciones comunes a todos los documentos. |
curl https://api.constaia.com/v1/batches \
-H "Authorization: Bearer $CONSTAIA_API_KEY" \
-F "files[]=@factura_001.pdf" \
-F "files[]=@factura_002.pdf" \
-F "files[]=@factura_003.pdf" \
-F 'options={"expect":"invoice","export":["xlsx"],"metadata":{"month":"2026-09"}}'Con multipart todos los documentos comparten opciones. El atajo -F expect=… de analyze no existe en lotes: usa options.
application/json: URLs o base64, con opciones por documento
{
"items": [
{ "file_url": "https://example.com/justificantes/123.pdf",
"options": { "checks": { "expected_amount": 45, "expected_reference": "INSCRIPCION 123" },
"metadata": { "registration_id": "123" } } },
{ "file_url": "https://example.com/justificantes/124.pdf",
"options": { "checks": { "expected_amount": 60, "expected_reference": "INSCRIPCION 124" },
"metadata": { "registration_id": "124" } } },
{ "file_base64": "JVBERi0xLjcK…", "filename": "125.pdf" }
],
"options": { "expect": "payment_receipt", "export": ["xlsx"], "metadata": { "event": "42" } }
}Cada item lleva file_url o file_base64 + filename, y opcionalmente sus options. Las URLs se descargan al recibir la petición con las mismas reglas que en analyze (https, 20 MB, 15 s): si una falla, la petición entera devuelve el error y no se crea nada.
Opciones comunes y por documento
Las opciones son las mismas de analyze, pero se reparten así:
| Opción | Ámbito |
|---|---|
export | Del lote: al terminar se genera un único fichero combinado con una fila por documento. Los documentos individuales no generan exportación propia. |
metadata | Del lote: vuelve en el objeto batch. No se copia a cada análisis. Para etiquetar cada documento, pon metadata en las options del item. |
El resto (expect, extract, checks, storage, ttl_hours, keep_results, language, processing…) | Por documento: las options comunes se aplican a cada item, y las options del item las sobrescriben. |
Las opciones se fusionan clave a clave, y checks también: los checks del item se añaden a los comunes y, si coinciden en una clave, gana el del item. En el ejemplo de arriba, cada justificante hereda expect: "payment_receipt" y lleva su propio expected_amount. Si pones checks: { "max_age_days": 30 } en las comunes y checks: { "expected_amount": 45 } en un item, ese item se valida con los dos. async no tiene efecto: los documentos de un lote siempre se procesan en segundo plano.
Límites y créditos
- Entre 1 y 100 documentos por lote. Más de 100 devuelve
400 batch_too_largey ninguno400 empty_batch, tanto en multipart como conitemsen JSON. - Mismos límites por fichero que en
analyze: 20 MB, JPEG/PNG/WEBP/HEIC/PDF, y hasta 200 páginas por PDF (los lotes siempre son asíncronos). - Con clave live, antes de crear nada se comprueba que tengas al menos 1 crédito por documento; si no,
402 insufficient_credits. El coste real de cada documento es el de un análisis normal (1 crédito por cada 2 páginas). En test no hay coste. - El lote es atómico. Antes de crear nada se descargan todas las
file_urly se validan todos los ficheros (formato, tamaño, páginas). Si uno falla, la petición devuelve el error de ese documento (si es de formato, tamaño o páginas, conparam: "items[i]", índice desde 0, y el nombre del fichero en el mensaje) y no se crea ni se cobra ningún análisis. Corrige ese documento y reenvía el lote completo. - Admite
Idempotency-Keypara reintentar sin crear el lote dos veces. Ver Idempotencia.
El objeto batch
{
"id": "bat_01J9Z8Q3K4M5N6P7Q8R9S0T1V2",
"object": "batch",
"status": "processing",
"livemode": false,
"total": 3,
"counts": { "queued": 3, "processing": 0, "completed": 0, "failed": 0, "valid": 0, "invalid": 0, "review": 0 },
"analyses": ["an_01J9Z8Q3K4M5N6P7Q8R9S0T1V3", "an_01J9Z8Q3K4M5N6P7Q8R9S0T1V4", "an_01J9Z8Q3K4M5N6P7Q8R9S0T1V5"],
"exports": {},
"metadata": { "month": "2026-09" },
"created_at": "2026-09-29T10:00:00.000Z",
"completed_at": null
}| Campo | Descripción |
|---|---|
id | Id con prefijo bat_. |
object | Siempre "batch". |
status | processing mientras quede algún documento pendiente; completed cuando todos han terminado (bien o con fallo). |
livemode | Modo de la clave con la que se creó. |
total | Número de documentos. |
counts | Por estado (queued, processing, completed, failed) y por veredicto (valid, invalid, review). Los contadores de veredicto solo cuentan documentos con expect. |
analyses | Ids de los análisis del lote, en orden de creación. |
exports | Formato → URL firmada del fichero combinado. Aparece al completarse el lote y caduca a las 24 h. |
metadata | La metadata común del lote. |
created_at, completed_at | Fechas ISO 8601; completed_at es null hasta que termina. |
Recuperar un lote
curl https://api.constaia.com/v1/batches/bat_01J9Z8Q3K4M5N6P7Q8R9S0T1V2 \
-H "Authorization: Bearer $CONSTAIA_API_KEY"Devuelve el mismo objeto con los contadores actualizados. Para el detalle de cada documento, recorre analyses con GET /v1/analyses/{id} o filtra el listado por la metadata que pusiste en cada item.
Webhooks de un lote
| Evento | Cuándo |
|---|---|
analysis.review_required | Un documento del lote termina con veredicto review. |
analysis.failed | Un documento del lote falla. |
batch.completed | Han terminado todos. data es el objeto batch, con exports si pediste export. |
Los documentos de un lote no emiten analysis.completed, para no recibir cien avisos. Al llegar batch.completed, lee cada análisis o descarga el fichero combinado. Detalles y verificación de firma en Webhooks.
Ejemplos
curl https://api.constaia.com/v1/batches \
-H "Authorization: Bearer $CONSTAIA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoices-2026-09" \
-d '{
"items": [
{ "file_url": "https://example.com/facturas/2026-0041.pdf" },
{ "file_url": "https://example.com/facturas/2026-0042.pdf" }
],
"options": { "expect": "invoice", "export": ["xlsx"], "metadata": { "month": "2026-09" } }
}'Para ver el flujo completo de un lote sin gastar créditos, usa una clave ck_test_ y nombra los ficheros como en Modo test (por ejemplo, factura_001.pdf devuelve una factura válida).
Siguientes pasos
Análisis guardados
Recupera, lista con filtros y paginación por cursor, exporta y borra análisis con /v1/analyses, y descarga exportaciones con las URLs firmadas de /v1/files.
GET /v1/document-types
Referencia de GET /v1/document-types: catálogo público de tipos de documento con campos, JSON Schema, validadores y checks aplicables, sin clave de API.