The notification
When you open a transaction you can give chmod a URL on your backend. As the transaction moves through its lifecycle — and most importantly when the decision exists — chmod calls that URL. The call is signed. chmod publishes a public key, and every notification carries a timestamp and a signature computed with the matching private key over that timestamp and the transaction id. Your backend checks the signature before doing anything else, and rejects calls whose timestamp is more than a few minutes old — a valid signature never expires on its own, so without the time check a captured call could be replayed later. Expect the same notification to arrive more than once now and then, and occasionally out of order. That is the nature of delivery over the internet, and your handler should treat a repeat as a no-op rather than applying it twice.The fetch
Whenever your backend wants the truth about a transaction, it asks chmod for it by id. The answer is the full transaction: where it is in its lifecycle, when each step happened, and — once analysis has finished — the decision with every finding behind it and everything that was extracted from the document and the selfie. This is what you act on. Because your backend requested it over its own authenticated connection, it cannot have been forged or replayed by anyone else, whatever arrived at your webhook. The fetch is also your safety net. A reconciliation job that periodically asks about transactions that never reached a final state will catch anything a lost notification would otherwise have left hanging.Putting the two together
1
The notification arrives
Verify the signature and the timestamp. Acknowledge immediately; do the work out of
band so a slow database never makes chmod think the delivery failed.
2
Fetch the transaction
Read the decision and the findings from the fetched transaction, never from the
notification body.
3
Act
Approve, reject, or escalate. Update the person. Record what you need.
What to keep
The full result contains document images, personal details and device signals — personal data under every privacy regime you operate in. Keep the decision, the finding codes, the transaction id and the time it was reached; that is enough for an audit trail, analytics and support conversations. Fetch the full result again by id on the rare occasions you need it, rather than storing it.What the person sees
By the time the decision exists, the person has already closed the flow and is looking at your app, which told them their document was being reviewed. Now you tell them the outcome — in your own words. The findings carry messages written for your operators. They say precisely which check failed, which is more than a genuine user needs and exactly what a fraudster wants. Map each finding to copy of your own: actionable guidance for the recoverable ones (“try again in better light”), a neutral message for the suspicious ones (“we couldn’t verify your identity; our team will be in touch”). See Decisions and issues for the buckets.The reference
The notification’s headers, the verification steps with code, and the full structure of a fetched transaction are in the API Reference:Webhooks
The request, the signature, and how to verify it.
Get transaction
Fetch a transaction by id.
Reading a result
Every field the transaction returns.

