Recurring invoices
What the recurring flag configures, what generates the next one, and what does not.
A recurring invoice is an ordinary invoice that Wajub copies into a new draft each cycle. Every copy still has to be sent and paid by the customer: nothing is debited automatically.
Marking an invoice recurring
There is no separate endpoint and no subscription resource. Two fields on the ordinary create call are the whole surface.
https://api.wajub.com/invoicesis_recurringbooleanoptionaldefault : falseinvoice_date. Only an invoice can recur: on a quote or an estimate, true answers 422.recurring_intervalenumoptionaldaily, weekly, monthly, quarterly or yearly. The gap between copies.recurring_frequencyenumoptionalrecurring_interval, same five values.customer_idstringoptionalEverything else on the invoice, the lines, the totals, the notes, behaves exactly as on a one-off.
curl https://api.wajub.com/invoices \
-H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_7Kq2mX9vL4tRb3nP8sZcWd1e",
"customer_name": "Amina Traoré",
"invoice_date": "2026-09-11",
"currency": "XAF",
"items": [
{ "name": "Retainer", "quantity": 1, "unit_price": 250000 }
],
"is_recurring": true,
"recurring_interval": "monthly"
}'The response is the same 201 Created as any other invoice, status: "draft" included, carrying
two recurring fields and no more.
recurring_frequency is a spelling, not a multiplier
recurring_frequency: "monthly" means every month, not a number of months. Update does not accept
it: send recurring_interval everywhere.
What the API cannot set
The recurrence has more settings, and none of them is on the API. An end after N occurrences, or an interval of every N months, cannot be set through the API.
| Setting | What it does | Where |
|---|---|---|
| A start date | Puts the first copy on a date you choose, instead of one interval after the invoice | The Dashboard form |
| An end date | The last day a cycle is generated for | The Dashboard form |
| An end after a number of copies | Stop after this many copies | Not available |
| A multiple of the interval | Every two months, every three weeks | Not available |
An end date entered in the Dashboard is applied: the cycle that falls on it is the last one generated, and the series then stops for good. A recurrence created through the API has no end rule at all: it runs until you stop it.
What comes back, and what does not
Four recurring fields come back on the invoice object.
| Field | On a recurring invoice | On a generated copy |
|---|---|---|
is_recurring | true while the series runs, false once it is stopped | false: a copy generates nothing |
recurring_interval | daily, weekly, monthly, quarterly or yearly | The template's, copied |
next_invoice_date | The date of the next copy, YYYY-MM-DD. null once the series is stopped or the invoice cancelled | null |
recurring_parent | null | The id of the recurring invoice it was generated from |
So a copy is the invoice whose recurring_parent is set. The end rule is not in the response, and
GET /invoices has no recurring filter, though the Dashboard list does.
How a cycle runs
The first copy is due one interval after the invoice's invoice_date, never in the past: a
backdated invoice does not produce the cycles that went by before it was recurring. A cycle is never
generated twice, even for a series switched off and on again. A copy cannot be made recurring itself
(422), and a duplicate of a recurring invoice is a plain draft that recurs only if you set it to.
On each cycle's date, Wajub copies every recurring invoice that is not cancelled, unless its end date has passed or your plan lacks the feature.
| The copy inherits | The copy has of its own |
|---|---|
| The lines, with their quantities, prices and taxes | No invoice_number until it is sent, like any draft |
| The currency and the whole-invoice discount | invoice_date, set to the cycle that just came due |
| The notes, terms, footer and payment instructions | due_date, thirty days later |
| The template, the language and the display settings | The customer block, re-read from the customer record |
| The payment methods it accepts | is_recurring: false. A copy is an ordinary invoice and never generates copies of its own |
Each cycle produces exactly one copy. A monthly, quarterly or yearly series never skips a month: one month after 31 January is 28 February, and the series goes on from the 28th. Cycle dates are in UTC.
Two of those deserve a second look. The customer block is re-snapshotted from the live customer
each time, so an address or a company name corrected on the record flows into the next document and
leaves the earlier ones untouched. And due_date is always thirty days after the copy's date,
whatever terms the original carried.
A copy is a draft, not a charge
Each generated invoice lands as draft, with amount_paid back to zero. It is not opened for
payment, not emailed, and not paid, and it stays a draft past its due date: only a sent invoice
turns overdue. Somebody still has to call /send and deliver the URL every
cycle, exactly as for a one-off. Recurrence saves you writing the document, nothing else.
No customer record, no copy
An invoice without customer_id never generates. An invoice addressed to a customer_name alone,
which is perfectly valid for a one-off, silently produces no copy. Pass customer_id when you set
is_recurring.
Stopping a recurrence
An end date, where the Dashboard set one, ends the series on its own. Otherwise you stop it, at any point and whatever the invoice's status, paid included.
https://api.wajub.com/invoices/{id}/stop-recurringcurl -X POST https://api.wajub.com/invoices/inv_LRQqYvlhrgUOE225KMKU/stop-recurring \
-H "Authorization: sk.xxxxxxxxxxxxxxxx…"The call takes no body. The invoice comes back with is_recurring: false and next_invoice_date: null, nothing else about it changes, and invoice.updated is sent. No copy is generated after
this, and the copies already generated stay as they are: each one is an invoice of its own, to send,
cancel or delete like any other. Stopping a series already stopped answers 200 and changes
nothing. In the Dashboard the same action is Stop recurring, in the invoice's actions menu.
Call it on the recurring invoice, not on a copy. A copy has no series of its own, so the call
answers 400 on it, with the template's id in recurring_parent:
Two other calls touch the series, and both are narrower. PUT /invoices/{id} with
is_recurring: false stops it too, but only while the invoice is a draft, since only a draft can
be edited. Cancelling the invoice stops generation as well, and clears
next_invoice_date, but cancelling is refused once it is paid.
What it costs in plan
Recurrence needs the Recurring billing feature, which starts at Growth.
The Dashboard refuses to save a recurring invoice without it. Without the plan, generation is
skipped and the document is left untouched, so a downgraded account resumes on its own if it
upgrades again, with the cycles that came due in the meantime. POST /invoices does not check the
plan, so creating a recurring invoice through the API succeeds on any plan and simply never
generates.