Recurring Invoices
A billing schedule that fires real customer invoices automatically on a weekly, monthly, quarterly, or annual cadence — define the template once and let the system generate the invoices.
A recurring invoice is a billing template, not an invoice itself. It holds the
customer, a set of line items, a frequency, a start date, and an optional end
date. Each day the system checks which templates are due and calls generateInvoice()
on them — creating a real customer invoice, advancing the
next invoice date by one period, and stamping last generated. The template stays
in place and fires again when its next date arrives, indefinitely or until the end date
passes.
Recurring invoices produce draft invoices. Review and send each one from Sales → Invoices, or automate approval with the Automation Builder.
Creating a recurring invoice #
New templates are created from Sales → Recurring Invoices → New Recurring Invoice. The form has two sections: Schedule and Line Items.
Schedule fields:
- Title — an internal name for the template (e.g. Monthly Retainer — Acme Corp). Required.
- Customer — the customer who will receive each generated invoice. Required.
- Frequency — how often to bill: Weekly, Monthly, Quarterly, or Annually. A schedule dated near the end of a month stays on the end of the month: bill on 31 January and the next invoice is 28 February (29 in a leap year), then 28 March — the date is clamped to the shortest month it meets and never rolls into the following month.
- Start Date — the date the schedule begins. Required.
- Next Invoice Date — the date the next invoice will fire. Required; set it to the same value as Start Date for immediate billing, or push it forward to skip an initial period. When creating via the API the field is optional and defaults to the start date if omitted.
- End Date — optional; leave blank to run forever. When today passes the end date, the template stops firing even if it is still marked active.
- Days Until Due — how many days after the invoice date the generated invoice is due. Defaults to
30. The due date on each generated invoice is computed astoday + days_until_dueat the moment of generation. - Tax Rate — an optional tax rate applied to each generated invoice. Leave blank for tax-exempt customers.
- Active — toggle off to pause the schedule without deleting the template. An inactive template is skipped during the daily run.
- Notes — carried verbatim onto every generated invoice's notes field.
Line items #
The Line Items section is a repeater of one or more rows. Each row is the template for a line on every generated invoice:
- Description — free-text label for the line. Required.
- Quantity — numeric, minimum 1. Required.
- Unit Price — entered in dollars in the UI (e.g.
250.00). Required.
Over the API, unit_price is in cents — send
25000for $250.00.
Line items are stored in RecurringInvoiceItem records linked to the template. They are
managed directly on the recurring invoice form, or independently via the
/api/v1/recurring-invoice-items endpoints. Every time the template fires, it creates
matching line items on the new CustomerInvoice with the same description, quantity, and
unit price.
How generation works #
When generateInvoice() runs:
- It sums
quantity × unit_priceacross all line items to compute the subtotal. - If a tax rate is attached, it calculates tax amount using that rate's formula.
- A
CustomerInvoiceis created in draft status withinvoice_date = today,due_date = today + days_until_due, andamount_due = subtotal + tax_amount. - Each line item is cloned onto the invoice.
last_generated_atis updated andnext_invoice_dateis advanced by one period.
The template's own isDueToday() check gates generation: it returns true only when the
template is active, next_invoice_date is today, and today has not passed end_date.
The recurring invoices list #
The list at Sales → Recurring Invoices shows each template's title, customer, frequency, next invoice date, end date (or Ongoing if none is set), and an active indicator. Sort by any column; filter or search by customer name or title.
Pausing and ending a schedule #
To pause billing without deleting the template, toggle Active off. The template
remains intact with all its line items and history, and will resume firing as soon as
you toggle it back on — picking up from whatever next_invoice_date currently is, so
adjust that date if you want to skip the period that elapsed while paused.
To end the schedule on a specific date, set End Date. Invoices already generated are unaffected — the end date only controls when new ones stop being issued.
Relationship to customer invoices #
Each fired invoice is a standalone CustomerInvoice linked to the same customer. From
that point it behaves exactly like a manually created invoice: you can add payments,
apply credit memos, and share it through the customer portal. The recurring template does
not track which invoices it has generated beyond updating last_generated_at — to see
the history, filter the invoice list by customer. See
Customer Invoices & Payments.
Doing it from the API #
# List recurring invoices (filter to active templates for one customer)
curl "https://your-domain.com/api/v1/recurring-invoices?customer_id=<id>&active=true" \
-H "Authorization: Bearer $TOKEN"
# Create a monthly recurring invoice with one line item
curl -X POST "https://your-domain.com/api/v1/recurring-invoices" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "<customer-id>",
"title": "Monthly Retainer",
"frequency": "monthly",
"start_date": "2026-07-01",
"days_until_due": 30,
"active": true
}'
# Add a line item to the template (unit_price in cents)
curl -X POST "https://your-domain.com/api/v1/recurring-invoice-items" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"recurring_invoice_id": "<recurring-invoice-id>",
"description": "Monthly support retainer",
"quantity": 1,
"unit_price": 150000
}'
The list endpoint accepts
customer_idandactive(boolean) query filters and is paginated at 50 per page. Line items accept arecurring_invoice_idfilter to scope results to a single template.DELETEon either endpoint soft-deletes — previously generated invoices are not affected.