SpareSpare Docs
GuidesAPI Reference

How Webhooks Work

Subscription model, authentication, request signing, base URLs, and the two signatures you will encounter.

Integration guide

Goal: Understand the subscription model, configure authentication, and register your first webhook subscription.

Estimated time: 15 minutes

Prerequisites

  • A Spare sandbox account with an active pis subscription
  • App ID, API key, and EC P-256 private key (registered in the Spare dashboard)
  • A publicly reachable HTTPS URL, or a tunnel such as ngrok for local development

How It Works

Spare webhook delivery has three participants: your application registers a subscription, Spare delivers signed events to the URL in that subscription, and your receiver acknowledges each delivery with 202 Accepted.

The usual sequence:

  1. Call GET /webhooks/catalog to see which products and resources are available on your tenant.
  2. Call POST /webhooks with your HTTPS URL, one product, and the resource types you want.
  3. Whenever a matching resource changes state, Spare sends a signed compact JWS to your URL.
  4. Your receiver reads the raw body, verifies the signature, returns 202 Accepted, and processes the event in the background.

What a Subscription Is

A subscription links one of your URLs to one slice of the event stream. It has four meaningful fields:

FieldDescription
urlThe HTTPS endpoint Spare posts to. Every matching event lands here.
productOne product per subscription. payments is available today.
resourcesThe resource types under that product you want events for.
statusActive delivers events. Inactive pauses delivery without deleting the subscription.

A subscription created with { "product": "payments", "resources": ["payment", "consent"] } receives every payment.* and every consent.* event at that URL.

Authentication and Request Headers

Subscription management uses the same API-key session token as the rest of the payments API.

HeaderWhenValue
AuthorizationAlwaysBearer <access_token>
x-tenantAlwaysUAE
Content-TypeCreate and updateapplication/json
x-signatureCreate and updateDetached ES256 JWS over the request body

Two Signatures, Two Directions

There are two different signatures in this integration and mixing them up is the most common setup mistake.

  • x-signature: something you put on your POST /webhooks and PATCH /webhooks/{webhookId} requests. It proves the call came from your application and the body was not altered. Spare verifies it before storing your subscription. This is the same mechanism as payment-request signing described on Request Signing.
  • Event body signature: something Spare puts on every delivery it sends to your URL. The body itself is a compact JWS, not plain JSON. Your receiver verifies this signature before acting on the event.

The two never appear on the same message.

Signing a Create or Update Request

POST /webhooks and PATCH /webhooks/{webhookId} require an x-signature header. The signing process matches payment-request signing:

  1. Produce the JSON body with fields sorted alphabetically. Omit any null or absent fields.
  2. Sign that canonical JSON with your registered EC P-256 private key using ES256.
  3. Send the signature as a detached JWS in the x-signature header: header..signature (payload segment is empty).

The body allow-list is url, description, status, product, and resources. Any other field is rejected with 400 before the signature is checked.

See Request Signing for key generation, serialization rules, and per-language examples.

Base URLs and Paths

The sandbox base URL for UAE:

https://api.sandbox.tryspare.ae

Subscription management lives under /webhooks (plural). The delivery verification key set lives at /webhook/jwks (singular). The two are easy to confuse:

GET  /webhooks/catalog       # subscription APIs, authenticated
GET  /webhook/jwks           # delivery verification keys, anonymous

Use the path from the relevant section. The difference of one character matters.

Next Steps

On this page