Primeros pasos

Inicio rápido

Este tutorial recorre todo el ciclo: obtener una clave, subir un documento, iniciar el procesamiento y recuperar los resultados, usando una factura como ejemplo. Si aún no has instalado curl o configurado una variable de entorno para tu clave, consulta Configuración del entorno primero.

Paso 1 — Obtén tu clave de API

Tu clave de API está en la página de configuración de tu perfil, en la sección API Key. La API v1 requiere un plan de pago (Básico o superior); las claves del plan Gratuito pasan la verificación de autenticación, pero cada llamada posterior devuelve un error plan_required. Las claves generadas a partir de ahora tienen el formato itt_live_<64 caracteres hexadecimales>; exporta la tuya como variable de entorno para no tenerla hardcodeada en un script:

export API_KEY="itt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Paso 2 — Sube un documento

POST /api/v1/documents acepta un file (multipart) o una url que el servidor descarga por ti; pasa exactamente uno. batch_name es opcional; si lo omites, la API genera uno automáticamente (se devuelve en la respuesta) y todos los documentos que quieras procesar juntos deben compartir el mismo batch_name. Este ejemplo usa url con una factura de muestra real alojada en nuestro propio sitio, por lo que se puede ejecutar tal cual, sin necesidad de un archivo local:

curl -X POST https://imagetotable.ai/api/v1/documents \
  -H "Authorization: Bearer $API_KEY" \
  -F "url=https://imagetotable.ai/static/samples/invoice.webp"
import os
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/documents",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    data={"url": "https://imagetotable.ai/static/samples/invoice.webp"},
)
print(response.json())
const formData = new FormData();
formData.append("url", "https://imagetotable.ai/static/samples/invoice.webp");

const response = await fetch("https://imagetotable.ai/api/v1/documents", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
  body: formData,
});
console.log(await response.json());

¿Tienes un archivo local? Reemplaza url por un campo multipart file; consulta Subir un documento en la Referencia para ver la lista completa de parámetros, incluidos batch_name, template_id y password.

La respuesta devuelve el ID del nuevo documento y el lote en el que se asignó — guarda batch_name, lo necesitarás en los siguientes dos pasos:

{
  "document_id": "3f9c9e2a-1b7d-4e2b-9a3e-2f5b6c7d8e9f",
  "batch_name": "260716-4K9P",
  "remaining_batch_capacity": 199
}

Subir un PDF de varias páginas en lugar de una imagen funciona igual, excepto que document_id se devuelve como un array — un documento por página — ya que cada página se procesa de forma independiente.

Paso 3 — Iniciar el procesamiento

POST /api/v1/batches/{batch_name}/process inicia la extracción. Puedes apuntarlo a una Plantilla guardada mediante template_id, o — como aquí — declarar los campos que deseas en línea con fields para una ejecución única:

curl -X POST https://imagetotable.ai/api/v1/batches/260716-4K9P/process \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "fields": [
          {"name": "invoice_number"},
          {"name": "invoice_date"},
          {"name": "vendor_name"},
          {"name": "total_amount"}
        ]
      }'
import os
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/batches/260716-4K9P/process",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
        "fields": [
            {"name": "invoice_number"},
            {"name": "invoice_date"},
            {"name": "vendor_name"},
            {"name": "total_amount"},
        ]
    },
)
print(response.json())
const response = await fetch("https://imagetotable.ai/api/v1/batches/260716-4K9P/process", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    fields: [
      { name: "invoice_number" },
      { name: "invoice_date" },
      { name: "vendor_name" },
      { name: "total_amount" },
    ],
  }),
});
console.log(await response.json());

Esto descuenta créditos de inmediato (un documento por llamada) y encola el/los documento(s) para procesamiento en segundo plano:

{
  "batch_name": "260716-4K9P",
  "queued": 1,
  "quality": "fast",
  "webhook_registered": false
}

Omite por completo fields y template_id y la API inferirá nombres de columna razonables por su cuenta. quality también es opcional — si lo omites, el procesamiento usará la configuración de velocidad/calidad de tu cuenta (consulta Configuración de la Cuenta y Comportamiento de la API). webhook_registered: false aquí solo significa que esta llamada en particular no incluyó webhook_url — no significa que no haya ningún webhook registrado para este lote; consulta la referencia de Lotes si estás registrando uno por separado mediante PUT .../webhook.

Paso 4 — Consulta y obtén tus resultados

El procesamiento es asíncrono: consulta GET /api/v1/batches/{batch_name} hasta que all_done sea true (unos segundos para un solo documento), o registra un webhook en lugar de consultar. El ciclo de vida completo se explica en la guía del Modelo de Tarea Asíncrona.

Una vez finalizado, obtén los resultados reorganizados:

curl https://imagetotable.ai/api/v1/batches/260716-4K9P/results \
  -H "Authorization: Bearer $API_KEY"
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/batches/260716-4K9P/results",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.json())
const response = await fetch("https://imagetotable.ai/api/v1/batches/260716-4K9P/results", {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());

El JSON de respuesta nunca cambia según el idioma: su estructura no varía según el cliente que envió la solicitud:

{
  "batch_name": "260716-4K9P",
  "status": "succeeded",
  "created_at": "2026-07-16T09:12:03Z",
  "started_at": "2026-07-16T09:12:05Z",
  "completed_at": "2026-07-16T09:12:14Z",
  "documents": [
    {
      "document_id": "3f9c9e2a-1b7d-4e2b-9a3e-2f5b6c7d8e9f",
      "filename": "invoice.jpg",
      "status": "succeeded",
      "created_at": "2026-07-16T09:12:03Z",
      "started_at": "2026-07-16T09:12:05Z",
      "completed_at": "2026-07-16T09:12:14Z",
      "line_items": [
        {
          "invoice_number": "INV-1042",
          "invoice_date": "2026-06-30",
          "vendor_name": "Acme Supply Co.",
          "total_amount": "1,284.50"
        }
      ]
    }
  ]
}

completed_at se establece cuando un documento (o, a nivel de lote, todos los documentos del lote) alcanza un estado terminal: succeeded, failed o canceled. Permanece null mientras esté en queued o processing, y a nivel de lote también permanece null hasta que todos los documentos del lote hayan finalizado, incluso si algunos terminaron antes.

Próximos pasos

A partir de aquí: lee Modelo de tarea asíncrona para conocer el ciclo de vida completo del estado, Webhooks para recibir notificaciones en lugar de consultar, y Referencia de la API para la lista completa de parámetros de cada endpoint.

📮 contact email: [email protected]