Total Access Docs
Webhooks

Event Catalog

Complete list of all webhook events with payload examples.

Event Catalog

All events that can trigger outbound webhooks, organized by category.

User events

EventTriggerKey Fields
user.createdNew user registereduser_id, email, first_name, last_name, role
user.loginUser signs inuser_id, email, ip_address, device_type, session_id
user.logoutUser signs outuser_id, email, session_id, session_duration_seconds
user.updatedUser profile updateduser_id, email, changes (field diff)
user.password_reset_requestedPassword reset requesteduser_id, email, reset_token_expires_at
user.password_changedPassword changeduser_id, email, changed_by
user.deactivatedUser deactivateduser_id, email, deactivated_by, reason
user.reactivatedUser reactivateduser_id, email, reactivated_by

Example payload — user.created

{
  "event": "user.created",
  "timestamp": "2026-07-22T12:00:00Z",
  "data": {
    "user_id": 123,
    "email": "[email protected]",
    "first_name": "John",
    "last_name": "Doe",
    "display_name": "John Doe",
    "role": "user",
    "is_active": true,
    "created_at": "2026-07-22T12:00:00Z",
    "created_by": 1
  }
}

Employee events

EventTriggerKey Fields
employee.createdNew employee addedemployee_id, employee_number, department, job_title
employee.onboardedEmployee onboarding completedemployee_id, user_id, onboarding_status
employee.linked_to_userEmployee linked to a user accountemployee_id, user_id, email
employee.certification_expiringCertification nearing expiryemployee_id, certification_type, expiry_date, days_until_expiry

Job events

EventTriggerKey Fields
job.createdNew job createdjob_id, item_number, title, status, priority, customer_name, assigned_to
job.assignedJob assigned to a userjob_id, assigned_to, assigned_by, previous_assignee
job.startedJob startedjob_id, status, started_by, started_at, location
job.completedJob completedjob_id, status, completed_by, actual_hours, signature_captured
job.cancelledJob cancelledjob_id, cancelled_by, cancellation_reason

Example payload — job.completed

{
  "event": "job.completed",
  "timestamp": "2026-07-22T14:30:00Z",
  "data": {
    "job_id": "job_550e8400",
    "item_number": "JOB-2026-0001",
    "title": "HVAC Installation - Building A",
    "status": "completed",
    "completed_by": "user_456",
    "completed_at": "2026-07-22T14:30:00Z",
    "actual_hours": 7.5,
    "completion_notes": "Installation successful. All units tested.",
    "signature_captured": true,
    "photos_attached": 3
  }
}

Project events

EventTriggerKey Fields
project.createdNew project createdproject_id, item_number, title, status, budget, project_manager
project.milestone_reachedProject milestone reachedproject_id, milestone_name, completion_percentage
project.status_changedProject status changedproject_id, previous_status, new_status, changed_by
project.completedProject completedproject_id, final_cost, budget_variance, total_tasks

Task events

EventTriggerKey Fields
task.createdNew task createdtask_id, item_number, title, parent_id, parent_type, assigned_to
task.completedTask completedtask_id, completed_by, actual_hours

Appointment events

EventTriggerKey Fields
appointment.createdNew appointment scheduledid, item_number, title, scheduled_start, scheduled_end, contact_name, location_name, location_address, location_id
appointment.scheduledAppointment scheduled (from job)id, item_number, title, scheduled_start, scheduled_end, contact_name, location_name, location_address, location_id
appointment.on_routeTechnician en route to appointmentappointment, old_status, new_status, location (lat/lng)
appointment.on_siteTechnician arrived on siteappointment, old_status, new_status, location (lat/lng)
appointment.checked_inTechnician checked inappointment, old_status, new_status, location (lat/lng)
appointment.completedAppointment completedappointment, old_status, new_status, location (lat/lng)
appointment.cancelledAppointment cancelledappointment, old_status, new_status

Appointment payloads include location fields resolved from the work item's location_id (referencing ta_locations) or the location_name/location_address stored directly on the work item. The appointment object in the payload is enriched with location_name, location_address, location_lat, and location_lng at dispatch time.

Example payload — appointment.created

