Skip to content

Bills and vendors

Explore here

Bills and vendors

The other side of the ledger: vendors, the bills they send, and what has been paid against them.

recurring bills

List

GET/v1/recurring-bills

List recurring-bill schedules.

Scope
bills:read
Effect
Read only
MCP tool
list_recurring_bills
Retries
Safe to repeat

Parameters

List parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
vendorIdoptionalqueryid—
activeoptionalqueryboolean—

Returns

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
FieldTypeNotes
vendorIdrequiredid—
titleoptionalstringup to 200 chars
frequencyrequiredenumOne of weekly, biweekly, monthly, quarterly, semiannually, annually
startDaterequiredstringmatches ^\d{4}-\d{2}-\d{2}$
endDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
occurrenceLimitoptionalintegermin 1 · max 600
netDaysoptionalintegermin 0 · max 365
categoryoptionalstringup to 80 chars
notesoptionalstringup to 4000 chars
currencyoptionalCurrency—
lineItems[]requiredobject[]up to 200 items · at least 1
lineItems[].idoptionalid—
lineItems[].descriptionoptionalstringWhat the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptionalintegerQuantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptionalenumHow 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[].unitPriceoptionalobjectPrice per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequiredinteger—
lineItems[].unitPrice.currencyrequiredCurrency—
lineItems[].rateBasisPointsoptionalinteger—
lineItems[].taxTreatmentoptionalstring—
lineItems[].taxRateBasisPointsoptionalinteger—
lineItems[].discountBasisPointsoptionalinteger—
lineItems[].presetKeyoptionalstringThe 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
missedoptionalenumOne of skip, issue
businessIdoptionalid—

Returns

data: object

Errors this route can answer besides the shared ones: NOT_FOUND, VALIDATION_FAILED.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/recurring-bills" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"vendorId":"<vendorId>","frequency":"weekly","startDate":"<startDate>"}'

recurring bills

Get

GET/v1/recurring-bills/{recurringBillId}

One recurring-bill schedule.

Scope
bills:read
Effect
Read only
MCP tool
get_recurring_bill
Retries
Safe to repeat

Parameters

Get parameters
NameInTypeNotes
recurringBillIdrequiredpathid—

Returns

data: RecurringBill

Example requestSample
curl -X GET "https://api.billingmart.com/v1/recurring-bills/{recurringBillId}" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

recurring bills

Pause

POST/v1/recurring-bills/{recurringBillId}/pause

Pause a recurring-bill schedule: no further bill is drafted until a person resumes it in the console.

Scope
bills:write
Effect
Writes a draft or record
MCP tool
pause_recurring_bill
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours

Parameters

Pause parameters
NameInTypeNotes
recurringBillIdrequiredpathid—

Returns

data: object

Errors this route can answer besides the shared ones: NOT_FOUND.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/recurring-bills/{recurringBillId}/pause" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

bills

List

GET/v1/bills

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
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
statusoptionalqueryenumOne of draft, open, partiallyPaid, paid, overdue, void
vendorIdoptionalqueryid—
jobIdoptionalqueryid—
discardedoptionalqueryboolean—

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
FieldTypeNotes
vendorNamerequiredstringup to 200 chars
currencyrequiredCurrency—
vendorIdoptionalid—
vendorEmailoptionalstringup to 320 chars
referenceoptionalstringup to 64 chars
issueDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
dueDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
categoryoptionalstringup to 80 chars
notesoptionalstringup to 4000 chars
lineItems[]optionalobject[]up to 200 items
lineItems[].idoptionalid—
lineItems[].descriptionoptionalstringWhat the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptionalintegerQuantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptionalenumHow 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[].unitPriceoptionalobjectPrice per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequiredinteger—
lineItems[].unitPrice.currencyrequiredCurrency—
lineItems[].rateBasisPointsoptionalinteger—
lineItems[].taxTreatmentoptionalstring—
lineItems[].taxRateBasisPointsoptionalinteger—
lineItems[].discountBasisPointsoptionalinteger—
lineItems[].presetKeyoptionalstringThe 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
businessIdoptionalid—
jobAllocations[]optionalobject[]up to 10 items
jobAllocations[].jobIdrequiredid—
jobAllocations[].amountrequiredobject—
jobAllocations[].amount.minorUnitsrequiredinteger—
jobAllocations[].amount.currencyrequiredCurrency—

