LeeFactura

Para desarrolladores

API de LeeFactura

Conecta tu programa con LeeFactura: consulta clientes, facturas emitidas, facturas escaneadas y los borradores de los modelos 303 y 130. La versión 1 es de solo lectura, en JSON, y va incluida en los planes Gestoría y Gestoría Pro.

Descarga la descripción en formato OpenAPI (JSON) para Postman, Insomnia o un generador de clientes.

Empezar

  1. El titular de la cuenta entra en el panel, Mi cuenta → API, y crea una clave con un nombre, los permisos que necesita y, si quiere, solo ciertos clientes.
  2. Copia la clave: se muestra una sola vez. En nuestra base de datos solo queda su huella, nunca la clave.
  3. Envíala en cada petición, en la cabecera Authorization.
curl https://leefactura.es/api/v1/account \
  -H "Authorization: Bearer lf_tu_clave_aqui"

Guarda la clave como una contraseña: da acceso a los datos de la cuenta. Si crees que la ha visto alguien más, revócala en el panel y deja de valer al instante.

Permisos

  • clients:read — Lista y ficha de los clientes.
  • invoices:read — Facturas de venta emitidas y facturas escaneadas.
  • taxes:read — Borradores de los modelos 303 y 130.

Una clave puede limitarse a algunos clientes: pedir otro cliente da 404, como si no existiera.

Listas, errores y topes

Las listas se paginan con page y per_page (50 por defecto, hasta 200) y devuelven data y pagination. Las fechas son AAAA-MM-DD y los importes, números en euros.

Un error siempre tiene la forma {"error": {"code", "message", "request_id"}}. Cada respuesta lleva la cabecera X-Request-Id: cítala si nos escribes.

EstadoCódigoQué significa
400invalid_parameterUn parámetro no es válido (el mensaje dice cuál).
401unauthorized / invalid_key / revoked_key / expired_keyFalta la clave, no vale, se ha revocado o ha caducado.
403insufficient_scope / plan_not_allowedLa clave no tiene el permiso de esa ruta, o el plan de la cuenta ya no incluye la API.
404not_foundNo existe, o la clave no llega a ese cliente.
405method_not_allowedLa versión 1 es de solo lectura: solo admite GET.
429rate_limitedSe ha pasado el tope por minuto o por día. Mira la cabecera Retry-After.
500internal_errorFallo nuestro. Cita el request_id al escribirnos.
503unavailableEl servicio no está disponible un momento: reintenta.

Topes por clave: Gestoría, 60 peticiones por minuto y 5000 al día; Gestoría Pro, 180 por minuto y 50.000 al día (UTC). Al pasarlos, la respuesta es 429 con Retry-After en segundos. Una cuenta puede tener hasta 10 claves activas.

Rutas

Base: https://leefactura.es/api/v1. Todas son GET.

GET /account

Quién es esta clave

Devuelve la cuenta, el plan, el alcance de la clave y sus topes. Sirve para comprobar que la clave funciona.

GET /account

{
  "account": {
    "id": "9d1e…",
    "name": "Gestoría Ejemplo",
    "plan": "gestoria"
  },
  "key": {
    "id": "c4a2…",
    "name": "Programa de la gestoría",
    "scopes": [
      "clients:read",
      "invoices:read"
    ],
    "client_ids": null,
    "expires_at": null
  },
  "limits": {
    "per_minute": 60,
    "per_day": 5000
  }
}

GET /clients

Lista de clientes

Los clientes de la cuenta que la clave puede ver, del más antiguo al más reciente.

Permiso: clients:read

  • page (consulta) — Página, desde 1.
  • per_page (consulta) — Resultados por página: de 1 a 200 (50 por defecto).
GET /clients?per_page=2

