Skip to main content
Webhooks tell your backend that a resource may have changed. They are a delivery channel, not a ledger, and they are the cheapest way to avoid polling everything.
Products counterpart: Exceptions and interventions covers what each money-edge event means for your operations team and who resolves it.

How it works

  1. Create an endpoint for an app environment. Stableyard returns its signing secret once.
  2. A resource changes, such as a payment succeeding or a deposit settling, and Stableyard records an event.
  3. Stableyard sends the event as a signed POST to every active endpoint in that app environment subscribed to the event name.
  4. Your handler verifies and records it, returns 2xx, then reads the resource for its current state.

An event is a prompt to read

An event says something changed. The resource says what is true now. Events are additive, may be delivered more than once and may arrive out of order, so never reconstruct state from delivery order: fetch the resource, such as GET /v2/payments/{paymentId}, and act on what it returns. See Reconciliation. New partner events are added over time. Your consumer must ignore an unknown event name safely rather than throw.

Creating an endpoint

Create endpoints in the Partner Dashboard, or from your backend with a credential that carries the v2:webhooks and v2:console permissions:
Stableyard sends partner-facing lifecycle events for every account owned by that app environment. A second endpoint with the same URL in the same app environment is refused with 409.
Store the signing secret immediately. Stableyard returns it once at creation and never again. If you lose it, rotate the endpoint’s secret with POST /v2/console/webhooks/{webhookId}/rotate-secret, which invalidates the previous one at once.

Managing an endpoint

An archived endpoint cannot be changed or reactivated: create a new one. Disabling, archiving or unsubscribing changes what happens to deliveries still waiting. See Delivery and retries.

Delivery guarantees

Delivery is at-least-once. A network failure can leave an HTTP outcome ambiguous on Stableyard’s side, so the same event may arrive again. Dedupe on two levels:
  • By x-stableyard-delivery for delivery-level retries, which reuse the same delivery attempt.
  • By x-stableyard-event-id plus the resource ID in the payload for resource-level processing.
If one endpoint succeeds while another subscribed to the same event fails, the successful endpoint is not sent the event again. An app environment may have only one active endpoint per URL; historical duplicate rows are collapsed by URL at delivery time. Failed deliveries are retried with backoff, then abandoned. See Delivery and retries.

What a delivery contains

Every delivery is a POST with a JSON body and these headers:
Every envelope contains id, name, apiVersion, createdAt and payload. id equals x-stableyard-event-id. apiVersion is the immutable date-version of the resource and event contract; use it to select your decoder rather than inferring the version from delivery time. What each payload carries is in the Event catalog. Public wallet Payments use an internal accounting principal for ledger ownership and webhook routing. Stableyard never exposes that principal as an account: its ID is removed from the delivery payload and headers.

A minimal handler

  1. Read the raw request bytes. Do not parse JSON first.
  2. Verify the signature. See Verifying signatures.
  3. In one database transaction, record x-stableyard-event-id under a unique constraint and apply the event. On a conflict, skip the business effect.
  4. Return 2xx after the transaction commits.
  5. Read the resource before acting on anything user-visible.
A 5xx from your handler is retried; a 400 is abandoned at once. Return 5xx when your own database is down, so the event comes back.

Event catalog

Every partner event, what it means and which to subscribe to.

Verifying signatures

Check each delivery’s HMAC-SHA256 signature before you trust it.

Delivery and retries

Retries, backoff, abandonment and requeueing a delivery.

Reconciliation

Why an event is a prompt to read the resource, and what to persist alongside the event ID.