A versioned OAuth 2.0 REST API and signed webhooks for your tournament data — contacts, live leaderboards, registrations, invitations, and more.
Every API call requires a short-lived Bearer token obtained from your API client. Create a client in Settings → API access, choose its scopes, then exchange credentials for a token.
Create an API client
Go to Settings → API access in your dashboard. Click Add client, name it, choose its scopes, and save. Copy the client secret shown once — it cannot be retrieved again.
Exchange credentials for a token
POST to /api/v1/oauth/token with grant_type=client_credentials and your client_id / client_secret (HTTP Basic or JSON body). You receive an access_token valid for 1 hour.
curl -s -X POST https://scramblesync.com/api/v1/oauth/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials"}'
# Response:
# { "access_token": "sat_…", "token_type": "Bearer",
# "expires_in": 3600, "scope": "contacts:read tournaments:read" }Call the API
Include Authorization: Bearer <access_token> on every request. When the token expires (after 1 hour), request a new one using your client credentials.
curl https://scramblesync.com/api/v1/contacts \
-H "Authorization: Bearer $TOKEN"A single base URL — https://scramblesync.com/api/v1 — covers every resource. All calls are tenant-isolated; a token can only ever see its own organization's data.
| Resource | What you can do | Scope(s) needed |
|---|---|---|
| Contacts & tags | List, create, update, delete contacts; bulk import; export CSV; manage tags. | contacts:read / contacts:write |
| Tournaments | List, read, and update tournaments; configure holes and scoring; change status; read teams and leaderboard. | tournaments:read / tournaments:write |
| Scores & scorecards | Read per-team hole scores; read hole-by-hole scorecards; correct scores. | scores:write / scorecards:read |
| Registrations | List and export registrations; issue refunds. | registrations:read / registrations:write |
| Invitations | Create, schedule, and read invitations; pull delivery stats. | invitations:read / invitations:write |
| Webhooks | Create, update, delete, and replay webhook endpoints; read delivery history. | webhooks:read / webhooks:write |
| Live-day ops | Check in teams/players; move teams; send messages; record bracket results. | checkin:write / teams:write / messages:write / brackets:write |
| Side games | Read brackets, raffles, auctions, flights, announcements, series standings. | brackets:read / raffles:read / auctions:read / announcements:read / flights:read / series:read |
Full scope list and per-endpoint requirements are in the interactive reference.
Pick an endpoint, drop in your token, and copy a ready-to-run command. This composes requests against the real v1 API — it does not send them from your browser.
Want to send real requests? Open the live reference or create an API client to mint your first token.
ScrambleSync pushes signed HTTP POST requests to your endpoint the moment an event fires — no polling required. Every delivery is retried with exponential backoff.
contact.created
A new contact is added to your organization.
registration.created
A golfer registers for one of your tournaments.
registration.paid
A registration payment is confirmed by Stripe.
invitation.delivered
An outbound invitation email is delivered.
Signature verification
Every delivery includes an X-ScrambleSync-Signature header of the form t=<timestamp>,v1=<hex-hmac>. Compute HMAC-SHA256 over t.<raw_body> using your signing secret and compare with a constant-time comparison. Reject deliveries where the timestamp is more than 5 minutes old.
Every non-2xx response shares the same envelope. Include X-Request-Id when contacting support.
{
"error": "Token does not have the required scope",
"code": "insufficient_scope",
"request_id": "a3f1c9d2-…"
}invalid_token401 — token missing, expired, or revokedinsufficient_scope403 — token lacks the required scopenot_found404 — resource does not exist or is not yoursvalidation_error400 — request body failed schema validationconflict409 — idempotency key reused with a different bodyrate_limited429 — over 600 req/min; check Retry-AfterExceeding the limit returns 429 with a Retry-After header. The limit is per API client, not per IP.
List endpoints return { data, page: { next_cursor, has_more } }. Pass ?cursor=&limit= (max 200, default 50) to page through results.
Include an Idempotency-Key header (up to 128 chars) on creation endpoints — contacts, imports, tags, invitations, and webhooks. Replaying the same key returns the original response.