Facturas recurrentes
Omite un ciclo, crea una recurrencia desde una factura, configura el envío automático, previsualiza el próximo documento y define campos fiscales por línea.
Una factura recurrente es una plantilla más una cadencia: Factuarea genera una factura real en cada ejecución programada. Esta guía cubre los controles que van más allá del create/update básico — omitir un ciclo, arrancar una recurrencia a partir de una factura existente, el envío automático por correo, la previsualización del documento calculado y los campos fiscales por línea que exige VeriFactu.
Todos los endpoints de abajo viven bajo https://api.factuarea.com/v1 y usan el
mismo envoltorio de error, paginación por
cursor y scopes que el
resto de la API.
Omitir la próxima generación
POST /v1/recurring_invoices/{recurring_invoice}/skipAvanza next_run_at exactamente un periodo sin generar una factura para el
ciclo actual. La ocurrencia omitida no cuenta para max_occurrences — el
contador de facturas generadas no se mueve. Úsalo para saltarte un periodo de
facturación (festivos, un cliente en pausa) manteniendo intacto el calendario.
Requiere el scope recurring_invoices:write. Devuelve 200 con el recurso de la
factura recurrente (fíjate en el next_run_at avanzado). Una recurrencia
cancelada o completada responde 422; una factura recurrente que pertenece a
otra empresa responde 404.
curl -X POST https://api.factuarea.com/v1/recurring_invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b/skip \
-H "Authorization: Bearer $FACTUAREA_API_KEY"Omitir registra una entrada skipped en la actividad de la factura recurrente
— el historial muestra que el ciclo se omitió a propósito, no que se perdió.
Crear una recurrencia desde una factura existente
POST /v1/invoices/{invoice}/create-recurringCopia las líneas, el cliente y la serie de una factura origen en una factura
recurrente nueva (con su propio UUID v7) y aplica la cadencia indicada en el
cuerpo. La factura origen queda intacta. Requiere el scope
recurring_invoices:write.
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
frequency | string | sí | daily, weekly, biweekly, monthly, quarterly, semiannual, yearly. |
start_on | string (YYYY-MM-DD) | sí | Primera ejecución programada. |
end_on | string (YYYY-MM-DD) | no | Última ejecución permitida. |
name | string | no | Etiqueta de la recurrencia (≤255). |
description | string | no | |
notes | string | no | |
metadata | object | no | Tus pares clave/valor. |
holiday_handling | string | no | Cómo desplazar una ejecución que cae en festivo. |
days_before_due | integer | no | Desfase de vencimiento de cada factura generada. |
max_occurrences | integer | no | Detener tras N facturas generadas. |
auto_delivery | object | no | Ver Envío automático. |
Devuelve 201 con la nueva factura recurrente y una cabecera Location que
apunta a ella. Una factura origen que pertenece a otra empresa responde 404.
curl -X POST https://api.factuarea.com/v1/invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a42/create-recurring \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"frequency": "monthly",
"start_on": "2026-07-01",
"max_occurrences": 12,
"auto_delivery": {
"send_automatically": true,
"recipients": ["billing@acme.example"]
}
}'Envío automático
El objeto auto_delivery — disponible al crear y actualizar una recurrente y en
create-recurring — manda por correo cada factura generada de forma automática.
| Campo | Tipo | Notas |
|---|---|---|
send_automatically | boolean | Interruptor maestro. false desactiva el envío. |
recipients | string[] | Destinatarios principales (email). |
cc | string[] | Destinatarios en copia (email). |
subject | string | Asunto personalizado (≤255). null usa el predeterminado. |
body | string | Cuerpo personalizado (≤5000). null usa el predeterminado. |
Cuando send_automatically es true, cada factura generada se manda por correo
a recipients (con cc opcional) usando subject/body. Poner
send_automatically a false desactiva el envío. Una lista recipients vacía
con send_automatically: true se rechaza con 422 — no hay a quién enviar.
{
"auto_delivery": {
"send_automatically": true,
"recipients": ["billing@acme.example"],
"cc": ["copy@acme.example"],
"subject": "Tu factura mensual",
"body": "Hola, aquí tienes tu factura de este periodo."
}
}Previsualizar el documento calculado
GET /v1/recurring_invoices/{recurring_invoice}/previewSin expand, preview devuelve solo la previsión de fechas — las próximas
fechas de ejecución (usa count para controlar cuántas).
Pasa expand=document para calcular además el próximo documento en seco: la
respuesta añade un bloque next_invoice con las lines resueltas y los
totals (subtotal, tax, total), construidos desde template_data sin
persistir nada. Úsalo para mostrarle al cliente qué contendrá exactamente la
próxima factura antes de emitirla.
curl -G https://api.factuarea.com/v1/recurring_invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b/preview \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
--data-urlencode "expand=document"{
"data": { "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b", "object": "recurring_invoice" },
"next_invoice": {
"lines": [
{ "description": "Cuota mensual", "quantity": 1, "unit_price": 500, "subtotal": 500 }
],
"totals": { "subtotal": 500, "tax": 105, "total": 605 }
}
}preview nunca crea una factura. Es una lectura pura — los totales en seco se
calculan en memoria desde template_data.
Campos fiscales por línea
Cada línea de template_data acepta los campos fiscales que necesitan VeriFactu
y el modelo tributario español. Se trasladan a cada factura generada.
| Campo | Tipo | Notas |
|---|---|---|
exemption_reason | string | Causa de exención / no sujeción según LIVA. Uno de E1–E6, N1, N2. null si no se informa. |
regime_key | string | Clave de régimen VeriFactu (ClaveRegimen, lista L8.1 de la AEAT). null si no se informa. |
retention | number | Porcentaje de retención IRPF (0–100). |
retention_rate_id | string (UUID v7) | Impuesto del catálogo aplicado como retención IRPF. Opaco — no cambia el cálculo de taxes/total (lo hace el porcentaje plano retention). |
surcharge | number | Porcentaje de recargo de equivalencia (0–100). |
surcharge_rate_id | string (UUID v7) | Impuesto del catálogo aplicado como recargo de equivalencia. Opaco — el porcentaje plano surcharge gobierna el cálculo. |
El recargo de equivalencia va ligado por ley al IVA de la línea. Los únicos pares
legales tax_rate → surcharge son:
IVA (tax_rate) | Recargo (surcharge) |
|---|---|
21 | 5.2 |
10 | 1.4 |
4 | 0.5 |
Enviar un exemption_reason, regime_key, retention_rate_id o
surcharge_rate_id fuera de su catálogo responde 422 con una lista
allowed_values en el error. Un par IVA↔recargo ilegal (p.ej. 21 con 1.4)
también se rechaza con 422.
{
"template_data": {
"lines": [
{
"description": "Consultoría",
"quantity": 1,
"unit_price": 1000,
"tax_rate": 21,
"surcharge": 5.2,
"retention": 15,
"regime_key": "01",
"exemption_reason": null
}
]
}
}