NewStripe: a buyer with a NIF always gets a standard invoice, and the simplified threshold is deprecated
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog
Recurring Invoices

Replace a recurring invoice (deprecated)

Scopeinvoices:write

Deprecated. The canonical form has a single update verb, PATCH /v1/companies/{company_id}/recurring-invoices/{recurring_invoice_id}, which is not a drop-in replacement: it changes only the fields present in the body. To reproduce a total replacement, send every field and pass null in the ones you want cleared.

Replaces the schedule, template lines and recipient of a recurring invoice with the body you send. Only allowed while the template is active or paused.

  • Not a partial update: leaving out end_date, payment_method (with its payment_iban, payment_swift and payment_term_days), notes or email_configuration clears them.
  • lines: replaced as a whole. Omitting them or sending null keeps the current ones, and an empty array is rejected.

Retires on 9 December 2026. See the migration guide for what moved where and what changes when you switch.


PUT
/v1/recurring-invoices/{recurring_invoice_id}
AuthorizationBearer <token>

Keys are prefixed beel_sk_, and each one carries the scopes it was created with: a key short of the scope an operation needs is answered 403. The scope an operation requires is shown next to its title, and the full catalogue lives in the Scopes reference.

Keys are created from the BeeL dashboard. They are secret credentials: do not share them or commit them to source control.

In: header

Path Parameters

recurring_invoice_idstring

Unique identifier (UUID) of the recurring invoice template, as returned when it is created or listed. A template of another company answers 404 with RECURRING_NOT_FOUND, exactly like one that does not exist.

Formatuuid
name?string
Match^\S.*$
Length1 <= length <= 255
frequency?string

Generation cadence: MONTHLY every month, QUARTERLY every 3 months, YEARLY every 12 months. Omitted, the current one is kept — it is never reset to MONTHLY.

Changing it reschedules the template. The next generation is recalculated on the new grid — the day_of_month dates anchored at start_date, one every cadence — so it can land months later than the one you saw before the call. If the template has already issued invoices, the landing respects that: it is never a period that was already billed, and never before today either — the first point of the new grid strictly after the last invoiced one. It also discards a pending skip: the skipped period only existed as a point of the old grid, and that grid is gone. Send the same cadence and nothing is rescheduled.

Value in"MONTHLY" | "QUARTERLY" | "YEARLY"
day_of_month?integer

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).

Range1 <= value <= 31
start_date?string

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.

Once the template has issued, only a different date is rejected with a 422 RECURRING_START_DATE_NOT_EDITABLE. Resending the value it already has is a no-op, so this request can keep sending the template complete, as it asks above.

Formatdate
draft_in_advance?boolean

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. Generating manually a period whose scheduled date is today or earlier emits it on the spot. Omitted, the current value is kept.

preview_days?integerDeprecated

Deprecated. Superseded by draft_in_advance, because the review window is no longer a number you pick: it is fixed at 5 days. Still accepted so nothing breaks — any value greater than 0 means the same as draft_in_advance: true, and 0 the same as false. When both are sent, draft_in_advance wins. It will be removed in a future version.

Range0 <= value <= 30
end_date?string|null
Formatdate
max_invoices?integer|null

Total number of invoices this template will generate before ending on its own, between 2 and 600. Like end_date, it is cleared when you leave it out: this is a replacement.

A recurrence ends in ONE way: open-ended, on end_date, or after max_invoices. Sending both with a value is rejected with RECURRING_END_MODE_CONFLICT. The range is not enforced by this schema on purpose, so the rejection carries its own code and its own message: below 2 you do not want a recurrence but a scheduled invoice (PUT /v1/companies/{company_id}/invoices/{invoice_id}/schedule).

Lowering it below the invoices already generated is rejected: issued invoices are fiscal facts and are not undone by moving the cap. Setting it exactly to the number already generated is accepted and ends the template in that same call.

series_id?string
Formatuuid
invoice_type?string
Value in"STANDARD" | "SIMPLIFIED"
customer_id?string|null

Recipient of the generated invoices. Send null to leave the template without a recipient; omit it to keep the current one.

Formatuuid
lines?|null

Template lines, replaced as a whole. Omit them (or send null) to keep the current ones — a template with no lines invoices nothing, so an empty array is rejected.