{
  "event": "appointment.created",
  "timestamp": "2026-07-22T09:00:00Z",
  "data": {
    "id": "apt_550e8400",
    "item_number": "APT-2026-0001",
    "title": "Service Call - HVAC Unit 3",
    "scheduled_start": "2026-07-22T10:00:00Z",
    "scheduled_end": "2026-07-22T11:00:00Z",
    "assigned_to": 456,
    "contact_name": "Acme Corporation",
    "location_name": "Building A - Server Room",
    "location_address": "123 Industrial Road, Johannesburg",
    "location_id": 42,
    "status": "scheduled",
    "parent_job_id": "job_abc123"
  },
  "metadata": {
    "item_type": "appointment",
    "item_id": "apt_550e8400",
    "user_id": 1,
    "client_id": 5,
    "client_name": "Facility Services Ltd"
  }
}

Route & delivery events

EventTriggerKey Fields
route.createdNew route createdroute_id, driver_name, vehicle_registration, total_stops, total_distance_km
route.startedRoute startedroute_id, started_at, driver_location, odometer_start
route.stop_completedRoute stop completedroute_id, stop_number, customer_name, proof_of_delivery, remaining_stops
route.completedRoute completedroute_id, total_stops_completed, actual_distance_km, duration_hours
delivery.completedDelivery completeddelivery_id, customer_name, delivered_by, proof_of_delivery, items_delivered

Purchase order events

EventTriggerKey Fields
purchase_order.createdNew purchase order createdpurchase_order_id, supplier_name, grand_total, line_items
purchase_order.approvedPurchase order approvedpurchase_order_id, approved_by, grand_total
purchase_order.receivedPurchase order received (GRN)purchase_order_id, grn_number, items_received, warehouse

Financial document events

Events for finance documents (invoices, quotes, credit notes, etc.) follow the pattern {doc_type}.{action}. The available events depend on the document types included in the client's Total Finance subscription tier.

EventTriggerKey Fields
invoice.createdInvoice createdinvoice_id, invoice_number, contact_name, grand_total, status
invoice.updatedInvoice updatedinvoice_id, changes (field diff)
invoice.paidInvoice marked as paidinvoice_id, paid_amount, payment_method, paid_at
invoice.voidedInvoice voidedinvoice_id, voided_by, reason
quote.createdQuote createdquote_id, quote_number, contact_name, grand_total, valid_until
quote.updatedQuote updatedquote_id, changes (field diff)
quote.acceptedQuote accepted by customerquote_id, accepted_by, accepted_at
quote.expiredQuote expiredquote_id, expired_at, valid_until
quote.convertedQuote converted to invoicequote_id, new_invoice_id
credit_note.createdCredit note createdcredit_note_id, credit_note_number, contact_name, grand_total, linked_invoice_id
credit_note.updatedCredit note updatedcredit_note_id, changes (field diff)
credit_note.appliedCredit note applied to invoicecredit_note_id, applied_to_invoice_id, applied_amount
purchase_order.createdPurchase order createdpurchase_order_id, supplier_name, grand_total, line_items
purchase_order.approvedPurchase order approvedpurchase_order_id, approved_by, grand_total
delivery_note.createdDelivery note createddelivery_note_id, delivery_note_number, contact_name, linked_invoice_id
proforma.createdProforma invoice createdproforma_id, proforma_number, contact_name, grand_total
sales_order.createdSales order createdsales_order_id, sales_order_number, contact_name, grand_total
supplier_invoice.createdSupplier invoice createdsupplier_invoice_id, supplier_name, grand_total
supplier_quote.createdSupplier quote createdsupplier_quote_id, supplier_name, grand_total, valid_until
expense.createdExpense createdexpense_id, expense_number, supplier_name, amount, category

Tier-filtered events

The financial document events visible in the Outbound Webhook Modal are filtered by the client's Total Finance subscription tier. Only events for document types included in the client's tier are shown. See Finance Tier Restrictions for details.

Example payload — invoice.created

{
  "event": "invoice.created",
  "timestamp": "2026-07-27T10:00:00Z",
  "data": {
    "invoice_id": "550e8400-e29b-41d4-a716-446655440000",
    "invoice_number": "INV-2026-0042",
    "contact_name": "Acme Corporation",
    "contact_id": 123,
    "grand_total": 15750.00,
    "currency": "ZAR",
    "status": "draft",
    "issue_date": "2026-07-27",
    "due_date": "2026-08-26",
    "line_items": [
      {
        "description": "Consulting services — July",
        "quantity": 15,
        "unit_price": 1050.00,
        "line_total": 15750.00
      }
    ]
  },
  "metadata": {
    "item_type": "invoice",
    "item_id": "550e8400-e29b-41d4-a716-446655440000",
    "user_id": 15,
    "client_id": 5,
    "client_name": "Facility Services Ltd"
  }
}

