data: RecurringBill[]. Pass meta.cursor back as cursor for the next page.
Example requestSample
curl -X GET "https://api.billingmart.com/v1/recurring-bills" \
-H "Authorization: Bearer $BILLINGMART_API_KEY"
recurring bills
Create
POST/v1/recurring-bills
Create a schedule that drafts a bill for a vendor on a frequency. Each occurrence is a DRAFT bill that a person opens; nothing is paid or approved. Totals are derived from the lines. A start date in the past answers 409 MISSED_OCCURRENCES with the count until missed is skip or issue.
Scope
bills:write
Effect
Writes a draft or record
MCP tool
create_recurring_bill
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours
Request body
JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.
Create request body
Field
Type
Notes
vendorIdrequired
id
—
titleoptional
string
up to 200 chars
frequencyrequired
enum
One of weekly, biweekly, monthly, quarterly, semiannually, annually
startDaterequired
string
matches ^\d{4}-\d{2}-\d{2}$
endDateoptional
string
matches ^\d{4}-\d{2}-\d{2}$
occurrenceLimitoptional
integer
min 1 · max 600
netDaysoptional
integer
min 0 · max 365
categoryoptional
string
up to 80 chars
notesoptional
string
up to 4000 chars
currencyoptional
Currency
—
lineItems[]required
object[]
up to 200 items · at least 1
lineItems[].idoptional
id
—
lineItems[].descriptionoptional
string
What the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptional
integer
Quantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptional
enum
How the price applies: fixed for one flat charge, hourly, daily, perUnit, percentage… Optional with a presetKey. — One of fixed, hourly, daily, weekly, monthly, perUnit, perMile, perKilometre, percentage
lineItems[].unitPriceoptional
object
Price per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequired
integer
—
lineItems[].unitPrice.currencyrequired
Currency
—
lineItems[].rateBasisPointsoptional
integer
—
lineItems[].taxTreatmentoptional
string
—
lineItems[].taxRateBasisPointsoptional
integer
—
lineItems[].discountBasisPointsoptional
integer
—
lineItems[].presetKeyoptional
string
The key of one of the business’s products and services (get_business_context lists them); the server fills what the line leaves out. — up to 64 chars
missedoptional
enum
One of skip, issue
businessIdoptional
id
—
Returns
data: object
Errors this route can answer besides the shared ones: NOT_FOUND, VALIDATION_FAILED.
List bills, newest first. A discarded draft is left out unless discarded=true.
Scope
bills:read
Effect
Read only
MCP tool
list_bills
Retries
Safe to repeat
Parameters
List parameters
Name
In
Type
Notes
limitoptional
query
integer
min 1 · max 50
cursoroptional
query
string
up to 256 chars
statusoptional
query
enum
One of draft, open, partiallyPaid, paid, overdue, void
vendorIdoptional
query
id
—
jobIdoptional
query
id
—
discardedoptional
query
boolean
—
Returns
data: Bill[]. Pass meta.cursor back as cursor for the next page.
Example requestSample
curl -X GET "https://api.billingmart.com/v1/bills" \
-H "Authorization: Bearer $BILLINGMART_API_KEY"
bills
Create
POST/v1/bills
Create a bill as a DRAFT. Totals are derived server-side from the lines, never taken from input.
Scope
bills:write
Effect
Writes a draft or record
MCP tool
create_bill
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours
Request body
JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.
Create request body
Field
Type
Notes
vendorNamerequired
string
up to 200 chars
currencyrequired
Currency
—
vendorIdoptional
id
—
vendorEmailoptional
string
up to 320 chars
referenceoptional
string
up to 64 chars
issueDateoptional
string
matches ^\d{4}-\d{2}-\d{2}$
dueDateoptional
string
matches ^\d{4}-\d{2}-\d{2}$
categoryoptional
string
up to 80 chars
notesoptional
string
up to 4000 chars
lineItems[]optional
object[]
up to 200 items
lineItems[].idoptional
id
—
lineItems[].descriptionoptional
string
What the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptional
integer
Quantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptional
enum
How the price applies: fixed for one flat charge, hourly, daily, perUnit, percentage… Optional with a presetKey. — One of fixed, hourly, daily, weekly, monthly, perUnit, perMile, perKilometre, percentage
lineItems[].unitPriceoptional
object
Price per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequired
integer
—
lineItems[].unitPrice.currencyrequired
Currency
—
lineItems[].rateBasisPointsoptional
integer
—
lineItems[].taxTreatmentoptional
string
—
lineItems[].taxRateBasisPointsoptional
integer
—
lineItems[].discountBasisPointsoptional
integer
—
lineItems[].presetKeyoptional
string
The key of one of the business’s products and services (get_business_context lists them); the server fills what the line leaves out. — up to 64 chars
curl -X GET "https://api.billingmart.com/v1/bills/{billId}" \
-H "Authorization: Bearer $BILLINGMART_API_KEY"
bills
Update
PATCH/v1/bills/{billId}
Update a bill. A DRAFT takes vendor, dates, reference, category, notes and lines (totals re-derived); an opened bill takes notes and category only; a void bill nothing.
Scope
bills:write
Effect
Writes a draft or record
MCP tool
update_bill
Retries
No Idempotency-Key on this route
Parameters
Update parameters
Name
In
Type
Notes
billIdrequired
path
id
—
Request body
JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.
Update request body
Field
Type
Notes
expectedUpdatedAtoptional
string
up to 40 chars
vendorIdoptional
id
—
vendorNameoptional
string
up to 200 chars
vendorEmailoptional
string
up to 320 chars
referenceoptional
string
up to 64 chars
issueDateoptional
string
matches ^\d{4}-\d{2}-\d{2}$
dueDateoptional
string
matches ^\d{4}-\d{2}-\d{2}$
categoryoptional
string
up to 80 chars
notesoptional
string
up to 4000 chars
lineItems[]optional
object[]
up to 200 items
lineItems[].idoptional
id
—
lineItems[].descriptionoptional
string
What the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptional
integer
Quantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptional
enum
How the price applies: fixed for one flat charge, hourly, daily, perUnit, percentage… Optional with a presetKey. — One of fixed, hourly, daily, weekly, monthly, perUnit, perMile, perKilometre, percentage
lineItems[].unitPriceoptional
object
Price per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequired
integer
—
lineItems[].unitPrice.currencyrequired
Currency
—
lineItems[].rateBasisPointsoptional
integer
—
lineItems[].taxTreatmentoptional
string
—
lineItems[].taxRateBasisPointsoptional
integer
—
lineItems[].discountBasisPointsoptional
integer
—
lineItems[].presetKeyoptional
string
The key of one of the business’s products and services (get_business_context lists them); the server fills what the line leaves out. — up to 64 chars
Charge a DRAFT bill to work records: the list replaces the one stored, and expectedUpdatedAt (the bill updatedAt you read) is required. Each amount is in the bill currency; together they never exceed the bill total, and what is left stays unallocated.
Scope
bills:write
Effect
Writes a draft or record
MCP tool
allocate_bill_to_jobs
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours
Parameters
Set allocations parameters
Name
In
Type
Notes
billIdrequired
path
id
—
Request body
JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.
Set allocations request body
Field
Type
Notes
expectedUpdatedAtrequired
string
up to 40 chars
allocations[]required
object[]
up to 10 items
allocations[].jobIdrequired
id
—
allocations[].amountrequired
object
—
allocations[].amount.minorUnitsrequired
integer
—
allocations[].amount.currencyrequired
Currency
—
Returns
data: object
Errors this route can answer besides the shared ones: INVALID_TRANSITION, ALLOCATION_EXCEEDS_TOTAL, CURRENCY_MISMATCH, JOB_CLOSED, NOT_FOUND, EDIT_CONFLICT.
Submit a DRAFT bill for approval. If the workspace policy covers its total, an approver must approve it before it can be opened; otherwise it answers that none is needed.
Scope
bills:write
Effect
Writes a draft or record
MCP tool
submit_bill_for_approval
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours
Parameters
Submit approval parameters
Name
In
Type
Notes
billIdrequired
path
id
—
Returns
data: object
Errors this route can answer besides the shared ones: NOT_FOUND, INVALID_TRANSITION.
Approve a bill that is waiting for approval, as the person whose API key this is. The person who entered the bill cannot (unless nobody else could); the last required approval opens the bill.
Scope
bills:approve
Effect
Writes a draft or record
MCP tool
None — REST and API keys only
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours
Parameters
Approve parameters
Name
In
Type
Notes
billIdrequired
path
id
—
Returns
data: object
Errors this route can answer besides the shared ones: NOT_FOUND, INVALID_TRANSITION, PERMISSION_DENIED.
A schedule that drafts bills: rent, software, insurance. Each occurrence is a DRAFT bill the hourly runner makes under a deterministic id; nothing is paid and nothing is approved by the schedule. With `openAutomatically` the runner also opens the draft through the bill-opening rules.
RecurringBill fields
Field
Type
Notes
idrequired
Id
—
tenantrequired
TenantRef
—
vendorIdrequired
Id
The vendor each bill is made for. The vendor's name and email are read from the vendor record when the bill is drafted, never copied here, so renaming a vendor renames the next bill.
titleoptional
string
Untrusted text—
frequencyrequired
RecurringFrequency
—
anchorDayoptional
integer
Day of the period to draft on; a 31 in a 30-day month clamps to the last day. The same rule as a recurring invoice, by the same shared code.
startDaterequired
DateOnly
—
endDateoptional
DateOnly
—
occurrenceLimitoptional
integer
Counts DRAFTED occurrences; skipped ones do not use it up.
skippedOccurrencesoptional
integer
SERVER-WRITTEN. Occurrences passed over on purpose when a resume or a timing edit would have drafted bills for dates before today and the caller chose missed: skip.
occurrencesIssuedoptional
integer
SERVER-WRITTEN. How many bills this schedule has drafted.
nextRunAtoptional
IsoTimestamp
SERVER-WRITTEN. Resolved from anchorDay in the tenant's timezone.
lastRunAtoptional
IsoTimestamp
—
blockedAtoptional
IsoTimestamp
SERVER-WRITTEN. When the runner parked this schedule because it could not draft (the vendor is archived or gone, or the draft is not valid). Cleared when a later run succeeds or the schedule is edited.
blockedCodeoptional
string
SERVER-WRITTEN. The error code the runner stopped on. A code, never tenant text.
currencyrequired
Currency
—
lineItemsrequired
LineItem[]
—
categoryoptional
string
Untrusted textCarried onto each bill.
notesoptional
string
Untrusted textCarried onto each bill.
netDaysoptional
integer
Due date = the bill date + netDays. Absent: the bill is drafted with no due date, and a person sets one before opening it.
openAutomaticallyoptional
boolean
Off when absent. When true the runner opens each drafted bill through the same rules as opening one by hand. Set only by a signed-in owner or admin: never by an API key or an agent.
activerequired
boolean
—
createdAtrequired
IsoTimestamp
—
updatedAtoptional
IsoTimestamp
—
createdByoptional
Id
—
lastWriteActoroptional
WriteActor
Who last wrote this record, and when, stamped by the server core. An EDIT_CONFLICT names it.
Object
Bill
A payable: money the tenant owes a vendor. Deliberately NOT an invoice with the sign flipped — a bill has no public link, no metering, no gateway path, and its lines are not rebillable without an explicit expense record.
Bill fields
Field
Type
Notes
idrequired
Id
—
tenantrequired
TenantRef
—
vendorIdoptional
Id
The vendor record the snapshot below was copied from. Optional: a one-off bill may name a vendor with no record.
vendorNamerequired
string
Untrusted text—
vendorEmailoptional
Email
—
referenceoptional
string
Untrusted textThe vendor's own invoice number.
statusrequired
BillStatus
—
currencyrequired
Currency
—
issueDateoptional
DateOnly
—
dueDateoptional
DateOnly
—
lineItemsoptional
LineItem[]
—
totalrequired
Money
—
amountPaidoptional
Money
SERVER-WRITTEN.
amountDueoptional
Money
SERVER-DERIVED.
categoryoptional
string
Untrusted text—
taxCategoryoptional
TaxCategoryCode
The tax category a person confirmed (a code of the taxonomy). Never set by a suggestion alone.
taxCategoryVersionoptional
string
The taxonomy edition taxCategory is a code of, e.g. us-sch-c-2026.
taxCategorySourceoptional
TaxCategorySource
—
taxScheduleCodeoptional
TaxCategoryCode
The TOP category taxCategory resolved to when it was confirmed (itself for a top category; a sub-category's parent), so a later rename or move never rewrites a past report.
taxScheduleLineoptional
string
The form line of taxScheduleCode at confirmation, e.g. Line 8; absent where the category is not a line of the form.
attachmentStoragePathoptional
string
—
notesoptional
string
Untrusted text—
paidAtoptional
IsoTimestamp
—
createdAtrequired
IsoTimestamp
—
updatedAtoptional
IsoTimestamp
—
discardedAtoptional
IsoTimestamp
. Set by a function when a never-numbered draft is discarded: it leaves every default list and cannot be sent or opened. Soft, never a status value (a money-enum addition is a breaking change).
discardedByoptional
Id
. The uid or credential that discarded it.
createdByoptional
Id
—
approvaloptional
BillApproval
The approval record, beside the status: written only by the approval functions, absent while the workspace has no approval policy or the bill never needed one.
lastWriteActoroptional
WriteActor
Who last wrote this record, and when — stamped by the server core. An EDIT_CONFLICT names it, so the person refused knows who saved the newer version.
jobAllocationsoptional
JobAllocation[]
The work records this bill is charged to.
jobIdsoptional
Id[]
FUNCTION-WRITTEN: the record ids named in jobAllocations, so a record can find its bills with one equality query. At most 50 ids.
meteredAtoptional
IsoTimestamp
When this bill was counted as a send because it is allocated to a work record. Counted once, never refused. FUNCTION-WRITTEN.
meteredPeriodoptional
string
The tenant-local month (YYYY-MM) in which it was counted. FUNCTION-WRITTEN.
Object
Vendor
Someone the tenant pays. Staff data written through the rules, never an identity: no contact key, no identity link, no verification. A bill copies the vendor's name and email into its own snapshot, so editing a vendor never rewrites a bill. Archived, never deleted.
Vendor fields
Field
Type
Notes
idrequired
Id
—
tenantrequired
TenantRef
—
namerequired
string
Untrusted textThe vendor's trading name; every API and MCP response wraps it in the data envelope.
contactNameoptional
string
Untrusted text—
emailoptional
Email
—
phoneoptional
PhoneE164
—
addressoptional
Address
—
taxIdoptional
string
The vendor's tax registration id. Sensitive business data: never logged, and an audit event records only that it changed.
defaultCategoryoptional
string
Untrusted textPre-fills a bill's category.
defaultTaxCategoryoptional
TaxCategoryCode
The tax category a new record of this payee starts from: it is suggested first, free of AI credits, and a person still confirms.
defaultCurrencyoptional
Currency
—
paymentTermsDaysoptional
integer
Net days. The console pre-fills a bill's due date as issue date + terms; the server never infers a due date from it.
notesoptional
string
Untrusted text—
archivedoptional
boolean
Absent on a fresh record: active is archived !== true.
createdAtrequired
IsoTimestamp
—
updatedAtoptional
IsoTimestamp
—
createdByoptional
Id
The creating user's uid. The rules refuse any other value on create and any change after.
updatedByoptional
Id
Who made the last change. On a console write the rules require the signed-in uid, so the audit trigger takes the actor from a stamp the rules verified; on a REST write, the credential id.
updatedViaoptional
enum
Which door made the last change. console is audited by the vendor trigger; rest writes its own audit row; seed is the sandbox demo-data seeder, which writes as the system and is audited by neither.
Next section
Reports and exports
Ageing, income, tax, settlement and reconciliation, computed from stored amounts, plus the accounting export.
We use Google Analytics on our website by default to understand visits. Choose Decline to turn it off; you can change this at any time on the Cookies page. We never send Google your name, email or account. Cookie policy