When events fire
When outbound events fire
COUNT queues webhook deliveries from Sequelize model hooks (afterCreate, afterUpdate, afterDestroy) on the relevant tables. Deliveries run asynchronously (worker). Nothing is emitted unless there is an active subscription for that exact event and workspace.
Skipping deliveries: Internal or bulk operations can pass { skipPartnerWebhook: true } in Sequelize save/update options — those operations do not enqueue partner webhooks.
Payload shape (summary)
| Event suffix | data in outbound envelope |
|---|---|
.created / .updated |
Serialized entity (UUID-based fields; see serializers in API implementation). |
.updated |
May include previousData when prior values are available. |
.deleted |
Minimal payload: { "id": "<resource-uuid>" } (resource UUID, not subscription UUID). |
Customers (customer.*)
Hooks run on the Customer model for the customer’s teamId.
| Event | When it fires |
|---|---|
customer.created |
After a new customer row is inserted (afterCreate) — any successful create from UI, API, imports, etc., unless skipPartnerWebhook is set. |
customer.updated |
After an update (afterUpdate) when the row is not being soft-deleted — e.g. name, email, or other field changes while isDeleted stays false. |
customer.deleted |
(1) Soft-delete: afterUpdate when isDeleted transitions from false → true (typical “delete” in app). (2) Hard delete: afterDestroy when the row is removed from the database. |
If you soft-delete a customer, you get customer.deleted, not customer.updated.
Vendors (vendor.*)
Same pattern as customers. Default queries exclude deleted vendors (beforeFind adds isDeleted: false unless overridden).
| Event | When it fires |
|---|---|
vendor.created |
After a new vendor is created (afterCreate). |
vendor.updated |
After an update that is not a soft-delete transition (afterUpdate). |
vendor.deleted |
(1) Soft-delete: isDeleted becomes true on update. (2) Hard delete: afterDestroy. |
Transactions (transaction.*)
| Event | When it fires |
|---|---|
transaction.created |
After a new transaction is created (afterCreate). |
transaction.updated |
After any successful update (afterUpdate) — including field changes and soft-delete updates if the row is updated in place with isDeleted: true. |
transaction.deleted |
After a hard delete removes the row (afterDestroy). |
Note: If your product soft-deletes transactions by setting isDeleted: true via update, the hook currently emits transaction.updated, not transaction.deleted. transaction.deleted is for destroys that actually remove the row.
Invoices (invoice.*)
| Event | When it fires |
|---|---|
invoice.created |
After a new invoice is created (afterCreate). |
invoice.updated |
After any successful update (afterUpdate) — line items, status, soft-delete flags, etc. |
invoice.deleted |
Only when the invoice record is destroyed (afterDestroy) — i.e. hard delete path. |
Note: If invoices are soft-deleted by updating isDeleted (or similar) without calling destroy, COUNT emits invoice.updated, not invoice.deleted.
Bills (bill.*)
| Event | When it fires |
|---|---|
bill.created |
After a new bill is created (afterCreate). |
bill.updated |
After any successful update (afterUpdate). |
bill.deleted |
When the bill row is destroyed (afterDestroy). |
Same caveat as invoices: soft-delete via update → bill.updated; physical delete → bill.deleted.
Summary table
| Entity | Created | Updated | Deleted |
|---|---|---|---|
| Customer | New row | Non-delete updates | Soft-delete (false→true) or hard delete |
| Vendor | New row | Non-delete updates | Soft-delete or hard delete |
| Transaction | New row | Any update (incl. soft-delete flag) | Hard delete only (destroy) |
| Invoice | New row | Any update (incl. soft-delete) | Hard delete (destroy) only |
| Bill | New row | Any update | Hard delete (destroy) only |
For transaction / invoice / bill, align your integration with whether your flows use soft vs hard delete so you subscribe to .updated vs .deleted correctly.
On this page
- When events fire