Public API
Programmatic access to your facility data. Bearer-token auth, per-key rate limits, signed outbound webhooks. Versioned at /api/public/v1.
Authentication
Mint a key from /settings/integrations/api-keys. Keys are owner-only to create, staff-readable to use. The plaintext appears once — store it; we keep only a hashed copy.
curl https://app.swingops.ai/api/public/v1/bookings \ -H 'Authorization: Bearer swo_<your-key>' \ -G \ --data-urlencode 'start=2026-06-01' \ --data-urlencode 'end=2026-06-30'
Rate limits
Per-key, per-minute — each key carries its own limit (default 60 req / min, set when the key is minted). Exceeding it returns 429 Too Many Requests; back off and retry.
Endpoints (v1)
/api/public/v1/bookingsRange query over bookings by start, end, and status.
/api/public/v1/familiesPaginated families with primary contact, athlete summary, wallet balance, and active/lapsed status. Params: limit (≤200), offset. Scope: families:read.
/api/public/v1/availabilityOpen start times for a lesson type, already filtered by your booking rules. Scope: availability:read.
/api/public/v1/lesson-typesYour bookable lesson types with duration and price. Scope: lesson_types:read.
/api/public/v1/bookingsCreate a booking for an existing family. Auto-assigns a coach and space, honors your booking rules, member-only windows, and prepayment config, and returns a checkout_url when payment is still owed. Body: lesson_type_id, family_id, start_at_utc (UTC), plus optional primary_athlete_id, staff_id, resource_id, notes. Scope: bookings:write.
/api/public/v1/bookings/{id}Reschedule a scheduled booking to a new start time, preserving its duration, with coach and resource conflict checks. Body: new_start_at_utc (UTC). Scope: bookings:write.
/api/public/v1/bookings/holdHold a slot briefly (does not confirm or charge). Scope: bookings:hold.
/api/public/v1/contactsUpsert a lead contact by phone or email. Scope: contacts:write.
A key with no scopes set can call every endpoint; a scoped key is limited to the scopes you grant it.
Outbound webhooks
Subscribe a URL from /settings/integrations/api-keys → Webhooks. We POST a signed JSON envelope when something happens. HMAC-SHA256 signature on header X-SwingInsight-Signature: t={ts},v1={hex} — the same scheme as the SwingInsight integration, so an existing verifier works unchanged. Signed input is {ts}.{raw_body}; the event type is also on x-swingops-event. Event types: booking.created, booking.updated, booking.canceled, transaction.succeeded.
{
"id": "evt_9f1c...",
"type": "booking.created",
"created_at": "2026-06-12T18:00:00Z",
"org_id": "...",
"data": { "...": "shape depends on the event type" }
}Delivery is durable: each event is enqueued before the first send, retried on a fixed backoff, then dead-lettered if every attempt fails. Idempotent on id — the same event re-delivered is a no-op for your receiver.