When Someone Calls You Back
Module 6 of 7 in the chapter Salesforce as an API Provider, chapter 8 of the Integration Architect course. Each module stands on its own. Previous: Your Own Door: Custom Apex REST · Next: Who’s at the Door
The question this module answers: When another system wants to tell Salesforce that something happened, by calling a webhook, where does that call land, and what has to be checked before you trust it?
In chapter 2, a delivery’s status changed and Salesforce called Redrock’s webhook. Salesforce was the client; Redrock’s webhook was the server, waiting to be told. That’s the easy direction. Salesforce makes outbound calls all day.
Now turn it around. Say Steve Trucking’s SMS provider texts a recipient that their delivery is on the way, and calls back a few seconds later to say whether the text arrived. The provider is the client now. It wants to call you, at an address you gave it, whenever something happens. That’s a webhook coming in.
Salesforce Has No Front Desk for This
Section titled “Salesforce Has No Front Desk for This”A webhook is just an HTTP POST to an address, usually with a JSON body. The sender doesn’t wait for a long answer; it wants a quick yes, and it will try again later if it doesn’t get one.
Salesforce has no built-in place to receive one. There’s no setting where you paste in “accept webhooks from the SMS provider.” Every door from module 1 that a program uses expects a token from the token server, and most webhook senders don’t sign in with OAuth. They send a secret-signed message to an address, and that’s all.
So you build the receiving end, and there are three places to build it.
Three Ways In
Section titled “Three Ways In”1. The integration layer receives it, then calls in. The webhook lands on your middleware, which is built to receive calls from the internet. It checks the message, and then calls Salesforce through a normal door with a normal token: a REST upsert, or your own Apex REST door from module 5. Salesforce never faces the sender. This is the first choice whenever you have an integration layer, and it’s how Steve Trucking handles the SMS provider.
2. The integration layer publishes a platform event. The same as the first, except the middleware doesn’t write the records itself. It publishes an event into Salesforce, through the REST API or the Pub/Sub API, and a flow or trigger inside Salesforce takes it from there (chapter 4 built one in Flow; chapter 11 goes deep). Good when several things inside Salesforce care about the same news, or when you want the work done after the webhook has already been answered.
3. Your own door, open to the internet. No middleware: an Apex REST service on a Salesforce Site, reachable without signing in, as the site’s guest user. It works, and for a small org without an integration layer it can be the only option. But look at what it is. It’s a public door, like the web forms in module 1, except this one runs your code. Everything that keeps it safe is now in that code, and the guest user must be able to do almost nothing. Chapter 13 covers guest users and why one should have almost no access. If you choose this, choose it on purpose and write down why.
Three ways in. Only one of them has Salesforce facing the internet.
Four Things Every Receiver Checks
Section titled “Four Things Every Receiver Checks”Whichever way in, the receiver does four things. Many webhook senders follow a common shape for them, written down as the Standard Webhooks specification, a community spec rather than an IETF standard (Standard Webhooks (opens in a new tab), checked 2026-10-31). Your sender may name its headers differently; the four checks are the same.
1. Is it really from them? Check the signature. You and the sender share a secret. The sender signs each message, and you sign it again on your side and compare. In the Standard Webhooks shape, the signature covers the message’s ID, its time and its body together, joined with dots: msg_id.timestamp.payload. Anyone can find your address. Only the sender has the secret. A message whose signature doesn’t match is thrown away, whatever it says. (In Apex, Crypto.generateMac does the signing; chapter 13 covers keeping the secret.)
2. Is it fresh? Check the time. A signed message can be copied and sent again, word for word, and its signature still matches. So the time is signed too, and the receiver rejects anything outside a short window. The spec’s words: verify the timestamp is “within some allowable tolerance of the current timestamp to prevent replay attacks.” Pick the window, a few minutes, and write it down.
3. Have I seen it before? Check the ID. Senders retry. If your answer was slow, or lost on the way back, the same webhook comes again, and the ID “remains the same no matter how many times a webhook that has failed is retried” (same spec). Keep the IDs you’ve processed, and when one comes back, answer yes and do nothing. Otherwise one text that arrived becomes two delivery notes. It’s the same idea as module 2’s upsert by key: doing it twice must leave the same result as doing it once.
4. Answer fast, then do the work. The sender counts any 2xx as delivered and anything else as a failure, and it will retry, the spec’s example schedule running for about three days. So check the message, store it or publish it, answer 200, and do the real work afterwards. A receiver that does all its processing before answering will time out under load, get the same message again, and make the load worse. Two answers from module 5 matter here too: 429 with Retry-After asks the sender to slow down, and under the spec, 410 Gone tells it to stop sending to this address.
What an Architect Decides Here
Section titled “What an Architect Decides Here”- Where webhooks land. The integration layer, by default. Your own door on a Site only on purpose, with the reason written down.
- The four checks, and who owns each. Signature, time window, duplicate IDs, a fast answer. In the middleware or in your code, but somewhere named.
- Where the secret lives, and how it changes. The spec allows more than one signature at a time so a secret can be replaced without stopping delivery.
- What happens after the yes. The work that runs after the
200, and where a failure there is logged and retried (chapter 14).
Explore
Section titled “Explore”- Standard Webhooks specification (opens in a new tab): the common shape for headers, signatures, retries and answers (checked 2026-10-31)
- The Client and Server Tango: chapter 2, Salesforce calling a webhook, the other direction
- Your Own Door: Custom Apex REST: module 5, building the door and answering errors
