Incoming webhook
Publish a URL, hand it to somebody else's system, and have a workflow start the moment they use it. The interesting parts are the secret and what you do with a payload you did not write.
This is the incoming direction: another system has news and calls you. You create a webhook, Expedify gives you a URL and a secret, you paste both into their configuration, and from then on every event they send starts a workflow.
Creating it takes a minute. The rest of this lesson is about the three things that make the difference between a webhook that works in a demo and one you can leave running.
What you get when you create one
A webhook is an object in its own right, separate from any workflow. Creating one hands you two strings:
URL https://<your-host>/hooks/<organisation id>/<slug>
Secret whsec_in_...The URL is public in the sense that matters: anything that can reach it can start your workflow. The secret is how the receiving end tells a real call from a stranger's. Give both to the other system — every sender worth integrating with has a field for each.
The webhook object also counts what it has received, which is the first thing to look at when nothing is happening. If the count is zero, the other system never called you and nothing in your workflow is the problem.
Binding a workflow to it
| Field | What it holds |
|---|---|
http_method | HTTP method filter One of: GET · POST · PUT · PATCH · DELETE Defaults to POST. |
http_method
- What it holds
- HTTP method filter One of:
GET · POST · PUT · PATCH · DELETEDefaults toPOST.
A workflow attaches to a webhook by its slug — the readable name you chose — rather than by an id you would have to look up. That is worth knowing when you write workflows outside the builder, because it means a workflow can name the webhook it wants and have it created if it does not exist yet.
A worked example
A partner's site posts leads. The workflow checks the payload is usable before it trusts it, and upserts rather than creating blindly.
Bound by slug, defensive about the payload
Two branches, because a webhook you do not control will eventually send you something unexpected.
Scroll for all 4 steps →
The condition is the whole point of the example. Somebody else's system is sending you data, and you did not write their validation. A test submission with an empty form, a change to their field names, a genuine customer who left the email blank — all of these arrive as a successful call. Checking the one field you cannot work without, before you use it, is the cheapest reliability you will ever buy.
And the write is an upsert, not a create. update with create_if_not_found on, keyed by email. Webhooks get retried and forms get submitted twice; a create would give you two contacts, and this gives you one either way. That is the CRM Manager lesson doing real work here.
The failure branch makes a task rather than doing nothing. A webhook that quietly discards malformed calls is a webhook that loses leads silently for a month.
Reading what they sent
| Reference | What you get |
|---|---|
{{alias.body}} | The JSON they posted. {{alias.body.email}} reaches into it, and nested paths work the same way. |
{{alias.headers}} | Their headers — where an event type or a delivery id often lives. |
{{alias.method}} | The verb used, when you accept more than one. |
{{alias.body}}
- What you get
- The JSON they posted. {{alias.body.email}} reaches into it, and nested paths work the same way.
{{alias.headers}}
- What you get
- Their headers — where an event type or a delivery id often lives.
{{alias.method}}
- What you get
- The verb used, when you accept more than one.
Read a real payload before you build against it. Send one call from the other system, look at what actually arrived, and write your references from that. Building from their documentation and discovering the field is emailAddress rather than email is an hour nobody enjoys — and it fails the way you now expect, with an empty value rather than an error.
What breaks
The same event can arrive twice. Senders retry when they do not get a clean answer, including when they did reach you and the reply was slow. Any workflow that creates something on receipt should be keyed on something in the payload — an email, an order number, their delivery id — so that a second delivery updates rather than duplicates.
An inactive workflow is a silently discarded event. The webhook accepts the call, its counter goes up, and nothing runs. The sender sees success. This is the most common “my webhook is broken” report and it is usually a workflow that was never activated after being saved.
Treat the payload as untrusted text. It arrives from outside your organisation and goes straight into CRM fields, emails and sometimes model prompts. Everything the Web Scraper lesson said about scraped text applies here with more force, because a webhook payload is written by whoever chose to call your URL.
A rotated secret is a broken integration until both ends know. You can regenerate the secret, and the moment you do, calls signed with the old one stop being accepted. Rotate deliberately, and update the sender in the same sitting.
Try it
- Create a webhook and copy both strings. Post to it yourself from any HTTP client with a small JSON body.
- Check the webhook's request count went up, then look at the workflow's execution and read
{{alias.body}}. That round trip is the whole feature. - Now deactivate the workflow and post again. The call still succeeds and nothing runs — that is the failure you will be asked to diagnose one day.
- Post the same body twice with the workflow active and confirm you get one contact rather than two. If you get two, the write is a create and should be an upsert.
- Post a body with the email missing and confirm the second branch fires. Then imagine that happening a hundred times unnoticed.
Next: Outgoing webhooks — the same idea pointed the other way, where you are the system with the news.
Related lessons
Base rates — what a piece of evidence is actually worth
A face-recognition system that is 99.9% accurate and almost entirely wrong, and a number that sent an innocent woman to prison. Both are the same arithmetic, and it is the arithmetic that decides what any piece of evidence is worth.
ReadConfirmation and survivorship — what you never looked for
Two questions about evidence you did not go looking for. One is a rule you have to discover, and one is a pattern in five famous people — and in both, the thing that would have told you the truth is the thing nobody checks.
ReadLoss aversion, sunk cost and regression — what it costs you
Four questions you answer about yourself rather than about a scenario, and your own answers are the finding. Then the pattern that makes praise look useless and criticism look like it works, whatever you actually do.
Read
