Skip to content

Event catalog

This is the complete, current list of the platform’s 45 events — the same list that drives webhooks, the Events API and hosted functions, and that the console’s event picker offers. Each sample below shows the event’s data field with the fields a real delivery carries (the values are illustrative) — it’s also exactly what a test delivery or a test function run sends. Expand an event to see it.

Three audiences determine who receives an event — see Webhooks for the full matching rules:

AudienceDelivered to
businessEvery app ACTIVE-installed in the business whose installation holds the event’s gating scope
appOnly the named app (lifecycle notices — installation state is irrelevant)
privacyLike business, but a compliance notice your app must act on

An event is recorded right after the change it describes has been committed to the books; see Events API for what that means for delivery.

EventScopeDescription
invoice.createdinvoices:readAn invoice was created (draft or issued).
invoice.updatedinvoices:readAn invoice was edited.
invoice.sentinvoices:readA draft invoice was issued and posted to the ledger.
invoice.paidinvoices:readAn invoice became fully paid.
invoice.voidedinvoices:readAn invoice was voided and its journal reversed.
invoice.written_offinvoices:readAll or part of an invoice was written off as bad debt.
invoice.created / invoice.updated sample
{ "id": "cm1invoice0000000000000001", "invoiceNumber": "INV-0042", "status": "DRAFT", "customerId": "cm1customer000000000000001", "total": 1150, "balanceDue": 1150, "issueDate": "2026-09-22", "dueDate": "2026-10-22" }
invoice.sent sample
{ "id": "cm1invoice0000000000000001", "invoiceNumber": "INV-0042", "status": "SENT", "customerId": "cm1customer000000000000001", "total": 1150, "balanceDue": 1150, "issueDate": "2026-09-22", "dueDate": "2026-10-22" }
invoice.paid sample
{ "id": "cm1invoice0000000000000001", "invoiceNumber": "INV-0042", "status": "PAID", "customerId": "cm1customer000000000000001", "total": 1150, "balanceDue": 0, "issueDate": "2026-09-22", "dueDate": "2026-10-22" }
invoice.voided sample
{ "id": "cm1invoice0000000000000001", "invoiceNumber": "INV-0042", "status": "VOID", "customerId": "cm1customer000000000000001", "total": 1150, "balanceDue": 1150, "issueDate": "2026-09-22", "dueDate": "2026-10-22" }
invoice.written_off sample
{ "id": "cm1invoice0000000000000001", "invoiceNumber": "INV-0042", "status": "WRITTEN_OFF", "customerId": "cm1customer000000000000001", "total": 1150, "balanceDue": 0, "issueDate": "2026-09-22", "dueDate": "2026-10-22", "writtenOffAmount": 1150 }
EventScopeDescription
payment.receivedpayments:readA customer payment was recorded.
payment.deletedpayments:readA customer payment was deleted and its journal reversed.
payment.received sample
{ "id": "cm1payment0000000000000001", "amount": 500, "paymentMethod": "BANK_TRANSFER", "invoiceId": "cm1invoice0000000000000001", "customerId": "cm1customer000000000000001" }

invoiceId names the invoice when the payment settles exactly one; it’s null for a payment on account or one allocated across several invoices — fetch the payment for the split. Each invoice the payment settles in full also gets its own invoice.paid.

