Gastos con IA
Manda la foto o el PDF de una factura y recibe el gasto listo para registrar — proveedor, NIT, número de factura, IVA y categoría — con el aviso de si ya estaba registrado.
Es el «Registrar gasto con IA» del panel, por API: tu sistema manda la factura (foto o PDF) y Verifika la lee y devuelve un borrador del gasto —proveedor, NIT, número de factura, fecha, total, subtotal, IVA, categoría sugerida y medio de pago— junto con los gastos parecidos que ya estén en el libro. Tú decides si lo creas.
Sirve para un bot que recibe facturas de proveedores por WhatsApp, para un correo que reenvía facturas electrónicas o para digitalizar la caja de recibos de la semana.
Antes de empezar
- El plan incluye los egresos y la lectura de facturas con IA (
features.expenses_moduleyfeatures.ai_expense_scanenGET /v1/plan). - La llave tiene
expenses.scan(leer facturas) y, para crear el gasto,expenses.write. Crear la llave. - Con una llave real. No tiene modo prueba (
403 TEST_MODE_UNAVAILABLEconvk_test_), pero leer una factura no crea nada hasta que lo pidas.
1. Lee la factura
Igual que el extracto de la conciliación, el archivo va de una de tres formas: multipart
con el campo file, fileBase64 + fileName, o fileUrl (https y pública). Foto (JPG, PNG,
WebP, HEIC) o PDF, hasta 15 MB.
curl -X POST https://api.verifika.tech/v1/expense-scans \
-H "Authorization: Bearer $VERIFIKA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@factura-fe-20931.pdf"{
"object": "expenseScan",
"id": "cmuhb7c8d0061x8w1f2g3h4jk",
"outcome": "EXTRACTED",
"message": null,
"documentKind": "INVOICE",
"confidence": "HIGH",
"draft": {
"amount": 357000,
"subtotal": 300000,
"tax": 57000,
"paidTo": "Harina La Espiga S.A.S.",
"vendorTaxId": "900123456-7",
"invoiceNumber": "FE-20931",
"occurredAt": "2026-10-10T05:00:00.000Z",
"categoryId": "cmt7xbfrm0003q3w121ldx6wz",
"categoryName": "Proveedores y mercancía",
"paymentMethod": "TRANSFER",
"accountLabel": null,
"notes": "20 bultos de harina"
},
"duplicates": [],
"file": { "attachmentId": "cmuhb7c9e0062x8w1m4n5b6vc", "fileName": "factura-fe-20931.pdf", "contentType": "application/pdf", "size": 84210 },
"expenseId": null,
"expense": null,
"expiresAt": "2026-10-18T21:20:00.000Z",
"createdAt": "2026-10-12T21:20:00.000Z"
}| Campo | Qué es |
|---|---|
outcome | EXTRACTED (se leyó), NOT_A_RECEIPT (no es una factura ni un recibo) o UNREADABLE (no se lee). En los dos últimos, message es la frase para la persona. |
draft | El gasto que se leyó. Lo que no se pudo leer viene en null. |
duplicates | Gastos parecidos que ya están en el libro: strength (STRONG o PROBABLE) y reasons (SAME_FILE, SAME_INVOICE_NUMBER, SAME_AMOUNT, SAME_DAY, NEAR_DAY, SIMILAR_PAYEE). [] = nada parecido. |
expiresAt | Hasta cuándo puedes crear el gasto con esta lectura: 6 días. Después, 410 EXPENSE_SCAN_EXPIRED. |
2. Crea el gasto
Si el borrador está bien —y duplicates está vacío o es otro gasto—, créalo. En expense van
tus correcciones o lo que la lectura no sacó (los mismos campos de
POST /v1/expenses):
curl -X POST https://api.verifika.tech/v1/expense-scans/cmuhb7c8d0061x8w1f2g3h4jk/expense \
-H "Authorization: Bearer $VERIFIKA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "expense": { "paidTo": "Harina La Espiga", "notes": "Pedido semanal" } }'Responde 201 con el gasto, que nace con source: "API" y la factura adjunta. Una lectura
crea un gasto: si repites la petición, te devuelve el mismo con 200.
¿Quieres leer y crear en un solo paso? Manda create: true en la lectura (y expense con las
correcciones, como texto JSON si vas por multipart). Si la lectura no sacó un dato obligatorio,
responde 422 EXPENSE_SCAN_INCOMPLETE con details.missing: mándalo en expense. Así también se
registra a mano un NOT_A_RECEIPT o un UNREADABLE, con su soporte adjunto.
Cuando parece repetido
Si al crear hay un gasto parecido, no crea nada y responde 409 EXPENSE_DUPLICATE con los
parecidos en details.duplicates. Si de verdad es otro gasto —el proveedor te factura lo mismo
cada semana—, vuelve a pedirlo con "allowDuplicate": true: es el «Registrar de todos modos» del
panel.
{
"error": {
"code": "EXPENSE_DUPLICATE",
"message": "Parece que este gasto ya está registrado. Si de verdad es otro, vuelve a pedirlo con `allowDuplicate: true`.",
"details": {
"scanId": "cmuhb7c8d0061x8w1f2g3h4jk",
"duplicates": [
{ "strength": "STRONG", "reasons": ["SAME_INVOICE_NUMBER", "SAME_AMOUNT"], "expense": { "object": "expense", "id": "cmtnox8lz00016kw11frj0rww", "…": "…" } }
]
}
}
}La factura, dónde queda
Se guarda en nuestro almacenamiento privado después de leerla (si la IA falla, no queda un archivo suelto por cada reintento). Al crear el gasto, se mueve a la carpeta de ese gasto; si nunca lo creas, se borra sola a los 7 días.
Límites y errores
Cada lectura es una consulta a la IA, así que tiene su propio freno, por negocio: 20 lecturas
por minuto y 300 al día (429 RATE_LIMITED). Para registrar gastos sin leerlos, usa
POST /v1/expenses, que no tiene ese límite.
| HTTP | code | Qué pasó |
|---|---|---|
409 | EXPENSE_DUPLICATE | Parece repetido: allowDuplicate: true si es otro. |
409 | ATTACHMENT_ALREADY_LINKED | Dos pedidos de crear a la vez: reintenta y recibes el gasto con 200. |
409 | EXPENSE_SCAN_ALREADY_USED | El gasto que se creó con esta lectura se borró, y con él su factura. Vuelve a leerla. |
410 | EXPENSE_SCAN_EXPIRED | La lectura venció (6 días). |
413 | FILE_TOO_LARGE | Más de 15 MB. |
415 | FILE_TYPE_NOT_ALLOWED | No es foto ni PDF (se mira el archivo, no la extensión). |
422 | EXPENSE_SCAN_INCOMPLETE | Falta un dato para crear el gasto (details.missing). |
503 | AI_UNAVAILABLE | La lectura con IA no está disponible: registra el gasto con POST /v1/expenses. |
La referencia de cada endpoint está en
Egresos → Gastos con IA. Por MCP, son las herramientas
scan_expense_receipt, get_expense_scan y create_expense_from_scan.
Conciliación por API
Sube el extracto del banco, mira qué cuadra con el libro, resuelve lo que falta en lote y descarga el reporte — lo mismo que la pantalla de Conciliación, desde tu ERP o tu bot.
Cuentas por cobrar
El cuaderno de fiados por API — crear clientes que deben, registrar abonos sin duplicarlos y saldar cuentas.