Returns

data: object

Example requestSample
curl -X POST "https://api.billingmart.com/v1/bills" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"vendorName":"<vendorName>","currency":"USD"}'

bills

Get

GET/v1/bills/{billId}

One bill with its lines and what is still due.

Scope
bills:read
Effect
Read only
MCP tool
get_bill
Retries
Safe to repeat

Parameters

Get parameters
NameInTypeNotes
billIdrequiredpathid—

Returns

data: Bill

Example requestSample
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
NameInTypeNotes
billIdrequiredpathid—

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Update request body
FieldTypeNotes
expectedUpdatedAtoptionalstringup to 40 chars
vendorIdoptionalid—
vendorNameoptionalstringup to 200 chars
vendorEmailoptionalstringup to 320 chars
referenceoptionalstringup to 64 chars
issueDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
dueDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
categoryoptionalstringup to 80 chars
notesoptionalstringup to 4000 chars
lineItems[]optionalobject[]up to 200 items
lineItems[].idoptionalid—
lineItems[].descriptionoptionalstringWhat the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptionalintegerQuantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptionalenumHow 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[].unitPriceoptionalobjectPrice per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequiredinteger—
lineItems[].unitPrice.currencyrequiredCurrency—
lineItems[].rateBasisPointsoptionalinteger—
lineItems[].taxTreatmentoptionalstring—
lineItems[].taxRateBasisPointsoptionalinteger—
lineItems[].discountBasisPointsoptionalinteger—
lineItems[].presetKeyoptionalstringThe 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

Returns

data: Bill

Errors this route can answer besides the shared ones: INVALID_TRANSITION, ACTION_PENDING_ON_TARGET.

Example requestSample
curl -X PATCH "https://api.billingmart.com/v1/bills/{billId}" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

bills

Payments

GET/v1/bills/{billId}/payments

The payments recorded against one bill, as ledger entries (entryId is what void_bill_payment takes), oldest first.

Scope
bills:read
Effect
Read only
MCP tool
list_bill_payments
Retries
Safe to repeat

Parameters

Payments parameters
NameInTypeNotes
billIdrequiredpathid—

Returns

data: LedgerEntry[]. Pass meta.cursor back as cursor for the next page.

Example requestSample
curl -X GET "https://api.billingmart.com/v1/bills/{billId}/payments" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

vendors

List

GET/v1/vendors

List vendors, newest first (contact details masked unless contacts:read).

Scope
bills:read
Effect
Read only
MCP tool
list_vendors
Retries
Safe to repeat

Parameters

List parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
archivedoptionalqueryboolean—

Returns

data: Vendor[]. Pass meta.cursor back as cursor for the next page.

Example requestSample
curl -X GET "https://api.billingmart.com/v1/vendors" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

vendors

Create

POST/v1/vendors

Create a vendor. Contact details are stored as given; nothing is verified or contacted.

Scope
bills:write
Effect
Writes a draft or record
MCP tool
create_vendor
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
FieldTypeNotes
namerequiredstringup to 200 chars
contactNameoptionalstringup to 200 chars
emailoptionalstringup to 320 chars
phoneoptionalstringup to 32 chars
taxIdoptionalstringup to 64 chars
defaultCategoryoptionalstringup to 80 chars
defaultCurrencyoptionalCurrency—
paymentTermsDaysoptionalintegermin 0 · max 365
notesoptionalstringup to 4000 chars
businessIdoptionalid—

Returns

data: object

Example requestSample
curl -X POST "https://api.billingmart.com/v1/vendors" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"<name>"}'

vendors

Get

GET/v1/vendors/{vendorId}

One vendor.

Scope
bills:read
Effect
Read only
MCP tool
get_vendor
Retries
Safe to repeat

Parameters

Get parameters
NameInTypeNotes
vendorIdrequiredpathid—

Returns

data: Vendor

Example requestSample
curl -X GET "https://api.billingmart.com/v1/vendors/{vendorId}" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

vendors

Update

PATCH/v1/vendors/{vendorId}

Update a vendor’s editable fields.

