Notifications
Last updated recently
Notifications
Formwork's characteristic failure is absence. A connected account's grant lapses, a preset stops matching, a destination starts timing out. Nothing errors. Every page still loads, every query still succeeds, and lead volume just quietly drops.
Notifications exist for that one problem. Everything else on this page follows from it.
The four channels
| Channel | Reaches | Good for |
|---|---|---|
| One person, in minutes | Anything you read once a day, or need a record of | |
| Slack | The whole team, immediately | Operational alerts somebody should act on now |
| Webhook | Your systems, not a person | Reacting automatically, with no human in the loop |
| Push | A device, interrupting you | Only things worth stopping what you are doing |
Three of those notify people. The webhook notifies a machine, which is why it is configured with an endpoint and a secret rather than an address, and why turning it on sends nothing to anybody.
Push is granted per device and browser, not per account. Enrolling your laptop does not enrol your phone.
The browser's permission prompt is effectively one-shot: if you decline it, Formwork cannot ask again, and you have to re-enable notifications for the site in your browser settings. That is why Formwork only ever asks when you press the enrol button, never when a page loads.
On iPhone and iPad, web push only works if you have added Formwork to your home screen. Safari in an ordinary tab receives nothing, and there is no way for the site to detect that and tell you.
Allowing notifications for the site is the first. The second is your operating system allowing the browser to post notifications at all, and nothing ever prompts you for it.
When the second is missing, every layer reports success and nothing appears on screen. The push is accepted, the service worker runs, the notification is created - and the OS discards it. Formwork will tell you the test worked, because from the server's side it did.
- macOS — System Settings → Notifications → your browser. Switch it on, and set the alert style to Banners or Alerts. Set to None the notification is delivered silently into Notification Center and never appears.
- Windows — Settings → System → Notifications, and check the browser is listed and on.
- Both — any Focus or Do Not Disturb mode suppresses everything regardless.
If your tests are sitting in Notification Center but never appeared on screen, this is the whole problem and the alert style is the setting to change.
Where the settings live
They are split by who they belong to.
- Configure → Notifications is the account. The Slack URL, the outbound webhook, the thresholds and the quiet hours are shared by everybody.
- Settings → Alerts is you. Which events you want, on which channels, and your enrolled push devices. Two people on the same account can want completely different alerts.
Send a test before you trust it
Every channel on the account page has a Send test button, and it is worth using every time you change something. A Slack URL with a character missing fails in exactly the same way as a Slack URL that is correct but whose channel was archived: silently, at the moment you needed it.
The test sends from the saved configuration, so save first. Testing an unsaved change would report the old value's result and send you looking for a bug you had already fixed.
Sending to your own system
The webhook channel posts JSON to an endpoint you own. By default the body is a fixed shape:
1{
2 "event": "destination.failing",
3 "category": "silent_failure",
4 "subjectId": "6a7b2c1d9e0f4a3b5c6d7e8f",
5 "title": "EDM SES is failing",
6 "body": "The last 5 calls to EDM SES failed.",
7 "url": "https://app.example.com/logs?buyerId=...",
8 "data": { "failures": 5, "lastStatus": 502 },
9 "sentAt": "2026-09-07T14:31:09.482Z"
10}event and subjectId together are what let your receiver deduplicate on its own side. data is
the structured half the human channels cannot carry - a price, a failure count, an HTTP status.
If the far end is a system you do not control and it already expects a particular shape, press Customise the body on the webhook card and write your own using those eight values as tokens:
1{
2 "text": "{{title}}",
3 "detail": "{{body}}",
4 "meta": {{{data}}}
5}Inside quotes, {{data}} arrives as an escaped JSON string. With no quotes, {{{data}}} arrives as
a real object. The preview beside the editor shows which you have written, filled in with example
values, and warns you if the result is not valid JSON. It is sent exactly as written - Formwork will
not quietly repair it, because then the preview would not be the truth.
Setting a signing secret adds an X-Formwork-Signature header: an HMAC-SHA256 of the body,
using your secret as the key, sent as sha256=<hex>. Recompute it on your side and compare. The
secret itself is never transmitted, so a signature is only valid for the one body it signs and is
useless for forging another. This is the same scheme Formwork's inbound webhooks use, deliberately -
one verifier works in both directions.
What Formwork will tell you about
Things that stopped working quietly
These are the ones worth having, and they are on by default.
- A connected account stopped working, because a token could not be refreshed or a grant was revoked
- A destination is failing repeatedly
- Every destination declined, repeatedly, so the waterfall is running and selling nothing
- A source has gone quiet
- Leads are arriving into a paused routing
- A preset has stopped matching, so everything is falling through to the default waterfall
- A source is capturing leads but routing nowhere
Limits and billing
Near a limit, at a limit, blocked by a limit, or a failed payment.
Individual leads
A lead arrived, a lead sold, a lead was rejected for a missing field, a postback gave up.
All off by default. At any real volume these are noise, and an alert you have learned to ignore is
worse than no alert, because you will ignore the important one sitting next to it. If you do turn
A lead sold on, set a floor price so only the ones worth knowing about interrupt you.
Account and security
New device, password changed, team member added or removed, API key created.
These cannot be switched off, and they only ever go by email. Someone who can silence "a team member was added" can add a team member unobserved, which makes the alert worth less than nothing.
Summaries
A daily or weekly rollup: leads in, sold, revenue, top destination, errors.
An account with no activity in the period gets no summary. A message telling you nothing happened is the fastest way to teach yourself to stop opening them.
When the checks actually run
Most alerts fire the moment the thing happens: a lead sells and the code that sold it says so. The seven silent-failure alerts cannot work that way, because each one is the absence of something. No code runs at the moment a source stops sending leads.
So those are found by a sweep that runs hourly and asks seven questions of your data. An alert about a destination failing can therefore be up to an hour behind the fifth failure, which is the trade for noticing it at all.
The summaries run on their own schedule: the daily at 13
UTC, the weekly at 13 UTC on Monday.This matters in one practical way. If you deliberately break something to test an alert, nothing happens immediately - the sweep has to come round. And if you fix it inside the hour, the alert may never fire, because by the time anyone looked there was nothing left to find.
Why you get one message and not five hundred
Every event has a cooldown: how long the same alert about the same thing stays quiet after it fires. A destination timing out on every lead for an hour produces one Slack message, not four hundred.
This is the setting that decides whether alerting is useful. Without it a single bad afternoon fills the channel, somebody mutes it, and every alert in this list stops working - including the ones that would have paid for themselves.
Cooldowns differ by event, because the useful repeat interval does. A revoked grant repeats every twelve hours, since the answer does not change until somebody reconnects. A lead selling has no cooldown at all, because each one is a different lead.
Quiet hours
Quiet hours hold back Slack and push overnight. Email is never held.
A Slack or push notification that fires inside your quiet window is dropped, not delayed. There is no queue that delivers it in the morning.
It is recorded, so you can see in the log that it happened and was suppressed. But nothing re-sends it. For alerts with a short cooldown this barely matters, since the problem is still there an hour later and the alert fires again. For the twelve-hour ones, a problem that starts at 22
may not reach Slack until the morning.If overnight coverage matters to you, leave email on for the silent-failure events. Email ignores quiet hours entirely.
Thresholds
Some events need a number, and the right number depends on your volume. All of them live on the account page:
- Percentage of a limit at which the warning fires
- Consecutive failures before a destination is called failing
- Consecutive leads with nothing accepted before the waterfall is called dead
- Hours of silence before a source is called quiet
- Minimum sale price worth notifying about
If an alert never arrives
Work down this list:
- Is the event switched on for you, on that channel, under Settings → Alerts? Preferences are per person, so a colleague receiving it does not mean you will.
- Is the channel configured and passing its test on the account page?
- Did it fire inside quiet hours on Slack or push?
- Is it inside its cooldown from a previous firing?
- Is it a silent-failure alert that the hourly sweep has not reached yet?
- For push: is this device still enrolled? Subscriptions expire, and Formwork removes them when the browser reports them as gone.
- For push, if the test says it worked: your operating system is almost certainly discarding it. See the note under the four channels above.