Skip to content

Recurring and automation

Explore here

Recurring and automation

Schedules that raise invoices on their own, the reminder cadence, and what the scheduled jobs will do next.

recurring

List

GET/v1/recurring

List recurring schedules.

Scope
recurring:read
Effect
Read only
MCP tool
list_recurring
Retries
Safe to repeat

Parameters

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

Returns

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

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

recurring

Get

GET/v1/recurring/{recurringId}

One recurring schedule.

Scope
recurring:read
Effect
Read only
MCP tool
get_recurring
Retries
Safe to repeat

Parameters

Get parameters
NameInTypeNotes
recurringIdrequiredpathid—

Returns

data: Recurring

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

recurring

Update

PATCH/v1/recurring/{recurringId}

Update a recurring schedule’s client, lines, title, terms or end, or pause or resume it. A new client removes any autopay. Autopay is NOT settable here — it needs recorded consent. A resume that would issue invoices for dates before today answers 409 MISSED_OCCURRENCES with the count, until `missed` is `skip` (they are never issued; an installment plan keeps every installment) or `issue` (they go out on the next run).

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

Parameters

Update parameters
NameInTypeNotes
recurringIdrequiredpathid—

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
clientIdoptionalid—
titleoptionalstring | null—
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
netDaysoptionalinteger | null—
endDateoptionalstring | null—
occurrenceLimitoptionalinteger | null—
activeoptionalboolean—
missedoptionalenumOne of skip, issue

Returns

data: Recurring

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

recurring

Pause

POST/v1/recurring/{recurringId}/pause

Pause a recurring schedule: no invoice is issued or charged until a person resumes it. Resuming is an action a person approves.

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

Parameters

Pause parameters
NameInTypeNotes
recurringIdrequiredpathid—

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/{recurringId}/pause" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

automation

Upcoming

GET/v1/automation/upcoming

What each scheduled job will do next for this workspace, computed from the SAME selection functions the schedulers run (never a second copy): the next tick in UTC and in the workspace’s own time, the records it would act on, and why.

Scope
business:read
Effect
Read only
MCP tool
automation_upcoming
Retries
Safe to repeat

Parameters

Upcoming parameters
NameInTypeNotes
joboptionalquerystringup to 40 chars
limitoptionalqueryintegermin 1 · max 50

Returns

data: AutomationUpcoming

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

scheduler runs

List

GET/v1/automation/runs

What the scheduled jobs actually did, newest first. A row exists only for a tick that acted on or failed for this workspace.

Scope
business:read
Effect
Read only
MCP tool
list_scheduler_runs
Retries
Safe to repeat

Parameters

List parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
joboptionalquerystringup to 40 chars

Returns

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

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

dunning

Get

GET/v1/dunning/cadence

Each business’s reminder cadence — the day offsets relative to the due date and when chasing stops — and whether it is the business’s own or the platform default.

Scope
business:read
Effect
Read only
MCP tool
get_dunning_cadence
Retries
Safe to repeat

Parameters

Get parameters
NameInTypeNotes
businessIdoptionalqueryid—

Returns

data: DunningCadenceView

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

Object

Recurring

A schedule that issues invoices. Each issue is a real send: it mints a number and meters against the tenant's plan in the tenant's own timezone. Autopay charges the vaulted method server-side; the amount is computed at charge, never carried on the schedule.

