Skip to content

Messages and activity

Explore here

Messages and activity

The delivery log of every email and text, the audit trail of who did what, and your own notifications and their settings.

messages

List

GET/v1/messages

The delivery log, newest first: what went, what was blocked or failed, and why; with `direction: inbound`, the texts customers sent to the workspace number. Contact keys and last-four digits only; a stored body has any link token redacted before it leaves, and an inbound body is a customer’s words, returned as untrusted data.

Scope
messages:read
Effect
Read only
MCP tool
list_messages
Retries
Safe to repeat

Parameters

List parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
clientIdoptionalqueryid—
invoiceIdoptionalqueryid—
paymentLinkIdoptionalqueryid—
threadIdoptionalqueryid—
directionoptionalqueryenumOne of inbound, outbound
channeloptionalqueryenumOne of email, sms
kindoptionalqueryenumOne of custom, reply, invoiceSent, reminder, receipt, optOutConfirmation, statement, verificationInvite, paymentLinkSent
statusoptionalqueryenumOne of blocked, queued, sent, delivered, failed

Returns

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

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

sms

Threads

GET/v1/sms/threads

The text conversations on the workspace number, most recent first: who texted (last four digits), the last message as untrusted data, unread count, the client it is linked to, and whether the number sent STOP. Inbox by default; archived: true for the archive. A credential confined to some businesses sees only threads linked to a client of one of them.

Scope
messages:read
Effect
Read only
MCP tool
list_sms_threads
Retries
Safe to repeat

Parameters

Threads parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
archivedoptionalqueryboolean—
unreadoptionalqueryboolean—
clientIdoptionalqueryid—

Returns

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

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

sms

Threads

GET/v1/sms/threads/{threadId}

One text conversation: the last message (untrusted data), unread count, linked client, suggested clients, and opt-out state. Its messages come from GET /v1/messages?threadId=.

Scope
messages:read
Effect
Read only
MCP tool
get_sms_thread
Retries
Safe to repeat

Parameters

Threads parameters
NameInTypeNotes
threadIdrequiredpathid—

Returns

data: SmsThread

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

activity

List

GET/v1/activity

The audit log, newest first: who did what, when. Owner/admin connections only (ROLE_SCOPE_CEILING), mirroring the admin-only Firestore rule.

Scope
activity:read
Effect
Read only
MCP tool
list_activity
Retries
Safe to repeat

Parameters

List parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
actionoptionalquerystringup to 64 chars
collectionoptionalquerystringup to 64 chars
subjectIdoptionalqueryid—

Returns

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

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

activity

Export

GET/v1/activity/export

Export the whole audit log as one CSV file, newest first, on every plan (the in-app view of a free workspace is limited to the last 30 days; this is not). Owner/admin connections only. At most 50 000 rows; `truncated` says when the file stops short. Returns a link that expires in ten minutes (`url`, with `urlUnavailable: true` instead when a link could not be signed), never the file body. Each export is itself written to the audit log.

Scope
activity:read
Effect
Read only
MCP tool
export_activity
Retries
Safe to repeat

Returns

data: ActivityExport

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

sms

Get settings

GET/v1/sms/settings

Whether the workspace texts its customers, which automatic texts are on (invoice sent, reminders, receipts), whose Twilio account and sender carry them — the platform’s shared number, or the workspace’s own — and when it last received a text. Never a credential: the account SID’s last four characters at most.

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

Returns

data: SmsSettingsView

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

notifications

List

GET/v1/notifications

The in-app notifications of the person behind this credential, newest first: what happened (a payment, an approval waiting, a trial ending), whether they have read it, and the ids of what it is about. Title and body come back as untrusted data.

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

Parameters

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

Returns

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

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

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

notifications

Get prefs

GET/v1/notifications/preferences

Which notification categories (transactional, reminder, upgrade, marketing) reach the person behind this credential, and on which channels (in-app, push, email), with the defaults filled in.

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

Returns

data: NotificationPrefs

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

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

Object

SmsThread

One text conversation with one phone number on the workspace's own Twilio number. FUNCTION-WRITTEN ONLY: the inbound webhook, the send path and the thread callables. 164)>`), the key outbound messages already carry, so a thread joins both directions. Read and unread belong to the workspace, like a shared mailbox.

SmsThread fields
FieldTypeNotes
idrequiredContactKey—
tenantrequiredTenantRef—
phoneE164requiredstringPII. Staff-readable only.
phoneLast4requiredstring—
clientIdoptionalIdSet only by exactly one VERIFIED contact match or by a staff link.
jobIdoptionalIdThe work record this conversation is linked to, by a staff member's linkSmsThreadJob (the record's client must be the thread's). Inbound and outbound texts on a linked thread are filed under that record.
clientVerifiedoptionalbooleanTrue when clientId came from a verified contact.
suggestedClientIdsoptionalId[]An unverified or ambiguous match. A suggestion grants nothing.
lastMessageAtrequiredIsoTimestamp—
lastInboundAtoptionalIsoTimestamp—
lastSnippetoptionalstringUntrusted text—
lastDirectionoptionalenum—
unreadrequiredintegerInbound texts not yet read by any staff member.
hasMediaoptionalboolean—
archivedAtoptionalIsoTimestamp—
optedOutoptionalbooleanThe number sent STOP to this workspace.
createdAtoptionalIsoTimestamp—
updatedAtoptionalIsoTimestamp—
alertedAtoptionalIsoTimestampWhen the last email alert for this thread was claimed: the cooldown reads it, in the same transaction that creates the notice.
heldSinceoptionalIsoTimestampWhen the first text arrived outside the alert hours with outsideHours: digest. Cleared when the digest goes.

Object

ActivityEntry

ActivityEntry 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

ActivityExport

ActivityExport 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

SmsSettingsView

SmsSettingsView 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

Notification

One line in ONE person's in-app inbox: the console's bell and,, the phones' inbox. Written only by Cloud Functions, one per recipient per event, so the id is `<eventId>__<recipientUid>` and a trigger that fires twice writes it once.

Notification fields
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
recipientUidrequiredIdThe one person this line is for. Server-decided from the event's recipients, never a payload field.
kindrequiredenumWhat happened. Today every kind is a StaffNotificationKind (the staff email of the same event); adds the platform's automated kinds.
categoryrequiredenumWhich preference governs it (NotificationPrefs). transactional: something happened in the workspace that the person answers for — always written to the inbox. reminder: a dated nudge, such as a trial ending.
titlerequiredstringUntrusted textThe one-line headline. Today built from static catalogue words, but rendered as text and returned inside the data envelope, because a later kind may quote a name.
bodyrequiredstringUntrusted textA short sentence under the headline. Never a card digit, a contact detail or agent text.
refoptionalNotificationRef—
eventIdrequiredIdThe event this line is one recipient's copy of — for a staff event, the staffNotifications document id.
createdAtrequiredIsoTimestamp—
readAtoptionalIsoTimestampWhen the recipient marked it read. The only field a client may write, and only the recipient.
expiresAtrequiredIsoTimestamp90 days after createdAt; the daily prune deletes it after this instant.

Object

NotificationPrefs

One person's notification preferences in one workspace: for each `NotificationCategory`, whether it reaches the in-app inbox, their devices (push) and their verified email. The id is the person's uid.

NotificationPrefs fields
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
uidrequiredIdWhose preferences — the verified token's uid of the call that wrote them.
categoriesrequiredNotificationCategoryPrefs—
updatedAtrequiredIsoTimestamp—
Next section

Actions and approvals

Anything that sends, moves money or changes the workspace is proposed here and waits for a signed-in person, or for the owner’s capped rule.

Continue to Actions and approvals →

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