Documentación

InvoiceExtract convierte cualquier factura o recibo PDF en datos JSON estructurados usando IA. Un endpoint, cualquier documento, respuesta en milisegundos.

¿Es tu primera vez usando una API? Tenemos una guía paso a paso pensada para ti.

Ver guía para principiantes →
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)

CampoTipoDescripción
file_base64stringArchivo en base64. Envía este O url, no ambos.
media_typestringTipo MIME del archivo. Default: application/pdf. También acepta image/jpeg, image/png, image/webp.
urlstringURL 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
CampoTipoDescripción
emailstringTu 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

HTTPErrorDescripción
401missing_api_keyNo se incluyó el header x-api-key
403invalid_api_keyAPI key incorrecta o desactivada
400missing_inputNo se envió file_base64 ni url
402payment_requiredSuscripción suspendida por pago fallido
422parse_errorEl documento no pudo ser interpretado
429limit_reachedLímite mensual de llamadas alcanzado
429rate_limit_exceededDemasiadas peticiones por minuto desde tu IP
500extraction_failedError interno. Intenta de nuevo.

Límites y planes

PlanLlamadas/mesRate limitPrecio
Free1060/min por IP$0
Basic50060/min por IP$49 USD/mes
Pro2,00060/min por IP$149 USD/mes
Business10,00060/min por IP$399 USD/mes

Tamaño máximo de archivo: 10 MB. Formatos aceptados: PDF, JPG, PNG, WEBP.