Inbound webhooks verified against whichever account owns the number

Carrier webhooks are signed by the account the message was delivered to, so verification tries the parent account and then the subaccount that actually owns the number.

What it is

HMAC-SHA1 verification over the full public request URL plus every POST parameter sorted by key, compared in constant time. The URL is reconstructed from the proxy's forwarded headers, not from the raw request URL. If the parent token fails and the payload names a different account, the owning account is looked up and its token is tried.

Also called: 11200 error · webhook signature · inbound text rejected · 403 from carrier

See it
Inbound webhooks verified against whichever account owns the number
Area
Integrations
Group
Twilio
System
Twilio
Solves
2 named problems
01The receiver rebuilds the URL from x-forwarded-proto and x-forwarded-host.
02It verifies against the platform token first.
03On failure, the AccountSid on the payload is used to find the owning account's binding.
A verification flow: signature → parent token (fail) → look up account by SID → subaccount token (pass) → message stored. Sample data — no customer information appears here.
How it works
  1. 1The receiver rebuilds the URL from x-forwarded-proto and x-forwarded-host.
  2. 2It verifies against the platform token first.
  3. 3On failure, the AccountSid on the payload is used to find the owning account's binding.
  4. 4That account's decrypted token is used for a second verification.
  5. 5An unknown account, or one with no stored credentials, is refused with a 403.
Why we built it

Recorded on the SMS receiver (Keith 08-14): 'This verified against the PLATFORM token only. Tenant numbers live on their own subaccounts, and Twilio signs with the token of the account the message was delivered to — so every inbound text to a subaccount number was rejected, Twilio logged 11200, and the message never reached the thread. Silently: the sender saw it send fine.' The proxy caveat is called out as 'the classic reason a correct implementation still rejects every request'.

The problem
  • Every inbound message to an isolated account's number was rejected.
  • Reconstructing the URL from the internal origin broke verification behind a proxy.
Sound familiar?
What you get
Replies arrive regardless of which account owns the number.
Forged requests are still refused, in constant time.
What's inside

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →