Events Reference
Subscribe an endpoint to the specific events it needs, or to Every event its owner's role may receive. An event is only delivered when the endpoint's owner could read the record it is about through the API: their role must reach the event's read scope, and the record must be one they can see.
Events are raised by the same code whether a change was made in the app, through the API or by an import, so an integration sees every change, whatever made it.
Each example below is the exact body your endpoint receives, with sample values. data.object has the same fields as the matching API endpoint at its standard tier; follow the event name to its schema in the API Reference. GET /webhook-events returns this catalogue to a token with webhooks:read.
Leave
| Event | Fires when | Owner needs |
|---|---|---|
leave.requested | A leave request was created. Sent for every new request, whatever its status: PENDING, or APPROVED when it needed no approval or was booked by the person's manager. | leaves:read |
leave.approved | A leave request was approved. | leaves:read |
leave.rejected | A leave request was rejected. | leaves:read |
leave.cancelled | A leave was cancelled or withdrawn. Sent when a pending request is withdrawn, an approved leave is cancelled by an administrator or manager, or a cancellation request is approved. previous.status is the status before. | leaves:read |
leave.cancellation_requested | Cancellation of an approved leave was requested. The person asked for their approved leave to be cancelled. It stays APPROVED until an approver decides. | leaves:read |
leave.updated | The dates, half days or type of a leave request changed. A pending request was edited. previous holds the old value of each changed field. | leaves:read |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "leave.requested",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmlve0hmarsh2026080300",
"user_id": "cmusr0lenafischer000000",
"leave_type_id": "cmlvt0annual00000000000",
"leave_type": {
"id": "cmlvt0annual00000000000",
"name": "Annual Leave",
"code": "ANNUAL",
"color": "#3b82f6",
"is_private": false
},
"status": "PENDING",
"start_date": "2026-08-03",
"end_date": "2026-08-07",
"start_half": "FULL_DAY",
"end_half": "FULL_DAY",
"start_time": null,
"end_time": null,
"total_days": 5,
"total_hours": null,
"reason": "Family trip to Tofino",
"decided_by_id": null,
"decided_at": null,
"decision_comment": null,
"rejection_reason": null,
"cancellation_requested_at": null,
"cancellation_request_reason": null,
"cancelled_at": null,
"submitted_at": "2026-07-14T16:20:05.000Z",
"created_at": "2026-07-14T16:20:05.000Z",
"updated_at": "2026-07-14T16:20:05.000Z"
}
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "leave.approved",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmlve0hmarsh2026080300",
"user_id": "cmusr0lenafischer000000",
"leave_type_id": "cmlvt0annual00000000000",
"leave_type": {
"id": "cmlvt0annual00000000000",
"name": "Annual Leave",
"code": "ANNUAL",
"color": "#3b82f6",
"is_private": false
},
"status": "APPROVED",
"start_date": "2026-08-03",
"end_date": "2026-08-07",
"start_half": "FULL_DAY",
"end_half": "FULL_DAY",
"start_time": null,
"end_time": null,
"total_days": 5,
"total_hours": null,
"reason": "Family trip to Tofino",
"decided_by_id": "cmusr0marcusokafor00000",
"decided_at": "2026-07-15T09:02:31.000Z",
"decision_comment": "Enjoy the trip.",
"rejection_reason": null,
"cancellation_requested_at": null,
"cancellation_request_reason": null,
"cancelled_at": null,
"submitted_at": "2026-07-14T16:20:05.000Z",
"created_at": "2026-07-14T16:20:05.000Z",
"updated_at": "2026-07-15T09:02:31.000Z"
}
},
"previous": {
"status": "PENDING"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "leave.rejected",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmlve0hmarsh2026080300",
"user_id": "cmusr0lenafischer000000",
"leave_type_id": "cmlvt0annual00000000000",
"leave_type": {
"id": "cmlvt0annual00000000000",
"name": "Annual Leave",
"code": "ANNUAL",
"color": "#3b82f6",
"is_private": false
},
"status": "REJECTED",
"start_date": "2026-08-03",
"end_date": "2026-08-07",
"start_half": "FULL_DAY",
"end_half": "FULL_DAY",
"start_time": null,
"end_time": null,
"total_days": 5,
"total_hours": null,
"reason": "Family trip to Tofino",
"decided_by_id": "cmusr0marcusokafor00000",
"decided_at": "2026-07-15T09:02:31.000Z",
"decision_comment": null,
"rejection_reason": "Quarter-end close that week. Could you move it to the following week?",
"cancellation_requested_at": null,
"cancellation_request_reason": null,
"cancelled_at": null,
"submitted_at": "2026-07-14T16:20:05.000Z",
"created_at": "2026-07-14T16:20:05.000Z",
"updated_at": "2026-07-15T09:02:31.000Z"
}
},
"previous": {
"status": "PENDING"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "leave.cancelled",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmlve0hmarsh2026080300",
"user_id": "cmusr0lenafischer000000",
"leave_type_id": "cmlvt0annual00000000000",
"leave_type": {
"id": "cmlvt0annual00000000000",
"name": "Annual Leave",
"code": "ANNUAL",
"color": "#3b82f6",
"is_private": false
},
"status": "CANCELLED",
"start_date": "2026-08-03",
"end_date": "2026-08-07",
"start_half": "FULL_DAY",
"end_half": "FULL_DAY",
"start_time": null,
"end_time": null,
"total_days": 5,
"total_hours": null,
"reason": "Family trip to Tofino",
"decided_by_id": "cmusr0marcusokafor00000",
"decided_at": "2026-07-15T09:02:31.000Z",
"decision_comment": "Enjoy the trip.",
"rejection_reason": null,
"cancellation_requested_at": null,
"cancellation_request_reason": null,
"cancelled_at": "2026-07-20T11:45:00.000Z",
"submitted_at": "2026-07-14T16:20:05.000Z",
"created_at": "2026-07-14T16:20:05.000Z",
"updated_at": "2026-07-20T11:45:00.000Z"
}
},
"previous": {
"status": "APPROVED"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "leave.cancellation_requested",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmlve0hmarsh2026080300",
"user_id": "cmusr0lenafischer000000",
"leave_type_id": "cmlvt0annual00000000000",
"leave_type": {
"id": "cmlvt0annual00000000000",
"name": "Annual Leave",
"code": "ANNUAL",
"color": "#3b82f6",
"is_private": false
},
"status": "APPROVED",
"start_date": "2026-08-03",
"end_date": "2026-08-07",
"start_half": "FULL_DAY",
"end_half": "FULL_DAY",
"start_time": null,
"end_time": null,
"total_days": 5,
"total_hours": null,
"reason": "Family trip to Tofino",
"decided_by_id": "cmusr0marcusokafor00000",
"decided_at": "2026-07-15T09:02:31.000Z",
"decision_comment": "Enjoy the trip.",
"rejection_reason": null,
"cancellation_requested_at": "2026-07-20T11:45:00.000Z",
"cancellation_request_reason": "Trip postponed to September.",
"cancelled_at": null,
"submitted_at": "2026-07-14T16:20:05.000Z",
"created_at": "2026-07-14T16:20:05.000Z",
"updated_at": "2026-07-20T11:45:00.000Z"
}
},
"previous": {
"cancellation_requested_at": null
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "leave.updated",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmlve0hmarsh2026080300",
"user_id": "cmusr0lenafischer000000",
"leave_type_id": "cmlvt0annual00000000000",
"leave_type": {
"id": "cmlvt0annual00000000000",
"name": "Annual Leave",
"code": "ANNUAL",
"color": "#3b82f6",
"is_private": false
},
"status": "PENDING",
"start_date": "2026-08-10",
"end_date": "2026-08-13",
"start_half": "FULL_DAY",
"end_half": "FULL_DAY",
"start_time": null,
"end_time": null,
"total_days": 4,
"total_hours": null,
"reason": "Family trip to Tofino",
"decided_by_id": null,
"decided_at": null,
"decision_comment": null,
"rejection_reason": null,
"cancellation_requested_at": null,
"cancellation_request_reason": null,
"cancelled_at": null,
"submitted_at": "2026-07-14T16:20:05.000Z",
"created_at": "2026-07-14T16:20:05.000Z",
"updated_at": "2026-07-16T08:30:12.000Z"
}
},
"previous": {
"end_date": "2026-08-07",
"start_date": "2026-08-03",
"total_days": 5
}
}
People
| Event | Fires when | Owner needs |
|---|---|---|
user.created | A person was added. Delivered when the endpoint owner may see the person in the directory. data.object is the directory (users:read) view of the person. | users:read |
user.updated | A person's directory or employment fields changed. A directory or employment field changed. previous holds the old values of the directory fields that changed. | users:read |
user.deactivated | A person's account was deactivated, including on completed offboarding. Sent when offboarding completes. | users:read |
user.reactivated | A person's account was reactivated. | users:read |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "user.created",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmusr4k2h0000ex01lena0001",
"first_name": "Lena",
"last_name": "Fischer",
"middle_name": null,
"preferred_name": null,
"email": "lena.fischer@northwind.example",
"job_title": "Operations Analyst",
"division": "North America",
"work_location": "Vancouver, BC",
"department_id": "cmdep4k2h0000ex01ops00001",
"manager_id": "cmusr4k2h0000ex01marc0001",
"role": "EMPLOYEE",
"level": "STANDARD",
"is_active": true,
"created_at": "2024-02-20T17:00:00.000Z",
"updated_at": "2026-09-01T17:00:00.000Z"
}
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "user.updated",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmusr4k2h0000ex01lena0001",
"first_name": "Lena",
"last_name": "Fischer",
"middle_name": null,
"preferred_name": null,
"email": "lena.fischer@northwind.example",
"job_title": "Senior Operations Analyst",
"division": "North America",
"work_location": "Vancouver, BC",
"department_id": "cmdep4k2h0000ex01ops00001",
"manager_id": "cmusr4k2h0000ex01marc0001",
"role": "EMPLOYEE",
"level": "STANDARD",
"is_active": true,
"created_at": "2024-02-20T17:00:00.000Z",
"updated_at": "2026-09-01T17:00:00.000Z"
}
},
"previous": {
"job_title": "Operations Analyst"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "user.deactivated",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmusr4k2h0000ex01lena0001",
"first_name": "Lena",
"last_name": "Fischer",
"middle_name": null,
"preferred_name": null,
"email": "lena.fischer@northwind.example",
"job_title": "Operations Analyst",
"division": "North America",
"work_location": "Vancouver, BC",
"department_id": "cmdep4k2h0000ex01ops00001",
"manager_id": "cmusr4k2h0000ex01marc0001",
"role": "EMPLOYEE",
"level": "STANDARD",
"is_active": false,
"created_at": "2024-02-20T17:00:00.000Z",
"updated_at": "2026-09-01T17:00:00.000Z"
}
},
"previous": {
"is_active": true
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "user.reactivated",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmusr4k2h0000ex01lena0001",
"first_name": "Lena",
"last_name": "Fischer",
"middle_name": null,
"preferred_name": null,
"email": "lena.fischer@northwind.example",
"job_title": "Operations Analyst",
"division": "North America",
"work_location": "Vancouver, BC",
"department_id": "cmdep4k2h0000ex01ops00001",
"manager_id": "cmusr4k2h0000ex01marc0001",
"role": "EMPLOYEE",
"level": "STANDARD",
"is_active": true,
"created_at": "2024-02-20T17:00:00.000Z",
"updated_at": "2026-09-01T17:00:00.000Z"
}
},
"previous": {
"is_active": false
}
}
Departments
| Event | Fires when | Owner needs |
|---|---|---|
department.created | A department was created. | departments:read |
department.updated | A department was changed. previous holds the old values of the fields that changed. | departments:read |
department.deleted | A department was deleted. A thin event: data.object carries only the id, because the department no longer exists. | departments:read |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "department.created",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmdep4k2h0000ex01ops00001",
"name": "Operations",
"code": "OPS",
"description": "Warehouse and dispatch operations",
"color": "#3b82f6",
"head_id": "cmusr4k2h0000ex01marc0001",
"is_active": true,
"member_count": 24,
"created_at": "2024-01-10T00:00:00.000Z",
"updated_at": "2026-08-14T21:30:00.000Z"
}
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "department.updated",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmdep4k2h0000ex01ops00001",
"name": "Operations and Yard",
"code": "OPS",
"description": "Warehouse and dispatch operations",
"color": "#3b82f6",
"head_id": "cmusr4k2h0000ex01marc0001",
"is_active": true,
"member_count": 24,
"created_at": "2024-01-10T00:00:00.000Z",
"updated_at": "2026-08-14T21:30:00.000Z"
}
},
"previous": {
"name": "Operations"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "department.deleted",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmdep4k2h0000ex01ops00001",
"object": "department"
}
}
}
Time tracking
Delivered only while time tracking is switched on for the organization. An event raised while it is off is not queued, and a queued delivery is cancelled if the module is switched off before it is sent.
| Event | Fires when | Owner needs |
|---|---|---|
time_entry.submitted | A time entry was submitted for approval. A completed entry that needs approval was created (by hand, by clocking out, or through the API), or an approved or rejected entry was changed and went back to PENDING. Delivered when time tracking is switched on, to endpoints whose owner may see the entry. | time_entries:read |
time_entry.approved | A time entry was approved. | time_entries:read |
time_entry.rejected | A time entry was rejected. | time_entries:read |
timesheet.finalized | A period timesheet was finalized. An approved timesheet was locked for payroll. Pay figures are never included in the event; read them with GET /timesheets/{id}. | timesheets:read |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "time_entry.submitted",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmte00000000000000000001",
"user_id": "cmusr0000000000000000012",
"user": {
"id": "cmusr0000000000000000012",
"first_name": "Lena",
"last_name": "Fischer"
},
"clock_in": "2026-10-08T16:00:00.000Z",
"clock_out": "2026-10-09T00:30:00.000Z",
"duration_minutes": 480,
"break_minutes": 30,
"project_id": "cmprj0000000000000000003",
"project": {
"id": "cmprj0000000000000000003",
"name": "Warehouse migration"
},
"task_id": "cmtsk0000000000000000007",
"task": {
"id": "cmtsk0000000000000000007",
"name": "Inventory count"
},
"description": "Cycle count, aisles 4 to 9",
"notes": null,
"tags": [
"onsite"
],
"is_billable": true,
"status": "ACTIVE",
"approval_status": "PENDING",
"approved_by_id": null,
"approved_at": null,
"source": "API",
"scheduled_shift_id": null,
"created_at": "2026-10-09T00:31:12.000Z",
"updated_at": "2026-10-09T00:31:12.000Z"
}
},
"previous": {
"approval_status": "REJECTED"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "time_entry.approved",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmte00000000000000000001",
"user_id": "cmusr0000000000000000012",
"user": {
"id": "cmusr0000000000000000012",
"first_name": "Lena",
"last_name": "Fischer"
},
"clock_in": "2026-10-08T16:00:00.000Z",
"clock_out": "2026-10-09T00:30:00.000Z",
"duration_minutes": 480,
"break_minutes": 30,
"project_id": "cmprj0000000000000000003",
"project": {
"id": "cmprj0000000000000000003",
"name": "Warehouse migration"
},
"task_id": "cmtsk0000000000000000007",
"task": {
"id": "cmtsk0000000000000000007",
"name": "Inventory count"
},
"description": "Cycle count, aisles 4 to 9",
"notes": null,
"tags": [
"onsite"
],
"is_billable": true,
"status": "ACTIVE",
"approval_status": "APPROVED",
"approved_by_id": "cmusr0000000000000000003",
"approved_at": "2026-10-09T15:12:40.000Z",
"source": "API",
"scheduled_shift_id": null,
"created_at": "2026-10-09T00:31:12.000Z",
"updated_at": "2026-10-09T00:31:12.000Z"
}
},
"previous": {
"approval_status": "PENDING"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "time_entry.rejected",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmte00000000000000000001",
"user_id": "cmusr0000000000000000012",
"user": {
"id": "cmusr0000000000000000012",
"first_name": "Lena",
"last_name": "Fischer"
},
"clock_in": "2026-10-08T16:00:00.000Z",
"clock_out": "2026-10-09T00:30:00.000Z",
"duration_minutes": 480,
"break_minutes": 30,
"project_id": "cmprj0000000000000000003",
"project": {
"id": "cmprj0000000000000000003",
"name": "Warehouse migration"
},
"task_id": "cmtsk0000000000000000007",
"task": {
"id": "cmtsk0000000000000000007",
"name": "Inventory count"
},
"description": "Cycle count, aisles 4 to 9",
"notes": null,
"tags": [
"onsite"
],
"is_billable": true,
"status": "ACTIVE",
"approval_status": "REJECTED",
"approved_by_id": "cmusr0000000000000000003",
"approved_at": "2026-10-09T15:12:40.000Z",
"source": "API",
"scheduled_shift_id": null,
"created_at": "2026-10-09T00:31:12.000Z",
"updated_at": "2026-10-09T00:31:12.000Z"
}
},
"previous": {
"approval_status": "PENDING"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "timesheet.finalized",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmtsh0000000000000000004",
"user_id": "cmusr0000000000000000012",
"user": {
"id": "cmusr0000000000000000012",
"first_name": "Lena",
"last_name": "Fischer"
},
"period_start": "2026-09-28",
"period_end": "2026-10-11",
"period_type": "BIWEEKLY",
"status": "FINALIZED",
"total_minutes": 4860,
"regular_minutes": 4800,
"overtime_minutes": 60,
"break_minutes": 300,
"paid_leave_minutes": 0,
"holiday_minutes": 0,
"entry_count": 10,
"submitted_at": "2026-10-11T23:40:00.000Z",
"approved_at": "2026-10-12T16:05:00.000Z",
"approved_by_id": "cmusr0000000000000000003",
"finalized_at": "2026-10-12T17:04:11.000Z",
"finalized_by_id": "cmusr0000000000000000002",
"document_id": null,
"created_at": "2026-09-28T07:00:00.000Z",
"updated_at": "2026-10-12T17:04:11.000Z"
}
},
"previous": {
"status": "APPROVED"
}
}
Expenses
Delivered only while expenses are switched on for the organization, with the same rule as time tracking when the module is switched off.
| Event | Fires when | Owner needs |
|---|---|---|
expense_report.submitted | An expense report was submitted. Sent when a report leaves draft. previous.status is the status before submission. | expenses:read |
expense_report.approved | An expense report was approved. Sent when an approver approves a report, or when the organization's auto-approve threshold approves it on submission. | expenses:read |
expense_report.rejected | An expense report was rejected. | expenses:read |
expense_report.paid | An expense report was marked as paid. | expenses:read |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "expense_report.submitted",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmexp0000000000000000042",
"report_number": "EXP-2026-0042",
"title": "Vancouver client workshop",
"description": "Two-day onboarding workshop with the Pacific region team.",
"trip_purpose": "Customer onboarding",
"report_type": "REIMBURSEMENT",
"status": "SUBMITTED",
"departure_date": "2026-09-14",
"return_date": "2026-09-16",
"currency": "CAD",
"total_expenses": 432.6,
"total_per_diems": 112.5,
"total_mileage": 60.48,
"total_tax": 20.6,
"grand_total": 605.58,
"submitted_by": {
"id": "cmusr0000000000000000014",
"first_name": "Lena",
"last_name": "Fischer"
},
"approver": {
"first_name": "Marcus",
"id": "cmusr0000000000000000009",
"last_name": "Okafor"
},
"department_id": "cmdep0000000000000000003",
"project_id": null,
"cost_center": "CC-410",
"is_billable": false,
"submitted_at": "2026-09-17T16:10:05.000Z",
"approved_at": null,
"approver_notes": null,
"rejection_reason": null,
"paid_at": null,
"payment_method": null,
"payment_reference": null,
"created_at": "2026-09-12T18:22:30.000Z",
"updated_at": "2026-09-17T16:10:05.000Z",
"payable_to": null,
"line_items": [
{
"id": "cmeli0000000000000000001",
"date": "2026-09-14",
"description": "Hotel, two nights",
"vendor": "Harbourfront Suites",
"expense_type": "ACCOMMODATION",
"expense_class": "Sales",
"currency": "CAD",
"exchange_rate": 1,
"amount_before_tax": 412,
"gst": 20.6,
"pst": 0,
"hst": 0,
"qst": 0,
"gratuity": 0,
"total": 432.6,
"total_in_base_currency": 432.6,
"receipt_id": "cmerc0000000000000000001",
"notes": null
}
],
"per_diems": [
{
"id": "cmepd0000000000000000001",
"date": "2026-09-15",
"per_diem_type": "FULL_DAY",
"quantity": 1,
"rate": 112.5,
"currency": "CAD",
"gst": 0,
"pst": 0,
"total": 112.5,
"total_in_base_currency": 112.5,
"meal_provided": false,
"notes": null
}
],
"mileage": [
{
"id": "cmeml0000000000000000001",
"date": "2026-09-16",
"description": "Client site visit",
"round_trip": true,
"distance": 84,
"unit": "KILOMETERS",
"rate_per_unit": 0.72,
"currency": "CAD",
"gst": 0,
"total": 60.48,
"total_in_base_currency": 60.48,
"notes": null
}
],
"receipts": [
{
"id": "cmerc0000000000000000001",
"file_name": "harbourfront-folio.pdf",
"mime_type": "application/pdf",
"size_bytes": 184220,
"uploaded_at": "2026-09-17T16:02:41.000Z"
}
]
}
},
"previous": {
"status": "DRAFT"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "expense_report.approved",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmexp0000000000000000042",
"report_number": "EXP-2026-0042",
"title": "Vancouver client workshop",
"description": "Two-day onboarding workshop with the Pacific region team.",
"trip_purpose": "Customer onboarding",
"report_type": "REIMBURSEMENT",
"status": "APPROVED",
"departure_date": "2026-09-14",
"return_date": "2026-09-16",
"currency": "CAD",
"total_expenses": 432.6,
"total_per_diems": 112.5,
"total_mileage": 60.48,
"total_tax": 20.6,
"grand_total": 605.58,
"submitted_by": {
"id": "cmusr0000000000000000014",
"first_name": "Lena",
"last_name": "Fischer"
},
"approver": {
"first_name": "Marcus",
"id": "cmusr0000000000000000009",
"last_name": "Okafor"
},
"department_id": "cmdep0000000000000000003",
"project_id": null,
"cost_center": "CC-410",
"is_billable": false,
"submitted_at": "2026-09-17T16:10:05.000Z",
"approved_at": "2026-09-18T15:41:12.000Z",
"approver_notes": "Within policy.",
"rejection_reason": null,
"paid_at": null,
"payment_method": null,
"payment_reference": null,
"created_at": "2026-09-12T18:22:30.000Z",
"updated_at": "2026-09-18T15:41:12.000Z",
"payable_to": null,
"line_items": [
{
"id": "cmeli0000000000000000001",
"date": "2026-09-14",
"description": "Hotel, two nights",
"vendor": "Harbourfront Suites",
"expense_type": "ACCOMMODATION",
"expense_class": "Sales",
"currency": "CAD",
"exchange_rate": 1,
"amount_before_tax": 412,
"gst": 20.6,
"pst": 0,
"hst": 0,
"qst": 0,
"gratuity": 0,
"total": 432.6,
"total_in_base_currency": 432.6,
"receipt_id": "cmerc0000000000000000001",
"notes": null
}
],
"per_diems": [
{
"id": "cmepd0000000000000000001",
"date": "2026-09-15",
"per_diem_type": "FULL_DAY",
"quantity": 1,
"rate": 112.5,
"currency": "CAD",
"gst": 0,
"pst": 0,
"total": 112.5,
"total_in_base_currency": 112.5,
"meal_provided": false,
"notes": null
}
],
"mileage": [
{
"id": "cmeml0000000000000000001",
"date": "2026-09-16",
"description": "Client site visit",
"round_trip": true,
"distance": 84,
"unit": "KILOMETERS",
"rate_per_unit": 0.72,
"currency": "CAD",
"gst": 0,
"total": 60.48,
"total_in_base_currency": 60.48,
"notes": null
}
],
"receipts": [
{
"id": "cmerc0000000000000000001",
"file_name": "harbourfront-folio.pdf",
"mime_type": "application/pdf",
"size_bytes": 184220,
"uploaded_at": "2026-09-17T16:02:41.000Z"
}
]
}
},
"previous": {
"status": "SUBMITTED"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "expense_report.rejected",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmexp0000000000000000042",
"report_number": "EXP-2026-0042",
"title": "Vancouver client workshop",
"description": "Two-day onboarding workshop with the Pacific region team.",
"trip_purpose": "Customer onboarding",
"report_type": "REIMBURSEMENT",
"status": "REJECTED",
"departure_date": "2026-09-14",
"return_date": "2026-09-16",
"currency": "CAD",
"total_expenses": 432.6,
"total_per_diems": 112.5,
"total_mileage": 60.48,
"total_tax": 20.6,
"grand_total": 605.58,
"submitted_by": {
"id": "cmusr0000000000000000014",
"first_name": "Lena",
"last_name": "Fischer"
},
"approver": {
"first_name": "Marcus",
"id": "cmusr0000000000000000009",
"last_name": "Okafor"
},
"department_id": "cmdep0000000000000000003",
"project_id": null,
"cost_center": "CC-410",
"is_billable": false,
"submitted_at": "2026-09-17T16:10:05.000Z",
"approved_at": null,
"approver_notes": null,
"rejection_reason": "Hotel folio is missing the second night.",
"paid_at": null,
"payment_method": null,
"payment_reference": null,
"created_at": "2026-09-12T18:22:30.000Z",
"updated_at": "2026-09-18T15:41:12.000Z",
"payable_to": null,
"line_items": [
{
"id": "cmeli0000000000000000001",
"date": "2026-09-14",
"description": "Hotel, two nights",
"vendor": "Harbourfront Suites",
"expense_type": "ACCOMMODATION",
"expense_class": "Sales",
"currency": "CAD",
"exchange_rate": 1,
"amount_before_tax": 412,
"gst": 20.6,
"pst": 0,
"hst": 0,
"qst": 0,
"gratuity": 0,
"total": 432.6,
"total_in_base_currency": 432.6,
"receipt_id": "cmerc0000000000000000001",
"notes": null
}
],
"per_diems": [
{
"id": "cmepd0000000000000000001",
"date": "2026-09-15",
"per_diem_type": "FULL_DAY",
"quantity": 1,
"rate": 112.5,
"currency": "CAD",
"gst": 0,
"pst": 0,
"total": 112.5,
"total_in_base_currency": 112.5,
"meal_provided": false,
"notes": null
}
],
"mileage": [
{
"id": "cmeml0000000000000000001",
"date": "2026-09-16",
"description": "Client site visit",
"round_trip": true,
"distance": 84,
"unit": "KILOMETERS",
"rate_per_unit": 0.72,
"currency": "CAD",
"gst": 0,
"total": 60.48,
"total_in_base_currency": 60.48,
"notes": null
}
],
"receipts": [
{
"id": "cmerc0000000000000000001",
"file_name": "harbourfront-folio.pdf",
"mime_type": "application/pdf",
"size_bytes": 184220,
"uploaded_at": "2026-09-17T16:02:41.000Z"
}
]
}
},
"previous": {
"status": "PENDING_APPROVAL"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "expense_report.paid",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmexp0000000000000000042",
"report_number": "EXP-2026-0042",
"title": "Vancouver client workshop",
"description": "Two-day onboarding workshop with the Pacific region team.",
"trip_purpose": "Customer onboarding",
"report_type": "REIMBURSEMENT",
"status": "PAID",
"departure_date": "2026-09-14",
"return_date": "2026-09-16",
"currency": "CAD",
"total_expenses": 432.6,
"total_per_diems": 112.5,
"total_mileage": 60.48,
"total_tax": 20.6,
"grand_total": 605.58,
"submitted_by": {
"id": "cmusr0000000000000000014",
"first_name": "Lena",
"last_name": "Fischer"
},
"approver": {
"first_name": "Marcus",
"id": "cmusr0000000000000000009",
"last_name": "Okafor"
},
"department_id": "cmdep0000000000000000003",
"project_id": null,
"cost_center": "CC-410",
"is_billable": false,
"submitted_at": "2026-09-17T16:10:05.000Z",
"approved_at": "2026-09-18T15:41:12.000Z",
"approver_notes": "Within policy.",
"rejection_reason": null,
"paid_at": "2026-09-25T17:00:00.000Z",
"payment_method": "Direct Deposit",
"payment_reference": "PAY-2026-0918",
"created_at": "2026-09-12T18:22:30.000Z",
"updated_at": "2026-09-25T17:00:00.000Z",
"payable_to": null,
"line_items": [
{
"id": "cmeli0000000000000000001",
"date": "2026-09-14",
"description": "Hotel, two nights",
"vendor": "Harbourfront Suites",
"expense_type": "ACCOMMODATION",
"expense_class": "Sales",
"currency": "CAD",
"exchange_rate": 1,
"amount_before_tax": 412,
"gst": 20.6,
"pst": 0,
"hst": 0,
"qst": 0,
"gratuity": 0,
"total": 432.6,
"total_in_base_currency": 432.6,
"receipt_id": "cmerc0000000000000000001",
"notes": null
}
],
"per_diems": [
{
"id": "cmepd0000000000000000001",
"date": "2026-09-15",
"per_diem_type": "FULL_DAY",
"quantity": 1,
"rate": 112.5,
"currency": "CAD",
"gst": 0,
"pst": 0,
"total": 112.5,
"total_in_base_currency": 112.5,
"meal_provided": false,
"notes": null
}
],
"mileage": [
{
"id": "cmeml0000000000000000001",
"date": "2026-09-16",
"description": "Client site visit",
"round_trip": true,
"distance": 84,
"unit": "KILOMETERS",
"rate_per_unit": 0.72,
"currency": "CAD",
"gst": 0,
"total": 60.48,
"total_in_base_currency": 60.48,
"notes": null
}
],
"receipts": [
{
"id": "cmerc0000000000000000001",
"file_name": "harbourfront-folio.pdf",
"mime_type": "application/pdf",
"size_bytes": 184220,
"uploaded_at": "2026-09-17T16:02:41.000Z"
}
]
}
},
"previous": {
"status": "APPROVED"
}
}
Documents
| Event | Fires when | Owner needs |
|---|---|---|
document.signed | A document assignment was signed. Sent each time a signer signs. signature_status becomes SIGNED once the last signer has signed; previous.signature_status is present when it changed. | documents:read |
document.declined | A document assignment was declined. Sent when a signer declines to sign. | documents:read |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "document.signed",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmdoc0000000000000000007",
"title": "Employment agreement",
"description": "Permanent full-time agreement, Operations.",
"category": "CONTRACT",
"file_name": "employment-agreement.pdf",
"mime_type": "application/pdf",
"size_bytes": 248113,
"version": 1,
"owner": {
"first_name": "Lena",
"id": "cmusr0000000000000000014",
"last_name": "Fischer"
},
"uploaded_by": {
"first_name": "Priya",
"id": "cmusr0000000000000000002",
"last_name": "Raman"
},
"requires_signature": true,
"signature_status": "SIGNED",
"signing_mode": "SEQUENTIAL",
"signature_deadline": "2026-10-01T06:59:59.000Z",
"signed_at": "2026-09-22T17:45:03.000Z",
"signed_by_id": "cmusr0000000000000000014",
"is_private": false,
"is_company_library": false,
"folder_id": null,
"tags": [
"onboarding"
],
"created_at": "2026-09-20T15:00:00.000Z",
"updated_at": "2026-09-22T17:45:03.000Z",
"signers": [
{
"assignment_id": "cmasg0000000000000000011",
"user": {
"first_name": "Priya",
"id": "cmusr0000000000000000002",
"last_name": "Raman"
},
"status": "SIGNED",
"signing_order": 1,
"due_date": "2026-10-01T06:59:59.000Z",
"viewed_at": "2026-09-21T14:12:00.000Z",
"signed_at": "2026-09-21T14:15:27.000Z",
"declined_at": null
},
{
"assignment_id": "cmasg0000000000000000012",
"user": {
"first_name": "Lena",
"id": "cmusr0000000000000000014",
"last_name": "Fischer"
},
"status": "SIGNED",
"signing_order": 2,
"due_date": "2026-10-01T06:59:59.000Z",
"viewed_at": "2026-09-22T17:40:10.000Z",
"signed_at": "2026-09-22T17:45:03.000Z",
"declined_at": null
}
]
}
},
"previous": {
"signature_status": "PENDING"
}
}
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "document.declined",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmdoc0000000000000000007",
"title": "Employment agreement",
"description": "Permanent full-time agreement, Operations.",
"category": "CONTRACT",
"file_name": "employment-agreement.pdf",
"mime_type": "application/pdf",
"size_bytes": 248113,
"version": 1,
"owner": {
"first_name": "Lena",
"id": "cmusr0000000000000000014",
"last_name": "Fischer"
},
"uploaded_by": {
"first_name": "Priya",
"id": "cmusr0000000000000000002",
"last_name": "Raman"
},
"requires_signature": true,
"signature_status": "DECLINED",
"signing_mode": "SEQUENTIAL",
"signature_deadline": "2026-10-01T06:59:59.000Z",
"signed_at": null,
"signed_by_id": null,
"is_private": false,
"is_company_library": false,
"folder_id": null,
"tags": [
"onboarding"
],
"created_at": "2026-09-20T15:00:00.000Z",
"updated_at": "2026-09-22T17:45:03.000Z",
"signers": [
{
"assignment_id": "cmasg0000000000000000011",
"user": {
"first_name": "Priya",
"id": "cmusr0000000000000000002",
"last_name": "Raman"
},
"status": "SIGNED",
"signing_order": 1,
"due_date": "2026-10-01T06:59:59.000Z",
"viewed_at": "2026-09-21T14:12:00.000Z",
"signed_at": "2026-09-21T14:15:27.000Z",
"declined_at": null
},
{
"assignment_id": "cmasg0000000000000000012",
"user": {
"first_name": "Lena",
"id": "cmusr0000000000000000014",
"last_name": "Fischer"
},
"status": "DECLINED",
"signing_order": 2,
"due_date": "2026-10-01T06:59:59.000Z",
"viewed_at": "2026-09-22T17:40:10.000Z",
"signed_at": null,
"declined_at": "2026-09-22T17:45:03.000Z"
}
]
}
},
"previous": {
"signature_status": "PENDING"
}
}
Testing
| Event | Fires when | Owner needs |
|---|---|---|
webhook.test | A test event sent on request to check an endpoint. Sent only when someone chooses "Send test event" or calls POST /webhooks/{id}/test. Use it to check that your endpoint verifies the signature and answers 2xx. | Nothing |
{
"id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ",
"type": "webhook.test",
"api_version": "v1",
"created_at": "2026-10-12T17:04:11.512Z",
"organization_id": "cmorg0000000000000000000",
"data": {
"object": {
"id": "cmwhk0000000000000000000",
"object": "webhook_endpoint",
"message": "A test event, sent on request to check that this endpoint receives and verifies events."
}
}
}
Changes to events
New event types may be added at any time. An endpoint subscribed to Every event starts receiving them automatically, so ignore types you do not recognise. Changing the shape of an existing event's payload follows the same rules as API fields: additions are made in place, and anything breaking would come with a new API version. See Versioning & Changes.
Webhooks Overview
How BookYourPTO webhooks push events to your HTTPS endpoint, who can create and own endpoints, what a payload contains and the limits that apply.
Verifying Signatures
Check that a webhook really came from BookYourPTO and was not replayed, with verification samples in Node.js, Python, PHP, Ruby, Go and C#.