Skip to main content
Securitize sends one POST to your webhook endpoint for every step of your activity: cash movements, token issuances, transactions, redemptions and payouts. Your Securitize contact registers the endpoint’s URL for your account, chooses with you which event types it receives, and hands you its signing secret, a whsec_ string, once.
The body is the event envelope: eventType says what happened, eventId identifies the event, data carries it.

Headers

The headers follow the Standard Webhooks specification under the svix- prefix. Read them case-insensitively.

Verify the signature

Every delivery is signed with your endpoint’s secret. Verify before you parse anything else.
  • Sign the raw bytes of the body, exactly as received, before any JSON parsing or re-serialisation.
  • Compare in constant time against each signature in svix-signature: during a secret rotation the header carries one per secret, and any one matching is enough.
  • Reject a timestamp more than 5 minutes from your clock, to stop a captured delivery being replayed later.
  • The secret is base64 after the whsec_ prefix; decode it before using it as the HMAC key.
The Standard Webhooks libraries and the svix libraries do all of this. By hand:
A delivery that fails verification: answer 401, log the svix-id, and do nothing with the body.

Acknowledge quickly

Any 2xx within 15 seconds acknowledges the delivery. Anything else, or no answer, is retried with increasing delays, from seconds to hours, for about a day; after that the delivery is marked failed. Acknowledge as soon as the event is durably stored, and do the work afterwards. A handler that calls your own systems before answering is the usual cause of timeouts, and every timeout is a retry you then have to deduplicate.

Apply it exactly once

Delivery is at least once and can be out of order: retries repeat an event, and the steps of one subscription or redemption are recorded by different parts of Securitize, so a later step can arrive first. timestamp in the envelope is when Securitize sent the event; the time the step happened is in data (date, sourceTransaction.date). A handler that follows the three rules:

Find what you missed

Every webhook sent to you stays readable: GET /webhook-events lists them newest first, with the body exactly as delivered, and GET /webhook-events/{eventId} returns one by its eventId or its svix-id. After an outage, page the list back to the start of the outage and apply what you do not have; your deduplication on eventId makes it safe. For anything older, or to confirm a final state, read the deposits and transactions themselves.

Your endpoint

  • HTTPS, publicly reachable, with a certificate a public CA issued.
  • Idempotent: a retry repeats a delivery, so applying the same event twice must change nothing.
  • One endpoint per environment: sandbox and production have different secrets and different events.
  • Monitoring. An endpoint that keeps failing can be disabled. Alert on your own 5xx rate, and tell your Securitize contact when you change the URL.