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.
  • 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 — 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 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 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_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.