Scope
bills:write
Effect
Writes a draft or record
MCP tool
update_vendor
Retries
No Idempotency-Key on this route

Parameters

Update parameters
NameInTypeNotes
vendorIdrequiredpathid—

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Update request body
FieldTypeNotes
nameoptionalstringup to 200 chars
contactNameoptionalstringup to 200 chars
emailoptionalstringup to 320 chars
phoneoptionalstringup to 32 chars
taxIdoptionalstringup to 64 chars
defaultCategoryoptionalstringup to 80 chars
defaultCurrencyoptionalCurrency—
paymentTermsDaysoptionalintegermin 0 · max 365
notesoptionalstringup to 4000 chars

Returns

data: Vendor

Example requestSample
curl -X PATCH "https://api.billingmart.com/v1/vendors/{vendorId}" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

vendors

Archive

POST/v1/vendors/{vendorId}/archive

Archive or restore a vendor. Never deleted: bills point at it.

Scope
bills:write
Effect
Writes a draft or record
MCP tool
archive_vendor
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours

Parameters

Archive parameters
NameInTypeNotes
vendorIdrequiredpathid—

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Archive request body
FieldTypeNotes
archivedoptionalboolean—

Returns

data: object

Example requestSample
curl -X POST "https://api.billingmart.com/v1/vendors/{vendorId}/archive" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

bills

Set allocations

POST/v1/bills/{billId}/allocations

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
NameInTypeNotes
billIdrequiredpathid—

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Set allocations request body
FieldTypeNotes
expectedUpdatedAtrequiredstringup to 40 chars
allocations[]requiredobject[]up to 10 items
allocations[].jobIdrequiredid—
allocations[].amountrequiredobject—
allocations[].amount.minorUnitsrequiredinteger—
allocations[].amount.currencyrequiredCurrency—

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.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/bills/{billId}/allocations" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"expectedUpdatedAt":"<expectedUpdatedAt>"}'

bills

Discard

POST/v1/bills/{billId}/discard

Discard a DRAFT bill. Refused once opened, or while an action on it is pending.

Scope
bills:write
Effect
Writes a draft or record
MCP tool
discard_draft_bill
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours

Parameters

Discard parameters
NameInTypeNotes
billIdrequiredpathid—

Returns

data: object

Errors this route can answer besides the shared ones: INVALID_TRANSITION, ACTION_PENDING_ON_TARGET.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/bills/{billId}/discard" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

bills

Submit approval

POST/v1/bills/{billId}/submit-approval

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
NameInTypeNotes
billIdrequiredpathid—

Returns

data: object

Errors this route can answer besides the shared ones: NOT_FOUND, INVALID_TRANSITION.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/bills/{billId}/submit-approval" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

bills

Approve

POST/v1/bills/{billId}/approve

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
NameInTypeNotes
billIdrequiredpathid—

Returns

data: object

Errors this route can answer besides the shared ones: NOT_FOUND, INVALID_TRANSITION, PERMISSION_DENIED.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/bills/{billId}/approve" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

bills

Reject

POST/v1/bills/{billId}/reject

Reject a bill that is waiting for approval, with a reason. It goes back to a draft the submitter can edit and submit again.

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

Reject parameters
NameInTypeNotes
billIdrequiredpathid—

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Reject request body
FieldTypeNotes
reasonrequiredstringup to 500 chars

Returns

data: object

Errors this route can answer besides the shared ones: NOT_FOUND, INVALID_TRANSITION, PERMISSION_DENIED.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/bills/{billId}/reject" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"reason":"<reason>"}'

Object

