Overview
Once deliveries are flowing, WHAWIT does three things with the failures:- Groups them into recurring failure modes, ranked by the deliveries they cost — a prevention backlog.
- Retries the ones a machine can fix, by calling an endpoint you register, under a policy you control.
- Escalates everything else to a human, with the agent’s read on each one attached.
Failure modes
Every failed delivery carries an error signature — a normalized form of the message, with ids, timestamps, IP addresses and varying numbers collapsed. Failures sharing a signature are one failure mode. Unlike a log search, these persist and accumulate. A failure mode records how many times it has occurred, how many distinct deliveries it cost, which of your customers hit it, when it was first and last seen, and a daily trend.Find them in the app under Reliability → Failure Modes, ranked by impact. The top row
is the highest-value fix available.
Ranking
Impact weighs affected deliveries above raw occurrences — a customer-facing unit is worth more than a repeated log line — and scales the result by attribution and failure class. Your own platform faults outrank a customer’s misconfiguration, permanent failures outrank retryable ones, and a muted mode scores zero and leaves the backlog entirely. Each mode carries a status you move as you work it:open, accepted, fixed or muted, plus a link to the prevention ticket in your own tracker.
Classification
Each mode is classified on two axes:transient | permanent | unknown
Would retrying help? A timeout or a 429 is transient. A validation error or a bad
credential is permanent — retrying it only wastes the attempt.
platform | customer | upstream | unknown
Whose fault it was. Your platform, your customer’s configuration, or a third party you
depend on.
API
Auto-recovery
WHAWIT does not reach into your systems. It calls an endpoint you register, and your endpoint decides how to re-drive the work.How the loop closes
1
A delivery fails or misses its deadline
Both are the same decision. Silence past a deadline needs recovering just as much as a
loud failure.
2
The policy is consulted
Does an enabled action match this failure? Is it under its attempt cap, its cooldown and
its daily cap? Does it need a human to approve?
3
WHAWIT calls your endpoint
A signed request describing the delivery. A 2xx means the retry was accepted — nothing
more.
4
Your retry emits normal outcome events
Whether the delivery actually recovered comes back the way everything else does. A later
success flips it to auto-recovered, and it counts as hands-off in the KPI.
5
Or it escalates
Attempts exhausted, or the failure was never retryable — it goes to the on-call path.
What is never retried
Two guards, applied before the policy is even consulted:- Permanent failures. A retry cannot fix a malformed payload or a missing field.
- Customer-attributed failures. A wrong credential in your customer’s configuration is not something another attempt resolves.
The policy
number
default:"3"
Hard ceiling on retries for one delivery.
number
default:"60"
Delay before the call goes out, giving a transient dip time to clear.
number
default:"120"
Minimum gap between two attempts on the same delivery.
number
default:"200"
Spend guard: attempts per action per UTC day.
boolean
default:"false"
Hold every trigger for a human decision.
low | medium | high | critical
Incidents strictly below this severity are auto-approved even when
requiresApproval is
set. Omit to require approval for everything.number
default:"60"
How long a pending approval stays actionable.
Choosing what it answers
An action’s trigger narrows what it may act on: by failure class, by attribution, by workflow type, by specific failure modes, and by tenant kind. An empty list means “any”.The request WHAWIT sends
Your endpoint receives a JSON body over HTTPS with two headers:
The MAC is computed over
`${timestamp}.${rawBody}`, Stripe-style, so a captured request cannot be replayed later against a receiver that checks the age of the timestamp.
Keys and endpoints
string
required
The id of a secret in GCP Secret Manager holding the signing key. The key itself never
touches the database, source control or an environment file — you store an id, not a
credential.
API
A refusal from
/recover is a 200 with status: "rejected" and a reason written for a person, not a 4xx. The reason is the point of the response; an error status would strip it out before anyone read it.
queued | pending_approval | rejected
queued is the only value that means a retry is actually going out.string
Why the policy decided what it did.
Configuring it
Actions, their policy and the approval inbox live under Reliability → Recovery in the app. The stats on each action separatesucceeded — your endpoint accepted the call — from recovered, the deliveries that actually came back green. The second is the number that matters.