Recurring fields
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
merchantAccountIdoptionalIdThe merchant account the invoices of this schedule are routed through. Absent means the business default, then the workspace default account.
clientIdrequiredId—
titleoptionalstringUntrusted text—
frequencyrequiredRecurringFrequency—
anchorDayoptionalintegerDay of the period to issue on. A 31 in a 30-day month clamps to the last day; that rule lives and is stated here so two implementations cannot disagree.
startDateoptionalDateOnly—
endDateoptionalDateOnly—
occurrenceLimitoptionalinteger600, what the server and REST accept. Counts ISSUED occurrences: skipped ones (below) do not use it up.
skippedOccurrencesoptionalintegerSERVER-WRITTEN. Occurrences passed over on purpose: when a resume, a past start date or a timing edit would have issued invoices for dates before today, the caller chose missed: skip.
occurrencesIssuedoptionalintegerSERVER-WRITTEN.
nextRunAtoptionalIsoTimestampSERVER-WRITTEN. Resolved from anchorDay in the tenant's timezone.
lastRunAtoptionalIsoTimestamp—
capRefusedoptionalobjectSERVER-WRITTEN. The send cap refused this schedule's occurrence occurrence at at, in the usage month period, on plan plan.
blockedAtoptionalIsoTimestampSERVER-WRITTEN, like nextRunAt. When the runner parked this schedule because it could not issue (a required invoice detail is missing). Absent on a schedule that is not parked.
blockedCodeoptionalstringSERVER-WRITTEN. The error code the runner stopped on. A code, never tenant text.
blockedDraftUpdatedAtoptionalIsoTimestampSERVER-WRITTEN. The updatedAt of the draft invoice the blocked run left behind, so a retry can tell whether it was changed since.
blockedScheduleUpdatedAtoptionalIsoTimestampSERVER-WRITTEN. The schedule's own updatedAt when it was parked: an edit after this moment means the block may be resolved and the runner tries again.
currencyrequiredCurrency—
languagerequiredLanguage—
feeOverrideoptionalInvoiceFeeOverrideCopied onto every invoice this schedule issues. Absent means the workspace default.
lineItemsrequiredLineItem[]—
customFieldsoptionalobjectUntrusted textkey, copied by the runner onto every invoice the schedule issues. A required field with no value here is why a schedule cannot issue.
installmentTotaloptionalMoneyAn installment plan: the whole amount split over occurrenceLimit occurrences by the money module's exact split — the last installment absorbs the remainder. Absent on an ordinary schedule. Additive.
netDaysoptionalinteger—
autopayoptionalAutopayConfig—
activerequiredboolean—
createdAtrequiredIsoTimestamp—
updatedAtoptionalIsoTimestamp—
createdByoptionalId—
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.

Object

AutomationUpcoming

AutomationUpcoming is computed by the server for this request, not a stored document, so no contract describes it. Its fields are the TypeScript type of the same name that the handler returns.

Object

SchedulerRun

What one scheduled job did for ONE tenant on one tick.

SchedulerRun fields
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
jobrequiredenumWhich scheduled function. The same names automation_upcoming answers with, so what-will-run and what-ran line up.
startedAtrequiredIsoTimestampThe tick's instant, and the second half of the document id.
finishedAtrequiredIsoTimestamp—
actedrequiredintegerHow many records the job acted on for this tenant.
failedrequiredintegerHow many it tried and could not. A row exists whenever this or acted is above zero.
recordIdsoptionalId[]The ids acted on, capped at 50 by the writer. truncated says when there were more.
truncatedoptionalbooleanTrue when the job acted on more records than recordIds carries.
errorCodesoptionalstring[]Catalogue codes for what failed, de-duplicated and capped at 20 by the writer. Never a provider body and never tenant text: a code only, so reading the log can never be a way to read a customer's data.
noteoptionalstringA short, SERVER-WRITTEN fact the counts cannot carry — skipped: no gateway credentials, purged. Never tenant- or agent-supplied text.
createdAtrequiredIsoTimestamp—
updatedAtoptionalIsoTimestamp—

Object

DunningCadenceView

DunningCadenceView is computed by the server for this request, not a stored document, so no contract describes it. Its fields are the TypeScript type of the same name that the handler returns.

Next section

Time, expenses, mileage and documents

Work logged during the month, billed onto an invoice exactly once, and paper read from a photo or PDF into a draft a person files. A CSV of clients, items or open invoices can be dry-run here; a person runs the import in the console.

Continue to Time, expenses, mileage and documents →

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