payment.deleted sample
{ "id": "cm1payment0000000000000001", "amount": 500 }
EventScopeDescription
customer.createdcustomers:readA customer was created.
customer.updatedcustomers:readA customer was edited, archived or restored.
customer.deletedcustomers:readA customer was deleted.
customer.created / customer.updated sample
{ "id": "cm1customer000000000000001", "customerCode": "C-0007", "name": "Acme Trading LLC", "email": "accounts@acme.example" }
customer.deleted sample
{ "id": "cm1customer000000000000001" }
EventScopeDescription
quote.createdquotes:readA quote was created.
quote.updatedquotes:readA quote was edited or changed status.
quote.convertedquotes:readA quote was converted into an invoice.
quote.deletedquotes:readA quote was deleted.
quote.created sample
{ "id": "cm1quote00000000000000001", "quoteNumber": "QT-0012", "status": "DRAFT", "customerId": "cm1customer000000000000001", "total": 2300 }
quote.updated sample
{ "id": "cm1quote00000000000000001", "quoteNumber": "QT-0012", "status": "SENT", "customerId": "cm1customer000000000000001", "total": 2300 }
quote.converted sample
{ "id": "cm1quote00000000000000001", "quoteNumber": "QT-0012", "invoiceId": "cm1invoice0000000000000001" }
quote.deleted sample
{ "id": "cm1quote00000000000000001", "quoteNumber": "QT-0012" }
EventScopeDescription
sales_return.createdsales-returns:readA sales return (credit note) was created.
sales_return.confirmedsales-returns:readA sales return was confirmed and posted to the ledger.
sales_return.refundedsales-returns:readCash was refunded against a sales return.
sales_return.voidedsales-returns:readA sales return was voided.
sales_return.created sample
{ "id": "cm1salesreturn00000000001", "returnNumber": "SR-0003", "status": "DRAFT", "total": 115 }
sales_return.confirmed sample
{ "id": "cm1salesreturn00000000001", "returnNumber": "SR-0003", "status": "CONFIRMED", "total": 115 }
sales_return.refunded sample
{ "id": "cm1salesreturn00000000001", "returnNumber": "SR-0003", "amount": 115 }
sales_return.voided sample
{ "id": "cm1salesreturn00000000001", "returnNumber": "SR-0003", "status": "VOID" }
EventScopeDescription
supplier.createdsuppliers:readA supplier was created.
supplier.updatedsuppliers:readA supplier was edited, archived or restored.
supplier.deletedsuppliers:readA supplier was deleted.
purchase.createdpurchases:readA purchase (bill) was created.
purchase.updatedpurchases:readA purchase (bill) was edited.
purchase.receivedpurchases:readA purchase was received and posted to the ledger.
purchase.voidedpurchases:readA purchase was voided and its journal reversed.
supplier_payment.createdsupplier-payments:readA payment to a supplier was recorded.
supplier_payment.deletedsupplier-payments:readA supplier payment was deleted and its journal reversed.
purchase_return.createdpurchase-returns:readA purchase return (debit note) was created.
purchase_return.confirmedpurchase-returns:readA purchase return was confirmed and posted to the ledger.
purchase_return.refundedpurchase-returns:readA supplier refund was recorded against a purchase return.
purchase_return.voidedpurchase-returns:readA purchase return was voided.
supplier.created / supplier.updated sample
{ "id": "cm1supplier000000000000001", "name": "Gulf Wholesale Co.", "email": "billing@gulfwholesale.example" }
supplier.deleted sample
{ "id": "cm1supplier000000000000001" }
purchase.created / purchase.updated sample
{ "id": "cm1purchase000000000000001", "purchaseNumber": "PUR-0019", "status": "DRAFT", "supplierId": "cm1supplier000000000000001", "total": 780 }

purchase.updated is sent on every successful edit of a purchase.

