The secret webhook signatures are made with
Shown so you can configure a verifier. Compare x-tone-signature against an HMAC-SHA256 of {timestamp}.{raw body} — the RAW body, before any JSON parsing.
Requires the admin scope. A key with less gets 403 insufficient_scope.
Authorization: Bearer tone_live_… or tone_test_…. The prefix IS the environment: a test key reaches only the sandbox, and no request field bridges the two.
In: header
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/integrations/webhooks/signing-secret"{ "data": { "note": "Signs every delivery to this endpoint as x-tone-signature.", "secret": "whsec_3f1a7f6e2b4c4d1e9a8b5c6d7e8f9a0b" }}Rotate the signing secret (old one keeps verifying for 24h)
🔴 During the overlap x-tone-signature carries SEVERAL space-delimited signatures, and a verifier that treats the header as one string starts rejecting everything. Accept the delivery if ANY of them matches. Deploy the new secret within the 24 hours.
Update a webhook endpoint
Change the URL, the subscribed events, or disable it. Disabling stops delivery without losing the endpoint, its secret or its history.