{
  "data": [
    {
      "id": "0b5b…",
      "name": "Taller Mecánico Juan",
      "tax_id": "12345678Z",
      "address": "Calle Mayor 1, 08001 Barcelona",
      "is_own_business": false,
      "is_freelancer": true,
      "created_at": "2026-02-03T09:12:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 2,
    "total": 1,
    "total_pages": 1
  }
}

GET /clients/{id}

Un cliente

La ficha de un cliente. 404 si no existe o la clave no llega a él.

Permiso: clients:read

  • id (ruta, obligatorio) — Identificador del cliente.
GET /clients/0b5b…

{
  "data": {
    "id": "0b5b…",
    "name": "Taller Mecánico Juan",
    "tax_id": "12345678Z",
    "address": null,
    "is_own_business": false,
    "is_freelancer": true,
    "created_at": "2026-02-03T09:12:00Z"
  }
}

GET /sales-invoices

Facturas de venta emitidas

Las facturas emitidas desde LeeFactura, de la más reciente a la más antigua, con su estado de cobro.

Permiso: invoices:read

  • client_id (consulta) — Solo los de este cliente.
  • from (consulta) — Fecha de emisión desde (AAAA-MM-DD, incluida).
  • to (consulta) — Fecha de emisión hasta (AAAA-MM-DD, incluida).
  • page (consulta) — Página, desde 1.
  • per_page (consulta) — Resultados por página: de 1 a 200 (50 por defecto).
GET /sales-invoices?client_id=0b5b…&from=2026-01-01

{
  "data": [
    {
      "id": "7f3c…",
      "client_id": "0b5b…",
      "number": "2026-0007",
      "year": 2026,
      "issue_date": "2026-03-01",
      "due_date": "2026-03-31",
      "invoice_type": "F1",
      "recipient": {
        "name": "Cliente SL",
        "tax_id": "B22222222",
        "address": "Calle 2",
        "postal_code": "08001",
        "city": "Barcelona",
        "province": "Barcelona",
        "country": "ES"
      },
      "lines": [
        {
          "description": "Reparación",
          "quantity": 2,
          "unit_price": 50,
          "vat_rate": 21,
          "exemption": null,
          "base": 100,
          "vat_amount": 21
        }
      ],
      "totals": {
        "base": 100,
        "vat": 21,
        "withholding_rate": null,
        "withholding_amount": null,
        "total": 121
      },
      "payment_method": "transferencia",
      "notes": null,
      "status": {
        "annulled": false,
        "annulled_at": null,
        "collection": {
          "state": "pendiente",
          "paid": 0,
          "pending": 121,
          "days_overdue": 0
        }
      },
      "rectification": null,
      "created_at": "2026-03-01T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 1,
    "total_pages": 1
  }
}

GET /sales-invoices/{id}

Una factura de venta

Una factura emitida con el mismo formato que en la lista. 404 si no existe o es de un cliente al que la clave no llega.

Permiso: invoices:read

  • id (ruta, obligatorio) — Identificador de la factura.
GET /sales-invoices/7f3c…

{
  "data": {
    "id": "7f3c…",
    "number": "2026-0007",
    "…": "…"
  }
}

GET /scanned-invoices

Facturas, tickets y albaranes escaneados

Los documentos leídos por la IA (solo los ya leídos), del más reciente al más antiguo. Sin enlaces al archivo original.

Permiso: invoices:read

  • client_id (consulta) — Solo los de este cliente.
  • type (consulta) — gasto, ingreso o albaran.
  • from (consulta) — Fecha de la factura desde (AAAA-MM-DD, incluida).
  • to (consulta) — Fecha de la factura hasta (AAAA-MM-DD, incluida).
  • page (consulta) — Página, desde 1.
  • per_page (consulta) — Resultados por página: de 1 a 200 (50 por defecto).
GET /scanned-invoices?type=gasto&from=2026-01-01

{
  "data": [
    {
      "id": "a91e…",
      "client_id": "0b5b…",
      "type": "gasto",
      "status": "completed",
      "source": "web",
      "created_at": "2026-03-02T08:30:00Z",
      "document": {
        "provider_name": "Ferretería Industrial SL",
        "tax_id": "B12345674",
        "tax_id_valid": true,
        "number": "A-2026-114",
        "date": "2026-02-28",
        "base": 100,
        "vat": 21,
        "total": 121,
        "withholding_amount": null,
        "withholding_category": null,
        "vat_breakdown": [
          {
            "rate": 21,
            "base": 100,
            "quota": 21,
            "type": "iva"
          }
        ],
        "deductible_expense_percentage": 100,
        "deductible_vat_percentage": 100,
        "confidence": "high",
        "reviewed": true
      }
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 1,
    "total_pages": 1
  }
}

GET /scanned-invoices/{id}

Un documento escaneado

Un documento leído por la IA con el mismo formato que en la lista.

Permiso: invoices:read

  • id (ruta, obligatorio) — Identificador del documento.
GET /scanned-invoices/a91e…

{
  "data": {
    "id": "a91e…",
    "type": "gasto",
    "…": "…"
  }
}

GET /tax-drafts/{model}

Borrador del modelo 303 o 130

El borrador de un cliente en un trimestre, con el mismo cálculo que el panel: orientativo, no una declaración. El modelo 130 es acumulado desde el 1 de enero.

Permiso: taxes:read

  • model (ruta, obligatorio) — 303 o 130.
  • client_id (consulta, obligatorio) — El cliente.
  • quarter (consulta, obligatorio) — Trimestre con la forma AAAA-Q1 a AAAA-Q4.
GET /tax-drafts/303?client_id=0b5b…&quarter=2026-Q3

{
  "data": {
    "model": "303",
    "client_id": "0b5b…",
    "quarter": "2026-Q3",
    "issued": {
      "base": 1000,
      "vat": 210,
      "invoices": 3,
      "ticket_days": 0
    },
    "received": {
      "base": 400,
      "deductible_vat": 84,
      "invoices": 5
    },
    "result": {
      "amount": 126,
      "to_pay": true
    },
    "equivalence_surcharge": {
      "received": 0,
      "issued": 0
    },
    "reverse_charge_base": 0,
    "warnings": [],
    "notice": "Borrador orientativo calculado con las facturas de LeeFactura: no sustituye la presentación ante la Agencia Tributaria. Revísalo con el asesor antes de presentarlo."
  }
}

Qué tener en cuenta

  • Los borradores de impuestos son orientativos: no sustituyen la presentación ante la Agencia Tributaria. Revísalos con el asesor.
  • Las facturas escaneadas son lo que ha leído la IA (con su campo reviewed si una persona las ha revisado). La API no devuelve los archivos originales.
  • La API no admite llamadas desde el navegador (no tiene CORS): llámala siempre desde tu servidor, para que la clave no llegue a una página web.
  • La versión 1 no crea ni modifica nada. Los cambios que rompan algo irán en una versión nueva (/api/v2); añadir campos a las respuestas no cuenta como romper.
  • ¿Necesitas otra ruta o un aviso automático (webhook)? Escríbenos a info@leefactura.es.

Deja de perder horas cada trimestre

Crea tu cuenta gratis, sube tu primer lote y ten tu borrador de IVA e IRPF listo en minutos.

Empezar gratis