Skip to main content

Bill Runs

A bill run turns rated transactions into invoices. Billerang exposes a single universal API for creating and running bill runs — there is no distinction between "cycle" and "ad-hoc" bill runs in the public contract.

The universal model

The universal bill run carries its own scope and aggregation rules. There is no inheritance from a billing cycle by default — when you attach a cycle, its fields become defaults for the BR, not constraints.

POST /api/v1/billingRuns (sync) and POST /api/v1/billingRuns/async (async + jobRunId).

Run types are auto-derived

ConditionrunType
billingCycleCode is setCYCLE
billingCycleCode is nullEXCEPTIONAL

You do not pick the run type — it follows from the scope you provide.

Scope sources

A bill run picks RatedTransactions through the intersection of four optional sources:

SourceEffect
billingCycleCodeBill all BAs assigned to the cycle. Inherits the BC's invoiceTypeEl, splitPerPaymentMethod, aggregation defaults, and validation script.
billingAccountCodes[]Explicit BA list. Combinable with the cycle (intersection).
filters (generic-API map)JPA-path filters on RatedTransaction. Operator prefixes supported: inList, fromRange, toRange, like, ne, gt, lt.
applicationEl (run gate, not a BA filter)Jakarta EL evaluated at job execution time. When false → the entire BR is skipped by the job.

To filter BAs or charges, use filters — not applicationEl.

Date semantics

The bill run consumes RatedTransactions that already exist. Charge-level nextChargeDate / nextInvoiceDate (on ChargeInstance) drive WO → RT generation by the rating engine — they are not bill-run inputs.

DateRole
invoiceDateDate stamped on invoices the run produces.
lastTransactionDateRT cutoff. Only RTs with usageDate < lastTransactionDate enter the run.
startDate / endDate (advanced)Filter billingAccount.nextInvoiceDate ∈ [startDate, endDate].

Process modes

processType controls the engine behaviour — how far the engine advances the BR's status.

UI labelBackend valueResult
Automated, ready for validationAUTOMATICStops at DRAFT_INVOICES; operator validates.
Manual progressMANUALStays at NEW; operator advances each step.
Automated validationFULL_AUTOMATICRuns end-to-end including validation, reaches VALIDATED.

runOptions.autoValidate is a separate HTTP-level flag for sync POSTs: block the response until VALIDATED. Only valid with processType=FULL_AUTOMATIC (other combos return 400).

Minimal example — bill one BA right now

TOKEN=$(./get-token.sh)
curl -X POST "https://api.billerang.com/api/v1/billingRuns" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"billingAccountCodes": ["BA_001"],
"invoiceDate": "2026-05-13T00:00:00Z",
"lastTransactionDate": "2026-05-13T23:59:59Z",
"processType": "FULL_AUTOMATIC",
"runOptions": { "autoValidate": true }
}'

Returns the full BR with status: "VALIDATED".

Cycle-based example — monthly run for all B2C accounts

curl -X POST "https://api.billerang.com/api/v1/billingRuns" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"code": "BR_MONTHLY_B2C_2026_05",
"description": "Monthly B2C billing",
"billingCycleCode": "Monthly_B2C",
"invoiceDate": "2026-05-01T00:00:00Z",
"lastTransactionDate": "2026-04-30T23:59:59Z",
"processType": "AUTOMATIC"
}'

code is the idempotency key — submitting the same code twice returns 409.

Filtered example — only USAGE charges for B2M customers

curl -X POST "https://api.billerang.com/api/v1/billingRuns" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"invoiceDate": "2026-05-13T00:00:00Z",
"lastTransactionDate": "2026-05-13T23:59:59Z",
"filters": {
"chargeInstance.chargeTemplate.chargeMainType": "USAGE",
"billingAccount.customer.customerCategory.code": "B2M"
},
"processType": "FULL_AUTOMATIC",
"runOptions": { "autoValidate": true }
}'

Full payload reference

See Aggregation Rules for the full set of aggregation knobs and Split Billing for the five native split mechanisms.

FieldTypeRequiredDefault
codestringnoauto-generated
descriptionstringno
billingCycleCodestringno
billingAccountCodesstring[]no
filtersobjectno
applicationElstringno
defaultInvoiceTypeCodestringno— (resolved per article)
invoiceDateISO-8601yes
lastTransactionDateISO-8601yes
processTypeenumnoFULL_AUTOMATIC
validationScriptCodestringno— (cycle's script)
disableAggregationbooleannoentity default
dateAggregationenumnoMONTH_OF_USAGE_DATE
discountAggregationenumnoFULL_AGGREGATION
useAccountingArticleLabelbooleannofalse (UI shows TRUE)
aggregateUnitAmountsbooleannofalse
ignoreSubscriptionsbooleannotrue
ignoreOrdersbooleannotrue (UI shows OFF)
ignoreUserAccountsbooleannotrue
ignoreServiceInstancesbooleannotrue
incrementalInvoiceLinesbooleannofalse
additionalAggregationFieldsstring[]no[]
runOptions.autoValidatebooleannofalse
runOptions.applyMinimumbooleannofalse
runOptions.applyThresholdbooleannofalse
runOptions.applyDiscountbooleannofalse
runOptions.rejectAutoActionenumnoMOVE
runOptions.suspectAutoActionenumnoMOVE
runOptions.computeDatesAtValidationbooleannofalse
runOptions.skipValidationScriptbooleannofalse

What happens after submit

The bill run progresses through a status pipeline driven by three independent jobs:

   ┌──────────────┐   ┌──────────────────┐   ┌─────────────────┐   ┌──────────────┐
│ BillingRun │──▶│ InvoiceLinesJob │──▶│ InvoicingJob │──▶│ PDF / XML │
│ created NEW │ │ _V2 │ │ _V2 / _V3 │ │ jobs │
└──────────────┘ └──────────────────┘ └─────────────────┘ └──────────────┘

For one-off API-driven runs, POST /api/v1/billingRuns fires the chain immediately. For recurring runs, configure a BillingRunJob JobInstance with a cron schedule + cycle list. See the section on scheduling below.

Recurring & one-time scheduled runs

The bill run entity itself has no schedule field. Scheduling is a first-class API: /api/v1/billingRunSchedules — see Scheduled Runs for the full reference.

In short, a schedule is a thin wrapper over a BillingRunJob JobInstance + its TimerEntity:

  • One-time (repeats: "NONE") — "schedule it before running it": fires once at a chosen date/time.
  • Recurring (repeats: "DAILY" | "WEEKLY" | "MONTHLY") — fires on a cron cadence.

The New Bill Run form's cadence selector (Run now / Run once at… / Recurring) routes the non-"now" choices to the schedule form. Manage schedules from /billRuns/schedules.

Errors

CodeCause
400 MISSING_INVOICE_DATEinvoiceDate missing.
400 INVALID_AUTO_VALIDATE_COMBOprocessType=AUTOMATIC or MANUAL with runOptions.autoValidate=true (deadlock).
400 INVALID_DATE_AGGREGATIONUnknown dateAggregation value.
400 INVALID_DISCOUNT_AGGREGATIONUnknown discountAggregation value.
400 UNKNOWN_BILLING_ACCOUNTA code in billingAccountCodes does not exist.
400 UNKNOWN_BILLING_CYCLEbillingCycleCode does not exist.
400 UNKNOWN_INVOICE_TYPEdefaultInvoiceTypeCode does not exist.
400 UNKNOWN_VALIDATION_SCRIPTvalidationScriptCode does not exist.
409Duplicate code.
422 NO_BILLABLE_TRANSACTIONSFilters + dates match no RTs/WOs.

See also