RecurringBill

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
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
vendorIdrequiredIdThe 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.
titleoptionalstringUntrusted text—
frequencyrequiredRecurringFrequency—
anchorDayoptionalintegerDay 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.
startDaterequiredDateOnly—
endDateoptionalDateOnly—
occurrenceLimitoptionalintegerCounts DRAFTED occurrences; skipped ones do not use it up.
skippedOccurrencesoptionalintegerSERVER-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.
occurrencesIssuedoptionalintegerSERVER-WRITTEN. How many bills this schedule has drafted.
nextRunAtoptionalIsoTimestampSERVER-WRITTEN. Resolved from anchorDay in the tenant's timezone.
lastRunAtoptionalIsoTimestamp—
blockedAtoptionalIsoTimestampSERVER-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.
blockedCodeoptionalstringSERVER-WRITTEN. The error code the runner stopped on. A code, never tenant text.
currencyrequiredCurrency—
lineItemsrequiredLineItem[]—
categoryoptionalstringUntrusted textCarried onto each bill.
notesoptionalstringUntrusted textCarried onto each bill.
netDaysoptionalintegerDue date = the bill date + netDays. Absent: the bill is drafted with no due date, and a person sets one before opening it.
openAutomaticallyoptionalbooleanOff 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.
activerequiredboolean—
createdAtrequiredIsoTimestamp—
updatedAtoptionalIsoTimestamp—
createdByoptionalId—
lastWriteActoroptionalWriteActorWho 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
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
vendorIdoptionalIdThe vendor record the snapshot below was copied from. Optional: a one-off bill may name a vendor with no record.
vendorNamerequiredstringUntrusted text—
vendorEmailoptionalEmail—
referenceoptionalstringUntrusted textThe vendor's own invoice number.
statusrequiredBillStatus—
currencyrequiredCurrency—
issueDateoptionalDateOnly—
dueDateoptionalDateOnly—
lineItemsoptionalLineItem[]—
totalrequiredMoney—
amountPaidoptionalMoneySERVER-WRITTEN.
amountDueoptionalMoneySERVER-DERIVED.
categoryoptionalstringUntrusted text—
taxCategoryoptionalTaxCategoryCodeThe tax category a person confirmed (a code of the taxonomy). Never set by a suggestion alone.
taxCategoryVersionoptionalstringThe taxonomy edition taxCategory is a code of, e.g. us-sch-c-2026.
taxCategorySourceoptionalTaxCategorySource—
taxScheduleCodeoptionalTaxCategoryCodeThe 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.
taxScheduleLineoptionalstringThe form line of taxScheduleCode at confirmation, e.g. Line 8; absent where the category is not a line of the form.
attachmentStoragePathoptionalstring—
notesoptionalstringUntrusted text—
paidAtoptionalIsoTimestamp—
createdAtrequiredIsoTimestamp—
updatedAtoptionalIsoTimestamp—
discardedAtoptionalIsoTimestamp. 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).
discardedByoptionalId. The uid or credential that discarded it.
createdByoptionalId—
approvaloptionalBillApprovalThe 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.
lastWriteActoroptionalWriteActorWho 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.
jobAllocationsoptionalJobAllocation[]The work records this bill is charged to.
jobIdsoptionalId[]FUNCTION-WRITTEN: the record ids named in jobAllocations, so a record can find its bills with one equality query. At most 50 ids.
meteredAtoptionalIsoTimestampWhen this bill was counted as a send because it is allocated to a work record. Counted once, never refused. FUNCTION-WRITTEN.
meteredPeriodoptionalstringThe 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
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
namerequiredstringUntrusted textThe vendor's trading name; every API and MCP response wraps it in the data envelope.
contactNameoptionalstringUntrusted text—
emailoptionalEmail—
phoneoptionalPhoneE164—
addressoptionalAddress—
taxIdoptionalstringThe vendor's tax registration id. Sensitive business data: never logged, and an audit event records only that it changed.
defaultCategoryoptionalstringUntrusted textPre-fills a bill's category.
defaultTaxCategoryoptionalTaxCategoryCodeThe tax category a new record of this payee starts from: it is suggested first, free of AI credits, and a person still confirms.
defaultCurrencyoptionalCurrency—
paymentTermsDaysoptionalintegerNet days. The console pre-fills a bill's due date as issue date + terms; the server never infers a due date from it.
notesoptionalstringUntrusted text—
archivedoptionalbooleanAbsent on a fresh record: active is archived !== true.
createdAtrequiredIsoTimestamp—
updatedAtoptionalIsoTimestamp—
createdByoptionalIdThe creating user's uid. The rules refuse any other value on create and any change after.
updatedByoptionalIdWho 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.
updatedViaoptionalenumWhich 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.

Continue to Reports and exports →

Try it against your sandbox

Create a bmk_test_ key in the console. It can only reach your sandbox workspace.

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