Skip to main content
Public API webhooks let an integration receive outbound FITsociety events at a public HTTPS endpoint. These endpoints are management resources and use the same OAuth Bearer authentication, scopes, idempotency, response envelope, and rate-limit metadata as other Public API resources.
/public/v1/webhooks, /public/v1/webhooks/{id}, and /public/v1/webhooks/deliveries manage outbound webhook subscriptions. Provider receiver routes below /public/v1/webhooks/*, such as payment provider callbacks or InBody sync triggers, are separate inbound callback routes and keep provider-specific authentication.

Scopes

Events

Webhook subscriptions validate event names against the backend event registry. Unknown names are rejected on create and update.

System

Members

Bookings and calendar

Finance

Products and credits

Forms

Progress

Documents

Payload contract

Every outbound delivery body has the same top-level shape: data is intentionally compact. It includes ids, statuses, timestamps, and changed field names where relevant. It does not include raw model documents. When an integration needs full detail, call the relevant scoped Public API read endpoint with the ids from data.
Webhook payloads do not include secrets, access tokens, API keys, raw provider responses, request headers, payment provider ids, PDF/download URLs, image or media URLs, invoice line items, note bodies, form answers, health notes, free text rejection/reason messages, or internal audit/history arrays.

Endpoints

Write requests require Idempotency-Key.

Target URL validation

Webhook targets must be public HTTPS URLs. The API rejects invalid URLs, non-HTTPS URLs, local-only hostnames, private IPv4 ranges, loopback addresses, link-local addresses, and private IPv6 addresses.

Request validation

The authenticated company is always derived from the Bearer token. Request payloads never accept companyId, createdByCoachId, secret hashes, retry counters, delivery timestamps, or signing-secret metadata.

Subscription response fields

List responses: Single subscription responses from create, get, update, and delete:

Create a webhook

The create response includes data.subscription.signingSecret exactly once. Store it securely. Later list and detail responses only return secret metadata: prefix, last4, and rotatedAt.

Update, delete, and test responses

PATCH /public/v1/webhooks/{id} and DELETE /public/v1/webhooks/{id} return data.subscription.id, name, status, events[], target.type, target.url, secret.prefix, secret.last4, secret.rotatedAt, lastDeliveryAt, lastSuccessAt, lastFailureAt, createdAt, and updatedAt. Delete is a soft delete: it sets data.subscription.status = deleted and removes the subscription from future list/get responses. POST /public/v1/webhooks/{id}/test queues a subscription.test event only for an active subscription. Test response fields:

Signing headers

FITsociety sends each outbound delivery as an HTTP POST with JSON body and these headers: The signature uses the one-time signing secret and this signed string:
The payload JSON is canonicalized by sorting object keys recursively and keeping array order. Receivers should reject stale timestamps and compare the computed signature in constant time. Outbound payloads use this shape:

Deliveries and retries

A delivery is successful only when the target returns an HTTP 2xx response. FITsociety stores the response status, a redacted response body preview, and the last error summary for debugging. Each delivery has maxAttempts: 3. Failed attempts are retried with exponential backoff, starting at 1 minute and then 2 minutes, with a 1 hour cap for future retry schedules. nextAttemptAt is null after success or exhaustion.

List deliveries

Delivery list and detail responses use the Public API envelope and include meta.rateLimit when the request passed through the Public API rate limiter. Delivery list response fields: Delivery detail response fields: