Webhook Subscription API
The subscription API lets a partner application (such as the StudioBase Zapier app) manage webhook subscriptions for the connected studio using the REST hook pattern: subscribe a target URL to an event type, receive signed event deliveries, unsubscribe when done.
Authentication
Every endpoint requires a bearer access token from the OAuth flow:
Authorization: Bearer sbat_…
A 401 with body {"error": "invalid_token"} means the token is missing,
expired, or the connection was revoked — refresh the token (or reconnect)
and retry. Transient failures return 500 {"error": "server_error"}.
Rate-limited requests return 429 {"error": "rate_limited"} with
X-RateLimit-* and Retry-After headers; limits are 30 requests/min per
connection for subscribe/unsubscribe and 60 requests/min per
connection for the other endpoints.
Get connection info
GET /api/zapier/me
Identifies the connected studio. Used as the connection test and label.
Success (200):
{
"studio_name": "Dance Trance",
"subdomain": "dance-trance"
}
Subscribe
POST /api/zapier/hooks
Content-Type: application/json
| Body field | Required | Description |
|---|---|---|
event_type | Yes | One of the subscribable event types, e.g. booking.created |
target_url | Yes | Public HTTPS URL to deliver events to (max 2000 characters) |
{
"event_type": "booking.created",
"target_url": "https://hooks.example.com/abc123"
}
Success (201):
{
"id": "1f4b2a6c-9d3e-4f7a-8b1c-2e5d7f9a0b3c"
}
Store the returned id — it is the handle for unsubscribing.
Errors (400) return a human-readable error string:
| Condition | error |
|---|---|
event_type not in the catalog | Unknown event type |
| More than 25 active hooks on the connection | Limit of 25 hooks per connection reached |
target_url is not a valid URL | Invalid URL |
target_url is not HTTPS | URL must use https |
target_url embeds credentials | Credentials in the URL are not allowed |
target_url points at a private/internal address | Private or internal addresses are not allowed, URL resolves to a private address, or Hostname does not resolve |
Unsubscribe
DELETE /api/zapier/hooks/{hookId}
Deletes the subscription identified by the id returned at subscribe time.
A token can only delete subscriptions created by its own connection.
Success (200): {} — idempotent; deleting an already-deleted
subscription also returns 200.
Sample events
GET /api/zapier/sample/{eventType}
Returns up to the studio's 3 most recent real events of the given type, or one realistic canned sample when the studio has none yet — useful for building field mappings during setup. Items are full event envelopes, identical in shape to live deliveries.
Success (200):
[
{
"id": "00000000-0000-4000-8000-00000000feed",
"type": "booking.created",
"version": 1,
"created_at": "2026-06-11T17:00:00.000Z",
"studio": {
"id": "9a1b2c3d-0000-4000-8000-000000000001",
"slug": "dance-trance"
},
"data": {
"booking_id": "7f0d6f9e-0000-4000-8000-000000000001",
"schedule_item_id": "7f0d6f9e-0000-4000-8000-000000000002",
"guest_name": "Alex Rivera",
"guest_email": "alex@example.com",
"payment_method": "card",
"amount_cents": 2500,
"class_name": "Morning Yoga Flow",
"class_start_time": "2026-06-12T09:00:00+00:00",
"instructor_name": "Jordan Lee"
}
}
]
Error (400): {"error": "Unknown event type"} for an event type not in
the catalog.