Integration
ServiceM8 webhooks: the event list, how to subscribe, and one example
ServiceM8 offers 25 webhook events, from job.created to job.invoice_paid, plus field level object webhooks. You subscribe by POSTing to api.servicem8.com/webhook_subscriptions/event with an OAuth token from a ServiceM8 public app. Your callback URL must return a 2xx within 10 seconds, or repeated failures can switch the subscription off.
Last checked 25 Sep 2026 against the sources listed at the end of this page.
What syncs, and when
| What | Direction | When | Notes |
|---|---|---|---|
| Job lifecycle | ServiceM8 to your callback URL | job.created, job.updated, job.status_changed, job.queued, job.completed | job.status_changed covers every status move; job.completed fires when a job is marked Completed. |
| Sales and money | ServiceM8 to your callback URL | job.quote_sent, job.quote_accepted, job.invoice_sent, job.invoice_paid, proposal.sent, proposal.viewed | job.invoice_paid means full payment was received. |
| Field work | ServiceM8 to your callback URL | job.checked_in, job.checked_out, job.note_added, job.photo_added, job.video_added, job.badge_added, job.badge_removed, form.response_created | Check in and check out are the staff member arriving at and leaving the site. |
| Customers and inbox | ServiceM8 to your callback URL | company.created, company.updated, inbox.message_received, job.review_received | company is ServiceM8's API name for a client. |
| Staff | ServiceM8 to your callback URL | staff.clocked_on, staff.clocked_off | Shift start and end. |
| Object (field) webhooks | ServiceM8 to your callback URL | POST /webhook_subscriptions/object with an object (for example job) and a comma separated list of fields | Fires when any listed field changes. The add-on version sends the record UUID, changed_fields, a UTC time and a resource_url. |
What does not sync
- The full record. A field webhook tells you what changed and where to fetch it (resource_url); you read the record from the REST API yourself.
- Webhooks for a plain API key integration. ServiceM8 lists webhooks as a benefit of public applications that use OAuth 2.0.
- A published signature scheme for REST webhook subscriptions. ServiceM8 documents HMAC SHA 256 signed JWTs for add-on callbacks, but its webhook subscription reference does not describe one.
- Unlimited retries. Repeated failed or slow deliveries can deactivate the subscription, so check it is still active if events stop.
Set it up
- Register as a ServiceM8 development partner and create an add-on to get an App ID and App Secret. You do not have to list it publicly.
- Implement OAuth 2.0: send the account owner to go.servicem8.com/oauth/authorize with the scopes you need, then exchange the code at go.servicem8.com/oauth/access_token. Access tokens last 3600 seconds, so store the refresh token.
- Stand up an HTTPS callback URL that returns 200 straight away and puts the payload on a queue. Do the real work after responding, because anything over 10 seconds counts as a timeout.
- Subscribe: POST to https://api.servicem8.com/webhook_subscriptions/event, form encoded, with event=job.completed and callback_url set to your endpoint. Add unique_id if you want to group subscriptions.
- For add-on callbacks, verify the JWT in the request body with your App Secret (HMAC SHA 256) before trusting it.
- Whatever arrives, re-read the job from the REST API with your own token before acting, so a forged or stale message cannot change anything.
- Complete a test job in a trial account, confirm your endpoint logged it, and alert yourself if no events arrive for a working day.
Two kinds of webhook
ServiceM8 has event webhooks and object webhooks. Event webhooks are business moments with names: a quote was accepted, an invoice was paid, a technician checked in. There are 25 of them, and they suit most automations because the name already says what happened.
Object webhooks watch fields. You name an object type such as job and a list of fields such as status or job_address, and ServiceM8 calls you when any of them change. Use these when there is no event for what you care about, and subscribe to as few fields as you can: ServiceM8's manifest guidance warns that every change invokes your add-on.
A working example: completed job to a spreadsheet
Say the office wants a row in a Google Sheet every time a job is completed, with the job number, client and total. Subscribe to job.completed with your callback URL. When a technician marks the job Completed, ServiceM8 POSTs to your endpoint. Your code returns 200 at once, then in the background uses its OAuth token to read the job from the REST API, looks up the client, and appends the row.
The re-read matters. It gives you current data rather than whatever was in the message, it keeps working if ServiceM8 adds fields to the payload, and it means a request from anyone other than ServiceM8 achieves nothing, because your code only trusts what the API returns. Log the job UUID you processed, so a repeated delivery does not add the row twice.
Verifying payloads
For add-on callbacks, ServiceM8 sends the event as a JSON Web Token in the request body, signed with HMAC SHA 256 using your add-on's App Secret, which only you and ServiceM8 know. Verify that signature before you read anything from it, and keep the App Secret out of code repositories. ServiceM8 warns that anyone with it can impersonate your app.
The REST webhook subscription reference only describes the callback's response rules, so design as if the message could be forged: HTTPS only, a hard to guess callback path, and an API re-read before any write.
Sources
- ServiceM8's event webhook subscription endpoint (POST https://api.servicem8.com/webhook_subscriptions/event, form encoded, with event, callback_url and optional unique_id) supports 25 events including job.created, job.completed, job.status_changed, job.quote_accepted, job.invoice_sent, job.invoice_paid, job.checked_in, form.response_created, inbox.message_received, job.review_received, proposal.viewed and staff.clocked_on. ServiceM8 Developer Documentation, checked 25 Sep 2026.
- The callback URL must return a successful 2xx response within 10 seconds; longer requests are treated as timeouts, and repeated failed deliveries, including timeouts, can cause the subscription to be automatically deactivated. ServiceM8 Developer Documentation, checked 25 Sep 2026.
- Object webhook subscriptions (POST /webhook_subscriptions/object) take an object type, a comma separated list of fields and a callback URL, and send a webhook when any of those fields change. ServiceM8 Developer Documentation, checked 25 Sep 2026.
- Webhook event data for add-ons includes the object type, the record UUID, changed_fields, a UTC time and a resource_url where the full record can be retrieved. ServiceM8 Developer Documentation, checked 25 Sep 2026.
- Web service add-on callbacks receive a JWT in the request body, signed with HMAC SHA 256 using the add-on's App Secret. ServiceM8 Developer Documentation, checked 25 Sep 2026.
- Webhooks are listed as a benefit of public applications using OAuth 2.0; public applications do not have to be listed on the add-on store; OAuth access tokens last 3600 seconds, and the App Secret must be kept secret. ServiceM8 Developer Documentation, checked 25 Sep 2026.
- ServiceM8 advises subscribing to the minimal object and field combination, as each change invokes the add-on. ServiceM8 Developer Documentation, checked 25 Sep 2026.