Skip to content
Knowledge ERP Docs

API Reference ↗
Sales

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. "Today" here, and in the dates below, is today on your account's calendar, in the timezone set in Account Settings.
  • 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 as today + days_until_due at 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 (printed on each invoice) — carried verbatim onto every generated invoice's notes, so it appears on each invoice's PDF and on the copy emailed to the customer.

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 25000 for $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:

  1. It sums quantity × unit_price across all line items to compute the subtotal.
  2. If a tax rate is attached, it calculates tax amount using that rate's formula.
  3. A CustomerInvoice is created in draft status with invoice_date = today, due_date = today + days_until_due, and amount_due = subtotal + tax_amount.
  4. Each line item is cloned onto the invoice.
  5. last_generated_at is updated and next_invoice_date is advanced by one period.

The daily job generates a template when it is active, its next_invoice_date is today on your account's calendar or up to two days behind it, and that date is not after its end_date. Two days covers a day your account's clock skipped when the clocks changed and a short outage. A template that is behind by up to two days is generated once, dated today, and moved to its next period. A template more than two days behind (for example one paused for weeks and switched back on, or created with a date in the past) does not bill the periods it missed: it is moved to its first date within the last two days or later, and is billed only if that date is within the last two days or today. This is noted in our logs, and old dates never turn into a batch of invoices. A date typed in far in the past (a weekly template dated before about the year 110, say) is too far back to move: it is left as it is, not billed, and noted in our logs each day until its date is corrected. Running the job twice in a day generates nothing the second time.

Generate Invoice Now, on a template's page, creates the invoice immediately, dated today, and the confirmation says what will happen to that template's next date. A template whose next date was today or ahead advances by one period as usual. A template that was behind moves to its first date after today: the invoice stands for the periods it missed, so they are not billed, and the daily job does not bill the same period again. The button is not shown once a template has run out (its next date is after its end date). If a template's date is too far in the past to move, the invoice is still created and a notice asks you to correct the date. Undo, on the entry in the new invoice's change log, removes the invoice and puts the template's date back.

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. If its next_invoice_date is then no more than two days behind, it generates once; if it is further behind, the periods it missed are skipped without invoices, so set the next date yourself if you want the next invoice on a particular day.

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_id and active (boolean) query filters and is paginated at 50 per page. Line items accept a recurring_invoice_id filter to scope results to a single template. DELETE on either endpoint soft-deletes — previously generated invoices are not affected.