Documentación
InvoiceExtract convierte cualquier factura o recibo PDF en datos JSON estructurados usando IA. Un endpoint, cualquier documento, respuesta en milisegundos.
Base URL:
https://invoiceextract-api-production.up.railway.app
Autenticación
Todas las peticiones a /extract y /keys/usage requieren una API key en el header x-api-key.
Obtén tu API key gratis en invoiceextract.com.mx — sin tarjeta de crédito.
# Header requerido en cada petición
x-api-key: iek_tu_api_key_aqui
POST /extract
Extrae datos estructurados de cualquier factura o recibo. Acepta PDF o imagen en base64, o una URL pública del documento.
POST
/extract
Requiere x-api-key
Parámetros del body (JSON)
| Campo | Tipo | Descripción |
|---|---|---|
| file_base64 | string | Archivo en base64. Envía este O url, no ambos. |
| media_type | string | Tipo MIME del archivo. Default: application/pdf. También acepta image/jpeg, image/png, image/webp. |
| url | string | URL pública del documento. Tu servidor lo descarga automáticamente. |
Envía file_base64 O url, nunca ambos al mismo tiempo.
Respuesta exitosa (200)
200 OK
{
"success": true,
"data": {
"document_type": "invoice",
"issuer": {
"name": "Papelería El Centro S.A.",
"tax_id": "PEC920314AB3",
"address": "Av. Juárez 145, CDMX",
"email": null,
"phone": null
},
"recipient": {
"name": "Tech Startup MX",
"tax_id": "TSM210601XY2",
"address": null
},
"document": {
"number": "F-2024-00892",
"date": "2024-11-15",
"due_date": null,
"currency": "MXN"
},
"amounts": {
"subtotal": 6080.00,
"tax_rate": 16,
"tax_amount": 972.80,
"discount": 0,
"total": 7052.80
},
"line_items": [
{
"description": "Resmas papel bond 75g",
"quantity": 10,
"unit_price": 450.00,
"amount": 4500.00
}
],
"payment": {
"method": "transfer",
"status": "paid"
},
"confidence": 0.97
},
"meta": {
"model": "claude-haiku-4-5",
"calls_used": 3,
"calls_remaining": 7,
"processed_at": "2024-11-15T14:32:10Z"
}
}
POST /keys/generate
Genera una nueva API key para el plan gratuito. La key se envía también por email.
POST
/keys/generate
No requiere autenticación
| Campo | Tipo | Descripción |
|---|---|---|
| string | Tu email. Se usa para enviarte la key y como identificador único de cuenta. |
{
"api_key": "iek_a3f8d2c1e5b7...",
"plan": "free",
"monthly_limit": 10
}
GET /keys/usage
Consulta el uso actual de tu API key — llamadas usadas, límite y plan.
GET
/keys/usage
Requiere x-api-key
{
"plan": "basic",
"calls_used": 87,
"limit": 500,
"email": "tu@email.com"
}
Ejemplos de integración
cURL
# Convierte el PDF a base64 primero BASE64=$(base64 -i factura.pdf) curl -X POST https://invoiceextract-api-production.up.railway.app/extract \ -H "x-api-key: iek_tu_key" \ -H "Content-Type: application/json" \ -d "{\"file_base64\": \"$BASE64\", \"media_type\": \"application/pdf\"}"
curl -X POST https://invoiceextract-api-production.up.railway.app/extract \ -H "x-api-key: iek_tu_key" \ -H "Content-Type: application/json" \ -d '{"url": "https://ejemplo.com/factura.pdf"}'
JavaScript (Node.js)
const fs = require('fs'); const fileBase64 = fs.readFileSync('factura.pdf').toString('base64'); const response = await fetch('https://invoiceextract-api-production.up.railway.app/extract', { method: 'POST', headers: { 'x-api-key': 'iek_tu_key', 'Content-Type': 'application/json', }, body: JSON.stringify({ file_base64: fileBase64, media_type: 'application/pdf' }), }); const { data } = await response.json(); console.log(data.amounts.total); // → 7052.80 console.log(data.issuer.tax_id); // → "PEC920314AB3" console.log(data.confidence); // → 0.97
const response = await fetch('https://invoiceextract-api-production.up.railway.app/extract', { method: 'POST', headers: { 'x-api-key': 'iek_tu_key', 'Content-Type': 'application/json', }, body: JSON.stringify({ url: 'https://ejemplo.com/factura.pdf' }), }); const { data } = await response.json(); console.log(data.amounts.total); // → 7052.80
// El usuario selecciona un archivo con <input type="file"> async function extractInvoice(file) { const toBase64 = f => new Promise((res, rej) => { const reader = new FileReader(); reader.onload = () => res(reader.result.split(',')[1]); reader.onerror = rej; reader.readAsDataURL(f); }); const base64 = await toBase64(file); const res = await fetch('https://invoiceextract-api-production.up.railway.app/extract', { method: 'POST', headers: { 'x-api-key': 'iek_tu_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ file_base64: base64, media_type: file.type }), }); return (await res.json()).data; }
Python
import base64, requests with open('factura.pdf', 'rb') as f: file_b64 = base64.b64encode(f.read()).decode() response = requests.post( 'https://invoiceextract-api-production.up.railway.app/extract', headers={'x-api-key': 'iek_tu_key'}, json={'file_base64': file_b64, 'media_type': 'application/pdf'}, ) data = response.json()['data'] print(f"Total: {data['amounts']['total']} {data['document']['currency']}") print(f"Emisor: {data['issuer']['name']}") print(f"Confianza: {data['confidence']}")
import requests response = requests.post( 'https://invoiceextract-api-production.up.railway.app/extract', headers={'x-api-key': 'iek_tu_key'}, json={'url': 'https://ejemplo.com/factura.pdf'}, ) data = response.json()['data'] print(data['amounts']['total'])
PHP
<?php $fileBase64 = base64_encode(file_get_contents('factura.pdf')); $response = file_get_contents( 'https://invoiceextract-api-production.up.railway.app/extract', false, stream_context_create(['http' => [ 'method' => 'POST', 'header' => "x-api-key: iek_tu_key\r\nContent-Type: application/json", 'content' => json_encode([ 'file_base64' => $fileBase64, 'media_type' => 'application/pdf', ]), ]]) ); $data = json_decode($response, true)['data']; echo "Total: " . $data['amounts']['total']; echo "Emisor: " . $data['issuer']['name'];
<?php $response = file_get_contents( 'https://invoiceextract-api-production.up.railway.app/extract', false, stream_context_create(['http' => [ 'method' => 'POST', 'header' => "x-api-key: iek_tu_key\r\nContent-Type: application/json", 'content' => json_encode(['url' => 'https://ejemplo.com/factura.pdf']), ]]) ); $data = json_decode($response, true)['data']; echo $data['amounts']['total'];
Códigos de error
| HTTP | Error | Descripción |
|---|---|---|
| 401 | missing_api_key | No se incluyó el header x-api-key |
| 403 | invalid_api_key | API key incorrecta o desactivada |
| 400 | missing_input | No se envió file_base64 ni url |
| 402 | payment_required | Suscripción suspendida por pago fallido |
| 422 | parse_error | El documento no pudo ser interpretado |
| 429 | limit_reached | Límite mensual de llamadas alcanzado |
| 429 | rate_limit_exceeded | Demasiadas peticiones por minuto desde tu IP |
| 500 | extraction_failed | Error interno. Intenta de nuevo. |
Límites y planes
| Plan | Llamadas/mes | Rate limit | Precio |
|---|---|---|---|
| Free | 10 | 60/min por IP | $0 |
| Basic | 500 | 60/min por IP | $49 USD/mes |
| Pro | 2,000 | 60/min por IP | $149 USD/mes |
| Business | 10,000 | 60/min por IP | $399 USD/mes |
Tamaño máximo de archivo: 10 MB. Formatos aceptados: PDF, JPG, PNG, WEBP.