← All posts
Engineering 02 Jul 2026 · 4 min read

Six webhooks we send, three you should actually handle

Only three of them change what a traveler sees. Start there, add the rest later.

Six wires descending into a panel, one ringing a green bell
The ones that ring a bell. Illustration: SimpleVisa

Six event types leave our system for yours. A new integration usually subscribes to all six on day one and writes a handler for each, which reads as thoroughness and is mostly filing.

One question sorts them, asked once per event: if this delivery never arrives, does anything a traveler can see become wrong? Three of the six answer no. The other three answer yes, and they answer within minutes.

The three that can wait

These describe things that have already happened and will stay happened. They are worth having in your database eventually. They are not worth holding a launch for.

The application received event, our acknowledgment that a submission landed and now has an identifier on our side. You made the call that created it, so the news is rarely news.
The order settled event, recording money movement against an application. This is what finance reconciles against at month end, and finance wants it accurate, not immediate.
The message logged event, marking that a support exchange happened between us and the traveler. It exists so an audit or a dispute has something to read later. Nobody reads it the day it lands.

Miss a day of these and a nightly poll puts it right before anyone notices the gap. Nothing on a screen goes stale in the meantime, because nothing on a screen depends on them.

The three that change what a traveler sees

The other three carry state a traveler is actively waiting on. Drop one and your interface goes on displaying something you already know to be untrue, which is a worse place to be than displaying nothing at all.

The application status change. Approved, rejected, or needs attention: the document state moved, and this is the thing the traveler keeps reloading your page to find out.
The action needed event. The government or our review team wants something from the traveler before the file goes further, usually a clearer photo or a passport number corrected to match the document page. The departure date does not pause while your queue catches up.
The order refund. The traveler has their money back. If your order screen still says paid, they will ask you why, and the agent who takes that call has nothing to tell them.

Handle these three and your screens tell the truth. Handle the first three and your ledger agrees with ours. Both are worth doing; only one has a traveler attached to it.

What the handler has to do

01

Answer first, process afterwards. Write the payload down, return success, and do the real work off the request. A handler that calls three internal services before replying will time out under load, which makes us redeliver, which adds to the load.

02

Dedupe on the event id. Delivery is at least once, and a redelivery carries the same id as the original. Keep the ids you have already processed and drop repeats on sight. It is the same reasoning as idempotency keys on requests going the other way.

03

Verify the signature before your code branches. Every delivery is signed against the secret in your console. Anything that fails the check should stop there, whatever it says about itself.

04

Ignore types you do not recognise. We add events as coverage grows. If an unfamiliar type raises in your handler, our next addition becomes your next incident. A default branch that quietly does nothing keeps that from ever being your problem.

One more thing catches people out. Order is not guaranteed. Two status changes seconds apart can reach you the wrong way round, so compare the timestamp on the payload with what you last stored and let the later one win. Skip that and an approval can be overwritten by the notice that came before it.

Two fields do most of the work

Every delivery carries a unique event id and a signature header. Dedupe on the first, verify the second, and everything after that is your own logic. Both are documented, with the payload shapes, for developers.

A v1 worth shipping

One endpoint. Three meanings handled on it: a document state that moved, an action the traveler owes somebody, a refund that has landed. A table of processed event ids so repeats cost nothing. A signature check in front of all of it. A default branch for everything else.

Then a nightly job that polls the applications you have open and corrects whatever a deploy window swallowed. Belt and braces, at the price of one cron entry.

That is an afternoon. The other three events carry on arriving while you decide what you want to do with them, and their payloads will look the same in six months as they do today.

Keep reading

All posts →
Product Timatic and modern visa APIs: what each is for The airline industry's compliance engine has done one job well since 1963. Knowing where that job ends tells you what to run beside it. 17 Aug 2026 · 8 min Revenue Visa ancillary revenue: the complete guide Seats and bags are saturated. The visa line is the rare ancillary with no cost of goods, no ops burden, and a traveler who is actively looking for help. 17 Aug 2026 · 11 min Product Elements are free on every model, including the API Why we stopped charging for the components that bring applications to us in the first place. 06 Aug 2026 · 4 min