Items1 <= items
payment_method?string
Value in"NONE" | "BANK_TRANSFER" | "CARD" | "CASH" | "CHECK" | "DIRECT_DEBIT" | "BIZUM" | "OTHER"
payment_iban?string|null
payment_swift?string|null
payment_term_days?integer|null
notes?string|null
send_automatically?boolean
email_configuration?|null

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PUT "https://app.beel.es/api/v1/recurring-invoices/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "frequency": "MONTHLY",
    "day_of_month": 0,
    "start_date": "2019-08-24",
    "end_date": "2019-08-24",
    "next_generation": "2019-08-24",
    "draft_in_advance": true,
    "status": "ACTIVE",
    "is_failing": false,
    "pause": {
      "reason": "GENERATION_FAILURE",
      "since": "2019-08-24T14:15:22Z",
      "blocker": "NIF_NOT_REGISTERED"
    },
    "completion": {
      "reason": "USER",
      "at": "2019-08-24T14:15:22Z"
    },
    "series_id": "0f6582ac-1e7e-41dc-a63a-24fccd074d0c",
    "series_code": "string",
    "invoice_type": "STANDARD",
    "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
    "recipient_fiscal_name": "string",
    "recipient_nif": "string",
    "recipient_alternative_id": {
      "type": "NIF_IVA",
      "number": "string",
      "country_code": "st"
    },
    "lines": [
      {
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "order": 0,
        "description": "string",
        "quantity": 0,
        "unit": "string",
        "unit_price": 0,
        "pricing_mode": "UNIT_PRICE",
        "total_excluding_tax": 1,
        "total_including_tax": 100,
        "discount_percentage": 0,
        "tax_type": "string",
        "vat_rate": 0,
        "regime_key": "string",
        "equivalence_surcharge_rate": 0,
        "irpf_rate": 0,
        "exemption_reason": "EXENTA_ART_20",
        "exemption_reason_text": "string"
      }
    ],
    "amount": 106,
    "payment_method": "string",
    "payment_iban": "string",
    "payment_swift": "string",
    "payment_term_days": 0,
    "notes": "string",
    "send_automatically": true,
    "email_configuration": {
      "recipients": [
        "string"
      ],
      "cc": [
        "string"
      ],
      "subject": "string",
      "message": "string"
    },
    "generated_invoices": 0,
    "max_invoices": 6,
    "last_generated_at": "2019-08-24T14:15:22Z",
    "last_generated_scheduled_date": "2026-05-01",
    "source_invoice_id": "0c7d5f47-8759-4ef4-82d5-705413539f77",
    "created_at": "2019-08-24T14:15:22Z",
    "updated_at": "2019-08-24T14:15:22Z"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The provided data is not valid",
    "details": {
      "field": "specific error message"
    }
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  },
  "type": "https://docs.beel.es/errors/INVOICE_NO_LINES",
  "title": "INVOICE_NO_LINES",
  "detail": "The invoice must have at least one line",
  "instance": "/v1/invoices/abc-123"
}
{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "You do not have permission to access this resource"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
{
  "success": false,
  "error": {
    "code": "INVOICE_NOT_FOUND",
    "message": "Invoice not found"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
{
  "success": false,
  "error": {
    "code": "CONCURRENT_MODIFICATION",
    "message": "The resource was modified by another request; read it again and retry"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The provided data is not valid",
    "details": {
      "field": "specific error message"
    }
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  },
  "type": "https://docs.beel.es/errors/INVOICE_NO_LINES",
  "title": "INVOICE_NO_LINES",
  "detail": "The invoice must have at least one line",
  "instance": "/v1/invoices/abc-123"
}
{
  "success": false,
  "error": {
    "code": "UNSUPPORTED_MEDIA_TYPE",
    "message": "Unsupported media type: text/plain. Supported: application/json"
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}

Get the generation history of a recurring invoice (deprecated) GET

**Deprecated.** Use `GET /v1/companies/{company_id}/recurring-invoices/{recurring_invoice_id}/history`. Returns the invoices previously generated from this recurring template, including their status and generation dates. **Only generated invoices**: this route never reports failed runs, skipped slots or pauses — the successor does. - **Response shape:** it differs from the successor's, and that is why this notice exists. This route is frozen as it shipped until its `Sunset` date: it returns the **whole** history in `data.history` and carries no `pagination`. The successor pages with `page`/`limit` and answers the first 20 entries by default. Send `limit` and read `data.pagination` when you migrate. **Retires on 9 December 2026.** See the [migration guide](https://docs.beel.es/changelog/resources-under-the-nif) for what moved where and what changes when you switch.

Update a recurring invoice (deprecated) PATCH

**Deprecated.** Use `PATCH /v1/companies/{company_id}/recurring-invoices/{recurring_invoice_id}`, which behaves identically. Updates only the fields present in the body, leaving every other field of the recurring invoice template as it is. - **Omitted vs `null`:** an omitted field keeps its current value; a field sent as `null` is cleared, and only where the request schema documents the field as nullable. - **`lines`:** replaced as a whole, not patched line by line. The recipient survives the change, and an empty array is rejected. - **`payment_method`:** replaced as a whole together with `payment_iban`, `payment_swift` and `payment_term_days` — send them in the same request or they are dropped. - **Schedule:** `frequency`, `day_of_month` and `start_date` stay put unless you send them; sending a new value for any of the three moves the next generation — resending the ones already in effect changes nothing. Changing `frequency` recalculates it on the new grid and discards a pending skip. `start_date` is only editable while the template has not generated any invoice yet. **Retires on 9 December 2026.** See the [migration guide](https://docs.beel.es/changelog/resources-under-the-nif) for what moved where and what changes when you switch.