Suppose I subscribe to the job.updated events webhook. Is there an ID that I can use to ensure that I don’t process the same event twice (in case of retries). Would this be the event.id field?
How reliable would the x-addon-unique-id header be? Can I use it internally for logging and tracing purposes? Or as bases to reject requests that were misconfigured.
How do I find the Account UUID for a ServiceM8 account so that I can make use of x-account-uuid header.
For event webhooks, the event.id field does appear unique, I’ve been using it for the same purpose as you’re asking about and haven’t seen any events with duplicate IDs.
Object webhooks have no such ID field though - They provide the list of changed fields, the record UUID and a timestamp, so you may need to track the last event timestamp for each record to avoid processing events from the past.
I haven’t seen any event or object webhooks come through without the x-account-uuid and x-addon-unique-id headers present. The x-addon-unique-id header is pulled from the unique_id field you initially supplied when creating the webhook subscription.
Short version: for webhook retries, design the endpoint to be idempotent, but we don’t currently have a published guarantee that event.id is the retry-stable dedupe key for job.updated deliveries. For the documented object-style webhook payload, the fields available for correlation are object, entry[0].uuid, entry[0].changed_fields, entry[0].time, and resource_url; event webhook subscriptions for job.updated are supported, but the public subscription reference doesn’t define event.id as the idempotency contract.
Webhook callbacks should return a successful 2xx within 10 seconds, otherwise the delivery is treated as a timeout, and repeated failed deliveries can deactivate the subscription. The Webhooks overview also notes that 4xx/5xx responses are retried for up to 72 hours, and 410 will unsubscribe the webhook. If you return 4xx/5xx to reject a request because it doesn’t match your expected routing, expect retries.
unique_id is documented as an optional identifier for grouping webhook subscriptions and is returned when listing subscriptions. We don’t currently have a public-doc contract for x-addon-unique-id as an authorization or idempotency header, so we’d treat it as routing/diagnostic context rather than the primary security or dedupe mechanism.
For the Account UUID, add-on event data includes auth.accountUUID, and the docs define it as the UUID of the ServiceM8 account which generated the event. The same doc says the Account UUID is always the UUID of the single record returned by the Vendors endpoint, and the REST API has GET /vendor.json, which returns Vendor records with a uuid field and requires the vendor OAuth scope.
Tom’s answer is broadly on the right track, with one important caveat: we don’t currently have a public documented guarantee that event.id is a stable idempotency or retry key, so we’d avoid treating it as the only contract for de-duping.
Event webhook subscriptions are documented for named events such as job.updated, with a callback URL and an optional unique_id for grouping subscriptions. Your callback URL should return a successful 2xx response within 10 seconds, otherwise failures or timeouts can lead to deactivation.
Object webhooks are documented as field-change notifications, and the documented payload includes object, entry[0].uuid, entry[0].changed_fields, entry[0].time, and resource_url, rather than a separate event ID. For object webhook de-dupe, use a composite key from those documented fields and keep your processing idempotent.
unique_id is documented as an optional grouping identifier for webhook subscriptions and is returned when listing subscriptions, so it’s useful for subscription management and logging. We can’t confirm x-addon-unique-id as a documented authentication or request-rejection mechanism, so don’t rely on that header alone as a security control.
For the account UUID, the docs state that auth.accountUUID is the UUID of the single record returned by the Vendors endpoint, and GET /api_1.0/vendor.json returns Vendor account information including uuid.