Cosmovex Tools

Twilio signature validation failing? Capture the SMS webhook and check X-Twilio-Signature

Twilio SMS with Hookwatch Webhook Tester

This inbox is set up for a Twilio phone number's incoming-message webhook. Text the number and the form post appears here with From, To, Body, MessageSid and every other parameter, plus X-Twilio-Signature. The Signature tab rebuilds Twilio's string, the full URL followed by the sorted parameters, and checks it with your Auth Token, so a URL mismatch is visible at a glance.

  1. Copy the inbox URL. It ends in /twilio/sms, and that full URL, including any query string, is part of what Twilio signs.
  2. In the Twilio Console open your number's Messaging Configuration and paste the URL under A message comes in, method HTTP POST. Status callbacks for outgoing messages can use the same URL.
  3. Send a text to the number, or press Send a signed test Twilio SMS here to see a known-good form post signed with the demo Auth Token.
  4. Select the request. The Body tab lists the form fields; the Signature tab shows the URL it signs with, prefilled with this inbox URL.
  5. Paste your Auth Token. If it is Invalid, edit the URL field until it is byte-for-byte what you configured in the Console; whatever makes it Valid is the URL your server must validate against.
twilio signature validation twilio webhook testertwilio signature validation failedx-twilio-signature validationtwilio sms webhook payloadtwilio incoming message webhook
Open Hookwatch Webhook Tester Free · Pro $5/mo · no account

What to know

Twilio does not sign the raw body the way most providers do. For a form POST it takes the full URL it requested, including scheme, host, path and query string, then appends every POST parameter sorted alphabetically by name, each name immediately followed by its value with no separators. It computes HMAC-SHA1 of that string with your account's Auth Token and sends the base64 result in X-Twilio-Signature. For JSON requests the URL carries a bodySHA256 query parameter instead, and the tool checks that hash against the body too.

Almost every "signature validation failed" report is a URL mismatch. Behind a load balancer or proxy your app often sees http:// instead of https://, an internal host name, a different port or a path without its prefix, and validates against that instead of the public URL Twilio called. Rebuild the URL from the configured public address, or from X-Forwarded-Proto and the Host header, and pass the full set of POST parameters, unmodified, to the helper library's validator. Whitespace trimming or dropping empty parameters also breaks the match.

Use the Auth Token, not an API key secret: requests are signed with the primary Auth Token of the account that owns the number, and a subaccount’s numbers are signed with that subaccount’s own token. After rotating the token, update every server that validates. Twilio expects TwiML in reply to an incoming message. The free inbox answers 200 with a JSON body, so the Console debugger logs error 12300 (Invalid Content-Type) for these test deliveries; the request is still captured. A Pro inbox can return text/xml with an empty <Response/> instead.

The SMS payload gives you what a reply handler needs: From and To in E.164 format, Body, NumMedia with MediaUrl0… for MMS, NumSegments, MessageSid and AccountSid. Keywords such as STOP, START and HELP are handled by Twilio's opt-out management on long codes before your logic runs, but the inbound message still reaches the webhook, so do not treat a STOP body as a normal reply.

Updated · Cosmovex

Questions

Why does Twilio signature validation fail when the token is right?

Because the URL you validate against differs from the URL Twilio called: http instead of https, a missing query string, an internal host or port, or a path stripped by a proxy. Paste your token in the Signature tab and adjust the URL field until it shows Valid; use exactly that URL in your server.

Which secret does Twilio use to sign webhooks?

The Auth Token of the account or subaccount that owns the phone number, from Console → Account → API keys & tokens. API key secrets are not used for request signing.

What is error 12300 in the Twilio debugger?

Twilio expected TwiML (XML) in the response and received another content type. This inbox replies with JSON on the free plan, so test deliveries log 12300, but the message is still captured here. A Pro inbox can be set to answer text/xml with <Response/>.

Does Twilio sign JSON webhooks the same way?

For JSON bodies Twilio adds a bodySHA256 parameter to the URL, signs the URL alone, and you check that the body hashes to bodySHA256. The tool runs both checks when the parameter is present.

Is my Auth Token sent to your server?

No. The HMAC-SHA1 is computed in your browser with WebCrypto. The Auth Token can also call the Twilio API, so it stays in this browser's storage only; use Forget to clear it.

The free plan covers everything on this page. Hookwatch Webhook Tester Pro ($5/mo, billed monthly) is described on the Hookwatch Webhook Tester page.