Skip to content
Developers · Server

HTTP API

For your servers: create and run tournaments, add players, sign your own users in, read results. The full reference, with every field, is at api.ocheso.com/docs. This page is the map.

Basics

  • Base URL https://api.ocheso.com. JSON in, JSON out, UTF-8.
  • Your server authenticates with an organisation secret key: Authorization: Bearer ochs_…. Make one in Studio → Developers, with only the scopes it needs: players, tournaments, invites, read.
  • A request that carries an Origin header is refused with 400: it came from a browser, which means the key is in a web page. Rotate any key that ever was.
  • Times are ISO 8601 in UTC. Clocks are in seconds.

Keys and tokens

TokenWho holds itLivesUsed for
ochs_…Your serverUntil revokedEverything on this page.
ochp_…Your page, for a moment10 minutesSigning one of your users into a widget.
oche_…The widget12 h or 7 daysThe player's actions inside the frame. You never handle it.
whsec_…Your serverUntil rotatedChecking webhook signatures.

Ocheso stores only a fingerprint of each, so a lost key can't be shown again: revoke it and make another.

Platform routes

Everything under /v1/platform takes a secret key and acts as your organisation.

RouteDoes
POST /v1/platform/player-tokensA 10-minute player token for one of your users; optionally limited to one tournament and entering them.
GET /v1/platform/tournamentsYour organisation's tournaments.
POST /v1/platform/tournamentsCreate one. The reply carries its hosted page and ready-made embed snippets.
GET · PATCH /v1/platform/tournaments/{slug}Read or change one.
POST /v1/platform/tournaments/{slug}/publishOpen entries. Also start, finish and archive.
POST /v1/platform/tournaments/{slug}/playersAdd up to 500: by email (invited) or by external_id (entered).
DELETE /v1/platform/tournaments/{slug}/players/{external_id}Take one of your users out.
GET /v1/platform/tournaments/{slug}/rosterWho is in or waiting, with external_id for your users. Also rounds and standings.
DELETE /v1/platform/players/{external_id}Erase one of your users: anonymised in past results, your id forgotten.

Create a tournament

curl
curl -s https://api.ocheso.com/v1/platform/tournaments \
  -H "Authorization: Bearer $OCHESO_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: friday-blitz-2026-11-06" \
  -d '{
    "title": "Friday Blitz",
    "game": "chess", "variant": "standard",
    "format": "arena", "arena_minutes": 60,
    "clock_base_s": 180, "clock_increment_s": 2,
    "starts_at": "2026-11-06T18:00:00Z",
    "autopilot": true, "min_players": 4
  }'
# 201 -> the tournament, plus hosted_url and embed: {script, iframe, link}

Formats are swiss (with rounds_count), round_robin, knockout and arena (with arena_minutes). Games are chess (standard) and checkers (international or brazilian). Your organisation's events are unrated and off Ocheso's public list unless you say otherwise.

Add players

curl
curl -s https://api.ocheso.com/v1/platform/tournaments/friday-blitz/players \
  -H "Authorization: Bearer $OCHESO_SECRET_KEY" -H "Content-Type: application/json" \
  -d '{"players": [
        {"email": "amina@example.com", "name": "Amina N."},
        {"external_id": "user-42", "name": "Jean-Paul M."}
      ]}'
# Emails are invited (and entered when they sign in with that address);
# your own users, by external_id, are entered at once.

The rest of the API

GroupWho calls itWhat's in it
PlatformYour server, with ochs_The routes above.
EmbedThe widget itselfTournament bundles, schedules, games and the widget's own sessions. Public reads are open to any origin and cached for a few seconds; you may read GET /v1/embed/t/{slug} to build your own display.
StudioStudio, as a signed-in organiserOrganisations, team, keys, webhooks, brand, players, installs and autopilot controls. Everything Studio does is here, under /v1/orgs.
InternalOcheso's autopilotThe scheduler's tick. Not callable from outside.

Errors

Errors are JSON with a sentence you can show and a code you can branch on.

Response
HTTP/1.1 409 Conflict
Content-Type: application/json

{"detail": "Entries are closed: the tournament has started.", "code": "conflict"}
StatusMeans
400Malformed, or a secret key sent from a browser (server_only).
401Missing, unknown or revoked key; an expired token or session.
403The key lacks the scope, or the organisation is suspended.
404No such tournament for your organisation (others' events look the same as missing).
409The state doesn't allow it: entries closed, a round already paired, full.
422A field is wrong; detail names it. Unknown fields are refused, not ignored.
429Too many requests (rate_limited). Retry after the seconds in Retry-After.
503Ocheso can't reach its database for a moment. Retry with backoff.

Retries and idempotency

Send Idempotency-Keyon a POST (any 1–255 visible characters, unique per action) and a retry within 24 hours gets the first reply instead of acting twice. Entering a player is an upsert and inviting an address twice answers "already", so those are safe to repeat even without one.

Limits

CommunityClubFederation
Player tokens a minute606003,000
Players per event644,0964,096
Live secret keys21050
Webhook endpoints–520
Email invites a day5005,00050,000
One player token serves every widget on a page for 10 minutes; the loader keeps it for 8. Minting one per page view of a signed-in user is the most you should need.

Every route, field and response is in the API reference.