CompanyRecurringInvoices

Derive a recurring invoice from an existing invoice

Creates a recurring invoice template of this company taking its lines, recipient, series, payment data and custom fields from an existing invoice, so only the recurrence has to be described.

  • from_invoice_id: the source invoice. It must belong to the company in the path, and one you cannot reach is reported the same way as one that does not exist. It is not modified by this call.
  • Recurrence: name, day_of_month and start_date are required; end_date and frequency are optional. The cadence is not taken from the source invoice — a one-off invoice has none to copy — so it is described here like any other recurrence field: every 1 (MONTHLY), 3 (QUARTERLY) or 12 (YEARLY) months, MONTHLY when omitted. It governs the step from the first invoice onwards, not where that first one lands.
  • VeriFactu: not inherited from the source invoice. Each generated invoice is registered with AEAT, or not, according to the company's regime when it is issued.
  • custom_fields: the template takes those of the source invoice, each with the label the field has now; a field the company has archived since is left out instead of failing the call.
post/v1/companies/{company_id}/recurring-invoices/derivations

Request

  • Base URL: https://app.beel.es/api
  • URL: https://app.beel.es/api/v1/companies/{company_id}/recurring-invoices/derivations
  • Auth: HTTP bearer

Headers

Idempotency-Keystring

Idempotency key to prevent duplicates in sensitive operations.

  • Any unique client-generated string (e.g. an order id). A UUID also works but is not required
  • Allowed characters: letters, digits, _ and - (max 255 chars)
  • Retrying with the same key replays the first response when it was a success (2xx) or a server error (5xx): same status and body, plus the header Idempotency-Replay: true. After a 5xx, check whether the operation took effect before retrying with a new key
  • A 4xx is not stored: the key is released, so the corrected request can reuse it
  • Stored responses expire 24 hours after processing

The key is scoped per user and environment, and bound to the request body, so retrying after a network timeout replays the stored response instead of repeating the operation.

StatusCodeWhen
400INVALID_IDEMPOTENCY_KEYThe key breaks the format rules above.
409IDEMPOTENCY_KEY_PROCESSINGThe first request is still in flight. Wait for the Retry-After seconds (2) and retry with the same key.
409IDEMPOTENCY_KEY_MISMATCHThe key was already used with a different body. Use a new key.

Request body

from_invoice_idstring uuid required

Invoice the template is derived from. It must belong to the company in the path; an invoice you cannot reach is reported the same way as one that does not exist.

namestring required
frequency'MONTHLY' | 'QUARTERLY' | 'YEARLY'

Generation cadence: MONTHLY every month, QUARTERLY every 3 months, YEARLY every 12 months. Omitted, MONTHLY applies.

It governs the step from the first invoice onwards, not where that first one lands: the first occurrence is the first day_of_month on or after start_date, found one month at a time whatever the cadence. A yearly template starting 15 February with day_of_month 10 first invoices on 10 March, then every 10 March after that — it does not wait a year.

day_of_monthinteger required

Day of the month the invoices are issued. A month that does not have that day falls back to its last day: a template on 31 issues on 28 February (29 in a leap year) and on 30 April. So 31 is how you ask for the last day of the month it generates in — there is no separate flag for it, and the accepted range stays 1–31.

The adjustment does not stick and the schedule does not drift: every generation is recalculated from the day_of_month you sent, never from the date it was adjusted to (31 Jan → 28 Feb → 31 Mar).

start_datestring date required

Date the subscription started. A past date is accepted and stored as sent — useful when migrating subscriptions from another system — but it never anchors generation in the past. next_generation becomes the first date of the template's own calendar on or after today (today included): the grid of day_of_month dates anchored at start_date, one every frequency. On a quarterly or yearly template that can be months from now, not this month. Invoices are never back-dated, so the missed periods are not generated. If today's period was already invoiced in the system you are migrating from, send a start_date of tomorrow (or of the next period) so it is not invoiced twice.

draft_in_advanceboolean

Whether the template prepares a draft for review before emitting. The window is fixed at 5 days and both options emit on the scheduled day. Omitted, the template is created without the review draft. Same field, same meaning and same default as when you create a template from scratch: deriving from an invoice does not give it a second semantics.

end_datestring date nullable
send_automaticallyboolean

Example request

{
  "email_configuration": {
    "recipients": [
      "user@example.com"
    ],
    "cc": [
      "user@example.com"
    ]
  }
}

Response

Recurring invoice created successfully from the source invoice

successboolean required

Example response

{
  "success": true,
  "data": {
    "draft_in_advance": true,
    "status": "ACTIVE",
    "pause": {
      "reason": "GENERATION_FAILURE",
      "blocker": "NIF_NOT_REGISTERED"
    },
    "lines": [
      {
        "pricing_mode": "UNIT_PRICE",
        "total_excluding_tax": 1,
        "total_including_tax": 100,
        "exemption_reason": "EXENTA_ART_20"
      }
    ],
    "amount": 106,
    "custom_fields": [
      {
        "key": "project",
        "label": "Project",
        "value": "Corporate website"
      }
    ],
    "max_invoices": 6,
    "last_generated_scheduled_date": "2026-05-01"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.