purchase.received sample
{ "id": "cm1purchase000000000000001", "purchaseNumber": "PUR-0019", "status": "RECEIVED", "supplierId": "cm1supplier000000000000001", "total": 780 }
purchase.voided sample
{ "id": "cm1purchase000000000000001", "purchaseNumber": "PUR-0019", "status": "VOID" }
supplier_payment.created sample
{ "id": "cm1supplierpay000000000001", "amount": 780, "supplierId": "cm1supplier000000000000001" }
supplier_payment.deleted sample
{ "id": "cm1supplierpay000000000001", "amount": 780 }
purchase_return.created sample
{ "id": "cm1purchasereturn0000000001", "returnNumber": "PR-0002", "status": "DRAFT", "total": 78 }
purchase_return.confirmed sample
{ "id": "cm1purchasereturn0000000001", "returnNumber": "PR-0002", "status": "CONFIRMED", "total": 78 }
purchase_return.refunded sample
{ "id": "cm1purchasereturn0000000001", "returnNumber": "PR-0002", "amount": 78 }
purchase_return.voided sample
{ "id": "cm1purchasereturn0000000001", "returnNumber": "PR-0002", "status": "VOID" }
EventScopeDescription
expense.createdexpenses:readAn expense was recorded.
expense.deletedexpenses:readAn expense was deleted and its journal reversed.
item.createditems:readA catalog item was created.
item.updateditems:readA catalog item was edited, archived or restored.
item.deleteditems:readA catalog item was deleted.
expense.created sample
{ "id": "cm1journalentry00000000001", "amount": 45, "expenseAccountCode": "6100", "date": "2026-09-22", "description": "Office supplies" }
expense.deleted sample
{ "id": "cm1journalentry00000000001" }
item.created / item.updated sample
{ "id": "cm1item000000000000000001", "itemCode": "SKU-100", "name": "Arabica beans 1kg", "type": "GOODS" }
item.deleted sample
{ "id": "cm1item000000000000000001" }
EventScopeDescription
journal_entry.createdjournal:readA manual journal entry was posted.
journal_entry.created sample
{ "id": "cm1journalentry00000000002", "entryNumber": "JE-0101", "date": "2026-09-22", "description": "Accrued rent" }

Audience app — delivered only to the named app’s webhooks, regardless of current installation state. See Installation & lifecycle.

EventDescription
app.installedYour app was installed in a business.
app.uninstalledYour app was uninstalled; its tokens are already revoked. business.redact follows in 48 hours.
app.scopes_updatedThe scopes granted to your app’s installation changed.
business.redactDelete everything you hold for this business: it uninstalled your app 48 hours ago. Your app data stored in OneBooks is deleted at the same time.
app_data.updatedA merchant edited one of your app data fields in OneBooks.
app.installed sample
{ "installationId": "cm1installation00000000001", "scopes": ["invoices:read", "app-data:write"], "source": "MARKETPLACE" }

source says how the business installed you: MARKETPLACE (managed install), OAUTH (authorization code), DEVICE (device flow) or SANDBOX (a console sandbox install). app.scopes_updated carries the installation’s full scope list after the change.

app.uninstalled sample
{ "installationId": "cm1installation00000000001", "uninstalledAt": "2026-09-22T10:00:00.000Z" }
app.scopes_updated sample
{ "installationId": "cm1installation00000000001", "scopes": ["invoices:read", "invoices:write", "app-data:write"] }
business.redact sample
{ "installationId": "cm1installation00000000001", "uninstalledAt": "2026-09-20T10:00:00.000Z" }

Sent once the installation has stayed uninstalled for 48 hours (OneBooks checks hourly, so it can arrive up to an hour later, and a check that can’t record it leaves it for the next one). A reinstall inside that window cancels it, and it’s never sent to an app that has been reinstalled.

app_data.updated sample
{ "id": "cm1appdatavalue00000000001", "resourceType": "INVOICE", "resourceId": "cm1invoice0000000000000001", "key": "tracking_number", "value": "1Z999AA10123456784" }

id is the app data value; resourceType and resourceId name the record the field sits on. The event’s own resourceType/resourceId in the Events API name that same record — the invoice here — not the value.

EventScopeDescription
customer.redactcustomers:readA customer’s personal data was erased in OneBooks; erase what you hold for them.
supplier.redactsuppliers:readA supplier’s personal data was erased in OneBooks; erase what you hold for them.
customer.redact sample
{ "customerId": "cm1customer000000000000001" }
supplier.redact sample
{ "supplierId": "cm1supplier000000000000001" }

Both are sent after OneBooks has anonymized the contact, and by then the earlier customer.created/customer.updated (or supplier.*) events about that contact already read { "id": …, "redacted": true } — see Privacy & data handling.

  • Webhooks — subscribe to these and receive signed HTTP deliveries.
  • Events API — pull the same events as a cursor-paginated catch-up feed.
  • Hosted functions — run your own code on business and privacy events (app-lifecycle events are webhook-only).