Skip to content

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.

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.

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.

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.

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.

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.