SwingOps

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)

GET/api/public/v1/bookings

Range query over bookings by start, end, and status.

GET/api/public/v1/families

Paginated families with primary contact, athlete summary, wallet balance, and active/lapsed status. Params: limit (≤200), offset. Scope: families:read.

GET/api/public/v1/availability

Open start times for a lesson type, already filtered by your booking rules. Scope: availability:read.

GET/api/public/v1/lesson-types

Your bookable lesson types with duration and price. Scope: lesson_types:read.

POST/api/public/v1/bookings

Create 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.

PATCH/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.

POST/api/public/v1/bookings/hold

Hold a slot briefly (does not confirm or charge). Scope: bookings:hold.

POST/api/public/v1/contacts

Upsert 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.