Outbound Webhooks
API endpoints for managing outbound webhook configurations.
Outbound Webhooks
Outbound webhooks send HTTP requests to your system when events occur in Total Access. Configure endpoints, subscribe to events, and set up authentication and retry policies.
List outbound webhooks
curl -X GET https://totalaccess.co.za/api/v1/work-items/webhooks \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"success": true,
"data": [
{
"id": 42,
"name": "Invoice Sync",
"description": "Syncs invoice events to external system",
"endpoint_url": "https://your-app.com/webhooks/ta",
"http_method": "POST",
"auth_type": "hmac",
"events": ["invoice.created", "invoice.paid"],
"item_type_filter": "invoice",
"item_subtype_filter": null,
"status_filter": null,
"retry_count": 3,
"retry_delay_seconds": 60,
"timeout_seconds": 30,
"is_active": true,
"last_triggered_at": "2026-07-22T14:00:00Z",
"last_success_at": "2026-07-22T14:00:00Z",
"last_failure_at": null,
"success_count": 1230,
"failure_count": 10,
"verification_status": "verified",
"verified_at": "2026-01-15T10:00:00Z",
"payload_version": "latest",
"payload_template": null,
"current_key_version": 1,
"grace_period_ends_at": null,
"dlq_alert_enabled": false,
"dlq_alert_threshold": 10,
"dlq_alert_email": null,
"created_by_user_id": 15,
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-07-22T14:00:00Z"
}
],
"available_events": ["invoice.created", "invoice.paid", "bill.created", ...],
"can_view_all_users": false
}Webhook IDs are numeric integers. The secret_key is masked in list views (first 10 characters shown).
Create outbound webhook
curl -X POST https://totalaccess.co.za/api/v1/work-items/webhooks \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Invoice Sync",
"endpoint_url": "https://your-app.com/webhooks/ta",
"http_method": "POST",
"events": ["invoice.created", "invoice.paid"],
"auth_type": "hmac",
"auth_credentials": null,
"custom_headers": {},
"item_type_filter": "invoice",
"item_subtype_filter": null,
"status_filter": null,
"retry_count": 3,
"retry_delay_seconds": 60,
"timeout_seconds": 30,
"is_active": true,
"require_verification": false,
"payload_version": "latest",
"dlq_alert_enabled": false,
"dlq_alert_threshold": 10
}'Response:
{
"success": true,
"data": {
"id": 43,
"name": "Invoice Sync",
"endpoint_url": "https://your-app.com/webhooks/ta",
"http_method": "POST",
"auth_type": "hmac",
"events": ["invoice.created", "invoice.paid"],
"item_type_filter": "invoice",
"item_subtype_filter": null,
"status_filter": null,
"retry_count": 3,
"retry_delay_seconds": 60,
"timeout_seconds": 30,
"is_active": true,
"verification_status": "verified",
"payload_version": "latest",
"current_key_version": 1,
"created_by_user_id": 15,
"created_at": "2026-07-22T15:00:00Z",
"updated_at": "2026-07-22T15:00:00Z"
},
"secret_key": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6"
}The secret_key is only returned once at creation time. Store it securely — it is needed to verify webhook signatures.
Authentication types
| Type | Header | Description |
|---|---|---|
hmac | X-TotalAccess-Signature: sha256=... | HMAC-SHA256 signature of the raw body (recommended) |
bearer | Authorization: Bearer <token> | Static bearer token in the Authorization header |
basic | Authorization: Basic <base64> | Username and password |
none | — | No authentication (not recommended) |
Always use HMAC authentication for outbound webhooks. The signing secret is generated automatically and shown once at creation time.
Event categories
Events are organized by module and entity type. See the Event Catalog for the complete list.
Finance document events are gated by subscription tier
Events in the Financial category (e.g. invoice.created, quote.paid, credit_note.issued) are filtered by the client's Total Finance subscription tier in the Outbound Webhook Modal. Only events for finance document types included in the client's tier are shown as selectable options when configuring a webhook.
This means if a client's tier does not include credit_note access, the credit_note.created and credit_note.issued events will not appear in the event selection UI. The server-side API still validates these restrictions when a webhook is created or updated.
See Finance Tier Restrictions for the list of gated document types.
Filters
Filters are flat fields on the webhook object (not nested). They restrict which events trigger a webhook delivery:
| Field | Type | Description |
|---|---|---|
item_type_filter | string | null | Only fire for this work item type (e.g. invoice, bill, job) |
item_subtype_filter | string | null | Only fire for this work item subtype |
status_filter | string | null | Only fire for this status (e.g. draft, paid, completed) |
Update outbound webhook
curl -X PATCH https://totalaccess.co.za/api/v1/work-items/webhooks/42 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Name",
"events": ["invoice.created", "invoice.paid", "bill.created"],
"is_active": false,
"item_type_filter": null,
"status_filter": "paid"
}'Delete outbound webhook
curl -X DELETE https://totalaccess.co.za/api/v1/work-items/webhooks/42 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Test an outbound webhook
Send a test event to verify your endpoint is reachable and can process the payload:
curl -X POST https://totalaccess.co.za/api/v1/work-items/webhooks/42/test \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event": "invoice.created",
"data": {
"id": "test_123",
"invoiceNumber": "TEST-001",
"amount": 100.00
}
}'Delivery records
Each delivery attempt is recorded in work_item_webhook_deliveries:
| Field | Description |
|---|---|
id | Delivery record ID |
event_type | Event type that triggered the delivery |
work_item_id | ID of the work item that triggered the event |
response_status | HTTP status code received (or null if failed) |
status | success, failed, pending, retrying |
error_message | Error details if failed |
duration_ms | Response time in milliseconds |
attempt_number | Which attempt (1-5) |
created_at | When the delivery was created |
delivered_at | Timestamp of the attempt |
See Webhook Logs for the logs API.