Skip to content

Set up a webhook endpoint

Create and manage webhook registrations through the Public API. A registration subscribes one company to one event and sends deliveries to one public HTTPS URL.

Back Office Settings > Webhook does not create these registrations and never displays them.

Before you begin

You need:

  • a company-manager Public API key;
  • the client and company identifiers used by your integration;
  • a public HTTPS endpoint that can read the raw request body and return a 2xx response.

Create a registration

curl --request POST \
  --url 'https://YOUR_ENV_DOMAIN/api/v2/management/webhook-registrations/' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'X-Client-ID: YOUR_CLIENT_ID' \
  --header 'X-Company-ID: YOUR_COMPANY_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "event_type": "class.updated",
    "url": "https://integrations.example.com/webhooks/bsport",
    "is_active": true
  }'

New registrations always use the immutable payload_version value v2. V1 creation returns HTTP 410 with code WHR-002. See existing V1 registrations for historical integrations.

Replace YOUR_ENV_DOMAIN with public.staging.bsport.io (staging) or public.production.bsport.io (production). See Environments.

The response includes the generated signing_secret. Store it as a secret and use it to verify every delivery. The secret remains visible when the registration is listed or retrieved.

Do not expose the signing secret

Never put the signing secret in source control, application logs, issue trackers or client-side code.

Payload version

The registration decides which payload version it delivers. A new registration always delivers V2 payloads, because V1 creation is retired. Existing registrations keep delivering V1 payloads and historical event names. The version does not change after creation. See Webhook event payloads.

Select an event

Each registration accepts one event_type from the event catalogue. Create additional registrations when the same endpoint must receive several event types.

Test a registration

Send one signed sample delivery to the registration's URL and read what your endpoint answered. A test also works on an inactive registration: create it with "is_active": false, test it, then activate it.

curl --request POST \
  --url 'https://YOUR_ENV_DOMAIN/api/v2/management/webhook-registrations/REGISTRATION_ID/test/' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'X-Client-ID: YOUR_CLIENT_ID' \
  --header 'X-Company-ID: YOUR_COMPANY_ID'

The response reports your endpoint's answer:

{
  "is_delivered": true,
  "http_status": 200,
  "failure_reason": null
}

is_delivered is true only for a 2xx status. Redirects are not followed, as for real deliveries.

The sample delivery has the envelope, headers and signature of a real delivery for the registration's event and payload version, so a V1 registration receives a V1 sample. Its data holds placeholder values generated from the event's schema in the event catalogue, such as 0 for IDs, never a real record of your company. A handler that fetches the resource by its ID gets a 404.

Each test is sent once, without retry, with a new X-Bsport-Webhook-Delivery-Id. You can send 5 tests per minute per company: see Rate limits.

When no response was received, http_status is null and failure_reason gives the cause:

failure_reason Cause
connect_timeout No connection opened within 2 seconds.
read_timeout No response byte within 5 seconds of sending the request or of the previous byte.
network_error The host name did not resolve or the connection failed.
invalid_destination_url The host resolves to a non-public address, or the URL is invalid. The address is checked again on every test.
tls_verification_error The endpoint's TLS certificate was rejected.

Update or disable a registration

Use PATCH to change the destination, event or active state. Updating a registration preserves its signing secret and immutable payload version. To replace a leaked secret, see Rotate the signing secret. The V2 route manages both V1 and V2 registrations. When updating a V1 registration, use its historical event names. The V1 route remains available for managing existing V1 registrations.

curl --request PATCH \
  --url 'https://YOUR_ENV_DOMAIN/api/v2/management/webhook-registrations/REGISTRATION_ID/' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'X-Client-ID: YOUR_CLIENT_ID' \
  --header 'X-Company-ID: YOUR_COMPANY_ID' \
  --header 'Content-Type: application/json' \
  --data '{"is_active": false}'

Webhook registrations cannot be deleted through the API. Disable a registration to stop future deliveries without losing its configuration.

Tenant isolation

List and retrieve operations return only registrations owned by the authenticated company. A registration belonging to another company is not visible or mutable, even when its identifier is known.

Next step

Implement signature verification and idempotent delivery handling, then use the event catalogue to model the events you subscribe to.