Compliance & audit events

EventTriggerKey Fields
audit.createdNew audit scheduledaudit_id, audit_type, auditor_name, scheduled_date
audit.completedAudit completedaudit_id, score, max_score, pass_fail, findings
incident.reportedIncident reportedincident_id, incident_type, severity, location, injuries
incident.resolvedIncident resolvedincident_id, resolution, root_cause, preventive_measures
inspection.completedInspection completedinspection_id, inspection_type, pass_fail, checklist_completed
certification.expiringCertification nearing expirycertification_id, holder_name, certification_type, days_until_expiry

Contact events

EventTriggerKey Fields
contact.createdNew contact createdcontact_id, contact_type, name, email, phone, tax_number
contact.updatedContact updatedcontact_id, changes (field diff)
contact.deletedContact deletedcontact_id, name, account_number
contact.status_changedContact status changedcontact_id, old_status, new_status, reason
contact_person.createdContact person addedcontact_person_id, contact_id, first_name, last_name, job_title
contact_person.updatedContact person updatedcontact_person_id, contact_id, changes
contact_person.deletedContact person deletedcontact_person_id, contact_id
contact_location.createdContact location addedlocation_id, contact_id, location_type, address, latitude, longitude
contact_location.updatedContact location updatedlocation_id, contact_id, changes
contact_location.deletedContact location deletedlocation_id, contact_id
contact_document.linkedDocument linked to contactcontact_id, work_item_id, item_type, item_number

Generic work item events

EventTriggerKey Fields
work_item.createdGeneric work item createdwork_item_id, item_number, item_type, title, status
work_item.updatedGeneric work item updatedwork_item_id, item_type, changes (field diff)
work_item.deletedGeneric work item deletedwork_item_id, item_type, deleted_by
work_item.comment_addedComment added to a work itemwork_item, comment (id, comment_text, is_internal, comment_type, user_id, user_name)
work_item.comment_updatedComment edited on a work itemwork_item, comment, changes (field diff)
work_item.comment_deletedComment soft-deleted from a work itemwork_item, comment (id, comment_text, comment_type, user_id, user_name)
work_item.comment_visibility_changedComment visibility toggled (internal ↔ public)work_item, comment, old_visibility (is_internal, comment_type), new_visibility (is_internal, comment_type)

The generic work_item.* events fire for custom work item types that don't have a specific event category (e.g. job.*, task.*).

Example payload — work_item.comment_added

{
  "event": "work_item.comment_added",
  "timestamp": "2026-07-27T08:00:00Z",
  "data": {
    "work_item": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "item_number": "JOB-2026-0001",
      "item_type": "job",
      "title": "HVAC Installation - Building A"
    },
    "comment": {
      "id": "c1a2b3c4-d5e6-7890-abcd-ef0123456789",
      "comment_text": "Unit 3 filter replaced, airflow restored.",
      "is_internal": false,
      "comment_type": "external",
      "user_id": 456,
      "user_name": "Jane Smith",
      "created_at": "2026-07-27T08:00:00Z"
    }
  }
}

Example payload — work_item.comment_visibility_changed

{
  "event": "work_item.comment_visibility_changed",
  "timestamp": "2026-07-27T08:05:00Z",
  "data": {
    "work_item": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "item_number": "JOB-2026-0001",
      "item_type": "job"
    },
    "comment": {
      "id": "c1a2b3c4-d5e6-7890-abcd-ef0123456789",
      "comment_text": "Internal note about customer complaint.",
      "is_internal": true,
      "comment_type": "internal"
    },
    "old_visibility": {
      "is_internal": false,
      "comment_type": "external"
    },
    "new_visibility": {
      "is_internal": true,
      "comment_type": "internal"
    }
  }
}

Payload envelope

All events use the same envelope format:

{
  "event": "<event_type>",
  "timestamp": "<ISO 8601>",
  "data": { ... }
}

The data object contains event-specific fields. See each event category above for the key fields included.

On this page