¿Vienes de Holded, Quipu u otro programa? Importamos tus facturas y contactos. Cómo funciona
FacturaYa

Desarrolladores

API de FacturaYa

Crea facturas con VERI*FACTU, presupuestos y facturas recibidas desde tu tienda, tu ERP o tus scripts. REST, JSON y webhooks firmados.

Plan gratis · 14 días de Empresa sin tarjeta

Autenticación

Crea un token en Ajustes → API. Puede ser de solo lectura o de lectura y escritura. Envíalo en cada petición:

Authorization: Bearer TU_TOKEN
Accept: application/json

La URL base es https://facturaya.net/api/v1. Todo lo que hace la API queda en tu cuenta, con las mismas reglas que la aplicación: numeración correlativa, impuestos, bloqueo de facturas emitidas y VERI*FACTU.

Límites

60 peticiones por minuto y un máximo diario según tu plan:

GratisSin API
Autónomo250 al día
Empresa1.000 al día
Con la API ampliada (9 €/mes)10.000 al día

Al superarlo la respuesta es 429 con la cabecera Retry-After.

Formato y errores

  • Fechas en AAAA-MM-DD. Importes como texto con dos decimales ("121.00"), para no perder céntimos.
  • Las listas van paginadas: ?page=2&per_page=50 (máximo 100), con links y meta.
  • 401 token no válido, 403 el plan o el token no lo permiten, 404 no existe en tu cuenta, 422 datos no válidos (con errors por campo).

Endpoints

Contactos

GET /contacts Lista de contactos. Filtro ?q= por nombre, NIF o email.
POST /contacts Crea un contacto: nombre, nif, email, telefono, direccion, codigo_postal, ciudad, provincia, pais, idioma, iban.
GET /contacts/{id} Un contacto.
PATCH /contacts/{id} Modifica los campos que envíes.

Productos e impuestos

GET /products Lista de productos y variantes. Filtros: q (nombre, SKU o código de barras), grupo.
POST /products Crea un producto: nombre, precio, impuestos[], sku, codigo_barras, stock.
GET /products/{id} Un producto. Si es una variante, trae grupo y opciones.
GET /product-groups/{id} Un producto con variantes: opciones, valores e ids de sus variantes.
GET /taxes Impuestos con sus ids, que usan las líneas de los documentos.

Facturas

GET /invoices Facturas emitidas y rectificativas. Filtros ?estado=, ?desde=, ?hasta=, ?contact_id=.
POST /invoices Crea un borrador, o una factura emitida con "emitir": true (numerada, con VERI*FACTU si lo tienes activo).
GET /invoices/{id} Una factura con sus líneas y el estado de sus registros VERI*FACTU.
GET /invoices/{id}/pdf PDF de una factura emitida.
GET /invoices/{id}/payments Cobros de una factura.
POST /invoices/{id}/payments Registra un cobro: importe, fecha, descripcion, bank_account_id.

Presupuestos y proformas

GET /estimates Presupuestos y proformas. Filtros ?tipo=presupuesto|proforma, ?estado=, ?desde=, ?hasta=, ?contact_id=.
POST /estimates Crea un presupuesto (o una proforma con "tipo": "proforma"), numerado en su serie.
GET /estimates/{id} Un presupuesto con sus líneas.
GET /estimates/{id}/pdf PDF del presupuesto.

Facturas recibidas

GET /purchases Facturas de proveedores. Filtros ?estado=, ?desde=, ?hasta=, ?contact_id=.
POST /purchases Registra una factura recibida: contact_id, numero (el del proveedor), fecha, categoria, lineas[].
GET /purchases/{id} Una factura recibida con sus líneas.

Webhooks

GET /webhooks Tus webhooks y el resultado del último envío.
POST /webhooks Crea un webhook: url (https) y eventos[]. Devuelve el secreto de firma una sola vez.
DELETE /webhooks/{id} Borra un webhook.

Ejemplo: emitir una factura

curl -X POST https://facturaya.net/api/v1/invoices \
  -H "Authorization: Bearer TU_TOKEN" \
  -H "Accept: application/json" -H "Content-Type: application/json" \
  -d '{
    "contact_id": 12,
    "emitir": true,
    "lineas": [
      {"concepto": "Mantenimiento web", "cantidad": "1", "precio": "95", "impuestos": [1]}
    ]
  }'

Los ids de impuestos salen de GET /taxes. Sin "emitir" se crea un borrador que puedes revisar en la aplicación.

Webhooks

Te avisamos con un POST en JSON a tu URL (https) cuando pasa algo en tu cuenta. Configúralos en Ajustes → API o con POST /webhooks. Eventos:

invoice.issued
Factura emitida
invoice.paid
Factura cobrada
payment.created
Cobro o pago registrado
estimate.created
Presupuesto creado
estimate.accepted
Presupuesto aceptado
estimate.rejected
Presupuesto rechazado
purchase.created
Factura recibida registrada
contact.created
Contacto creado
{
  "id": "evt_01JB…",
  "type": "invoice.issued",
  "created": "2026-10-27T10:00:00+01:00",
  "data": { "id": 381, "numero": "F-2026-0042", "total": "115.95", … }
}

Cada envío lleva la cabecera FacturaYa-Signature: t=…,v1=…: v1 es el HMAC-SHA256, con tu secreto, de t, un punto y el cuerpo tal cual llega. Compruébalo y rechaza envíos con más de 5 minutos:

$body = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_FACTURAYA_SIGNATURE']), $sig);
$expected = hash_hmac('sha256', $sig['t'].'.'.$body, getenv('FACTURAYA_WEBHOOK_SECRET'));
if (! hash_equals($expected, $sig['v1']) || abs(time() - (int) $sig['t']) > 300) {
    http_response_code(400);
    exit;
}

Responde con un 2xx en menos de 10 segundos. Si no, reintentamos a los 1, 5 y 30 minutos, y a las 2 y 6 horas. Tras 20 fallos seguidos el webhook se desactiva y lo verás en Ajustes → API. El mismo evento puede llegar más de una vez: usa su id para no procesarlo dos veces.

Emite tu primera factura hoy

Crea la cuenta en un minuto. Sin tarjeta.

Empieza gratis