Webhooks
Instead of asking Sotirea over and over whether something has changed, give it an address on your own server and it will tell you as it happens. A webhook is that address and the events you want sent to it.
Events
Section titled “Events”| Event | When |
|---|---|
payment.awaiting_approval |
A payment is held for people to approve. |
payment.sent |
A payment is on the network, with its tx_hash. Sent again with the new hash after a speed-up or cancel. |
payment.confirmed |
A payment is final. |
payment.failed |
A payment did not happen. |
payment.stuck |
A payment the network has not taken for 15 minutes. |
deposit.arriving |
Money is seen arriving in a vault, not yet final. |
deposit.received |
A deposit is final and in the vault’s balance. |
gas.low |
A gas pool dropped below the level you set. |
Webhooks are added in the console, under Developers and Webhooks, or by a key that can
manage them, with POST /v1/webhooks. An organisation can
have up to 10. Each must be an https address that resolves to a public address: Sotirea will not
deliver to a private, local or internal network.
What arrives
Section titled “What arrives”Each event is a POST of JSON:
{ "id": "0a6e2c1f-5b7d-4e1a-9c3b-2f8d6e4a1b70", "type": "payment.confirmed", "created_at": "2026-11-08T14:03:22Z", "api_version": "1", "environment": "test", "data": { "object": "payment", "id": "api:12:payout-42", "reference": "payout-42", "purpose": "payment", "status": "confirmed", "vault_id": 7, "chain_id": "eip155:84532", "to": "0x000000000000000000000000000000000000dEaD", "asset": "native", "amount": "1000000000000000", "tx_hash": "0x5e1d…" }}data describes what the event is about as it stood when it happened, and nothing that changes
later. Fetch the payment or deposit for anything more. A deposit’s data has object deposit,
its state, vault_reference, sweep, tx_hash, from, to, asset and amount; a low gas
pool’s has its network, address and level. The reference has every field.
Checking it came from Sotirea
Section titled “Checking it came from Sotirea”Anyone can send a request to your webhook address, so check every one before acting on it.
Sotirea signs each delivery to the Standard Webhooks
specification, with the secret shown once when the webhook was added (it starts whsec_):
webhook-id: the event’s id, the same on every retry of it;webhook-timestamp: when it was sent, in seconds;webhook-signature:v1,followed by the base64 HMAC-SHA256 of<webhook-id>.<webhook-timestamp>.<body>, keyed with the secret’s base64-decoded value.
Refuse a delivery whose signature does not match or whose timestamp is more than five minutes
from now, and check the body exactly as it arrived, before any parsing. Sotirea’s Go and
TypeScript clients do all of this in one call (VerifyWebhook, verifyWebhook), and so does the
Standard Webhooks library for your language.
Answering, and retries
Section titled “Answering, and retries”Answer with any 2xx within 10 seconds. Anything else, a redirect included, or no answer in
time, counts as a failure, and Sotirea tries again: after 5 seconds, 5 minutes, 30 minutes, 2
hours and 5 hours, then every 10 hours, for about two days in all. Do the slow work after you have
answered.
A delivery that never succeeds is listed with the webhook, and can be sent again once you have fixed what refused it. A webhook whose deliveries have all failed for three days, at least ten times in a row, is turned off: the people who manage webhooks are emailed, nothing more is sent to it, and turning it back on starts its count again.
A new secret
Section titled “A new secret”Give a webhook a new secret from the console or with
POST /v1/webhooks/{id}/secret, and choose how long the old
one keeps working: not at all, an hour, a day or a week. Until it stops, each delivery carries a
signature from each secret, space separated, so a receiver holding either verifies it. Deploy the
new secret within that time and the change needs no downtime.