Webhooks tell your system the moment something changes in Avaza, so it doesn't have to keep asking. For example, subscribe to invoice_sent and Avaza posts to your web page whenever an invoice is sent, or marked as sent.
You manage subscriptions through the API, with a personal access token or an OAuth app. See getting started with the Avaza API.
Before you start
- Scopes: the token or app needs
webhook_notifications, plus the read scope for the records you want to hear about (see the table below). The matching write scope works too. - Roles: Administrators can see and manage every subscription in the account. Finance Managers, Portfolio Managers, Project Managers, Project Collaborators and Timesheet/Expense Users can manage their own. Other roles can't use the webhook endpoints.
- An endpoint: a web address that accepts POST requests. It must be an
httporhttpsURL on a public address, not a local or private network. Usehttps.
Subscribe to an event
Post the event and your address to https://api.avaza.com/api/Webhook. Each subscription covers one event, so subscribe once per event.
curl -X POST https://api.avaza.com/api/Webhook \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"target_url": "https://yourapp.example.com/avaza-webhook", "event": "timesheet_created", "secret": "YOUR_WEBHOOK_SECRET"}'secret is optional, up to 255 characters (see below). Avaza answers 201 with the new subscription's ID, for example {"ID": 10}. If the same app already has that event on that address, you get 409 instead.
Events
Records | Events | Scope |
|---|---|---|
Companies (customers) |
|
|
Contacts |
|
|
Team members |
|
|
Projects |
|
|
Tasks |
|
|
Timesheets |
|
|
Expenses |
|
|
Schedule bookings |
|
|
Invoices |
|
|
Estimates |
|
|
Bills |
|
|
To ask for another event, contact Avaza support.
You only receive notifications about records your user can see. Administrators receive everything. A Timesheet/Expense User only hears about their own timesheets and expenses. Team member events go to Administrators only, and invoice, estimate and bill events to Administrators and Finance Managers.
Changes made in the Avaza web app and through the Avaza MCP Server send webhooks. Changes you make through the API only send them if the request includes "SendWebhooks": true, so your integration doesn't hear its own changes back.
Handle a notification
Avaza posts a JSON array with one item: a snapshot of the record at the moment of the event, plus four fields that identify the notification. Here is a timesheet_created notification:
[
{
"TimeSheetEntryID": 18528,
"Duration": 4.0,
"EntryDate": "2026-09-14T00:00:00Z",
"UserIDFK": 93,
"ProjectIDFK": 137,
"TimeSheetCategoryIDFK": 21,
"Notes": "Drafted the launch email",
"TimeSheetEntryApprovalStatusCode": "Draft",
"isBillable": true,
"isInvoiced": false,
"DateCreated": "2026-09-14T05:25:36Z",
"DateUpdated": "2026-09-14T05:25:36Z",
"WebhookNotificationItemID": 552301,
"SubscriptionID": 10,
"EventCode": "timesheet_created",
"AccountID": 4521
}
]Each event has its own fields. The _deleted events carry only the IDs, because the record is gone. To see the exact format of an event, point a test subscription at a free service such as Webhook.site.
- Answer with a 2xx status, such as 200, as soon as you've stored the notification. Do the slow work afterwards.
- Check the secret. If you set one, every notification has the header
Authorization: Basicfollowed by your secret in Base64. Reject posts without it. - Answer 410 Gone to unsubscribe. Avaza then deletes that subscription.
Retries
If your endpoint doesn't answer with a 2xx status, Avaza tries again with growing gaps: after about 10 minutes, then 30 minutes, 90 minutes, 190 minutes and so on. Retries go out every 15 minutes, so each gap can be up to 15 minutes longer. After 14 retries, about 11 days, Avaza drops the notification.
A retry sends the same snapshot with the same WebhookNotificationItemID, so use that ID to skip duplicates. The snapshot shows the record as it was when the event happened, not as it is now.
List and delete subscriptions
Call | What it does |
|---|---|
| Lists subscriptions: every one in the account for Administrators, your own for everyone else |
| Gets one subscription |
| Deletes a subscription by its ID |
| Deletes the subscriptions for an address |
You can only delete subscriptions that were created with the same app or personal access token, and only your own unless you're an Administrator. A delete answers 200 even if nothing matched, so list the subscriptions afterwards to check.