Factuarea API

Recurring invoices

Skip a cycle, create a recurrence from an invoice, configure auto-delivery, preview the next document and set per-line fiscal fields.

A recurring invoice is a template plus a cadence: Factuarea generates a real invoice on every scheduled run. This guide covers the controls that go beyond basic create/update — skipping a cycle, bootstrapping a recurrence from an existing invoice, automatic email delivery, previewing the computed document and the per-line fiscal fields that VeriFactu requires.

All endpoints below live under https://api.factuarea.com/v1 and use the same error envelope, cursor pagination and scopes as the rest of the API.

Skip the next generation

POST /v1/recurring_invoices/{recurring_invoice}/skip

Advances next_run_at by exactly one period without generating an invoice for the current cycle. The skipped occurrence is not counted against max_occurrences — the generated-invoice counter does not move. Use it to jump over a billing period (holidays, a paused client) while keeping the schedule intact.

Requires the recurring_invoices:write scope. Returns 200 with the recurring-invoice resource (note the advanced next_run_at). A cancelled or completed recurrence responds 422; a recurring invoice that belongs to another company responds 404.

curl -X POST https://api.factuarea.com/v1/recurring_invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b/skip \
  -H "Authorization: Bearer $FACTUAREA_API_KEY"

Skipping logs a skipped entry in the recurring-invoice activity — the history shows the cycle was deliberately omitted, not missed.

Create a recurrence from an existing invoice

POST /v1/invoices/{invoice}/create-recurring

Copies the lines, client and series of a source invoice into a brand-new recurring invoice (its own UUID v7) and applies the cadence supplied in the body. The source invoice is untouched. Requires the recurring_invoices:write scope.

FieldTypeRequiredNotes
frequencystringyesdaily, weekly, biweekly, monthly, quarterly, semiannual, yearly.
start_onstring (YYYY-MM-DD)yesFirst scheduled run.
end_onstring (YYYY-MM-DD)noLast allowed run.
namestringnoLabel for the recurrence (≤255).
descriptionstringno
notesstringno
metadataobjectnoYour key/value pairs.
holiday_handlingstringnoHow to shift a run that falls on a holiday.
days_before_dueintegernoDue date offset for each generated invoice.
max_occurrencesintegernoStop after N generated invoices.
auto_deliveryobjectnoSee Auto-delivery.

Returns 201 with the new recurring invoice and a Location header pointing to it. A source invoice that belongs to another company responds 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"]
    }
  }'

Auto-delivery

The auto_delivery object — available on recurring create, update and create-recurring — emails every generated invoice automatically.

FieldTypeNotes
send_automaticallybooleanMaster switch. false disables sending.
recipientsstring[]Primary recipients (email).
ccstring[]Carbon-copy recipients (email).
subjectstringCustom subject (≤255). null uses the default.
bodystringCustom body (≤5000). null uses the default.

When send_automatically is true, each generated invoice is emailed to recipients (with optional cc) using subject/body. Setting send_automatically to false turns delivery off. An empty recipients list with send_automatically: true is rejected with 422 — there is no one to send to.

{
  "auto_delivery": {
    "send_automatically": true,
    "recipients": ["billing@acme.example"],
    "cc": ["copy@acme.example"],
    "subject": "Your monthly invoice",
    "body": "Hi, here is your invoice for this period."
  }
}

Preview the computed document

GET /v1/recurring_invoices/{recurring_invoice}/preview

Without expand, preview returns only the date forecast — the upcoming run dates (use count to control how many).

Pass expand=document to also compute the next document as a dry-run: the response adds a next_invoice block with the resolved lines and totals (subtotal, tax, total), built from template_data without persisting anything. Use it to show the customer exactly what the next invoice will contain before it is issued.

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": "Monthly retainer", "quantity": 1, "unit_price": 500, "subtotal": 500 }
    ],
    "totals": { "subtotal": 500, "tax": 105, "total": 605 }
  }
}

preview never creates an invoice. It is a pure read — the dry-run totals are computed in memory from template_data.

Per-line fiscal fields

Each line of template_data accepts the fiscal fields VeriFactu and the Spanish tax model need. They flow into every generated invoice.

FieldTypeNotes
exemption_reasonstringLIVA exemption / non-subjection cause. One of E1E6, N1, N2. null if not informed.
regime_keystringVeriFactu regime key (ClaveRegimen, AEAT list L8.1). null if not informed.
retentionnumberIRPF withholding percentage (0–100).
retention_rate_idstring (UUID v7)Catalog tax applied as IRPF withholding. Opaque — does not change the taxes/total computation (the flat retention percentage does).
surchargenumberEquivalence surcharge percentage (0–100).
surcharge_rate_idstring (UUID v7)Catalog tax applied as equivalence surcharge. Opaque — the flat surcharge percentage drives the maths.

The equivalence surcharge is tied to the line VAT by law. The only legal tax_ratesurcharge pairs are:

VAT (tax_rate)Surcharge (surcharge)
215.2
101.4
40.5

Sending an exemption_reason, regime_key, retention_rate_id or surcharge_rate_id outside its catalog responds 422 with an allowed_values list in the error. An illegal VAT↔surcharge pair (e.g. 21 with 1.4) is also rejected with 422.

{
  "template_data": {
    "lines": [
      {
        "description": "Consulting",
        "quantity": 1,
        "unit_price": 1000,
        "tax_rate": 21,
        "surcharge": 5.2,
        "retention": 15,
        "regime_key": "01",
        "exemption_reason": null
      }
    ]
  }
}

On this page