POST to it whenever one of your
sub-accounts changes: a workspace is created, suspended or restored, or a subscription or add-on
changes. These are agency webhooks, separate from the workspace webhooks
that fire on activity inside a workspace.
The events
There are six:
The suspend, restore, plan and add-on events fire whether the change was made in the agency
console or over the Agency API, so one subscription keeps you
in sync with both.
workspace.created is the exception: the console has no create button, so it
fires only from a branded sign-up or from the API.
workspace.created fires only for a brand-new sub-account created by a branded sign-up or by
POST /workspaces. Two other ways a workspace can join your agency do not fire it: an existing
customer adding a second workspace from the workspace switcher, and your own workspace being moved
under your agency when you took a reseller plan. Both appear in your sub-accounts list without a
webhook, so if you must catch every workspace, reconcile periodically against GET /workspaces.
Client workspaces covers all three arrival paths.Setting one up
You can manage webhook endpoints from the agency console, under Reseller Dashboard → Webhooks, or over the API with the/webhooks endpoints in the sidebar. In the console each endpoint’s row
carries Test, Rotate secret, Edit and Remove.
1
Register an endpoint
In the console, select + Add webhook. Add your endpoint URL (it must be publicly reachable
over HTTPS) and subscribe to the events you care about.
2
Store the signing secret
A signing secret is generated for you and returned once, on creation. Store it; you use it
to verify every delivery. If you lose it, select Rotate secret on the endpoint’s row to get
a new one, which invalidates the old one.
3
Send a test
Use the test event to confirm your endpoint is reachable and your signature check works before
relying on it. In the reseller dashboard, select Test on the endpoint’s row. A test payload
carries an extra
"test": true.The payload
Every delivery has the same envelope. Onlydata varies by event:
subscription.changed payload adds the new plan; addon.granted and addon.revoked add an
addon object. Each event page in the sidebar shows its exact payload.
Headers
Verifying a delivery
The signature is an HMAC-SHA256 of the raw request body, keyed by your endpoint’s secret. Compute it over the bytes exactly as received; parsing and re-serialising the JSON first changes the bytes, and the signature will never match.Responding
Return any2xx to acknowledge. A non-2xx (or a timeout) is treated as a failure and retried
twice more, after roughly 10s then 60s (three attempts in total). After the third the
delivery is marked failed and not retried again.
Nothing is lost silently: every attempt is recorded. In the reseller dashboard, open Webhooks
and look under Recent deliveries, which lists the last 30 deliveries across all your endpoints
with columns Webhook, Event, Result and When. Result shows the outcome and the
HTTP status your endpoint returned, for example error · 500. The section only appears once there
has been at least one delivery. Each endpoint’s row also shows its most recent outcome inline, as
last: success or last: error.
One case is never retried. DMLY re-checks your endpoint’s host at delivery time, because DNS can
change between saving the endpoint and sending to it. If that check fails, nothing is sent: the
delivery shows in Recent deliveries as an error with no HTTP status, and no further attempt is
made.

