Event Types
- Data Entity Events
- User Activity Events
- SMS Events
- Bookkeeping Events
- External Account Events
- Plaid Events
- Call Booking Events
- Export Events
Data entity events follow
EntityName.operation and generally use thin payloads.Example payload:{
"id": "Customer_created_7bcef4fd-9458-49d0-a7e7-589f5e6f2683_03f6c94f-574d-42ca-a6cd-fecf2a2aeccb",
"type": "Customer.created",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"entity_id": "7bcef4fd-9458-49d0-a7e7-589f5e6f2683",
"entity_external_id": "cust_2001"
}
}
| Entity | Events |
|---|---|
| BankTransaction | BankTransaction.created, BankTransaction.updated, BankTransaction.archived |
| Bill | Bill.created, Bill.updated, Bill.archived |
| BillPayment | BillPayment.created, BillPayment.updated, BillPayment.archived |
| Business | Business.created, Business.updated, Business.archived |
| BusinessTask | BusinessTask.created, BusinessTask.updated, BusinessTask.archived |
| Customer | Customer.created, Customer.updated, Customer.archived |
| CustomerCredit | CustomerCredit.created, CustomerCredit.updated, CustomerCredit.archived |
| CustomerPayout | CustomerPayout.created, CustomerPayout.updated, CustomerPayout.archived |
| CustomerRefund | CustomerRefund.created, CustomerRefund.updated, CustomerRefund.archived |
| GeneralLedgerAccount | GeneralLedgerAccount.created, GeneralLedgerAccount.updated, GeneralLedgerAccount.archived |
| Invoice | Invoice.created, Invoice.updated, Invoice.archived |
| InvoicePayment | InvoicePayment.created, InvoicePayment.updated, InvoicePayment.archived |
| InvoiceWriteOff | InvoiceWriteOff.created, InvoiceWriteOff.updated, InvoiceWriteOff.archived |
| TaxProfile | TaxProfile.created, TaxProfile.updated, TaxProfile.archived |
| TimeEntry | TimeEntry.created, TimeEntry.updated, TimeEntry.archived |
| Trip | Trip.created, Trip.updated, Trip.archived |
| Vehicle | Vehicle.created, Vehicle.updated, Vehicle.archived |
| Vendor | Vendor.created, Vendor.updated, Vendor.archived |
| VendorCredit | VendorCredit.created, VendorCredit.updated, VendorCredit.archived |
| VendorPayout | VendorPayout.created, VendorPayout.updated, VendorPayout.archived |
| VendorRefund | VendorRefund.created, VendorRefund.updated, VendorRefund.archived |
Events with additional metadata
BusinessTask lifecycle webhooks include the current active task count for the business in addition to the standard lifecycle entity fields.Show BusinessTask example payload
Show BusinessTask example payload
{
"id": "BusinessTask_created_7bcef4fd-9458-49d0-a7e7-589f5e6f2683_03f6c94f-574d-42ca-a6cd-fecf2a2aeccb",
"type": "BusinessTask.created",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"entity_id": "7bcef4fd-9458-49d0-a7e7-589f5e6f2683",
"entity_external_id": null,
"open_task_count": 3
}
}
User activity events use the
activity.* namespace.Example payload:{
"id": "activity_categorize_bank_transaction_44bb48bd-4af1-4e6f-a38a-fb24e5575dc7",
"type": "activity.categorize_bank_transaction",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"transaction_id": "34db2910-5919-4985-8e7f-56dd83e76ed5",
"categorization_method": "API",
"categorization": null,
"matchType": "INVOICE_PAYMENT",
"created_at": "2026-03-31T16:42:11Z"
}
}
activity.categorize_bank_transactionactivity.load_pnlactivity.load_balance_sheetactivity.load_cashflow_statementactivity.create_custom_accountactivity.archive_custom_accountactivity.reactivate_custom_accountactivity.upload_custom_account_csvactivity.export_pnl_csvactivity.export_pnl_excelactivity.export_pnl_comparison_csvactivity.export_pnl_month_over_monthactivity.export_pnl_line_item_excelactivity.export_balance_sheet_csvactivity.export_balance_sheet_excelactivity.export_cashflow_csvactivity.export_cashflow_excelactivity.export_transactions_csvactivity.export_transactions_excelactivity.export_pnl_pdfactivity.export_trial_balance_excelactivity.export_ar_aging_excelactivity.export_business_expenses_excelactivity.export_business_income_excelactivity.export_business_mileage_excelactivity.export_personal_expenses_excelactivity.export_personal_income_excelactivity.export_personal_mileage_excelactivity.export_time_tracking_excelactivity.export_schedule_c_excelactivity.generate_tax_packet
SMS events use the
sms.* namespace.Example payload:{
"id": "sms_message_received_SM1234567890",
"type": "sms.message_received",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"message_id": "SM1234567890",
"direction": "RECEIVED",
"body": "Classify this as utilities",
"phone_number": "+15551234567",
"delivery_status": null,
"at": "2026-03-31T16:48:55Z"
}
}
sms.message_receivedsms.message_deliveredsms.message_delivery_failed
Bookkeeping webhooks notify you about onboarding completion, first-month purchase date changes, and bookkeeping context events. A bookkeeping context event is a normalized audit-style event, so many bookkeeping actions share the same webhook type,
Sent at the end of a business’s Layer bookkeeping onboarding call, when their bookkeeping configuration’s
Sent when a business’s first purchased bookkeeping month changes on its bookkeeping configuration. Use this to keep your records in sync when Layer sets or updates the
Sent when Layer records a bookkeeping context event for a business, such as a transaction categorization, task update, period status change, connected account change, adjustment entry, or closing date update.Example payload:
bookkeeping_event.created; use data.resource_type and data.action to distinguish what happened.Event types
bookkeeping_onboarding.completedbookkeeping_purchase_date.updatebookkeeping_event.created
bookkeeping_onboarding.completed
Sent at the end of a business’s Layer bookkeeping onboarding call, when their bookkeeping configuration’s onboarding_date is set for the first time.Example payload:{
"id": "bookkeeping_onboarding_completed_a43f6b83-8932-4ced-b6b1-0199313274ca_03f6c94f-574d-42ca-a6cd-fecf2a2aeccb",
"type": "bookkeeping_onboarding.completed",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"bookkeeping_configuration_id": "a43f6b83-8932-4ced-b6b1-0199313274ca",
"onboarding_date": "2026-05-07",
"first_month_purchased_date": "2026-01-01",
"activation_at": "2026-01-01T05:00:00Z"
}
}
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this webhook event |
type | string | Always bookkeeping_onboarding.completed |
business_id | string (UUID) | The Layer business ID |
business_external_id | string or null | Your external identifier for the business, if set |
data.bookkeeping_configuration_id | string (UUID) | The ID of the bookkeeping configuration that completed onboarding |
data.onboarding_date | string (date) | The date when bookkeeping onboarding was completed, in YYYY-MM-DD format |
data.first_month_purchased_date | string (date) or null | The business’s first purchased bookkeeping month, in YYYY-MM-DD format. null when no first-month-purchased value is set on the bookkeeping configuration. |
data.activation_at | string (date-time) | The business’s activation timestamp, in ISO 8601 format. Always present. |
When This Webhook Fires
Thebookkeeping_onboarding.completed webhook fires when Layer updates the business’s bookkeeping configuration at the end of their onboarding call.This webhook only fires when the
onboarding_date transitions from unset (null) to a value. Subsequent updates to onboarding_date do not trigger additional webhooks.bookkeeping_purchase_date.update
Sent when a business’s first purchased bookkeeping month changes on its bookkeeping configuration. Use this to keep your records in sync when Layer sets or updates the first_month_purchased_date.Example payload:{
"id": "bookkeeping_purchase_date_update_00000000-0000-0000-0000-000000000002_03f6c94f-574d-42ca-a6cd-fecf2a2aeccb",
"type": "bookkeeping_purchase_date.update",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"bookkeeping_configuration_id": "00000000-0000-0000-0000-000000000002",
"first_month_purchased_date": "2024-01-01"
}
}
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this webhook event |
type | string | Always bookkeeping_purchase_date.update |
business_id | string (UUID) | The Layer business ID |
business_external_id | string or null | Your external identifier for the business, if set |
data.bookkeeping_configuration_id | string (UUID) | The ID of the bookkeeping configuration whose purchase date changed |
data.first_month_purchased_date | string (date) or null | The business’s first purchased bookkeeping month, in YYYY-MM-DD format. null when the first-month-purchased value has been cleared. |
When This Webhook Fires
Thebookkeeping_purchase_date.update webhook fires whenever a business’s first_month_purchased_date changes.first_month_purchased_date can change more than once, so you may receive this event multiple times for the same business with each event having a unique id.bookkeeping_event.created
Sent when Layer records a bookkeeping context event for a business, such as a transaction categorization, task update, period status change, connected account change, adjustment entry, or closing date update.Example payload:{
"id": "bookkeeping_event_created_4d2df66e-ae15-4241-9f6b-9c4bdf19f83e",
"type": "bookkeeping_event.created",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"id": "4d2df66e-ae15-4241-9f6b-9c4bdf19f83e",
"resource_type": "BOOKKEEPING_PERIOD",
"resource_id": "77d54b21-d7d7-4bfc-8f33-2845e4f8e07a",
"action": "PERIOD_STATUS_CHANGED",
"summary": "Bookkeeper status changed period",
"actor": "MANUAL_BOOKKEEPER",
"count": null,
"event_at": "2026-03-31T16:52:44Z",
"accounting_date": "2026-03-31T04:59:59.999999999Z",
"previous_state": "TO_DO",
"new_state": "DONE"
}
}
Bookkeeping context fields
| Field | Description |
|---|---|
id | Unique bookkeeping context event ID. |
resource_type | Bookkeeping resource affected by the event. |
resource_id | ID of the affected resource, when applicable. |
action | Specific bookkeeping action that occurred. |
summary | Human-readable event summary. |
actor | Actor that caused the event. |
count | Count associated with batch events, when applicable. |
event_at | Timestamp when the event occurred. |
accounting_date | Accounting-effective timestamp, when applicable. |
previous_state | Previous value or state, when applicable. |
new_state | New value or state, when applicable. |
Bookkeeping context actions
| Resource type | Actions |
|---|---|
BANK_TRANSACTION | CATEGORIZED, RECATEGORIZED |
BANK_TRANSACTION_BATCH | BATCH_CATEGORIZED |
TASK | TASK_CREATED, TASK_ANSWERED, TASK_COMPLETED |
BOOKKEEPING_PERIOD | PERIOD_STATUS_CHANGED |
BOOKKEEPING_STEP | STEP_COMPLETED |
CONNECTED_ACCOUNT | ACCOUNT_CONNECTED, ACCOUNT_DISCONNECTED, ACCOUNT_NEEDS_REPAIR, ACCOUNT_REPAIRED, ACCOUNT_CREATED, ACCOUNT_ARCHIVED, ACCOUNT_REACTIVATED |
ADJUSTMENT_ENTRY | CUSTOM_ENTRY_CREATED, CLOSING_ACTION_CREATED |
ACCOUNTING_CONFIGURATION | CLOSING_DATE_UPDATED |
Actors
actor can be USER, AI_BOOKKEEPER, MANUAL_BOOKKEEPER, SYSTEM, or UNKNOWN.External account events use the
external_accounts.* namespace.
These events include the current count of external accounts that need repair for the business.Example payload:{
"id": "external_accounts_account_connected_03f6c94f-574d-42ca-a6cd-fecf2a2aeccb",
"type": "external_accounts.account.connected",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"provider": "plaid",
"at": "2026-03-31T16:50:29Z",
"link_id": "719b0d31-ba7b-4f1b-982a-c6334b0a544b",
"external_link_id": "plaid_item_123",
"account_ids": [
"92762148-f10b-42a5-b37f-b1e23fa3faca"
],
"external_account_ids": [
"plaid_account_456"
],
"accounts_needing_repair_count": 0
}
}
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this webhook event. |
type | string | The external account event type (e.g., external_accounts.account.connected). |
business_id | string (UUID) | The Layer business ID |
business_external_id | string or null | Your external identifier for the business, if set |
data.provider | string | The external account provider (e.g., plaid). |
data.at | string (date-time) | ISO 8601 timestamp when the event occurred. |
data.link_id | string (UUID) | Layer’s internal ID for the external account link. |
data.external_link_id | string | The provider’s ID for the link (e.g., Plaid Item ID). |
data.account_ids | array | Layer IDs of the affected external accounts. |
data.external_account_ids | array | Provider IDs of the affected external accounts. |
data.accounts_needing_repair_count | integer | Number of external accounts across the business that currently need repair. Only counts accounts where the parent bank account has notify_when_disconnected enabled. Excludes archived accounts. |
Event types
external_accounts.link.connectedexternal_accounts.link.disconnectedexternal_accounts.link.archivedexternal_accounts.link.reactivatedexternal_accounts.link.needs_repairexternal_accounts.link.repairedexternal_accounts.account.connectedexternal_accounts.account.archivedexternal_accounts.account.reactivatedexternal_accounts.account.needs_repairexternal_accounts.account.repaired
Plaid-specific events use the
plaid.* namespace.Example payload:{
"id": "plaid_link_token_created_Aim3b8jJC9eRyfy",
"type": "plaid.link.token_created",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"created_at": "2026-03-31T16:50:29Z",
"plaid_request_id": "Aim3b8jJC9eRyfy"
}
}
plaid.link.token_created
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this webhook event. Suffixed with the Plaid request id. |
type | string | Always plaid.link.token_created |
business_id | string (UUID) | The Layer business ID |
business_external_id | string or null | Your external identifier for the business, if set |
data.created_at | string (date-time) | When the link token was created |
data.plaid_request_id | string | The Plaid request_id returned by Plaid for the link-token-create call. Useful when correlating with Plaid logs or support tickets. |
When This Webhook Fires
Theplaid.link.token_created webhook fires whenever Layer mints a Plaid link token for a business. This corresponds to the user initiating the Plaid Link flow (e.g. clicking “Add Account” or starting an update-mode reconnect). The event fires before the user selects an institution or completes the flow, so it can be used as a click-level signal. To know when a connection is actually established, listen for external_accounts.link.connected.Call booking events use the
call_booking.* namespace. They notify you when a call booked through Calendly is scheduled, rescheduled, or canceled.Example payload:{
"id": "call_booking_scheduled_00000000-0000-0000-0000-000000000001_03f6c94f-574d-42ca-a6cd-fecf2a2aeccb",
"type": "call_booking.scheduled",
"business_id": "8e7a359e-7af5-4f6e-b786-6ddfd1807c32",
"business_external_id": "biz_101",
"data": {
"calendly_event_uri": "https://api.calendly.com/scheduled_events/76b3fb2d-b5d8-4d60-b969-cef8bd2900de",
"invitee_name": "Jane Provider",
"invitee_email": "jane@example.com",
"event_start_at": "2024-01-15T12:00:00Z",
"event_end_at": "2024-01-15T12:30:00Z",
"purpose": "BOOKKEEPING_ONBOARDING",
"previous_calendly_event_id": null
}
}
Event types
call_booking.scheduledcall_booking.rescheduledcall_booking.canceled
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this webhook event. |
type | string | The call booking event type (for example, call_booking.scheduled). |
business_id | string (UUID) | The Layer business ID. |
business_external_id | string or null | Your external identifier for the business, if set. |
data.calendly_event_uri | string or null | Calendly scheduled-event API URI for the call. |
data.invitee_name | string or null | Name of the invitee who booked the call. Contains personally identifiable information (PII). |
data.invitee_email | string or null | Email of the invitee who booked the call. Contains PII. |
data.event_start_at | string (date-time) | ISO 8601 start time of the call. Required. |
data.event_end_at | string (date-time) or null | ISO 8601 end time of the call. |
data.purpose | string | Purpose of the call: BOOKKEEPING_ONBOARDING or ADHOC. Required. |
data.previous_calendly_event_id | string or null | Calendly event ID of the booking that was replaced. Populated only on call_booking.rescheduled. |
When This Webhook Fires
call_booking.scheduledfires for a new booking.call_booking.rescheduledfires when an existing booking moves to a new time.call_booking.canceledfires when an existing booking is canceled without being rescheduled.
A reschedule is delivered as a single
call_booking.rescheduled event. Layer does not also send call_booking.canceled and call_booking.scheduled events for the same reschedule.Export events use the
export.* namespace and notify you when an async export finishes.These events are client-scoped: the payload includes id, type, and data, and does not include top-level business_id / business_external_id.Example payload:{
"id": "export_completed_00000000-0000-0000-0000-000000000006",
"type": "export.completed",
"data": {
"export_id": "00000000-0000-0000-0000-000000000006",
"business_id": null,
"export_type": "billing_report",
"status": "completed",
"error": null
}
}
export.completedexport.failed
export.completed, call Fetch export to retrieve the download_url.