Roundr API · v1.0.0 · https://api.roundr.com

Dokumentacja API

Odczytuj turnieje, śledź je na żywo i importuj zgłoszenia oraz mecze z własnych systemów.

Wprowadzenie

API Roundr to to samo API, z którego korzystają aplikacje Roundr. Komunikuje się w formacie JSON przez HTTPS, a każda ścieżka zaczyna się od /v1.

Integracje uwierzytelniają się kluczem API. Aplikacje przeglądarkowe korzystają z sesji zalogowanej osoby, a tablety na kortach i ekrany z poświadczeń otrzymanych podczas dołączania.

Klucze API

  1. Administrator organizacji otwiera jej ustawienia w Sterowaniu i tworzy klucz.
  2. Wybierz zakresy klucza, czyli odczyt turniejów, import uczestników i meczów albo oba, oraz datę jego wygaśnięcia.
  3. Skopiuj klucz. Zaczyna się od key_ i jest wyświetlany tylko raz.

Klucz może robić dokładnie to, na co pozwalają jego zakresy, i nic więcej. Nigdy nie punktuje meczu ani nie zmienia drabinki.

Uwierzytelnianie

Wyślij klucz w nagłówku Authorization jako token typu bearer albo w nagłówku X-API-Key.

curl https://api.roundr.com/v1/tournaments \
  -H "Authorization: Bearer key_..."

Błędy

Każdy błąd zawiera stały error_code obok czytelnego komunikatu message. Decyzje podejmuj na podstawie kodu; komunikat jest przeznaczony dla ludzi i może się zmienić.

{
  "ok": false,
  "error": { "code": 404, "message": "Not found", "error_code": "not_found" }
}

Limity żądań

Każdy klucz ma limit dla każdego rodzaju żądań, znacznie powyżej tego, co zwykle wysyła integracja. Po jego przekroczeniu odpowiedzią jest 429 z kodem błędu rate_limited, a nagłówek Retry-After podaje, kiedy spróbować ponownie.

Czas rzeczywisty

Aby śledzić turniej na żywo, odczytaj raz jego migawkę, a następnie nasłuchuj jego strumienia zdarzeń server-sent events. Powiadomienie mówi tylko, że coś się zmieniło: aby poznać aktualny stan, odczytaj zasób ponownie. Po przerwie wznów od ostatniego kursora albo odczytaj zmiany, które nastąpiły od niego.

Wersjonowanie

Zmiany w ramach /v1 wyłącznie dodają: nowe endpointy, nowe pola i nowe kody błędów. Nic, na czym klient już polega, nie jest usuwane ani zmieniane.

Endpointy

Wszystkie endpointy udostępniane przez API, wygenerowane z dokumentu OpenAPI, na podstawie którego testowany jest serwer. Opisy są w języku angielskim.

Dokument OpenAPI

Authentication

Browser sign-in through the Cognito Hosted UI, and the caller's own session. Served on the shared API host and on every tenant host; a session is issued by, and only valid on, the host that issued it.

Start a browser sign-in

GET/v1/auth/loginPubliczny

Reached by navigation, not by fetch. Stores a one-time sign-in transaction (state, nonce, PKCE verifier), sets a short-lived roundr_login cookie bound to it, and redirects to the Cognito Hosted UI, which returns to /v1/auth/callback on the same host.

return_to is a path on the page's own origin to land on afterwards. Anything that is not a plain absolute path (protocol-relative, a backslash, whitespace, an API path) is replaced by /, so a bad link still signs the user in.

intent=signup opens the Hosted UI on its sign-up page instead of its sign-in page, with the same transaction and the same callback: anyone may create an account, which belongs to no organization until one admits it or the person creates one (POST /v1/organizations). Any other value is a sign-in.

Not available on hosts that serve no sign-in, or where Cognito is not configured.

Parametry

  • return_tozapytanie · string

  • intentzapytanie · string

  • providerzapytanie · string

    A federated provider's name on the user pool, from /v1/auth/options, which sends the browser straight to that provider rather than to the Hosted UI's own page. Any other value opens the Hosted UI.

Odpowiedzi

  • 302To the Cognito Hosted UI. Sets roundr_login.
  • 404Sign-in is not available on this host.
  • 429Too many sign-ins started from this IP, or, for a caller already signed in, its
Przykład
curl 'https://api.roundr.com/v1/auth/login'

Complete a browser sign-in

GET/v1/auth/callbackPubliczny

Where the Hosted UI returns the browser. Requires both the state it echoes and the roundr_login cookie the same browser was given; either alone is refused, which is what stops one person's sign-in being completed in another's browser. The transaction is used up whether or not the callback succeeds.

On success the code is exchanged with PKCE, the ID token is verified (signature, issuer, audience, nonce), and the Cognito identity is found by issuer and subject or, the first time, registered as a new account. Registration needs a verified email address that no other account holds; accounts are never linked by email. A new account belongs to no organization.

The browser is redirected to its return_to with a new roundr_session cookie, or, when the callback registered the account, first to /sign-in/welcome with that return_to, where the person confirms the name the provider gave (DEV-713). Any session it already had is ended. On failure it is redirected to /sign-in with signin_error set to one of failed, email_unverified, email_in_use, account_disabled or unavailable; that list is append-only.

Parametry

  • codezapytanie · string

  • statezapytanie · string

Odpowiedzi

  • 302To the page, signed in or with signin_error. Always clears roundr_login.
  • 404Sign-in is not available on this host.
  • 429Too many callbacks from this IP, or, for a caller already signed in, its read
Przykład
curl 'https://api.roundr.com/v1/auth/callback'

Who the caller is, and for which organization

GET/v1/auth/sessionWymaga uwierzytelnienia

Answers for any credential. principal is present when the request acts for an organization: on a tenant host when the user is a member of it, on the shared API host once one is chosen. csrf_token is present for a browser session and must accompany every write it makes, as X-CSRF-Token.

Odpowiedzi

  • 200The caller.
  • 401No credential, or one that no longer authenticates.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/auth/session' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "user": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "email": "string"
    },
    "principal": {
      "type": "user",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "organization_admin"
      ],
      "tournament_roles": [
        {
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "role": "tournament_director"
        }
      ],
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "organizations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "slug": "string",
        "kind": {}
      }
    ],
    "active_organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "csrf_token": "string",
    "operator": true,
    "public_origin": "string",
    "legal_pending": [
      {
        "document": "terms",
        "version": "string",
        "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "organization_name": "string"
      }
    ]
  }
}

Choose the organization a browser session acts for

POST/v1/auth/organizationWymaga uwierzytelnienia

On the shared API host only; a tenant host acts for its own organization. The user must be an active member. The session is replaced by a new one, because its authority changes, so the response carries a new CSRF token and sets a new roundr_session.

Treść żądania

  • organization_idstring (uuid)wymagany

Odpowiedzi

  • 200The new session.
  • 401No session.
  • 403csrf_rejected: no Roundr page Origin, or a wrong X-CSRF-Token.
  • 404Not an organization the user is an active member of.
  • 422Not a browser session, a tenant host, or no organization id.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/organization' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
}'
200
{
  "ok": true,
  "data": {
    "user": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "email": "string"
    },
    "principal": {
      "type": "user",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "organization_admin"
      ],
      "tournament_roles": [
        {
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "role": "tournament_director"
        }
      ],
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "organizations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "slug": "string",
        "kind": {}
      }
    ],
    "active_organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "csrf_token": "string",
    "operator": true,
    "public_origin": "string",
    "legal_pending": [
      {
        "document": "terms",
        "version": "string",
        "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "organization_name": "string"
      }
    ]
  }
}

End the browser session

POST/v1/auth/logoutWymaga uwierzytelnienia

Ends the session and clears its cookie. Always succeeds, signed in or not.

logout_url, when present, ends the Cognito Hosted UI's own session too. A page should navigate to it: otherwise the next sign-in on that browser completes without a password, which on a shared venue laptop signs in the previous user.

Odpowiedzi

  • 200Signed out.
  • 403csrf_rejected, for a browser session without its page Origin and token.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/logout' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "logout_url": "https://example.com"
  }
}

Which ways in this host offers

GET/v1/auth/optionsPubliczny

What the sign-in page draws: a password form when this instance signs people in with an email address and a password on its own page (/v1/auth/password/*), and a button per federated provider the web app client supports, read from Cognito, which /v1/auth/login?provider= sends the browser straight to. Both are false and empty on a host that offers no sign-in, where the page falls back to the Hosted UI link.

Odpowiedzi

  • 200The options.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/auth/options'
200
{
  "ok": true,
  "data": {
    "password": true,
    "providers": [
      "string"
    ]
  }
}

Sign in with an email address and a password

POST/v1/auth/password/sign-inPubliczny

Sign-in on Roundr's own page, beside the Hosted UI flow: the server asks Cognito with the password, verifies the tokens it answers with, finds or registers the account exactly as /v1/auth/callback does (DEV-11), ends any session the browser already had and sets a new roundr_session cookie. The page then re-reads /v1/auth/session and goes to return_to, reduced to a plain path on the page's origin as the Hosted UI's is.

Anonymous and state-changing, so it is accepted only with a Roundr page's Origin (csrf_rejected otherwise) and limited per address. A wrong password and an unknown address are one refusal, invalid_credentials. An address not yet confirmed is email_unverified; an account Cognito wants an authenticator code or a new password from is sign_in_challenge, which the Hosted UI takes.

Treść żądania

  • emailstringwymagany

  • passwordstringwymagany

  • return_tostring

Odpowiedzi

  • 200Signed in; sets roundr_session.
  • 401invalid_credentials.
  • 403csrf_rejected, email_unverified, account_disabled, password_reset_required or sign_in_challenge.
  • 404Password sign-in is not offered on this host.
  • 409email_in_use: the address belongs to another Roundr account.
  • 422validation_failed.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503sign_in_unavailable: Cognito could not be asked.
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/password/sign-in' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "password": "string",
  "return_to": "string"
}'
200
{
  "ok": true,
  "data": {
    "return_to": "string",
    "registered": true
  }
}

Create a Cognito user for an email address

POST/v1/auth/password/sign-upPubliczny

Registers the address on the user pool, which sends it a confirmation code; /v1/auth/password/confirm completes it. The Roundr account itself is created at the first sign-in (DEV-11). Same Origin check and per-address limit as sign-in.

Treść żądania

  • emailstringwymagany

  • namestringwymagany

  • passwordstringwymagany

Odpowiedzi

  • 200Done. Nothing to show but the next step.
  • 403csrf_rejected.
  • 404Password sign-in is not offered on this host.
  • 409email_in_use.
  • 422validation_failed or password_policy.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503sign_in_unavailable.
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/password/sign-up' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "name": "string",
  "password": "string"
}'
200
{
  "ok": true,
  "data": {}
}

Confirm an address with the code Cognito sent it

POST/v1/auth/password/confirmPubliczny

Treść żądania

  • emailstringwymagany

  • codestringwymagany

Odpowiedzi

  • 200Done. Nothing to show but the next step.
  • 403csrf_rejected.
  • 404Password sign-in is not offered on this host.
  • 410code_expired: ask for another with /v1/auth/password/resend.
  • 422validation_failed or code_invalid.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503sign_in_unavailable.
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/password/confirm' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "code": "string"
}'
200
{
  "ok": true,
  "data": {}
}

Send the confirmation code again

POST/v1/auth/password/resendPubliczny

Answers 200 for any well-formed address, known to the pool or not, so the route lists no addresses. Limited more tightly than sign-in: each call costs a message.

Treść żądania

  • emailstringwymagany

Odpowiedzi

  • 200Done. Nothing to show but the next step.
  • 403csrf_rejected.
  • 404Password sign-in is not offered on this host.
  • 422validation_failed.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503sign_in_unavailable.
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/password/resend' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string"
}'
200
{
  "ok": true,
  "data": {}
}

Send a password reset code

POST/v1/auth/password/forgotPubliczny

Answers 200 for any well-formed address, known to the pool or not; /v1/auth/password/reset takes the code with the new password. Limited as resend is.

Treść żądania

  • emailstringwymagany

Odpowiedzi

  • 200Done. Nothing to show but the next step.
  • 403csrf_rejected.
  • 404Password sign-in is not offered on this host.
  • 422validation_failed.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503sign_in_unavailable.
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/password/forgot' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string"
}'
200
{
  "ok": true,
  "data": {}
}

Set a new password with the reset code

POST/v1/auth/password/resetPubliczny

Treść żądania

  • emailstringwymagany

  • codestringwymagany

  • passwordstringwymagany

Odpowiedzi

  • 200Done. Nothing to show but the next step.
  • 403csrf_rejected.
  • 404Password sign-in is not offered on this host.
  • 410code_expired: ask for another with /v1/auth/password/forgot.
  • 422validation_failed, code_invalid or password_policy.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503sign_in_unavailable.
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/password/reset' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "code": "string",
  "password": "string"
}'
200
{
  "ok": true,
  "data": {}
}

Turn a one-time court or display code into a credential

POST/v1/auth/redeemPubliczny

What /join/{code} and /display/join/{code} call. The code came from a QR image or was read out as a PIN; it is single-use and short-lived, and redeeming it consumes it in the same transaction that creates the credential, so two scans of one code yield one device and one redemption_code_redeemed.

With the default cookie transport a browser receives a roundr_session cookie naming the new credential and never sees its secret; the page then replaces its URL with the clean Panel or Display URL. Any session the browser already had is ended. With bearer, for a native client's secure store, the response carries the crt_ or dsp_ secret exactly once and sets no cookie.

Anonymous and limited per client IP, sized for a crew setting up a hall behind one address. A code that is found and refused counts against itself and locks after repeated refusals; a guess that finds nothing is only ever counted per IP. Not available on hosts that serve no sign-in.

Treść żądania

  • codestringwymagany

  • purposestringwymagany

    Which page the code was presented on; a code for the other purpose is unknown.

    courtdisplay

  • transportstring

    cookiebearer

Odpowiedzi

  • 200The device's credential, as a session cookie or as a bearer secret.
  • 404redemption_code_invalid: no such code, another organization's on this host,
  • 409redemption_code_redeemed: the code has already become a credential.
  • 410redemption_code_expired: ask for a new code.
  • 422Missing or malformed fields.
  • 429rate_limited for too many attempts from this IP, or for a caller already
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/redeem' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "string",
  "purpose": "court",
  "transport": "cookie"
}'
200
{
  "ok": true,
  "data": {
    "credential": "string",
    "principal": {
      "type": "user",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "organization_admin"
      ],
      "tournament_roles": [
        {
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "role": "tournament_director"
        }
      ],
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "expires_at": "2026-09-27T10:30:00Z",
    "csrf_token": "string"
  }
}

Tell what a typed or scanned code is, without spending it

POST/v1/auth/codes/inspectWymaga uwierzytelnienia

The join screen asks this first, so one field takes a court code, a display code and a court setup code alike. A court or display code is named by its purpose and then redeemed at /v1/auth/redeem; its state is not reported here, so a spent or expired one is refused at redemption. A setup code comes with its tournament's name and courts, one of which the tablet then joins at /v1/auth/setup/join. Limited per address like redemption, and a refused setup code counts towards its lock.

Treść żądania

  • codestringwymagany

Odpowiedzi

  • 200What the code is.
  • 404redemption_code_invalid: no such code, or another organization's on this host.
  • 409redemption_code_redeemed: the setup code has admitted as many tablets as it allows.
  • 410redemption_code_expired: the code expired or was withdrawn; ask for a new one.
  • 422Missing or malformed fields.
  • 429rate_limited for too many attempts from this IP, or for a caller already
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/codes/inspect' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "string"
}'
200
{
  "ok": true,
  "data": {
    "kind": "court",
    "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "tournament_name": "string",
    "courts": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

Make this device a court's Panel with a court setup code

POST/v1/auth/setup/joinWymaga uwierzytelnienia

The tablet chose court_id from the setup code's courts. It gets a court credential exactly as a court code gives one, created from a court code of its own that names the setup code, and the setup code counts one more device. A browser gets a session cookie, a native client (bearer) the secret once.

Treść żądania

  • codestringwymagany

  • court_idstring (uuid)wymagany

  • transportstring

    cookiebearer

Odpowiedzi

  • 200The device's credential, as a session cookie or as a bearer secret.
  • 404redemption_code_invalid: no such code, or another organization's on this host.
  • 409redemption_code_redeemed: the setup code has admitted as many tablets as it allows.
  • 410redemption_code_expired: the code expired or was withdrawn; ask for a new one.
  • 422Missing or malformed fields.
  • 429rate_limited for too many attempts from this IP, or for a caller already
Przykład
curl -X POST 'https://api.roundr.com/v1/auth/setup/join' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "string",
  "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "transport": "cookie"
}'
200
{
  "ok": true,
  "data": {
    "credential": "string",
    "principal": {
      "type": "user",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "organization_admin"
      ],
      "tournament_roles": [
        {
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "role": "tournament_director"
        }
      ],
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "expires_at": "2026-09-27T10:30:00Z",
    "csrf_token": "string"
  }
}

List a tournament's court setup codes

GET/v1/tournaments/{tournamentId}/setup-codesWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization. Newest first, including codes that expired or were withdrawn in the last day. A code's plaintext is never shown again after it was issued.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The setup codes.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/setup-codes' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "setup_codes": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "kind": "qr",
        "expires_at": "2026-09-27T10:30:00Z",
        "max_devices": 0,
        "devices_joined": 0,
        "revoked": true
      }
    ]
  }
}

Issue a court setup code

POST/v1/tournaments/{tournamentId}/setup-codesWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization. Whoever sets the courts up enters it on each tablet and chooses the tablet's court there. It admits at most max_devices tablets, lives lifetime_seconds (eight hours unless given, a day at most) and can be withdrawn. A PIN is eight digits unused by any court or display code; join_url opens the same choice for a QR code, with the code in the fragment: it admits tablet after tablet for hours, and a fragment reaches neither a server log nor a referrer.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • kindstring

    qrpin

  • max_devicesintegerwymagany

  • lifetime_secondsinteger

Odpowiedzi

  • 201The setup code, with its one copy of the plaintext.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409tournament_closed: the tournament is closed, and admits no device (DEV-25).
  • 422validation_failed: a kind other than qr or pin, a cap outside 1 to 64, or a lifetime outside a minute to a day.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/setup-codes' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "kind": "qr",
  "max_devices": 1,
  "lifetime_seconds": 60
}'
201
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "kind": "qr",
    "expires_at": "2026-09-27T10:30:00Z",
    "max_devices": 0,
    "devices_joined": 0,
    "revoked": true,
    "code": "string",
    "join_url": "https://example.com"
  }
}

Withdraw a court setup code

DELETE/v1/tournaments/{tournamentId}/setup-codes/{setupCodeId}Wymaga uwierzytelnienia

No further tablet joins with it. Tablets it already admitted keep their court; each is revoked on its own, as any court device is. Withdrawing a code already withdrawn answers revoked: false.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • setupCodeIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200Whether a live code was withdrawn.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404The tournament is outside the principal's scope, or the id is malformed.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/tournaments/{tournamentId}/setup-codes/{setupCodeId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "revoked": true
  }
}

Issue a one-time code that admits a scoring device to a court

POST/v1/tournaments/{tournamentId}/courts/{courtId}/redemption-codesWymaga uwierzytelnienia

For a tournament director of the tournament or an administrator of the organization. The court must belong to the caller's organization and to the tournament in the path, checked with the organization from the caller's principal; a court outside either is not found. join_url is the page the QR image should encode, on this host's page origin.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • courtIdścieżka · string (uuid)wymagany

Treść żądania

  • kindstring

    A QR code is a 256-bit secret; a PIN is eight digits a referee can read out, with a shorter life.

    qrpin

  • lifetime_secondsinteger

    Defaults to fifteen minutes for a QR code and ten for a PIN; clamped to a minute and an hour.

Odpowiedzi

  • 201The code, shown once, and the page URL that redeems it.
  • 401No credential.
  • 403The caller is not a director of this tournament or an administrator of the organization.
  • 404No such court or display under this organization and tournament.
  • 409tournament_closed: the tournament is closed, and admits no device (DEV-25).
  • 422A kind that is not qr or pin, or a lifetime that is not a whole number.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts/{courtId}/redemption-codes' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "kind": "qr",
  "lifetime_seconds": 60
}'
201
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "code": "string",
    "kind": "qr",
    "purpose": "court",
    "expires_at": "2026-09-27T10:30:00Z",
    "join_url": "https://example.com"
  }
}

Issue a one-time code that admits a venue display

POST/v1/tournaments/{tournamentId}/displays/{displayId}/redemption-codesWymaga uwierzytelnienia

As for a court code, for a named display. The redeemed display session reads the approved venue projection and cannot score.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • displayIdścieżka · string (uuid)wymagany

Treść żądania

  • kindstring

    A QR code is a 256-bit secret; a PIN is eight digits a referee can read out, with a shorter life.

    qrpin

  • lifetime_secondsinteger

    Defaults to fifteen minutes for a QR code and ten for a PIN; clamped to a minute and an hour.

Odpowiedzi

  • 201The code, shown once, and the page URL that redeems it.
  • 401No credential.
  • 403The caller is not a director of this tournament or an administrator of the organization.
  • 404No such court or display under this organization and tournament.
  • 409tournament_closed: the tournament is closed, and admits no device (DEV-25).
  • 422A kind that is not qr or pin, or a lifetime that is not a whole number.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/displays/{displayId}/redemption-codes' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "kind": "qr",
  "lifetime_seconds": 60
}'
201
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "code": "string",
    "kind": "qr",
    "purpose": "court",
    "expires_at": "2026-09-27T10:30:00Z",
    "join_url": "https://example.com"
  }
}

Create an organization

POST/v1/organizationsWymaga uwierzytelnienia

For any browser session on the shared API host: an account is free to create, and so is an organization, which the person then administers (DEV-15). The slug is derived from the name and is an operator's handle only; a tenant hostname is a separate provisioning step. An account creates at most 5 organizations (validation_errors.organizations past that), a bound on what a script can leave behind rather than a security boundary.

As choosing an organization, the session is replaced by one acting for the new organization as organization_admin, so the response carries a new CSRF token and sets a new roundr_session. A tenant host acts for its own organization and creates none.

Treść żądania

  • namestringwymagany

    The organization's name, as its staff and players will see it.

  • kindobject

    What the organization is (DEV-39), the person's choice.

Odpowiedzi

  • 201The new session, acting for the new organization.
  • 401No session.
  • 403csrf_rejected: no Roundr page Origin, or a wrong X-CSRF-Token.
  • 422validation_failed: no name or one over 200 characters (name), a kind that is
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organizations' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "kind": {}
}'
201
{
  "ok": true,
  "data": {
    "user": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "email": "string"
    },
    "principal": {
      "type": "user",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "organization_admin"
      ],
      "tournament_roles": [
        {
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "role": "tournament_director"
        }
      ],
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "organizations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "slug": "string",
        "kind": {}
      }
    ],
    "active_organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "csrf_token": "string",
    "operator": true,
    "public_origin": "string",
    "legal_pending": [
      {
        "document": "terms",
        "version": "string",
        "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "organization_name": "string"
      }
    ]
  }
}

Account

What a signed-in person sees of their own playing, across every tournament that linked one of its players to their account. Read by the account, not by a principal: a person with no organization chosen has matches to see, and a device or a machine key has none.

Tell what a staff invitation offers, without spending it

POST/v1/staff-invitations/inspectWymaga uwierzytelnienia

Open to whoever holds the code, signed in or not, so the invitation page can say what signing up is for: the tournament, its organization, the roles and who sent it. On a customer's host another organization's invitation is unknown. A spent, withdrawn or expired invitation is refused as redemption would refuse it, and the refusal counts towards its lock; one the signed-in caller redeemed reads as accepted instead. Invitations looked at or redeemed from one client address are limited to thirty an hour, and refused with 429 while that cannot be checked.

Treść żądania

  • codestringwymagany

    The fragment of the invitation link.

Odpowiedzi

  • 200What the invitation offers.
  • 404redemption_code_invalid: no such invitation, or another organization's on this
  • 409redemption_code_redeemed: someone has already accepted it.
  • 410redemption_code_expired: it expired or was withdrawn; ask for a new one.
  • 422validation_failed: no code.
  • 429rate_limited for too many invitations tried from this address;
Przykład
curl -X POST 'https://api.roundr.com/v1/staff-invitations/inspect' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "string"
}'
200
{
  "ok": true,
  "data": {
    "invitation": {
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_name": "string",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "organization_name": "string",
      "roles": [
        "tournament_director"
      ],
      "invited_by_name": "string",
      "expires_at": "2026-09-27T10:30:00Z",
      "tournament_closed": true,
      "accepted": true
    }
  }
}

Accept a staff invitation as the signed-in person

POST/v1/staff-invitations/redeemWymaga uwierzytelnienia

The invitation is found by its keyed digest and consumed, with its row locked, in the transaction that grants its roles, so it works once: two people accepting one link at once yield one grant and one redemption_code_redeemed. The person becomes a member of the organization if they were not one; a role they already held stays as it was, and granted lists only the new ones. Each grant names whoever sent the invitation as its grantor, and the invitation names who redeemed it. The caller who redeemed it asking again is answered as the first time, with nothing granted. A closed tournament is refused as tournament_closed and a person suspended in the organization with 403, neither counting against the invitation. Roles are read on every request, so a session on the organization's own host acts on them at once; on the shared host the client then chooses the organization at /v1/auth/organization.

Treść żądania

  • codestringwymagany

Odpowiedzi

  • 200The roles are the caller's.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account; or a person
  • 404redemption_code_invalid: no such invitation, or another organization's on this
  • 409redemption_code_redeemed: someone else accepted it first; or tournament_closed.
  • 410redemption_code_expired: it expired or was withdrawn.
  • 422validation_failed: no code.
  • 429rate_limited for too many invitations tried from this address, or a spent
Przykład
curl -X POST 'https://api.roundr.com/v1/staff-invitations/redeem' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "string"
}'
200
{
  "ok": true,
  "data": {
    "redemption": {
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "tournament_director"
      ],
      "granted": [
        "tournament_director"
      ]
    }
  }
}

Delete the signed-in person's account

DELETE/v1/meWymaga uwierzytelnienia

GDPR Art. 17, by the person's own hand (DEV-37). confirmation is the address the account signs in with, as the person typed it (case and surrounding spaces aside), which the client collects in a dialog saying what is deleted and what stays with the organizers. The sign-in behind the request must be recent, within details.within_seconds of a 403 reauthentication_required: a browser session's own sign-in (choosing an organization keeps it), or a token's auth_time.

In one transaction the account's row is scrubbed and disabled (its name becomes "Deleted account" wherever an organization's records still name it), its sign-in identities, memberships, roles, follows and umpired matches are deleted, its pending registrations withdrawn, and every tournament player and registration unlinked from it. Tournament records stay the organizers'. An organization that held nothing but the account goes with it. Afterwards the session cookie is expired, every other session of the account ends on its next request, and the identity provider's user is removed where this deployment administers it.

Treść żądania

  • confirmationstringwymagany

    The address the account signs in with.

Odpowiedzi

  • 200Deleted. The session cookie is expired in the same answer.
  • 401No session or token, or the account was already gone.
  • 403reauthentication_required: the sign-in is older than details.within_seconds;
  • 409organization_needs_administrator: the account is the only administrator of
  • 422validation_failed on confirmation: not the address the account signs in with.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "confirmation": "string"
}'
200
{
  "ok": true,
  "data": {
    "deleted": true
  }
}

A copy of everything Roundr holds about the signed-in person

GET/v1/me/exportWymaga uwierzytelnienia

GDPR Art. 15 and 20 (DEV-37): a JSON file of what Roundr holds about the person across every organization, which the browser saves. format is roundr.personal-data and version 1; sections holds one object per area: the account (profile, date of birth, classes, sharing), sign-in identities (issuer and subject), organizations and roles, registrations, the tournaments' players linked to the account with their matches, followed players, club memberships with the numbers the club keeps, umpired matches, and a count of the organizations' records that name the account as who did something. A section added later is additive; a changed shape moves version.

Spends a budget of its own, ten an hour for a person.

Odpowiedzi

  • 200The file, as an attachment named roundr-personal-data-YYYY-MM-DD.json.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/export' \
  -H 'Authorization: Bearer key_...'
200
{
  "format": "roundr.personal-data",
  "version": 1,
  "produced_at": "2026-09-27T10:30:00Z",
  "account_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "sections": {}
}

The account's own matches

GET/v1/me/matchesWymaga uwierzytelnienia

The matches the signed-in person is to play and the results of those they played, in every tournament whose staff linked one of its players to their account (DEV-15). On a tenant host, that organization's tournaments alone; on the shared API host, every organization's. A draft or cancelled tournament's matches are not shown, nor a suspended organization's.

Built field by field, as Live's projection is: each match carries what the tournament's own reads show that player, the sides' display names, the court, the reference, the start and the score, and nothing about any account. Upcoming matches are soonest first, one with no start yet last; results are newest first.

Parametry

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Odpowiedzi

  • 200The two lists, either possibly empty.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404A junior_id that is not a junior of the caller's.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/matches' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "upcoming": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "venue_time_zone": "string",
          "organization_name": "string",
          "on_live": true
        },
        "side": "home",
        "sides": {
          "home": "string",
          "away": "string"
        },
        "court_name": "string",
        "external_ref": "string",
        "scheduled_start": "2026-09-27T10:30:00Z",
        "status": "scheduled",
        "score": {
          "games": [
            {
              "home": null,
              "away": null,
              "complete": null
            }
          ],
          "games_won": {
            "home": 0,
            "away": 0
          },
          "serving": null,
          "interval": true,
          "winner": null,
          "outcome": null
        }
      }
    ],
    "results": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "venue_time_zone": "string",
          "organization_name": "string",
          "on_live": true
        },
        "side": "home",
        "sides": {
          "home": "string",
          "away": "string"
        },
        "court_name": "string",
        "external_ref": "string",
        "scheduled_start": "2026-09-27T10:30:00Z",
        "status": "scheduled",
        "score": {
          "games": [
            {
              "home": null,
              "away": null,
              "complete": null
            }
          ],
          "games_won": {
            "home": 0,
            "away": 0
          },
          "serving": null,
          "interval": true,
          "winner": null,
          "outcome": null
        }
      }
    ]
  }
}

The league teams the person captains

GET/v1/me/teamsWymaga uwierzytelnienia

The teams the signed-in person captains (DEV-49), withdrawn ones left out. On a tenant host, those of that organization's leagues, or of that club, alone.

Odpowiedzi

  • 200The teams, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/teams' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "teams": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "league": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "season": "string",
          "owner": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "kind": "association"
          }
        },
        "club": null,
        "name": "string",
        "status": "entered",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "entered_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

A team the person captains, with its roster

GET/v1/me/teams/{teamId}Wymaga uwierzytelnienia

With candidates, the club's active members in the league's sport, whom the roster is chosen from.

Parametry

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The team.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no team the person captains.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/teams/{teamId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "players": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "captains": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ],
    "candidates": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

Replace the roster of a team the person captains

PUT/v1/me/teams/{teamId}/rosterWymaga uwierzytelnienia

As the club's administrators do, under the same rule (DEV-49).

Parametry

  • teamIdścieżka · string (uuid)wymagany

Treść żądania

  • membersstring (uuid)[]

  • guestsstring (email)[]

  • namesstring[]

Odpowiedzi

  • 200The team with its new roster.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no team the person captains.
  • 409league_refused with details.reason no_such_account, too_many_guests,
  • 422validation_failed under members.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/teams/{teamId}/roster' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "members": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "guests": [
    "[email protected]"
  ],
  "names": [
    "string"
  ]
}'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "players": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "captains": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ],
    "candidates": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

The season of a team the person captains

GET/v1/me/teams/{teamId}/seasonWymaga uwierzytelnienia

As the club's staff read it (DEV-49).

Parametry

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The season.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no team the person captains.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/teams/{teamId}/season' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "league": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "owner": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "name": "string",
      "sport": "badminton",
      "season": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "points": {
        "win": 0,
        "draw": 0,
        "loss": 0
      },
      "guest_allowance": 0,
      "entries_open": true,
      "live_published": true,
      "rubbers": [
        {
          "code": "string",
          "ruleset": {
            "id": "string",
            "version": "string",
            "engine_version": "string"
          },
          "entry_gender": "men"
        }
      ],
      "created_at": "2026-09-27T10:30:00Z"
    },
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ],
    "table": {
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "position": 0
      },
      "standings": [
        {
          "team": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "club": null
          },
          "played": 0,
          "won": 0,
          "drawn": 0,
          "lost": 0,
          "rubbers_for": 0,
          "rubbers_against": 0,
          "games_for": 0,
          "games_against": 0,
          "points": 0
        }
      ],
      "ties": [
        {
          "fixture": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "division": {
              "id": null,
              "name": null
            },
            "round": 0,
            "position": 0,
            "home": {
              "id": null,
              "name": null,
              "club": null
            },
            "away": {
              "id": null,
              "name": null,
              "club": null
            },
            "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "start_time": "string"
          },
          "home_lineup_given": true,
          "away_lineup_given": true,
          "started": true,
          "decided": true,
          "home_rubbers": 0,
          "away_rubbers": 0,
          "rubbers": [
            {
              "code": null,
              "tournament_id": null,
              "match_id": null,
              "status": null,
              "winner": "home",
              "home_games": null,
              "away_games": null,
              "not_fielded_by": "home"
            }
          ]
        }
      ]
    }
  }
}

A line-up of a team the person captains

GET/v1/me/teams/{teamId}/fixtures/{fixtureId}/lineupWymaga uwierzytelnienia

As the club's staff read it.

Parametry

  • teamIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The line-up.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no fixture of a team the person captains.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/teams/{teamId}/fixtures/{fixtureId}/lineup' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tie": {
      "fixture": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      },
      "home_lineup_given": true,
      "away_lineup_given": true,
      "started": true,
      "decided": true,
      "home_rubbers": 0,
      "away_rubbers": 0,
      "rubbers": [
        {
          "code": "string",
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "status": "string",
          "winner": "home",
          "home_games": 0,
          "away_games": 0,
          "not_fielded_by": "home"
        }
      ]
    },
    "roster": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "opponent": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "previous": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "rubbers": [
      {
        "code": "string",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "entry_gender": "men"
      }
    ]
  }
}

Give or change a line-up of a team the person captains

PUT/v1/me/teams/{teamId}/fixtures/{fixtureId}/lineupWymaga uwierzytelnienia

As the club's administrators do, under the same rule (DEV-49).

Parametry

  • teamIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Treść żądania

  • new_playersstring[]

    Players without an account to put on the roster by name before the line-up is read (DEV-51), after everyone on it. A name the roster holds already changes nothing. Refused as roster_full when the roster would pass forty players.

  • rubbersobject[]wymagany

    Every rubber of the league's tie once, one of them fielded at least.

    Pola

Odpowiedzi

  • 200The line-up.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no fixture of a team the person captains.
  • 409league_refused with details.reason not_on_roster, plays_too_often, roster_full or tie_started.
  • 422validation_failed under rubbers: every rubber of the tie once, with one player or a pair as its ruleset says or not_fielded and nobody, and one rubber fielded at least. Under new_players: a list of names.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/teams/{teamId}/fixtures/{fixtureId}/lineup' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "new_players": [
    "string"
  ],
  "rubbers": [
    {
      "code": "string",
      "not_fielded": true,
      "players": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ]
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "tie": {
      "fixture": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      },
      "home_lineup_given": true,
      "away_lineup_given": true,
      "started": true,
      "decided": true,
      "home_rubbers": 0,
      "away_rubbers": 0,
      "rubbers": [
        {
          "code": "string",
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "status": "string",
          "winner": "home",
          "home_games": 0,
          "away_games": 0,
          "not_fielded_by": "home"
        }
      ]
    },
    "roster": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "opponent": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "previous": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "rubbers": [
      {
        "code": "string",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "entry_gender": "men"
      }
    ]
  }
}

The clubs the person is a member of

GET/v1/me/clubsWymaga uwierzytelnienia

The signed-in person's memberships of clubs (DEV-39), with those they asked for or were invited to, and the numbers the club keeps for them. Open ones first, newest first, ended ones kept. On a tenant host, that organization's alone.

Odpowiedzi

  • 200The memberships, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/clubs' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "memberships": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "club": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "person": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "email": "string"
        },
        "sport": "badminton",
        "member_number": "string",
        "licence_number": "string",
        "status": "requested",
        "side": "club",
        "awaiting": "club",
        "proposed_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Ask to join a club

POST/v1/me/clubsWymaga uwierzytelnienia

The club's administrators accept or decline. On a tenant host, that organization's club alone.

Treść żądania

  • club_idstring (uuid)wymagany

  • sportstringwymagany

    A sport Roundr runs. Append-only.

    badminton

Odpowiedzi

  • 201The request.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no such club.
  • 409membership_refused, with details.reason: not_a_club or already_open.
  • 422validation_failed under club_id or sport.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/clubs' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "club_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "sport": "badminton"
}'
201
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Accept a club's invitation

POST/v1/me/clubs/{membershipId}/acceptWymaga uwierzytelnienia

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The membership as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no such membership of the person.
  • 409membership_refused, with details.reason: not_awaiting_you (the other side answers) or ended (propose a new one).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/clubs/{membershipId}/accept' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Leave a club, or decline or withdraw a proposal

POST/v1/me/clubs/{membershipId}/endWymaga uwierzytelnienia

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The membership, ended.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404not_found: no such membership of the person.
  • 409membership_refused, with details.reason: not_awaiting_you (the other side answers) or ended (propose a new one).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/clubs/{membershipId}/end' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Find a club by name

GET/v1/me/club-directoryWymaga uwierzytelnienia

Active clubs whose name contains every word of q, by name, at most 20. On a tenant host, that organization alone.

Parametry

  • qzapytanie · stringwymagany

Odpowiedzi

  • 200The clubs found, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on q (2 to 100 characters).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/club-directory' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "clubs": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

The players organizations linked to the account

GET/v1/me/playersWymaga uwierzytelnienia

Each tournament player whose staff linked it to the signed-in person's account, so its matches are theirs (DEV-15), newest tournament first: the name the tournament has, the tournament and whose it is. On a tenant host, that organization's alone. A link is announced to the account as player_linked, and the person takes a wrong one back with DELETE /v1/me/players/{playerId}.

Parametry

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Odpowiedzi

  • 200The linked players, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404A junior_id that is not a junior of the caller's.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/players' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "players": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "starts_on": "2026-09-27"
        },
        "organization_name": "string"
      }
    ]
  }
}

Take back an organization's link between the account and a player

DELETE/v1/me/players/{playerId}Wymaga uwierzytelnienia

Removes the link only: the player, its name and its matches stay the organization's record, and the account no longer reads them as its own, as deleting the account does for every link. Allowed for a closed tournament too, since the link is the account's and not the tournament's record.

Parametry

  • playerIdścieżka · string (uuid)wymagany

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Odpowiedzi

  • 200The link is gone.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404No player of this id is linked to the account, or a junior_id that is not a junior of the caller's.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/players/{playerId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "unlinked": true
  }
}

What the account says of the person

GET/v1/me/profileWymaga uwierzytelnienia

The signed-in person's date of birth, which an event with an age category checks when they enter it (DEV-27), or null, their class in each discipline, which an event with a class rule checks (DEV-31), and the language they last used Roundr in, which their emails are written in (DEV-35), or null. Only a person has a profile.

Odpowiedzi

  • 200The profile.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/profile' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "profile": {
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "locale": "string"
    }
  }
}

Give, change or take back the account's date of birth and classes

PUT/v1/me/profileWymaga uwierzytelnienia

date_of_birth is required, a date from 1900 to today, or null to take it back. It leaves the account only when an entry into an age category is accepted, when the tournament's staff see it on that player; nothing public ever shows it. The log records that it changed, never what it is. classes is optional: the person's own class in each discipline, which an event with a class rule checks, copied to the player when an entry is accepted, where the staff may correct it (DEV-31).

locale is optional: the language the client shows, one of the locales Roundr supports, which the account's emails are written in (DEV-35). A body with locale alone changes the locale and nothing else, so a client reports its language without the date it never read; any other body needs date_of_birth.

Treść żądania

  • date_of_birthstring | null (date)

  • classesobject

    Classes by discipline, each a code in any case, or null or blank to clear it. A discipline left out keeps its class.

    Pola
  • localestring

    A locale Roundr supports, as SUPPORTED_LOCALES in packages/i18n/src/locale.ts lists them.

    afarbgbnbscacsdadeelenen-AUen-CAen-GBeses-MXetfafifilfrfr-CAhehihrhuidisitjakoltlvmsnlnoplptpt-BRroruskslsqsrsr-Latnsvswthtrukurvizh-Hanszh-Hant

Odpowiedzi

  • 200The profile as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account, or an account no longer active.
  • 422validation_failed on date_of_birth: missing, not a real date, before 1900 or still to come; on classes: not an object of disciplines, or a value that is not a class code; or on locale: not a locale Roundr supports.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/profile' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "date_of_birth": "2026-09-27",
  "classes": {
    "singles": "string",
    "doubles": "string",
    "mixed": "string"
  },
  "locale": "af"
}'
200
{
  "ok": true,
  "data": {
    "profile": {
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "locale": "string"
    }
  }
}

Change the name the account is shown under

PUT/v1/me/nameWymaga uwierzytelnienia

The signed-in person's name, trimmed, of 1 to 200 characters, as registration takes it. A first sign-in through a provider registers under the name the provider gave, and the page that follows asks the person to confirm or correct it (DEV-713). Only a person has a name to change; a junior's is their guardian's to change.

Treść żądania

  • namestringwymagany

Odpowiedzi

  • 200The name as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account, a junior's record, or an account no longer active.
  • 422validation_failed on name: empty once trimmed, or longer than 200 characters.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/name' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
200
{
  "ok": true,
  "data": {
    "name": "string"
  }
}

Accept changed versions of the legal texts

POST/v1/me/legal-acceptancesWymaga uwierzytelnienia

Accept what legal_pending on the session names: the current terms of use for the person, and the current data processing agreement for an organization they administer (terms section 17). Only a pending version is accepted: one the server has moved past, one already accepted, or an organization the person does not administer is refused, and nothing of the body is recorded. Not accepting is allowed; the previous terms then stay the person's, and the session names the texts again. The answer is what is still pending.

Treść żądania

  • acceptancesLegalAcceptanceItem[]wymagany

    Pola

Odpowiedzi

  • 200What the account still has to accept.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account, or a guardian acting for a junior.
  • 422validation_failed on acceptances: not a non-empty list, or an item that is not one of the pending versions.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/legal-acceptances' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "acceptances": [
    {
      "document": "terms",
      "version": "string",
      "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "pending": [
      {
        "document": "terms",
        "version": "string",
        "organization_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "organization_name": "string"
      }
    ]
  }
}

The juniors the account is a guardian of

GET/v1/me/juniorsWymaga uwierzytelnienia

Each junior's record (DEV-36): the name, date of birth and classes their guardians keep for them, whether they hold their own account now, whether a handover would be taken today (may_hand_over, from own_account_age, counted by the date), the expiry of a handover code still outstanding, their guardians, the caller marked you, and the invitations to another guardian still waiting, which name nobody.

Odpowiedzi

  • 200The juniors, possibly none, by name.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/juniors' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "juniors": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "date_of_birth": "2026-09-27",
        "classes": {
          "singles": null,
          "doubles": null,
          "mixed": null
        },
        "own_account": true,
        "may_hand_over": true,
        "handover_expires_at": "2026-09-27T10:30:00Z",
        "guardians": [
          {
            "display_name": "string",
            "since": "2026-09-27T10:30:00Z",
            "you": true
          }
        ],
        "invitations": [
          {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "created_at": "2026-09-27T10:30:00Z"
          }
        ]
      }
    ],
    "own_account_age": 0
  }
}

Add a junior the account acts for

POST/v1/me/juniorsWymaga uwierzytelnienia

Writes a record of the junior's own, which nobody signs in to, and makes the caller its first guardian. The junior's entries, matches and career are then theirs, and the guardian acts for them with ?junior_id= on the account's routes. An account manages at most twelve juniors.

Treść żądania

  • display_namestringwymagany

  • date_of_birthstring | null (date)wymagany

  • classesobject

    Classes by discipline, each a code in any case, or null or blank to clear it. A discipline left out keeps its class.

    Pola

Odpowiedzi

  • 201The junior.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on display_name, date_of_birth or classes, or with
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/juniors' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "display_name": "string",
  "date_of_birth": "2026-09-27",
  "classes": {
    "singles": "string",
    "doubles": "string",
    "mixed": "string"
  }
}'
201
{
  "ok": true,
  "data": {
    "junior": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "own_account": true,
      "may_hand_over": true,
      "handover_expires_at": "2026-09-27T10:30:00Z",
      "guardians": [
        {
          "display_name": "string",
          "since": "2026-09-27T10:30:00Z",
          "you": true
        }
      ],
      "invitations": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "created_at": "2026-09-27T10:30:00Z"
        }
      ]
    }
  }
}

Change what a junior's record says

PUT/v1/me/juniors/{juniorId}Wymaga uwierzytelnienia

For any of the junior's guardians. classes left out keeps the junior's. Refused as own_account once the record is handed over: the junior keeps their own profile.

Parametry

  • juniorIdścieżka · string (uuid)wymagany

Treść żądania

  • display_namestringwymagany

  • date_of_birthstring | null (date)wymagany

  • classesobject

    Classes by discipline, each a code in any case, or null or blank to clear it. A discipline left out keeps its class.

    Pola

Odpowiedzi

  • 200The junior as the record now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a junior of the caller's, whether or not it exists.
  • 422validation_failed on a field, or details.problem own_account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/juniors/{juniorId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "display_name": "string",
  "date_of_birth": "2026-09-27",
  "classes": {
    "singles": "string",
    "doubles": "string",
    "mixed": "string"
  }
}'
200
{
  "ok": true,
  "data": {
    "junior": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "own_account": true,
      "may_hand_over": true,
      "handover_expires_at": "2026-09-27T10:30:00Z",
      "guardians": [
        {
          "display_name": "string",
          "since": "2026-09-27T10:30:00Z",
          "you": true
        }
      ],
      "invitations": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "created_at": "2026-09-27T10:30:00Z"
        }
      ]
    }
  }
}

Stop being a junior's guardian

DELETE/v1/me/juniors/{juniorId}/guardianshipWymaga uwierzytelnienia

The caller's guardianship ends; the junior's other guardians keep theirs. The last guardian of a junior who does not sign in as themselves is refused as last_guardian: the record would be nobody's to act for.

Parametry

  • juniorIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The guardianship has ended.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a junior of the caller's.
  • 422validation_failed with details.problem last_guardian.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/juniors/{juniorId}/guardianship' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "left": true
  }
}

Invite a second guardian by the address of their account

POST/v1/me/juniors/{juniorId}/guardian-invitationsWymaga uwierzytelnienia

The address is looked up as a partner's is (DEV-18): the answer says only whether an active account holds it, as account_unknown or a waiting invitation, and nothing of the account is read or kept but its id. The invited person accepts from their own account. Inviting the same account again is the invitation already waiting. The lookup spends the partner lookup's two budgets, 20 an hour per account and 100 per client address, and is refused with 429 over either or while either cannot be checked.

Parametry

  • juniorIdścieżka · string (uuid)wymagany

Treść żądania

  • emailstringwymagany

Odpowiedzi

  • 201The junior, with the invitation waiting.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a junior of the caller's.
  • 422validation_failed on email, or details.problem account_unknown,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/juniors/{juniorId}/guardian-invitations' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string"
}'
201
{
  "ok": true,
  "data": {
    "junior": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "own_account": true,
      "may_hand_over": true,
      "handover_expires_at": "2026-09-27T10:30:00Z",
      "guardians": [
        {
          "display_name": "string",
          "since": "2026-09-27T10:30:00Z",
          "you": true
        }
      ],
      "invitations": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "created_at": "2026-09-27T10:30:00Z"
        }
      ]
    }
  }
}

Withdraw an invitation to another guardian

DELETE/v1/me/juniors/{juniorId}/guardian-invitations/{invitationId}Wymaga uwierzytelnienia

Parametry

  • juniorIdścieżka · string (uuid)wymagany

  • invitationIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The junior without the invitation.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not an invitation waiting for a junior of the caller's.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/juniors/{juniorId}/guardian-invitations/{invitationId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "junior": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "own_account": true,
      "may_hand_over": true,
      "handover_expires_at": "2026-09-27T10:30:00Z",
      "guardians": [
        {
          "display_name": "string",
          "since": "2026-09-27T10:30:00Z",
          "you": true
        }
      ],
      "invitations": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "created_at": "2026-09-27T10:30:00Z"
        }
      ]
    }
  }
}

Give a junior the code that hands their record over

POST/v1/me/juniors/{juniorId}/handoverWymaga uwierzytelnienia

Once the junior has reached own_account_age by the date of birth on their record, a guardian gets a one-time code, shown this once and kept only as its keyed digest. The junior signs up with an account of their own and redeems it (POST /v1/me/handover), and the record, with its entries and career, becomes that account. The code works for fourteen days; issuing another replaces it.

Parametry

  • juniorIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 201The code and when it expires.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a junior of the caller's.
  • 422validation_failed with details.problem date_of_birth_required, too_young
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/juniors/{juniorId}/handover' \
  -H 'Authorization: Bearer key_...'
201
{
  "ok": true,
  "data": {
    "handover": {
      "code": "string",
      "expires_at": "2026-09-27T10:30:00Z"
    }
  }
}

Invitations to become a junior's guardian

GET/v1/me/guardian-invitationsWymaga uwierzytelnienia

The junior each is for and the guardian who sent it, oldest first.

Odpowiedzi

  • 200The invitations, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/guardian-invitations' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "invitations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "junior_name": "string",
        "invited_by_name": "string",
        "created_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Decline an invitation to become a guardian

DELETE/v1/me/guardian-invitations/{invitationId}Wymaga uwierzytelnienia

Parametry

  • invitationIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The invitation is gone.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not an invitation waiting for the caller.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/guardian-invitations/{invitationId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "declined": true
  }
}

Become a junior's guardian

POST/v1/me/guardian-invitations/{invitationId}/acceptanceWymaga uwierzytelnienia

Parametry

  • invitationIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The junior the caller now guards.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not an invitation waiting for the caller.
  • 422validation_failed with details.problem not_an_account or too_many_juniors.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/guardian-invitations/{invitationId}/acceptance' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "junior": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "date_of_birth": "2026-09-27",
      "classes": {
        "singles": null,
        "doubles": null,
        "mixed": null
      },
      "own_account": true,
      "may_hand_over": true,
      "handover_expires_at": "2026-09-27T10:30:00Z",
      "guardians": [
        {
          "display_name": "string",
          "since": "2026-09-27T10:30:00Z",
          "you": true
        }
      ],
      "invitations": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "created_at": "2026-09-27T10:30:00Z"
        }
      ]
    }
  }
}

Take over the record a guardian kept for you

POST/v1/me/handoverWymaga uwierzytelnienia

With the account the junior has just made, and the code a guardian gave them. The code is found by its keyed digest and consumed in the transaction that moves the account's sign-in to the junior's record, so it works once. The account's address, name, umpired matches and followed players move with it, and the account itself is deleted; one that already plays, staffs or guards is refused as account_in_use, since a code does not merge two histories. A browser's session is replaced by one naming the record, written inside the redemption; a bearer token finds the record on its next request. keep_guardians says whether the guardians may still act for the junior; otherwise their guardianship ends here. Codes tried from one client address are limited to ten an hour, and refused with 429 while that cannot be checked.

Treść żądania

  • codestringwymagany

    As given, in any case, with or without its hyphens.

  • keep_guardiansboolean

Odpowiedzi

  • 200The record is the caller's; a browser's cookie now names it.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on code or keep_guardians, or with details.problem
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/handover' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "string",
  "keep_guardians": true
}'
200
{
  "ok": true,
  "data": {
    "handover": {
      "guardians_kept": true
    }
  }
}

The guardians still acting for a person who signs in as themselves

GET/v1/me/guardiansWymaga uwierzytelnienia

The guardians a junior kept when their record was handed over; none for anyone else.

Odpowiedzi

  • 200The guardians, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/guardians' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "guardians": [
      {
        "display_name": "string",
        "since": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

End every guardianship over the caller

DELETE/v1/me/guardiansWymaga uwierzytelnienia

Nobody acts for the caller any more; their guardians keep nothing of them.

Odpowiedzi

  • 200No guardians remain.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/guardians' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "guardians": [
      {
        "display_name": "string",
        "since": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

The account's career

GET/v1/me/careerWymaga uwierzytelnienia

Every match the signed-in person's linked players stood on a side of (DEV-32), in the tournaments GET /v1/me/matches reads: on a tenant host that organization's, on the shared API host every organization's. Each match is sent as Live sends one, with the side and participant the account stood on and the record it counts in, singles, doubles or mixed, read off its ruleset and its draw's entry rule.

draws are the published draws those matches are in, as Live sends a draw, narrowed to the account: its own entries, the nodes of its own matches and its own rows of a group's standings. The places a draw decided for the account (its titles and finals) are read from these, and the statistics from the matches, on the client.

Parametry

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Odpowiedzi

  • 200The career, possibly empty.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404A junior_id that is not a junior of the caller's.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/career' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tournaments": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      }
    ],
    "matches": [
      {
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "side": "home",
        "discipline": "singles",
        "draw_name": "string",
        "sides": {
          "home": "string",
          "away": "string"
        },
        "court_name": "string",
        "match": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "participants": {
            "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
          },
          "external_ref": "string",
          "scheduled_start": "2026-09-27T10:30:00Z",
          "sequence": 0,
          "not_before": "2026-09-27T10:30:00Z",
          "started_at": "2026-09-27T10:30:00Z",
          "ended_at": "2026-09-27T10:30:00Z",
          "draw": null,
          "status": "scheduled",
          "score": {
            "games": [
              null
            ],
            "games_won": {
              "home": null,
              "away": null
            },
            "serving": null,
            "interval": true,
            "winner": null,
            "outcome": null
          }
        }
      }
    ],
    "draws": [
      {
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "draw": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "code": "string",
          "age_rule": null,
          "class_rule": null,
          "format": "knockout",
          "size": 0,
          "group_count": 0,
          "third_place": true,
          "all_places": true,
          "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "qualifiers": 0,
          "seed_bands": true,
          "feeds": [
            {
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null,
              "source_match_id": null,
              "external_ref": null,
              "takes": "winner_of",
              "position": null,
              "group": null,
              "group_place": null,
              "participant_id": null,
              "void": null,
              "seed": null,
              "seed_banded": null
            }
          ],
          "entries": [
            {
              "participant_id": null,
              "seed": null,
              "position": null,
              "group": null,
              "group_place": null,
              "association": null,
              "ranking_position": null
            }
          ],
          "matches": [
            {
              "match_id": null,
              "round": null,
              "slot": null,
              "group": null,
              "places": null,
              "home_source": null,
              "away_source": null
            }
          ],
          "standings": null
        }
      }
    ]
  }
}

Whether the account shows its results to players it has played

GET/v1/me/sharingWymaga uwierzytelnienia

"Show my results to players I have played" (DEV-32), off until the person turns it on. A head-to-head between two accounts is read only while both have it on.

Odpowiedzi

  • 200The answer.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/sharing' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "sharing": {
      "results_to_opponents": true
    }
  }
}

Show or stop showing the account's results to players it has played

PUT/v1/me/sharingWymaga uwierzytelnienia

Treść żądania

  • results_to_opponentsbooleanwymagany

Odpowiedzi

  • 200The answer as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account, or an account no longer active.
  • 422validation_failed on results_to_opponents: missing or not a boolean.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/sharing' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "results_to_opponents": true
}'
200
{
  "ok": true,
  "data": {
    "sharing": {
      "results_to_opponents": true
    }
  }
}

The players the account can compare itself against

GET/v1/me/head-to-headWymaga uwierzytelnienia

The other accounts the signed-in person met on the opposite side of a result, in a tournament published on Live, who show their results to players they have played (DEV-32); one per account and organization, most meetings first. Nobody while the caller does not show their own. Each is named by their player row at their latest tournament on Live in that organization, its id and the name its staff entered, and never by the account. A partner is not an opponent, and nobody is matched by name.

Odpowiedzi

  • 200The caller's own answer and the opponents.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/head-to-head' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "sharing": {
      "results_to_opponents": true
    },
    "opponents": [
      {
        "player_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "meetings": 1
      }
    ]
  }
}

The account against another it has played

GET/v1/me/head-to-head/{playerId}Wymaga uwierzytelnienia

The signed-in person against the account the player row is linked to, in that player's organization's tournaments on Live (DEV-32): every result between them, where they stood on opposite sides, and both records there, each result as the statistics count it and with nothing else, no names, tournament or ids.

404 alike whenever the caller or the other account does not show their results, the player is linked to nobody or to the caller, is another organization's on a tenant host, or the two never met on Live, so the answer says nothing of an account.

Parametry

  • playerIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The head-to-head.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404No head-to-head with this player, for any of the reasons above.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/head-to-head/{playerId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "organization_name": "string",
    "opponent": {
      "player_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string"
    },
    "you": {
      "results": [
        {
          "discipline": "singles",
          "side": "home",
          "venue_time_zone": "string",
          "starts_on": "2026-09-27",
          "status": "completed",
          "score": {
            "games": [
              null
            ],
            "games_won": {
              "home": null,
              "away": null
            },
            "serving": null,
            "interval": true,
            "winner": null,
            "outcome": null
          },
          "scheduled_start": "2026-09-27T10:30:00Z",
          "started_at": "2026-09-27T10:30:00Z",
          "ended_at": "2026-09-27T10:30:00Z"
        }
      ]
    },
    "them": {
      "results": [
        {
          "discipline": "singles",
          "side": "home",
          "venue_time_zone": "string",
          "starts_on": "2026-09-27",
          "status": "completed",
          "score": {
            "games": [
              null
            ],
            "games_won": {
              "home": null,
              "away": null
            },
            "serving": null,
            "interval": true,
            "winner": null,
            "outcome": null
          },
          "scheduled_start": "2026-09-27T10:30:00Z",
          "started_at": "2026-09-27T10:30:00Z",
          "ended_at": "2026-09-27T10:30:00Z"
        }
      ]
    },
    "matches": [
      {
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "side": "home",
        "discipline": "singles",
        "draw_name": "string",
        "sides": {
          "home": "string",
          "away": "string"
        },
        "court_name": "string",
        "match": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "participants": {
            "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
          },
          "external_ref": "string",
          "scheduled_start": "2026-09-27T10:30:00Z",
          "sequence": 0,
          "not_before": "2026-09-27T10:30:00Z",
          "started_at": "2026-09-27T10:30:00Z",
          "ended_at": "2026-09-27T10:30:00Z",
          "draw": null,
          "status": "scheduled",
          "score": {
            "games": [
              null
            ],
            "games_won": {
              "home": null,
              "away": null
            },
            "serving": null,
            "interval": true,
            "winner": null,
            "outcome": null
          }
        },
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "venue_time_zone": "string",
          "starts_on": "2026-09-27"
        }
      }
    ]
  }
}

The players the account follows on Live

GET/v1/me/followingWymaga uwierzytelnienia

The players followed on Live that the signed-in person saved to their account (DEV-32), by tournament, newest tournament first, each list in the order they were followed. On a tenant host that organization's tournaments alone. A tournament taken off Live stays, with on_live false, so a follow is not lost while it is republished.

Odpowiedzi

  • 200The follows, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/following' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tournaments": [
      {
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "organization_name": "string",
          "starts_on": "2026-09-27",
          "on_live": true
        },
        "players": [
          {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ]
      }
    ]
  }
}

Replace the players the account follows at a tournament

PUT/v1/me/following/{tournamentId}Wymaga uwierzytelnienia

The whole list, so a retry means the same thing twice; none to follow nobody there any more. Only at a tournament this host's Live shows, and only its own players.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • player_idsstring (uuid)[]wymagany

Odpowiedzi

  • 200The list as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404No tournament this host's Live shows under that id.
  • 422validation_failed on player_ids: not a list of up to 100 distinct players of the tournament.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/following/{tournamentId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "player_ids": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ]
}'
200
{
  "ok": true,
  "data": {
    "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "player_ids": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ]
  }
}

The account's notifications

GET/v1/me/notificationsWymaga uwierzytelnienia

The signed-in person's inbox (DEV-35), newest first, with how many are unread. On a tenant host it is that organization's notifications alone; on the shared API host every organization's, as every read scoped by a person is. next_before is null on the last page; sent back as before, it asks for the page after. The signed-in bar asks for limit=1, since it wants the count. Only a person has notifications.

Parametry

  • beforezapytanie · string

    The next_before of the page before, as it was given. Opaque.

  • limitzapytanie · integer

    How many to send, 1 to 50; 50 when left out.

Odpowiedzi

  • 200A page of notifications, possibly none, and the unread count.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on before: not a cursor this list gave out; or on limit: not 1 to 50.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/notifications' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "notifications": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "type": "partner_invited",
        "payload": {},
        "organization": null,
        "path": "string",
        "created_at": "2026-09-27T10:30:00Z",
        "read_at": "2026-09-27T10:30:00Z"
      }
    ],
    "unread_count": 0,
    "next_before": "string"
  }
}

Mark one notification read

POST/v1/me/notifications/{notificationId}/readWymaga uwierzytelnienia

Marks the notification read, keeping the time it was first read when it already was. A notification of another account, or of another organization on a tenant host, is not found.

Parametry

  • notificationIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The notification and the unread count after it.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404No such notification of this account here.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/notifications/{notificationId}/read' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "notification": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "type": "partner_invited",
      "payload": {},
      "organization": null,
      "path": "string",
      "created_at": "2026-09-27T10:30:00Z",
      "read_at": "2026-09-27T10:30:00Z"
    },
    "unread_count": 0
  }
}

Mark every notification read

POST/v1/me/notifications/read-allWymaga uwierzytelnienia

Marks every unread notification the list on this host shows read.

Odpowiedzi

  • 200How many were unread, and the unread count after.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/notifications/read-all' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "marked": 0,
    "unread_count": 0
  }
}

Which notifications come by email and by push

GET/v1/me/notification-preferencesWymaga uwierzytelnienia

Every notification type, the channels after the inbox it goes by (channels), and for each whether the account gets it that way and whether that is on unless turned off (DEV-35): email for what keeps, web push to the account's devices for match-day news, a match called to its court and a next match moved (DEV-45). A channel a type does not go by reads as off. The inbox always has every notification. The preferences are the account's wherever it signs in. The types told only to an organization's administrators, the membership_* ones and club_membership_requested (DEV-39), are left out for an account that administers no organization; a choice saved for one is kept.

push_public_key is the VAPID public key a browser subscribes with (applicationServerKey), from the server rather than the build so a new key needs no new client; null when this instance sends no web push, and then the client offers none.

Odpowiedzi

  • 200The preferences.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/notification-preferences' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "preferences": [
      {
        "type": "partner_invited",
        "channels": [
          "email"
        ],
        "email": true,
        "email_by_default": true,
        "push": true,
        "push_by_default": true
      }
    ],
    "push_public_key": "string",
    "email_suppression": null
  }
}

Turn notification emails and pushes on or off

PUT/v1/me/notification-preferencesWymaga uwierzytelnienia

preferences lists the types to change, each with email, push or both on or off. A type left out keeps what it had, and so does a channel left out, so a client that does not know a newer type or channel does not turn it off. An email or a push already waiting to be sent follows the change. A choice for a channel the type does not go by is kept and never used.

Treść żądania

  • preferencesobject[]wymagany

    Pola

Odpowiedzi

  • 200The preferences as they now stand.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on preferences: not a list, a type Roundr does not know, an email or push that is not true or false, or neither of them given.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/notification-preferences' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "preferences": [
    {
      "type": "partner_invited",
      "email": true,
      "push": true
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "preferences": [
      {
        "type": "partner_invited",
        "channels": [
          "email"
        ],
        "email": true,
        "email_by_default": true,
        "push": true,
        "push_by_default": true
      }
    ],
    "push_public_key": "string",
    "email_suppression": null
  }
}

Send email to my address again

DELETE/v1/me/email-suppressionWymaga uwierzytelnienia

The person's word that their address takes email again (DEV-111), after SES reported a hard bounce or a complaint for it and Roundr stopped writing to it (email_suppression in the preferences). Clears the stop, whether there was one or not, and answers with the preferences as they now read. A court device, a display and a machine key have no address and are refused.

Odpowiedzi

  • 200The preferences, with email_suppression null.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/email-suppression' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "preferences": [
      {
        "type": "partner_invited",
        "channels": [
          "email"
        ],
        "email": true,
        "email_by_default": true,
        "push": true,
        "push_by_default": true
      }
    ],
    "push_public_key": "string",
    "email_suppression": null
  }
}

The devices the account turned web push on in

GET/v1/me/push-subscriptionsWymaga uwierzytelnienia

Each browser the account turned push on in (DEV-45), oldest first, by what it is listed as (its browser and system, read from the user agent when it was turned on) and when its push service last took or refused a message. The endpoint and the keys are never sent back.

Odpowiedzi

  • 200The devices.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/push-subscriptions' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "subscriptions": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "label": "string",
        "created_at": "2026-09-27T10:30:00Z",
        "last_success_at": "2026-09-27T10:30:00Z",
        "last_failure_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Turn web push on for this browser

PUT/v1/me/push-subscriptionsWymaga uwierzytelnienia

Keeps the subscription the browser's PushManager.subscribe() gave, as PushSubscription.toJSON() writes it, against the account (DEV-45). Match-day notifications the account wants by push go to it from then on: a match called to its court and a next match moved, the player's own and those of players the account follows on Live. On a customer host it is told only that organization's news, since its service worker opens that host's pages; on the platform's site, every organization's.

Saving the same browser again updates it and keeps its id, which is how a client learns the id of its own device. An endpoint another account held moves to this one: one browser is one device. Only the push services of the browsers Roundr supports are taken (Google's, Mozilla's, Apple's and Microsoft's).

Treść żądania

  • endpointstring (uri)wymagany

  • keysobjectwymagany

    Pola

Odpowiedzi

  • 200The device, as the list shows it.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on endpoint (not https, or not at a browser push service), keys.p256dh or keys.auth.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
  • 503push_unavailable: this instance sends no web push.
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/push-subscriptions' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "endpoint": "https://example.com",
  "keys": {
    "p256dh": "string",
    "auth": "string"
  }
}'
200
{
  "ok": true,
  "data": {
    "subscription": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "label": "string",
      "created_at": "2026-09-27T10:30:00Z",
      "last_success_at": "2026-09-27T10:30:00Z",
      "last_failure_at": "2026-09-27T10:30:00Z"
    }
  }
}

Turn web push off for a device

DELETE/v1/me/push-subscriptions/{subscriptionId}Wymaga uwierzytelnienia

The device is told nothing more. The web app removes its own device when the person signs out there and unsubscribes the browser as well; a device whose browser gave the subscription up is removed by the relay when its push service says so.

Parametry

  • subscriptionIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The device is gone.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404The account has no device of this id.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/push-subscriptions/{subscriptionId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "removed": true
  }
}

The matches the account umpired on its own panel

GET/v1/me/umpired-matchesWymaga uwierzytelnienia

The finished personal matches the signed-in person kept on their account (DEV-34), newest ended first, fifty at a time. next_before is null on the last page; sent back as before, it asks for the page after. The host a request arrives on changes nothing: the matches are the account's wherever it signs in.

Parametry

  • beforezapytanie · string

    The next_before of the page before, as it was given. Opaque.

Odpowiedzi

  • 200A page of matches, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 422validation_failed on before: not a cursor this list gave out.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/umpired-matches' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "matches": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "setup": {},
        "status": "confirmed",
        "result": {
          "winner": "home",
          "outcome": "completed",
          "games": [
            {
              "home": null,
              "away": null
            }
          ]
        },
        "started_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z",
        "saved_at": "2026-09-27T10:30:00Z"
      }
    ],
    "next_before": "string"
  }
}

One of the account's umpired matches, with its history

GET/v1/me/umpired-matches/{matchId}Wymaga uwierzytelnienia

The match as kept: its summary, the state the server's replay started from and the events it derived, from which a client rebuilds the timeline, the statistics and the scoresheet. The stored events are the record, not a fresh replay, so an engine that changes later does not change a match kept before it.

Parametry

  • matchIdścieżka · string (uuid)wymagany

    The match id the device generated for the match.

Odpowiedzi

  • 200The match.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404No match of this account under that id, whether none exists or another account's does.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/umpired-matches/{matchId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "ruleset": {
      "id": "string",
      "version": "string",
      "engine_version": "string"
    },
    "setup": {},
    "status": "confirmed",
    "result": {
      "winner": "home",
      "outcome": "completed",
      "games": [
        {
          "home": 0,
          "away": 0
        }
      ]
    },
    "started_at": "2026-09-27T10:30:00Z",
    "ended_at": "2026-09-27T10:30:00Z",
    "saved_at": "2026-09-27T10:30:00Z",
    "initial_state": {
      "revision": 0,
      "status": "scheduled",
      "data": {}
    },
    "events": [
      {
        "revision": 0,
        "index": 0,
        "type": "string",
        "payload": {},
        "command_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "client_timing": {},
        "actor": null,
        "recorded_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Keep a finished match on the account

PUT/v1/me/umpired-matches/{matchId}Wymaga uwierzytelnienia

Sent once the result is confirmed on the device: the ruleset, the client's own description of the match and the accepted commands in the order the device accepted them. The server replays them through the ruleset's adapter from its initial state, as it decides a tournament match's commands for the device that holds its scoring session, undo included, and keeps its own reading: the events, the state they end in and the result read off it (DEV-34).

A command the rules refuse, an unknown type, a command id sent twice, correct_score or reopen_result, or a sequence that does not end in a confirmed result refuses the whole upload as umpired_match_invalid.

Idempotent by match id. The same commands again answer 200 with the match as it was kept, setup included; different commands under an id already kept, or an id another account holds, are idempotency_key_reused, one answer for both. started_at and ended_at are the first and last commands' authored_at, the upload's time where the last command sent none.

Parametry

  • matchIdścieżka · string (uuid)wymagany

    The match id the device generated for the match.

Treść żądania

  • rulesetobjectwymagany

    Pola
  • setupobjectwymagany

    The client's description of the match, at most 16 KiB encoded; kept as sent.

  • commandsobject[]wymagany

    The accepted commands, in the order the device accepted them.

    Pola

Odpowiedzi

  • 200The same commands were kept under this id already; the match as it was kept.
  • 201The match is kept.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account; or csrf_rejected.
  • 409idempotency_key_reused: the id is kept with other commands, or by another
  • 422validation_failed: the body is not an upload, details.validation_errors
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/me/umpired-matches/{matchId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "ruleset": {
    "id": "string",
    "version": "string"
  },
  "setup": {},
  "commands": [
    {
      "command_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "type": "string",
      "payload": {},
      "client_timing": {
        "authored_at": "2026-09-27T10:30:00Z",
        "rally_started_at": "2026-09-27T10:30:00Z",
        "rally_ended_at": "2026-09-27T10:30:00Z",
        "held_from": "2026-09-27T10:30:00Z"
      }
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "ruleset": {
      "id": "string",
      "version": "string",
      "engine_version": "string"
    },
    "setup": {},
    "status": "confirmed",
    "result": {
      "winner": "home",
      "outcome": "completed",
      "games": [
        {
          "home": 0,
          "away": 0
        }
      ]
    },
    "started_at": "2026-09-27T10:30:00Z",
    "ended_at": "2026-09-27T10:30:00Z",
    "saved_at": "2026-09-27T10:30:00Z",
    "initial_state": {
      "revision": 0,
      "status": "scheduled",
      "data": {}
    },
    "events": [
      {
        "revision": 0,
        "index": 0,
        "type": "string",
        "payload": {},
        "command_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "client_timing": {},
        "actor": null,
        "recorded_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Delete one of the account's umpired matches

DELETE/v1/me/umpired-matches/{matchId}Wymaga uwierzytelnienia

Only the person deletes a match; there is nobody else it belongs to.

Parametry

  • matchIdścieżka · string (uuid)wymagany

    The match id the device generated for the match.

Odpowiedzi

  • 200The match is gone.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account; or csrf_rejected.
  • 404No match of this account under that id, whether none exists or another account's does.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/umpired-matches/{matchId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  }
}

SES bounces and complaints, by Amazon SNS

POST/v1/webhooks/sesPubliczny

Where SES reports a hard bounce or a complaint (DEV-111), delivered by Amazon SNS, so Roundr stops writing to the address. Anonymous: SNS presents no credential, so a message is believed only when its TopicArn is one configured in SES_FEEDBACK_TOPIC_ARNS, its signature verifies against the certificate at its SigningCertURL, an Amazon SNS host, and its Timestamp is within an hour. An instance with no topic configured believes no message.

A SubscriptionConfirmation is confirmed by fetching its SubscribeURL, an Amazon SNS address only. A Notification whose message is a permanent bounce stops each bounced recipient's account, and a complaint each complaining recipient's; a transient bounce, a delivery and anything else stop nothing. SNS retries a 5xx and takes any other answer as delivered, so the status is the contract: 200 for a message acted on or with nothing to act on, 403 for one that does not verify, 422 for a body that is no SNS message, 500 for a failure a retry may clear.

Treść żądania

object

Odpowiedzi

  • 200The message was believed, and acted on where it named a bounce or a complaint.
  • 403The message does not verify, or names a topic this instance did not subscribe.
  • 422validation_failed: the body is empty, too large, or no SNS message.
  • 500internal_error: the stop could not be stored, or the subscription not confirmed. SNS retries.
Przykład
curl -X POST 'https://api.roundr.com/v1/webhooks/ses' \
  -H 'Content-Type: application/json' \
  -d '{}'
200
{
  "ok": true,
  "data": {
    "received": true
  }
}

Tournaments

The tournament feed: the snapshot a client starts from, the durable change feed it catches up on, and the stream it listens to. HTTP stays authoritative. A notification announces that an aggregate changed and at which revision, never what it changed to; the client fetches the canonical projection through a GET, so a notification that goes missing costs a fetch and never a score. Every request here reauthorizes the principal's tournament and court scope, and a cursor carries no authority.

One consistent read of a tournament, and the cursor it was taken at

GET/v1/tournaments/{tournamentId}/snapshotWymaga uwierzytelnienia

Where a client starts, and where it starts again after 410 cursor_expired. The tournament, its courts and its matches are read under REPEATABLE READ with an explicit consistent snapshot, so they and snapshot_cursor come from one read view: any change the snapshot does not show carries a greater cursor. The client stores the projection and the cursor and opens the stream, or pages the change feed, after snapshot_cursor, and nothing falls between the two.

A match here is the shape GET /v1/matches/{matchId} returns. A court device receives only its own court and the matches on it. A display receives what its projection shows, the courts chosen for it and the matches on them, the matches on no court while it lists them, and every match of a draw whose standings it shows, with only the participants of those matches; its projection is read in the same view, so a later change of it arrives on the stream. Staff and a machine key issued tournaments:read see the whole tournament. A tournament outside the principal's scope or organization is not found, never forbidden.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The snapshot.
  • 401No credential.
  • 403insufficient_scope: a machine key that was not issued tournaments:read. It is
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/snapshot' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    },
    "courts": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "sort_order": 0,
        "status": "open",
        "revision": 0
      }
    ],
    "participants": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "kind": "single",
        "display_name": "string",
        "external_ref": "string",
        "players": [
          {
            "full_name": "string",
            "given_name": "string",
            "family_name": "string",
            "family_name_first": true,
            "position": 1,
            "nationality": "string"
          }
        ]
      }
    ],
    "matches": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "participants": {
          "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
        },
        "external_ref": "string",
        "scheduled_start": "2026-09-27T10:30:00Z",
        "sequence": 0,
        "not_before": "2026-09-27T10:30:00Z",
        "started_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z",
        "confirmed_at": "2026-09-27T10:30:00Z",
        "officials": null,
        "draw": null,
        "scoring_session_epoch": 0,
        "state": {
          "revision": 0,
          "status": "scheduled",
          "data": {}
        }
      }
    ],
    "snapshot_cursor": "string",
    "display": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0,
      "court_scope": "all",
      "show_upcoming": true,
      "upcoming_count": 1,
      "standings_draw_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "show_header": true,
      "show_seeds": true,
      "layout": "cards"
    },
    "draws": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "format": "knockout",
        "size": 0,
        "third_place": true,
        "matches": [
          {
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "round": 0,
            "slot": 0,
            "group": 0,
            "places": null,
            "home_source": {
              "kind": "position",
              "position": null,
              "match_id": null,
              "external_ref": null,
              "void": null,
              "participant_id": null,
              "group": null,
              "rank": null,
              "tied": null,
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null
            },
            "away_source": {
              "kind": "position",
              "position": null,
              "match_id": null,
              "external_ref": null,
              "void": null,
              "participant_id": null,
              "group": null,
              "rank": null,
              "tied": null,
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null
            }
          }
        ]
      }
    ]
  }
}

Durable catch-up on a tournament's notifications

GET/v1/tournaments/{tournamentId}/changesWymaga uwierzytelnienia

The retained outbox rows after a cursor, as the notifications the stream would have delivered, in cursor order and paginated. Rows are read from MySQL regardless of whether the relay has published them yet, so a client can poll this while the stream is unavailable and a blocked relay cannot hide a change from it.

next_cursor is the last row scanned, not the last item returned. A court device, a display or a machine key may not see every row, and a hidden one is left out of items rather than replaced, so the cursor advances past what the principal may not see; items can be empty while has_more is true, and the client keeps paging by next_cursor until has_more is false. next_cursor is null only when the page scanned nothing.

A position that has fallen out of retention is 410 cursor_expired, and the client takes a new snapshot rather than continuing from a gap.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • after_cursorzapytanie · string

    The last cursor the client handled. Absent, the page starts at the beginning of the feed, which is 410 cursor_expired once its earliest rows have been pruned; a client with no position takes a snapshot instead.

  • limitzapytanie · integer

    Rows scanned per page, hidden ones included.

Odpowiedzi

  • 200A page of notifications, possibly empty.
  • 401No credential.
  • 403insufficient_scope: a machine key that was not issued tournaments:read. It is
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 410cursor_expired: the position has fallen out of retained history, or is ahead of
  • 422validation_failed: after_cursor is not a stream cursor, or limit is outside 1 to 500.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/changes' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "items": [
    {
      "event_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "stream_cursor": "string",
      "aggregate_type": "match",
      "aggregate_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "aggregate_revision": 0,
      "type": "string",
      "occurred_at": "2026-09-27T10:30:00Z"
    }
  ],
  "next_cursor": null,
  "has_more": true
}

Listen to a tournament's notifications

GET/v1/tournaments/{tournamentId}/streamWymaga uwierzytelnienia

A server-sent event stream of the tournament's notifications, for the browser's EventSource opened with withCredentials and for a native client's own streaming HTTP. Authentication is the session cookie or a bearer credential in the request headers, never a token in the URL: a URL ends up in history, referrers, proxy logs and analytics.

The stream resumes from the earlier of Last-Event-ID, the browser's delivered position, and after_cursor, the client's handled position, because replaying a handled notification is harmless and skipping one that was delivered but never processed loses it. Without either it starts at the current end of the feed, so a client with no position takes a snapshot first and resumes after its cursor. A position behind what the stream store retains but inside outbox retention is served from the durable feed first and then from the stream; one that has fallen out of retention is 410 cursor_expired.

A retry: line comes first. Each message carries id: <stream_cursor> and one data: line holding either a RealtimeNotification or, for a row the principal may not see, a StreamCheckpoint whose only field is that same cursor, so a court device, a display or a machine key advances past a hidden row without learning it. A display's projection is read when the stream opens and again after each notification of a change to that display, so every row after the change is narrowed by it. A comment line : heartbeat is written at the configured interval while nothing is new. The stream closes after its maximum lifetime, and when the stream store cannot be read; the client reconnects with Last-Event-ID, which EventSource does on its own.

Every error is answered before any frame: a client that has read a frame holds an open stream. 429 rate_limited means the principal already holds its share of open streams, or has spent its read budget; 503 realtime_unavailable means streaming is switched off, the stream store is unreachable, or the deployment already holds as many streams as it allows. Both carry Retry-After, and the client polls the change feed meanwhile. A stream refused for its share, or with a 503, leaves commands and canonical reads unaffected.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • after_cursorzapytanie · string

    The last cursor the client handled, from its own storage, persisted only once a notification has been fully processed.

  • Last-Event-IDnagłówek · string

    The last message id the browser delivered, which EventSource sends when it reconnects. The server issued it, so a value that is not a stream cursor is ignored rather than refused.

Odpowiedzi

  • 200An open stream: a retry: line, then messages whose id is a StreamCursor
  • 401No credential.
  • 403insufficient_scope: a machine key that was not issued tournaments:read. It is
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 410cursor_expired: the position has fallen out of retained history, or is ahead of
  • 422validation_failed: after_cursor is not a stream cursor.
  • 429rate_limited: the principal already holds its share of open streams. They are
  • 503realtime_unavailable: streaming is switched off, the stream store is
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/stream' \
  -H 'Authorization: Bearer key_...'
200
"string"

Draws

Draws, knockout and round robin: a draft listed, seeded, placed and arranged, then published into matches. A knockout draw places its entries on the lines of a bracket; a round-robin draw places them into groups, in which every entry plays every other, and ranks each group by its standings. Writes are for an administrator of the organization or the tournament's director, reads for its referee as well; a hall display reads the standings of the draws its projection names, and nothing else here. Every draft edit names the revision it was made against, and a published draw is not changed structurally again.

The tournament's draws, drafts and published

GET/v1/tournaments/{tournamentId}/drawsWymaga uwierzytelnienia

Every draw of the tournament, ordered by name, each whole: its entries and, once published, its matches. For the tournament's staff: an administrator of the organization, and the tournament's director and referee.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The draws.
  • 401No credential.
  • 403insufficient_scope: the caller is none of the tournament's staff. An
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/draws' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "draws": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "format": "knockout",
        "standings_rules": "string",
        "third_place": true,
        "consolation": true,
        "all_places": true,
        "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "qualifiers_per_group": 0,
        "qualifiers": 0,
        "seed_bands": true,
        "feeds": [
          {
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string",
            "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "takes": "winner_of",
            "position": 0,
            "group": 0,
            "group_place": 0,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "void": true,
            "seed": 0,
            "seed_banded": true
          }
        ],
        "entry_gender": "men",
        "age_rule": null,
        "class_rule": null,
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "status": "draft",
        "size": 0,
        "group_count": 0,
        "revision": 0,
        "lot_drawn": true,
        "seeds_moved": true,
        "placement_method": "entry_order",
        "published_at": "2026-09-27T10:30:00Z",
        "entries": [
          {
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "seed": 0,
            "position": 0,
            "group": 0,
            "group_place": 0,
            "association": "string",
            "ranking_position": 0
          }
        ],
        "matches": [
          {
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "round": 0,
            "slot": 0,
            "group": 0,
            "places": null,
            "home_source": {
              "kind": "position",
              "position": null,
              "match_id": null,
              "external_ref": null,
              "void": null,
              "participant_id": null,
              "group": null,
              "rank": null,
              "tied": null,
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null
            },
            "away_source": {
              "kind": "position",
              "position": null,
              "match_id": null,
              "external_ref": null,
              "void": null,
              "participant_id": null,
              "group": null,
              "rank": null,
              "tied": null,
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null
            }
          }
        ]
      }
    ]
  }
}

Make a draw, as an empty draft

POST/v1/tournaments/{tournamentId}/drawsWymaga uwierzytelnienia

A draft with no entries, pinned to the ruleset its matches will be played under. code is the prefix of the references publication gives the matches (MS makes MS-1, MS-2 and on in a knockout, MS-A1 in group A of a round robin); it is stored upper-case, and both it and the name are unique in the tournament. format is knockout when not given; a round_robin draw records the rules its standings are ranked by, bwf-gcr-16.2, which the draw keeps. A knockout draw may be made playing for third place or with a consolation, or playing off every place, which takes neither of the other two (/options changes all three while it is a draft); a round-robin draw with any of them is refused. A knockout draw may instead be fed by the groups of a published round robin of the tournament, source_draw_id with qualifiers_per_group: it takes no entries, its bracket is laid out at once (size is set) with the group winners where seeds 1 onwards would stand and each runner-up in the half its group's winner is not in, and its first sides are group_rank sources that the server fills as each group completes. It may play for third place and have a consolation, whose losers are those of its own first round and which is refused at once when its bracket cannot play one, or play off every place; one round robin feeds one draw. Any draw may be made with an entry rule, entry_gender (/entry-rule changes it while it is a draft). Announced as draw_created on the draw aggregate.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

  • codestringwymagany

  • ruleset_idstringwymagany

  • ruleset_versionstringwymagany

  • formatstring

    knockoutround_robin

  • third_placeboolean

    A knockout draw's match between the losers of its semi-finals.

  • consolationboolean

    A knockout draw's consolation, created with it at publication; its code is the draw's with a C, so the draw's has at most 15 characters.

  • all_placesboolean

    A knockout draw whose losers play on in placement groups of its own bracket, so that every place is decided; refused with third_place or consolation, on this field.

  • source_draw_idstring (uuid)

    The published round robin of the tournament whose groups feed this knockout draw; sent with qualifiers_per_group or not at all.

  • qualifiers_per_groupinteger

    How many of each group go on, from its winner down: at most as many as the smallest group holds, and 2 to 256 in all.

  • qualifiersinteger | null

    Makes a knockout draw a qualifying draw of this many qualifiers: its lines are cut into that many sections, it plays until each section has a winner, and those winners are its qualifiers, which another draw may be fed by (PUT /v1/draws/{drawId}/feeds). Refused on this field with any other option, a source, or a round-robin format. Sent by every server that serves feeds.

  • entry_genderstring | null

    A draw's entry rule: men takes male players, women female ones, mixed a pair of one of each and only on a ruleset played by pairs, and null anyone. An entry is refused only where a player's recorded gender contradicts it, never for a gender nobody recorded.

    menwomenmixednull

  • age_ruleone of

    A draw's age category, or null for any age. under 15 is U15, a player who does not turn 15 in the calendar year of the tournament's start; over 35 is 35+, one who turns 35 or more that year (DEV-27). Sent by every server that keeps age categories; a client reading an older one takes its absence for any age.

    Pola
  • class_ruleone of

    A draw's class rule, or null for every class: the player classes it admits in its discipline (Discipline), in the order of the organization's scale. A pair enters when both players hold an admitted class (DEV-31). Sent by every server that keeps classes; a client reading an older one takes its absence for every class.

    Pola

Odpowiedzi

  • 201The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed: a missing or overlong name, a code that is not letters and
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/draws' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "code": "string",
  "ruleset_id": "string",
  "ruleset_version": "string",
  "format": "knockout",
  "third_place": true,
  "consolation": true,
  "all_places": true,
  "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "qualifiers_per_group": 1,
  "qualifiers": 1,
  "entry_gender": "men",
  "age_rule": null,
  "class_rule": null
}'
201
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

One draw, with its entries and its matches

GET/v1/draws/{drawId}Wymaga uwierzytelnienia

Parametry

  • drawIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is none of the tournament's staff. An
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/draws/{drawId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Delete a draft

DELETE/v1/draws/{drawId}Wymaga uwierzytelnienia

A draft only: a published draw has matches and is refused as draw_locked. Announced as draw_deleted on the draw aggregate.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The draft is gone.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/draws/{drawId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "deleted": true
  }
}

List the draft's entries, with their seeds

PUT/v1/draws/{drawId}/entriesWymaga uwierzytelnienia

Replaces the entries whole, in the order given, which is the order a placement in entry order fills the bracket or the groups with. Every line and every group is cleared: a new list is placed again. Each entry is a participant of the tournament of the kind the ruleset is played by (a pair for a doubles ruleset), once; a seed is one of 1 to the entry count, held once. A knockout draw takes at most 256 entries, the largest bracket, and a round-robin draw 416, 26 groups of 16. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • entriesobject[]wymagany

    Pola

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/entries' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "entries": [
    {
      "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "seed": 1
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Place every entry in the bracket or into groups

POST/v1/draws/{drawId}/placementWymaga uwierzytelnienia

A knockout draw: the bracket is the smallest power of two that takes every entry. Seed i stands on rank i's line of the standard order, the byes go to the top ranks so that two never meet, and the unseeded entries fill the remaining lines top to bottom. A round-robin draw, into group_count groups, which it requires and a knockout draw refuses as format_mismatch: the seeds in seed order one to each group, 1 to G, then snaking back, G to 1; the unseeded each to the group with the fewest entries, the lowest on a tie, so no two groups differ by more than one. A group plays with 2 to 16 entries, and its seeds stand first by seed number, then the unseeded as they arrived. Either way the unseeded go entry_order in the order listed, lot in the order of a lot the server draws once and records on the draw. gcr_draw, a knockout draw's only, is the draw of BWF General Competition Regulations Regulation 11 instead, from the same recorded lot: seed 1 at the top line and seed 2 at the bottom, seeds 3-4, 5-8, 9-16 and 17-32 drawn by lot into the quarters, eighths, sixteenths and thirty-seconds no earlier seed holds, at the top line of a section in the top half and the bottom line in the bottom half; the byes on the lines Section 5.3.8's Tables 1 to 7 give the entry count, whichever seed the lot put beside them; one Member's entries kept apart (GCR 11.12), its first and second ranked in opposite halves and, wherever possible, none of its entries meeting in the first round, a Member being the players' association, a pair's only when both share it; and the rest drawn into the lines left. A Member's entries rank by seed, then by ranking position, then by the lot. It takes seeds numbered 1 upwards without a gap, at most 2 below 16 entries, 4 below 32, 8 below 64, 16 below 128 and 32 from 128 (GCR 11.8.1), and refuses any other seeding as regulation_seeding. bec_championships_draw is the same draw with the seeds Badminton Europe's European Championships allow (Appendix I 7.2): 8 from 17 entries, and GCR 11.8.1's at 16 or fewer. Each entry of a draw by the regulations answers the association and ranking_position the draw read, so it is made again from its record. A round-robin draw refuses both as format_mismatch on method. Placing again replaces the lines or the groups. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • methodstringwymagany

    entry_orderlotgcr_drawbec_championships_draw

  • group_countinteger | null

    A round-robin draw's groups, named A onwards; none for a knockout draw.

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/draws/{drawId}/placement' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "method": "entry_order",
  "group_count": 1
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Number the seeds from the entries' ranking

POST/v1/draws/{drawId}/seeds-from-rankingWymaga uwierzytelnienia

Numbers the draft's seeds from the ranking positions its entries carry (Participant.ranking), as BWF GCR 11.6 numbers them from the World Ranking: the highest ranked seed 1, the next seed 2, for count seeds, or as many as GCR 11.8.1 allows for the entry count when it is left out. An entry without a ranking position is not seeded; every seed the draft held before is replaced, and the placement is cleared, as a new entry list clears it. Entries at one position are ordered by a lot the server draws (GCR 11.6.1) and does not keep, since the seeds it gave are kept; seeds_drawn_by_lot names them, for the director to change by listing the entries again. Roundr computes no ranking: it reads the one the director entered or imported, and positions from more than one ranking, told apart by name and date, are refused as ranking_mixed on ranking. No entry with a ranking position is ranking_missing on ranking, and a count outside 1 to the entry count seed_out_of_range on count. A draw fed by groups refuses it as format_mismatch. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • countinteger | null

    How many seeds; left out or null, as many as GCR 11.8.1 allows.

Odpowiedzi

  • 200The draft as seeded, and the seeds a lot decided.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/draws/{drawId}/seeds-from-ranking' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "count": 1
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    },
    "seeds_drawn_by_lot": [
      0
    ]
  }
}

Stand the entries on the lines given

PUT/v1/draws/{drawId}/positionsWymaga uwierzytelnienia

The director's swaps, sent as the whole arrangement so that a retry means the same thing twice: every entry and every fed place, once, on a line of the placed bracket, with never two byes against each other, and in a qualifying draw an entry in each half of every section. The lot on record stays. A knockout draw's only: a round-robin draw is arranged by /groups, and refused here as format_mismatch. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • positionsobject[]wymagany

    Pola

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/positions' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "positions": [
    {
      "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "feed": 1,
      "position": 1
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Publish the placed draft into its matches

POST/v1/draws/{drawId}/publishWymaga uwierzytelnienia

One transaction. Every match is created as an ordinary match, pinned to the draw's ruleset. A knockout draw's are referenced {code}-{n} round by round and top to bottom, skipping the first-round pairings a bye leaves unplayed; a side a line fills starts with its entry, and a side fed by a winner starts empty. A round-robin draw's are every group's, in the order of play of BWF GCR 16.4 for groups of 3 to 7 and of the circle method for the rest, referenced {code}-{letter}{n} (MS-A1) by group and number in the group's order of play, with both sides their entries; a round's slots run on from one group to the next. Each match is announced as match_created at revision 0, and then the draw as draw_published. From then on the draw is not changed structurally; a late withdrawal is a walkover.

A knockout draw that plays for third place gets one more match, the final round's second slot, numbered last, whose sides are loser_of its semi-finals. One with a consolation creates it in the same transaction: a second knockout draw, published, named after the draw with its code in brackets and coded with the draw's code and a C (MS makes MSC, its matches MSC-1 on), its matches announced after the main draw's and it as draw_published after the main draw. Its bracket is half the main one's, laid out from it with no lot: its line p takes the loser of the main draw's first-round pairing p, which for a pairing that is a bye is the loser of the second-round match the bye leads to, and only when that loser is the entry the bye sent through, since a consolation takes an entry who lost the first match they played. Where two byes stand side by side, the upper line takes their second-round match's loser and the lower is a bye. A draw fed by groups lays out its consolation the same way from its lines of ranks; a qualifier's first match is its first in the knockout, and the loser of one whose rank was void is nobody, so that line is void.

A knockout draw that plays off every place gets its placement groups' matches in every round after the first, numbered round by round with the main bracket's, top to bottom within a round, so all of round 2 is numbered before round 3. Round r's slots are split into groups of size / 2^r; group g plays for the places from g × size / 2^(r − 1) + 1, group 0 is the main bracket, and round r + 1's group 2g takes the winners of round r's group g in order and group 2g + 1 their losers, as loser_of sides of the same draw. The match for third is round log2(size)'s slot 2. A pairing with one side absent is no match: its side goes through keeping its source, which may name a match two rounds back or more, and a pairing with none sends nobody on. Each placement match carries places, the places it decides between, counted over the entrants who can reach it, so a bye takes no place.

Refused while any entry has no line or no group (not_placed, on positions or groups); with third_place_unplayable when the bracket has no two semi-finals to play for third (two or three entries); with consolation_unplayable for a bracket of two, or when the draw also plays for third place and a semi-final can be an entrant's first match, whose loser both would take (a bracket of four, or of eight with a bye); and on the code, or the name, when a match of the tournament already holds one of the references the draw would give or a draw holds the consolation's code or name.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/draws/{drawId}/publish' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Set whether a knockout draft plays for third place, has a consolation and plays off every place

PUT/v1/draws/{drawId}/optionsWymaga uwierzytelnienia

The options, sent whole so that a retry means the same thing twice; all_places left out is false, as a client older than it sends the other two. Whether the bracket can play them is asked at publication, since the entries may change until then (/publish). A round-robin draw asked for any is refused as format_mismatch, and a consolation of a draw coded with 16 characters as consolation_unplayable, since its code adds a C; so is a consolation a draw fed by groups cannot play, since its bracket is laid out when it is made. all_places with either other option is refused on all_places: every place includes the match for third, and every loser already plays on. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • third_placebooleanwymagany

  • consolationbooleanwymagany

  • all_placesboolean

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/options' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "third_place": true,
  "consolation": true,
  "all_places": true
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Set who may enter a draft by gender

PUT/v1/draws/{drawId}/entry-ruleWymaga uwierzytelnienia

The draft's entry rule, sent whole so that a retry means the same thing twice: entry_gender is required, and null lifts the rule. A rule the entries already listed contradict is refused as gender_mismatch on entry_gender, with details.participant_ids naming them; a mixed rule on a ruleset played by singles as mixed_needs_pairs. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • entry_genderstring | nullwymagany

    A draw's entry rule: men takes male players, women female ones, mixed a pair of one of each and only on a ruleset played by pairs, and null anyone. An entry is refused only where a player's recorded gender contradicts it, never for a gender nobody recorded.

    menwomenmixednull

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/entry-rule' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "entry_gender": "men"
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Set a draft's age category

PUT/v1/draws/{drawId}/age-ruleWymaga uwierzytelnienia

The draft's age category, sent whole so that a retry means the same thing twice: age_rule is required, and null lifts it. Nothing already entered is refused: a player entering themselves is checked at registration, and Control warns about an entry the staff make (DEV-27). Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • age_ruleone ofwymagany

    A draw's age category, or null for any age. under 15 is U15, a player who does not turn 15 in the calendar year of the tournament's start; over 35 is 35+, one who turns 35 or more that year (DEV-27). Sent by every server that keeps age categories; a client reading an older one takes its absence for any age.

    Pola

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/age-rule' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "age_rule": null
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Set a draft's class rule

PUT/v1/draws/{drawId}/class-ruleWymaga uwierzytelnienia

The player classes the draft admits in its discipline, sent whole so that a retry means the same thing twice: class_rule is required, and null lifts it. Nothing already entered is refused: a player entering themselves is checked at registration, and Control warns about an entry the staff make (DEV-31). Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • class_ruleone ofwymagany

    A draw's class rule, or null for every class: the player classes it admits in its discipline (Discipline), in the order of the organization's scale. A pair enters when both players hold an admitted class (DEV-31). Sent by every server that keeps classes; a client reading an older one takes its absence for every class.

    Pola

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/class-rule' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "class_rule": null
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Stand the entries in the groups given

PUT/v1/draws/{drawId}/groupsWymaga uwierzytelnienia

The director's moves between groups and changes of order, sent as the whole arrangement so that a retry means the same thing twice. Group i is the i-th list, named by the i-th letter, and an entry's place in its group is its order in the list, which is the position the order of play is read by. Every entry stands in one group, once; 1 to 26 groups, each of 2 to 16 entries. A draft need not be placed first. The lot on record stays. A round-robin draw's only: a knockout draw is arranged by /positions, and refused here as format_mismatch. Every problem is given on groups. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • groupsone of[][]wymagany

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/groups' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "groups": [
    [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ]
  ]
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

A round-robin draw's standings, group by group

GET/v1/draws/{drawId}/standingsWymaga uwierzytelnienia

Computed on every read from the group matches as they stand, never stored: a confirmation or a reopening moves the match's revision and announces it, which is when to read again. Only a confirmed match counts; a result nobody has confirmed may still be corrected. Each group is ranked by the rules the draw records, bwf-gcr-16.2: matches won; two level by the match between them; three or more by game difference, then point difference, going to the match between two whenever a step leaves exactly two level; three or more still level share a rank, lots, until the group is complete and a lot is drawn for the tie (/lots), which ranks them from that rank in the order it drew, lot_drawn. A lot ranks only the tie it was drawn for, the same entries level at the same rank; a correction that leaves another tie leaves it out of force. An entry that did not complete its group matches (it retired, gave a walkover, was disqualified or was ended out by the referee, or was either side of a double walkover) has all its results deleted, its opponents' included, and is listed last, withdrawn. Until the group is complete the ranking is provisional: where the match between two has not been played, the differences decide in its place. For the tournament's staff, as the draws are, and for a hall display whose projection names the draw (standings_draw_ids), read again on every request; a display is refused every other draw as it is refused the draws themselves.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The standings.
  • 401No credential.
  • 403insufficient_scope: the caller is none of the tournament's staff. An
  • 404No such draw in the principal's organization, one in a tournament outside the
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/draws/{drawId}/standings' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "name": "string",
    "code": "string",
    "standings_rules": "string",
    "groups": [
      {
        "group": 0,
        "name": "string",
        "matches_confirmed": 0,
        "matches_total": 0,
        "complete": true,
        "rows": [
          {
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "rank": 0,
            "tied": true,
            "withdrawn": true,
            "played": 0,
            "won": 0,
            "lost": 0,
            "games_won": 0,
            "games_lost": 0,
            "points_won": 0,
            "points_lost": 0,
            "decided_by": null
          }
        ]
      }
    ]
  }
}

Feed a draft from other draws of its tournament

PUT/v1/draws/{drawId}/feedsWymaga uwierzytelnienia

Replaces whatever fed the draft (DEV-30). Each source gives the draft one fed place for each match of a round of a published knockout of the same tournament: its winner, from the round that gives each section of a qualifying draw its winner (the default for winners), or its loser, from any round. The places are numbered in the order asked, each source's matches top to bottom, and placed with the entries as unseeded entries not yet known; like a new entry list, this clears the placement. A match sends its winner and its loser to one place each. Refused with details.problem on feeds: source_unusable (not a published knockout of the tournament, a round it does not play, or winners of any round but a qualifying draw's last), source_taken (the source sends those losers on already, or another draw is fed by them), kind_mismatch, entry_repeated (one round asked twice), entry_count, or format_mismatch for a draw fed by groups. Announced as draw_changed.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • expected_revisionintegerwymagany

  • feedsobject[]wymagany

    Pola

Odpowiedzi

  • 200The draw as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such draw in the principal's organization, or one in a tournament outside the
  • 409draw_locked: the draw is published, and a published draw is not changed
  • 422validation_failed: a malformed body, or a draw that cannot be played as asked,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/draws/{drawId}/feeds' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_revision": 1,
  "feeds": [
    {
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "takes": "winners",
      "round": 1
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Move the seeds of a published knockout draw after a seed withdraws

POST/v1/draws/{drawId}/seed-withdrawalWymaga uwierzytelnienia

BWF GCR 11.3, the Seed Withdrawal Movement, for seeds who withdraw after the draw and before play. A withdrawn seed's line is taken by a remaining seed of the next seeding group (1-2, 3-4, 5-8, 9-16, 17-32), the one in that section of the draw; each seed who moves leaves a line filled the same way, and the lines the lowest seeds leave are taken by unseeded entries: the best ranked in the director's ranking, a tie and the unranked by a lot the server draws, onto lines the lot draws. The lines those entries leave are taken by reserves, in order (Regulation 13); a line nobody takes stays empty, its side void, and the entrant opposite goes through by walkover, which an official records. A seed keeps its number where it moves. The seeds who withdraw leave the draw's entries, a reserve promoted becomes one, and each line that changes is its match's own SidePlaced batch naming the movement, announced as match_sides_changed; the draw is announced last as draw_seeds_moved. The tournament's director or referee moves them, once per draw (11.3.1), and only while no match a line feeds has begun.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • withdrawnstring (uuid)[]wymagany

    The seeds who withdraw, each once, in any order.

  • reservesstring (uuid)[]

    Participants of the tournament not in the draw, promoted in this order into the lines the unseeded entries leave, in line order. At most one for each such line; none leaves them empty.

Odpowiedzi

  • 201What the movement did, in the order it did it, and the draw as it now stands.
  • 401No credential.
  • 403Not the tournament's director or referee: an administrator of the organization
  • 404No such draw in the principal's organization or scope, or not a published
  • 422validation_failed, with details.problem where the draw refuses it:
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/draws/{drawId}/seed-withdrawal' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "withdrawn": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "reserves": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ]
}'
201
{
  "ok": true,
  "data": {
    "movement": {
      "withdrawn": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "moves": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "from": 1,
          "to": 1
        }
      ],
      "promoted": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "to": 1
        }
      ],
      "vacant": [
        1
      ]
    },
    "draw": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "code": "string",
      "format": "knockout",
      "standings_rules": "string",
      "third_place": true,
      "consolation": true,
      "all_places": true,
      "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "consolation_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "qualifiers_per_group": 0,
      "qualifiers": 0,
      "seed_bands": true,
      "feeds": [
        {
          "feed": 0,
          "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "source_draw_name": "string",
          "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "takes": "winner_of",
          "position": 0,
          "group": 0,
          "group_place": 0,
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "void": true,
          "seed": 0,
          "seed_banded": true
        }
      ],
      "entry_gender": "men",
      "age_rule": null,
      "class_rule": null,
      "ruleset": {
        "id": "string",
        "version": "string",
        "engine_version": "string"
      },
      "status": "draft",
      "size": 0,
      "group_count": 0,
      "revision": 0,
      "lot_drawn": true,
      "seeds_moved": true,
      "placement_method": "entry_order",
      "published_at": "2026-09-27T10:30:00Z",
      "entries": [
        {
          "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "seed": 0,
          "position": 0,
          "group": 0,
          "group_place": 0,
          "association": "string",
          "ranking_position": 0
        }
      ],
      "matches": [
        {
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "round": 0,
          "slot": 0,
          "group": 0,
          "places": null,
          "home_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          },
          "away_source": {
            "kind": "position",
            "position": 0,
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "void": true,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "group": 0,
            "rank": 0,
            "tied": true,
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string"
          }
        }
      ]
    }
  }
}

Draw the lot for a tie in a complete group

POST/v1/draws/{drawId}/lotsWymaga uwierzytelnienia

BWF GCR 16.2.4.2 ranks three or more entries still level after points by drawing lots. The server draws sixteen random bytes, orders the tied entries by them and records the lot with the group, the rank, the entries in order, who drew it and when, so the order can be drawn again from the record. Nothing draws a lot on its own: the tournament's director or referee asks for it, as the regulation's drawing is an official's act. participant_ids names the entries the official saw tied at rank, the rank they share, so a lot is never drawn on a tie a correction made meanwhile. From then on the standings rank the tie by the lot (lot_drawn), and the knockout draw the group feeds takes the ranks it settled, each as that match's own SidePlaced batch naming the lot, as a confirmation places them. A lot ranks only the tie it was drawn for; a correction that leaves another tie leaves it on record and out of force, and the new tie is drawn afresh. A tie a lot ranks is never drawn again. Announced as draw_lot_drawn on the round robin's draw aggregate, which a hall display showing its standings is told of too.

Parametry

  • drawIdścieżka · string (uuid)wymagany

Treść żądania

  • groupintegerwymagany

    The group, from 1 for A.

  • rankintegerwymagany

    The rank the tied entries share, the first of the places they tie for.

  • participant_idsstring (uuid)[]wymagany

    The entries tied at rank, in any order.

Odpowiedzi

  • 201The lot, and the draw's standings ranked by it.
  • 401No credential.
  • 403Not the tournament's director or referee: an administrator of the organization
  • 404No such draw in the principal's organization or scope, a knockout draw, or a
  • 409lot_refused, with details.reason: group_incomplete (a match of the group is
  • 422validation_failed: a group the draw does not have, a rank below 1, or fewer
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/draws/{drawId}/lots' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "group": 1,
  "rank": 1,
  "participant_ids": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ]
}'
201
{
  "ok": true,
  "data": {
    "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "name": "string",
    "code": "string",
    "standings_rules": "string",
    "groups": [
      {
        "group": 0,
        "name": "string",
        "matches_confirmed": 0,
        "matches_total": 0,
        "complete": true,
        "rows": [
          {
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "rank": 0,
            "tied": true,
            "withdrawn": true,
            "played": 0,
            "won": 0,
            "lost": 0,
            "games_won": 0,
            "games_lost": 0,
            "points_won": 0,
            "points_lost": 0,
            "decided_by": null
          }
        ]
      }
    ],
    "lot": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "group": 0,
      "rank": 0,
      "order": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "drawn_at": "2026-09-27T10:30:00Z"
    }
  }
}

Live

The anonymous public scoreboard: an organization's page and the tournaments it has published on Live. A customer's host serves its own organization's page and tournaments; the platform's site (roundr.com, which reads the shared API host) serves any organization's published tournament or match by its id, and no list. No credential is read and none is needed; a tournament nobody published is not found, exactly as an id that does not exist. Every answer carries an ETag, and a client polls with If-None-Match rather than holding a stream open: Live's audience is unbounded, and a bodiless 304 is the cheapest answer there is. Reads are budgeted per client address, an IPv6 address by its /64.

The organization's public page, and its tournaments on Live

GET/v1/public/tournamentsPubliczny

The organization the request's host belongs to, by name, and the tournaments it has published on Live, newest first. Served on a customer host only: the shared API host and the platform's own hosts belong to no organization and answer 404, so there is no list of every organization's tournaments.

Parametry

  • If-None-Matchnagłówek · string

    The ETag of the projection the client last read. When it still describes the projection the answer is a bodiless 304; compared weakly, so a W/ a compressing proxy added still matches.

Odpowiedzi

  • 200The organization and its published tournaments.
  • 304The projection is the one If-None-Match named. No body; the tag is sent again so a
  • 404not_found. For a tournament or match: none by that id, one of a tournament not
  • 429rate_limited: the client's address has spent Live's budget of reads, which is
Przykład
curl 'https://api.roundr.com/v1/public/tournaments'
200
{
  "ok": true,
  "data": {
    "organization": {
      "name": "string"
    },
    "tournaments": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27",
        "status": "draft",
        "match_minutes": 1,
        "league_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ],
    "leagues": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "organization_name": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      }
    ]
  }
}

A tournament published on Live

GET/v1/public/tournaments/{tournamentId}Publiczny

The explicitly public projection of one tournament: its name, dates, zone, venue and organization's name, its courts, every match with its sides' names, its place in the schedule and in its draw, its status and its score, and every published draw with its bracket or groups and a round-robin draw's standings. Nothing else: no participant's players, reference or contact, no staff, device or credential, no Referee's briefing, no match history and no draft draw.

On a customer's host, only that organization's tournaments. On the platform's site, the apex and the shared API host its pages read, any organization's published tournament. The demo host serves none. A tournament not published on Live, one outside the host's reach, and an id that does not exist are one identical 404.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • If-None-Matchnagłówek · string

    The ETag of the projection the client last read. When it still describes the projection the answer is a bodiless 304; compared weakly, so a W/ a compressing proxy added still matches.

Odpowiedzi

  • 200The tournament's public projection.
  • 304The projection is the one If-None-Match named. No body; the tag is sent again so a
  • 404not_found. For a tournament or match: none by that id, one of a tournament not
  • 429rate_limited: the client's address has spent Live's budget of reads, which is
Przykład
curl 'https://api.roundr.com/v1/public/tournaments/{tournamentId}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "organization_name": "string",
      "venue_name": "string",
      "venue_time_zone": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "match_minutes": 1,
      "league_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "courts": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "sort_order": 0
      }
    ],
    "participants": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "nationalities": [
          "string"
        ],
        "players": [
          {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ]
      }
    ],
    "matches": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "participants": {
          "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
        },
        "external_ref": "string",
        "scheduled_start": "2026-09-27T10:30:00Z",
        "sequence": 0,
        "not_before": "2026-09-27T10:30:00Z",
        "started_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z",
        "draw": null,
        "status": "scheduled",
        "score": {
          "games": [
            {
              "home": null,
              "away": null,
              "complete": null
            }
          ],
          "games_won": {
            "home": 0,
            "away": 0
          },
          "serving": null,
          "interval": true,
          "winner": null,
          "outcome": null
        }
      }
    ],
    "draws": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "age_rule": null,
        "class_rule": null,
        "format": "knockout",
        "size": 0,
        "group_count": 0,
        "third_place": true,
        "all_places": true,
        "main_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "qualifiers": 0,
        "seed_bands": true,
        "feeds": [
          {
            "feed": 0,
            "source_draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "source_draw_name": "string",
            "source_match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "external_ref": "string",
            "takes": "winner_of",
            "position": 0,
            "group": 0,
            "group_place": 0,
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "void": true,
            "seed": 0,
            "seed_banded": true
          }
        ],
        "entries": [
          {
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "seed": 0,
            "position": 0,
            "group": 0,
            "group_place": 0,
            "association": "string",
            "ranking_position": 0
          }
        ],
        "matches": [
          {
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "round": 0,
            "slot": 0,
            "group": 0,
            "places": null,
            "home_source": {
              "kind": "position",
              "position": null,
              "match_id": null,
              "external_ref": null,
              "void": null,
              "participant_id": null,
              "group": null,
              "rank": null,
              "tied": null,
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null
            },
            "away_source": {
              "kind": "position",
              "position": null,
              "match_id": null,
              "external_ref": null,
              "void": null,
              "participant_id": null,
              "group": null,
              "rank": null,
              "tied": null,
              "feed": null,
              "source_draw_id": null,
              "source_draw_name": null
            }
          }
        ],
        "standings": null
      }
    ],
    "entry_lists": [
      {
        "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "age_rule": null,
        "class_rule": null,
        "drawn": true,
        "entry_count": 0,
        "entries": [
          {
            "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "associations": [
              null
            ]
          }
        ]
      }
    ],
    "ties": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "round": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "start_time": "string",
        "decided": true,
        "home_rubbers": 0,
        "away_rubbers": 0,
        "rubbers": [
          {
            "code": "string",
            "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "not_fielded_by": "home"
          }
        ]
      }
    ]
  }
}

One match of a tournament published on Live

GET/v1/public/matches/{matchId}Publiczny

The match as GET /v1/public/tournaments/{tournamentId} carries it, with its tournament, its court and its two sides' names, so the match's own page reads it in one request. Served on the hosts that serve its tournament: its organization's own and the platform's site. A match of a tournament not published on Live, one outside the host's reach, and an id that does not exist are one identical 404.

Parametry

  • matchIdścieżka · string (uuid)wymagany

  • If-None-Matchnagłówek · string

    The ETag of the projection the client last read. When it still describes the projection the answer is a bodiless 304; compared weakly, so a W/ a compressing proxy added still matches.

Odpowiedzi

  • 200The match's public projection.
  • 304The projection is the one If-None-Match named. No body; the tag is sent again so a
  • 404not_found. For a tournament or match: none by that id, one of a tournament not
  • 429rate_limited: the client's address has spent Live's budget of reads, which is
Przykład
curl 'https://api.roundr.com/v1/public/matches/{matchId}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "organization_name": "string",
      "venue_name": "string",
      "venue_time_zone": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "match_minutes": 1,
      "league_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "court": null,
    "participants": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "nationalities": [
          "string"
        ],
        "players": [
          {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ]
      }
    ],
    "match": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "participants": {
        "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      },
      "external_ref": "string",
      "scheduled_start": "2026-09-27T10:30:00Z",
      "sequence": 0,
      "not_before": "2026-09-27T10:30:00Z",
      "started_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z",
      "draw": null,
      "status": "scheduled",
      "score": {
        "games": [
          {
            "home": 0,
            "away": 0,
            "complete": true
          }
        ],
        "games_won": {
          "home": 0,
          "away": 0
        },
        "serving": null,
        "interval": true,
        "winner": null,
        "outcome": null
      }
    }
  }
}

An organization's page on the platform's site

GET/v1/public/organizations/{slug}Publiczny

What a customer's host answers at GET /v1/public/tournaments, for an organization found by its slug on the platform's site, the apex and the shared API host its pages read (DEV-645): its name and the tournaments and leagues it published on Live. The address an organization with no host of its own shares, roundr.com/o/{slug}. An organization that published nothing has no page; it, a suspended one, a slug that names none and any other host are one identical 404.

Parametry

  • slugścieżka · stringwymagany

  • If-None-Matchnagłówek · string

    The ETag of the projection the client last read. When it still describes the projection the answer is a bodiless 304; compared weakly, so a W/ a compressing proxy added still matches.

Odpowiedzi

  • 200The organization's page.
  • 304Unchanged since the tag named in If-None-Match.
  • 404not_found.
  • 429rate_limited: the client's address has spent Live's budget of reads, which is
Przykład
curl 'https://api.roundr.com/v1/public/organizations/{slug}'
200
{
  "ok": true,
  "data": {
    "organization": {
      "name": "string"
    },
    "tournaments": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27",
        "status": "draft",
        "match_minutes": 1,
        "league_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ],
    "leagues": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "organization_name": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      }
    ]
  }
}

A league published on Live

GET/v1/public/leagues/{leagueId}Publiczny

A league its administrators published (DEV-50): its points and the codes of its tie, its match days, and each division's table and ties, read from the started ties' matches as they stand. Teams by name and club; never a roster, a line-up, a captain, a guest or a team the league has not placed. A rubber names its match (match_id), and a match day its tournament, only where that tournament is itself on Live within the host's reach, whose page shows the players. Served on the hosts that serve its organization's tournaments; a league not published, one outside the host's reach, and an id that does not exist are one identical 404. The tag is a digest of the answer.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • If-None-Matchnagłówek · string

    The ETag of the projection the client last read. When it still describes the projection the answer is a bodiless 304; compared weakly, so a W/ a compressing proxy added still matches.

Odpowiedzi

  • 200The league's public projection.
  • 304The projection is the one If-None-Match named. No body; the tag is sent again so a
  • 404not_found. For a tournament or match: none by that id, one of a tournament not
  • 429rate_limited: the client's address has spent Live's budget of reads, which is
Przykład
curl 'https://api.roundr.com/v1/public/leagues/{leagueId}'
200
{
  "ok": true,
  "data": {
    "league": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "season": "string",
      "organization_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "points": {
        "win": 0,
        "draw": 0,
        "loss": 0
      },
      "rubbers": [
        "string"
      ]
    },
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ],
    "divisions": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "standings": [
          {
            "team": {
              "id": null,
              "name": null,
              "club_name": null
            },
            "played": 0,
            "won": 0,
            "drawn": 0,
            "lost": 0,
            "rubbers_for": 0,
            "rubbers_against": 0,
            "games_for": 0,
            "games_against": 0,
            "points": 0
          }
        ],
        "ties": [
          {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "round": 0,
            "home": {
              "id": null,
              "name": null,
              "club_name": null
            },
            "away": {
              "id": null,
              "name": null,
              "club_name": null
            },
            "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "start_time": "string",
            "started": true,
            "decided": true,
            "home_rubbers": 0,
            "away_rubbers": 0,
            "rubbers": [
              null
            ]
          }
        ]
      }
    ]
  }
}

A Live tournament's page, named for a link preview

GET/v1/public/pages/tournaments/{tournamentId}Publiczny

The web application's page for a Live address, with the tournament and its organization named in its title and link preview (DEV-646). A chat app or a social network reads a shared link's HTML and runs no script, so the page carries the names itself: the static hosts answer the Live address from here. Found by Live's own rules and the host's reach; what Live would not show, an id that does not exist, the demo host and a spent read budget are the page unchanged, which is not an error. Not a JSON read, and not for an application to call.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The page, as HTML.
  • 500The web build is not where the server expects it; the vhost then sends the page from disk.
Przykład
curl 'https://api.roundr.com/v1/public/pages/tournaments/{tournamentId}'
200
"string"

A Live match's page, named for a link preview

GET/v1/public/pages/matches/{matchId}Publiczny

The web application's page for a Live address, with the match's two sides and its tournament named in its title and link preview (DEV-646). A chat app or a social network reads a shared link's HTML and runs no script, so the page carries the names itself: the static hosts answer the Live address from here. Found by Live's own rules and the host's reach; what Live would not show, an id that does not exist, the demo host and a spent read budget are the page unchanged, which is not an error. Not a JSON read, and not for an application to call.

Parametry

  • matchIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The page, as HTML.
  • 500The web build is not where the server expects it; the vhost then sends the page from disk.
Przykład
curl 'https://api.roundr.com/v1/public/pages/matches/{matchId}'
200
"string"

A Live league's page, named for a link preview

GET/v1/public/pages/leagues/{leagueId}Publiczny

The web application's page for a Live address, with the league, its season and its organization named in its title and link preview (DEV-646). A chat app or a social network reads a shared link's HTML and runs no script, so the page carries the names itself: the static hosts answer the Live address from here. Found by Live's own rules and the host's reach; what Live would not show, an id that does not exist, the demo host and a spent read budget are the page unchanged, which is not an error. Not a JSON read, and not for an application to call.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The page, as HTML.
  • 500The web build is not where the server expects it; the vhost then sends the page from disk.
Przykład
curl 'https://api.roundr.com/v1/public/pages/leagues/{leagueId}'
200
"string"

Registration

Personal registration for a tournament (DEV-18). A director opens a tournament and offers its draft draws as the events that take entries; anyone reads what an open tournament offers on its organization's host or the platform's site, as Live is read; a signed-in person enters an event alone or naming a partner, who confirms from their own account; and the tournament's director or an administrator of the organization accepts a complete registration into the participants or declines it. Only a person registers: a court device, a display and a machine key have no account.

Whether the tournament takes entries, until when, and in which events

GET/v1/tournaments/{tournamentId}/registrationWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization. A tournament whose settings were never saved reads as closed, with no event, at revision 0.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The settings.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/registration' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "registration": {
      "open": true,
      "closes_at": "2026-09-27T10:30:00Z",
      "opens_at": "2026-09-27T10:30:00Z",
      "withdrawals_close_at": "2026-09-27T10:30:00Z",
      "public_associations": true,
      "draw_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "revision": 0
    }
  }
}

Open or close the tournament for registration

PUT/v1/tournaments/{tournamentId}/registrationWymaga uwierzytelnienia

Replaces the settings whole, as a form holds them, so a retry means the same thing twice. An event is a draft draw of the tournament not fed by the groups of another, and a draw that is published later stops taking entries on its own. Opening needs at least one event and a closing time, if there is one, still to come; closing takes any. An opening time, when there is one, comes before the closing time, open or not. opens_at, withdrawals_close_at and public_associations came later: left out, each keeps what is stored, so a client that has never heard of them clears nothing (DEV-27). For a director of the tournament or an administrator of the organization; a referee, a court or display credential and a machine key are refused. A change moves the settings' revision once, and is logged with who made it.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • openbooleanwymagany

  • closes_atstring | null (date-time)wymagany

    An instant with its offset; Control asks for it at the venue's clock.

  • opens_atstring | null (date-time)

    When entries open, an instant with its offset; null to take them as soon as the tournament is open. Left out, it stays as it is.

  • withdrawals_close_atstring | null (date-time)

    After this instant a player can no longer withdraw an entry themselves; the staff still can. Null for no deadline. Left out, it stays as it is.

  • public_associationsboolean

    Whether Live's entry list shows each entry's club or association. Left out, it stays as it is; off until a director turns it on.

  • draw_idsstring (uuid)[]wymagany

Odpowiedzi

  • 200The settings as they now stand.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed: a field of the wrong shape, or details.problem
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/tournaments/{tournamentId}/registration' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "open": true,
  "closes_at": "2026-09-27T10:30:00Z",
  "opens_at": "2026-09-27T10:30:00Z",
  "withdrawals_close_at": "2026-09-27T10:30:00Z",
  "public_associations": true,
  "draw_ids": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ]
}'
200
{
  "ok": true,
  "data": {
    "registration": {
      "open": true,
      "closes_at": "2026-09-27T10:30:00Z",
      "opens_at": "2026-09-27T10:30:00Z",
      "withdrawals_close_at": "2026-09-27T10:30:00Z",
      "public_associations": true,
      "draw_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "revision": 0
    }
  }
}

The tournament's registrations

GET/v1/tournaments/{tournamentId}/registrationsWymaga uwierzytelnienia

Every registration for the tournament, those waiting for an answer first, then the newest. For a director of the tournament or an administrator of the organization. A player is named as they enter, with whether they confirmed; no account or address is shown.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The registrations.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/registrations' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "registrations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "organization_name": "string",
          "venue_time_zone": "string",
          "starts_on": "2026-09-27",
          "ends_on": "2026-09-27"
        },
        "event": {
          "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "code": "string",
          "age_rule": null,
          "class_rule": null
        },
        "entry_window": {
          "opens_at": "2026-09-27T10:30:00Z",
          "closes_at": "2026-09-27T10:30:00Z",
          "withdrawals_close_at": "2026-09-27T10:30:00Z"
        },
        "kind": "single",
        "status": "pending",
        "display_name": "string",
        "complete": true,
        "players": [
          {
            "position": 1,
            "full_name": "string",
            "given_name": "string",
            "family_name": "string",
            "family_name_first": true,
            "confirmed": true,
            "you": true
          }
        ],
        "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "registered_at": "2026-09-27T10:30:00Z",
        "decided_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z",
        "revision": 1
      }
    ]
  }
}

Accept a registration into the participants, decline it, or withdraw an accepted one

POST/v1/tournaments/{tournamentId}/registrations/{registrationId}/decisionWymaga uwierzytelnienia

Accepting a complete registration finds the tournament's participant of exactly its players, or creates one, each player being the tournament's player already linked to that account or a new one linked to it; it enters the participant at the end of the event's draw while the draw is a draft, which clears the draft's lines as any change to its entries does, and says so in entered. Declining records who and when, and frees the players' places. Withdrawing an accepted entry, for a player who tells the organizers they cannot play, takes it out of the event's draft whatever the withdrawal deadline says, and keeps the participant and the decision; a draw being placed or published is refused as draw_made, since the staff then take the entry out in the draw. The same decision again is answered as it stands. For a director of the tournament or an administrator of the organization, and logged with who decided.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • registrationIdścieżka · string (uuid)wymagany

Treść żądania

  • decisionstringwymagany

    Append-only. withdraw is sent by every server that withdraws for a player.

    acceptdeclinewithdraw

Odpowiedzi

  • 200The registration as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization, or not a registration for it.
  • 422validation_failed: decision is neither, or details.problem is
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/registrations/{registrationId}/decision' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "decision": "accept"
}'
200
{
  "ok": true,
  "data": {
    "registration": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      },
      "event": {
        "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "age_rule": null,
        "class_rule": null
      },
      "entry_window": {
        "opens_at": "2026-09-27T10:30:00Z",
        "closes_at": "2026-09-27T10:30:00Z",
        "withdrawals_close_at": "2026-09-27T10:30:00Z"
      },
      "kind": "single",
      "status": "pending",
      "display_name": "string",
      "complete": true,
      "players": [
        {
          "position": 1,
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "confirmed": true,
          "you": true
        }
      ],
      "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "registered_at": "2026-09-27T10:30:00Z",
      "decided_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z",
      "revision": 1
    },
    "entered": true
  }
}

What a tournament offers someone who would enter it

GET/v1/public/tournaments/{tournamentId}/registrationPubliczny

The tournament's name, dates and zone, whether it takes entries now, from and until when, until when a player may withdraw, and the events that do, each with the kind of participant that enters it and its age category. A tournament open for entries from a time still to come is found, answers open: false, and names its window and its events, so a link handed out early says when to come back (DEV-27). Served by Live's rules on the organization's own host and on the platform's site, which finds a tournament by its id as its Live does (DEV-671): no credential is read, the client address spends Live's budget, and a tournament that is neither published on Live nor taking entries, another organization's on a tenant host, and an id that does not exist are one identical 404. A tournament on Live that takes none answers open: false and no events, so no draft's name is shown before it is offered. A closed tournament takes none whatever its settings say, so it is found only on Live. Not cached: the answer turns at the opening and closing times.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The offer.
  • 404not_found. For a tournament or match: none by that id, one of a tournament not
  • 429rate_limited: the client's address has spent Live's budget of reads, which is
Przykład
curl 'https://api.roundr.com/v1/public/tournaments/{tournamentId}/registration'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27"
    },
    "open": true,
    "opens_at": "2026-09-27T10:30:00Z",
    "closes_at": "2026-09-27T10:30:00Z",
    "withdrawals_close_at": "2026-09-27T10:30:00Z",
    "events": [
      {
        "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "kind": "single",
        "age_rule": null,
        "class_rule": null,
        "discipline": "singles"
      }
    ]
  }
}

The account's registrations and the invitations it was sent

GET/v1/me/registrationsWymaga uwierzytelnienia

Every registration naming the signed-in person, as the one who registered or as the partner named, newest first; you marks their own player, and an invitation is their player not yet confirmed. An invitation withdrawn or declined before it was confirmed is not listed to the invited account. On a tenant host, that organization's alone; on the shared API host, every active organization's, as GET /v1/me/matches reads.

Parametry

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Odpowiedzi

  • 200The registrations, possibly none.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404A junior_id that is not a junior of the caller's.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/me/registrations' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "registrations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "organization_name": "string",
          "venue_time_zone": "string",
          "starts_on": "2026-09-27",
          "ends_on": "2026-09-27"
        },
        "event": {
          "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "code": "string",
          "age_rule": null,
          "class_rule": null
        },
        "entry_window": {
          "opens_at": "2026-09-27T10:30:00Z",
          "closes_at": "2026-09-27T10:30:00Z",
          "withdrawals_close_at": "2026-09-27T10:30:00Z"
        },
        "kind": "single",
        "status": "pending",
        "display_name": "string",
        "complete": true,
        "players": [
          {
            "position": 1,
            "full_name": "string",
            "given_name": "string",
            "family_name": "string",
            "family_name_first": true,
            "confirmed": true,
            "you": true
          }
        ],
        "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "registered_at": "2026-09-27T10:30:00Z",
        "decided_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z",
        "revision": 1
      }
    ]
  }
}

Enter an event of a tournament

POST/v1/me/registrationsWymaga uwierzytelnienia

On the tournament's own host or the platform's site, where its Live page is, for a signed-in person who needs no membership of the organization. A single enters alone; a pair names the partner by the address their Roundr account holds and by partner_name, the name the registrant gives them. The address is looked up only once the tournament takes entries in the event and the event is a pair's, and nothing of the account behind it is read: the partner is invited under partner_name and confirms from their own account, where their own name takes over. Whether the partner already holds a place in the event is told to the partner at confirmation, never here. An account holds one place in an event while its registration is pending or accepted. A tournament neither on Live nor taking entries is not found; one on Live that takes none is refused as closed, and one on Live that has been closed as tournament_closed. A lookup spends two budgets, 20 an hour per account and 100 an hour per client address, and is refused with 429 over either or while either cannot be checked.

Parametry

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Treść żądania

  • tournament_idstring (uuid)wymagany

  • draw_idstring (uuid)wymagany

  • full_namestring

    The name the registrant enters under, the account's by default. Required without family_name.

  • given_namestring | null

  • family_namestring | null

  • family_name_firstboolean

  • partner_emailstring | null

  • partner_namestring | null

    Required with partner_email, unless partner_family_name is given; how the partner is shown until they confirm.

  • partner_given_namestring | null

  • partner_family_namestring | null

  • partner_family_name_firstboolean

  • partner_junior_idstring | null (uuid)

    Instead of partner_email: one of the caller's juniors, confirmed at once, since the caller answers for both (DEV-36). partner_name is optional beside it; the junior's record names them by default.

  • partner_selfboolean

    Instead of partner_email, with junior_id, the caller themselves as the junior's partner, confirmed at once.

Odpowiedzi

  • 201The registration, pending.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a tournament this host may show: another organization's on a tenant
  • 409tournament_closed: the tournament has been closed (DEV-25).
  • 422validation_failed: a field of the wrong shape, partner_name missing beside
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/registrations' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "full_name": "string",
  "given_name": "string",
  "family_name": "string",
  "family_name_first": true,
  "partner_email": "string",
  "partner_name": "string",
  "partner_given_name": "string",
  "partner_family_name": "string",
  "partner_family_name_first": true,
  "partner_junior_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "partner_self": true
}'
201
{
  "ok": true,
  "data": {
    "registration": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      },
      "event": {
        "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "age_rule": null,
        "class_rule": null
      },
      "entry_window": {
        "opens_at": "2026-09-27T10:30:00Z",
        "closes_at": "2026-09-27T10:30:00Z",
        "withdrawals_close_at": "2026-09-27T10:30:00Z"
      },
      "kind": "single",
      "status": "pending",
      "display_name": "string",
      "complete": true,
      "players": [
        {
          "position": 1,
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "confirmed": true,
          "you": true
        }
      ],
      "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "registered_at": "2026-09-27T10:30:00Z",
      "decided_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z",
      "revision": 1
    }
  }
}

Withdraw an entry, or decline an invitation

DELETE/v1/me/registrations/{registrationId}Wymaga uwierzytelnienia

Either player withdraws a pending registration, freeing both places, or an accepted one while its draw is a draft not yet placed, which takes the entry out of the draw and keeps the participant and the decision (DEV-27). Both only until the tournament's withdrawal deadline; after it the staff withdraw an entry. The partner it named declines the invitation the same way, deadline or not, since they hold no place. A registration withdrawn already is answered as it stands; a declined one is refused.

Parametry

  • registrationIdścieżka · string (uuid)wymagany

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Odpowiedzi

  • 200The registration as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a registration naming the account, or on a tenant host not that organization's.
  • 409tournament_closed: the tournament of the registration has been closed (DEV-25).
  • 422validation_failed with details.problem not_pending (the staff declined
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/me/registrations/{registrationId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "registration": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      },
      "event": {
        "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "age_rule": null,
        "class_rule": null
      },
      "entry_window": {
        "opens_at": "2026-09-27T10:30:00Z",
        "closes_at": "2026-09-27T10:30:00Z",
        "withdrawals_close_at": "2026-09-27T10:30:00Z"
      },
      "kind": "single",
      "status": "pending",
      "display_name": "string",
      "complete": true,
      "players": [
        {
          "position": 1,
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "confirmed": true,
          "you": true
        }
      ],
      "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "registered_at": "2026-09-27T10:30:00Z",
      "decided_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z",
      "revision": 1
    }
  }
}

Confirm a place as the partner a registration named

POST/v1/me/registrations/{registrationId}/confirmationWymaga uwierzytelnienia

The invited partner confirms under the name given, or their own account's, which replaces the name the registrant gave them, and the pair is complete for the staff to accept. The name is full_name or its parts, as at registration; a whole name that is exactly the one the registrant gave keeps the parts they entered. Refused as already_entered when the account holds a place in the event already: only the partner learns that.

With junior_id, a guardian confirms for their junior (DEV-36): an invitation the junior holds, or one addressed to the guardian's own account, which is how another family names a junior. The place becomes the junior's, their record is checked against the event's age and class rules, and their record's name is the default.

Parametry

  • registrationIdścieżka · string (uuid)wymagany

  • junior_idzapytanie · string (uuid)

    A junior the caller is a guardian of, to read or act for them rather than for the caller (DEV-36). The caller is recorded as who did it; the junior's is what it is about. A junior that is not the caller's is 404.

Treść żądania

  • full_namestring | null

  • given_namestring | null

  • family_namestring | null

  • family_name_firstboolean

Odpowiedzi

  • 200The registration as it now stands.
  • 401No session or token.
  • 403A court device, a display or a machine key, which has no account.
  • 404Not a registration naming the account, or on a tenant host not that organization's.
  • 409tournament_closed: the tournament of the registration has been closed (DEV-25).
  • 422validation_failed: full_name of the wrong shape, or details.problem
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/me/registrations/{registrationId}/confirmation' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "full_name": "string",
  "given_name": "string",
  "family_name": "string",
  "family_name_first": true
}'
200
{
  "ok": true,
  "data": {
    "registration": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "tournament": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "organization_name": "string",
        "venue_time_zone": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27"
      },
      "event": {
        "draw_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "age_rule": null,
        "class_rule": null
      },
      "entry_window": {
        "opens_at": "2026-09-27T10:30:00Z",
        "closes_at": "2026-09-27T10:30:00Z",
        "withdrawals_close_at": "2026-09-27T10:30:00Z"
      },
      "kind": "single",
      "status": "pending",
      "display_name": "string",
      "complete": true,
      "players": [
        {
          "position": 1,
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "confirmed": true,
          "you": true
        }
      ],
      "participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "registered_at": "2026-09-27T10:30:00Z",
      "decided_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z",
      "revision": 1
    }
  }
}

Control

Tournament administration: what Control does to a tournament outside a match's score. An administrator of the organization creates tournaments; an administrator or that tournament's director does everything inside one. The participants are open to any principal that may read the tournament but a display, since a court device may be given any match; a display reads only the sides of the matches its projection shows, from its snapshot. Draws are under Draws. A tournament outside the principal's scope is not found, never forbidden, so nothing here maps one tenant's tournaments for another.

A machine key (key_) is an organization's own system reading its tournaments and loading their participants and matches; the draws and standings under Draws are for staff alone. Issued tournaments:read, it lists the tournaments, reads participants, snapshots, the change feed, the stream, matches and their events, and exports results; issued tournaments:import, it imports. It administers nothing else and scores nothing, whatever it holds, and one issued for a tournament sees that tournament alone. It reads no draw and no display, so the feed announces one to it only as a cursor checkpoint.

The venue time zones a tournament accepts

GET/v1/time-zonesWymaga uwierzytelnienia

Exactly the IANA zones POST /v1/tournaments accepts, as the server's time zone database names them, UTC included. A browser's own list keeps names the database has retired (Asia/Calcutta, Europe/Kiev), which the server refuses, so a form that offers a zone asks here. Staff only.

Odpowiedzi

  • 200The zones, in the database's order.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/time-zones' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "time_zones": [
      "string"
    ]
  }
}

The organization's tournaments

GET/v1/tournamentsWymaga uwierzytelnienia

Every tournament of the caller's organization, newest first: by start date, or by creation for one without, then by name. Staff only. A signed-in member sees the whole list whatever roles they hold, because a director of one tournament still has to find it; the roles decide what may be done inside one. A machine key issued tournaments:read lists them too, or only its own when it was issued for one tournament. A court or display credential is refused: it is scoped to one tournament, which it reads through the snapshot.

Odpowiedzi

  • 200The tournaments, possibly none.
  • 401No credential.
  • 403insufficient_scope: not a staff credential, nor a machine key issued tournaments:read.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tournaments": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "venue_time_zone": "string",
        "venue_name": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27",
        "status": "draft",
        "revision": 0,
        "referee_briefing": {
          "call_language": "en",
          "time_clock": true,
          "warm_up_minutes": 1,
          "referee_on_site": true,
          "rally_start_tracking": true,
          "rally_start_required": true,
          "auto_confirm_result": true,
          "overrule_mark": true,
          "result_extras": true,
          "theme": "system",
          "interface_language": "string",
          "announcements": "all",
          "speak_calls": true,
          "input_delay": "off",
          "touch_mode": "native",
          "point_vibration": true,
          "point_tone": true,
          "call_guard": true,
          "keyboard_shortcuts": true,
          "court_diagram": true,
          "scoresheet": true,
          "scoresheet_expand": true,
          "court_chooses_match": true
        },
        "live_published": true,
        "show_nationalities": true,
        "public_page_qr": true,
        "name_style": {},
        "schedule_assumptions": {
          "match_minutes": 1,
          "rest_minutes": 0
        }
      }
    ]
  }
}

Create a tournament

POST/v1/tournamentsWymaga uwierzytelnienia

For an administrator of the organization only: a tournament director's authority is a grant on a tournament that already exists, so nobody else can hold it here. The new tournament is a draft at revision 1 and is announced on its own feed as tournament_created. venue_time_zone is the IANA zone every venue-local date and time of the tournament is read in, which is why it is required from the start, and ends_on may not fall before starts_on.

A draft is prepared in full, entries, draws, schedule, registration and Live included, and holds none of the organization's places (DEV-19), so creating one is never refused for the plan. Its match day begins with its first court or display code, its first court setup code or a scoring session taken from Control, which start it (active, announced as tournament_started) and may be refused as plan_limit_reached (DEV-47). A started tournament holds its place until it is closed, whatever its dates (DEV-706).

Treść żądania

  • namestringwymagany

  • venue_time_zonestringwymagany

    An IANA time zone, such as Europe/Berlin.

  • starts_onstring | null (date)

  • ends_onstring | null (date)

    Not before starts_on.

Odpowiedzi

  • 201The tournament.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 422validation_failed, with details.validation_errors keyed by field: a missing
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "venue_time_zone": "string",
  "starts_on": "2026-09-27",
  "ends_on": "2026-09-27"
}'
201
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Change how every court tablet of a tournament runs its matches

PATCH/v1/tournaments/{tournamentId}/referee-briefingWymaga uwierzytelnienia

The Referee's briefing (ITTO Section 3.4): what the Referee decides for every umpire of the tournament before play, applied by each court tablet to the matches it scores, and how the tablets look and answer a finger, since a court tablet has no settings of its own (DEV-33). The Laws of a match stay in its pinned ruleset (DEV-9); nothing here changes the meaning of a command already accepted, so it is not versioned the way a ruleset is.

A field left out, or null, keeps its value, so a form and an integration that sets one switch both send only what they mean to change. A change moves the tournament's revision once and is announced on the tournament aggregate as referee_briefing_changed, which every court device of the tournament receives; a briefing equal to the stored one changes nothing and announces nothing.

It is the Referee's decision, so a referee of the tournament may set it, as may a director of the tournament and an administrator of the organization. A court or display credential reads it on the snapshot and never sets it.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • call_languagestring

    The published vocabulary the umpire's calls are quoted from, which is not the tablet's interface language: en is the BWF's (Vocabulary, Section 4.1.5), de-DE the DBV's and de-AT the ÖBV's. A vocabulary may be added; a client meeting one it does not know uses English.

    ende-DEde-AT

  • time_clockboolean

  • warm_up_minutesinteger

  • referee_on_siteboolean

  • rally_start_trackingboolean

  • rally_start_requiredboolean

  • auto_confirm_resultboolean

  • overrule_markboolean

  • result_extrasboolean

  • themestring

    The palette court tablets paint in; system follows each tablet's own light or dark mode.

    systemlightdark

  • interface_languagestring

    The language of the tablets' interface, which is not the call vocabulary: system for each tablet's own, or a language tag as the client's catalogs are named (de, pt-BR, zh-Hans). The server checks only the shape; a tablet given a language it has no catalog for runs in its own.

  • announcementsstring

    How much of a pause's announcement a tablet shows unasked. The call that ends the pause is always shown; except-start keeps only the introduction of the players.

    allexcept-startnone

  • speak_callsboolean

  • input_delaystring

    How long the rally keys ignore a second tap after a point, 0, 400 or 800 ms.

    offstandardlong

  • touch_modestring

    Whether a rally key scores when the finger lifts (native) or when it lands (fast).

    nativefast

  • point_vibrationboolean

  • point_toneboolean

  • call_guardboolean

  • keyboard_shortcutsboolean

  • court_diagramboolean

  • scoresheetboolean

  • scoresheet_expandboolean

  • court_chooses_matchboolean

Odpowiedzi

  • 200The tournament with the briefing as it now stands.
  • 401No credential.
  • 403insufficient_scope: not a referee or director of the tournament, nor an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed, with details.validation_errors keyed by field: a call
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/referee-briefing' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "call_language": "en",
  "time_clock": true,
  "warm_up_minutes": 1,
  "referee_on_site": true,
  "rally_start_tracking": true,
  "rally_start_required": true,
  "auto_confirm_result": true,
  "overrule_mark": true,
  "result_extras": true,
  "theme": "system",
  "interface_language": "string",
  "announcements": "all",
  "speak_calls": true,
  "input_delay": "off",
  "touch_mode": "native",
  "point_vibration": true,
  "point_tone": true,
  "call_guard": true,
  "keyboard_shortcuts": true,
  "court_diagram": true,
  "scoresheet": true,
  "scoresheet_expand": true,
  "court_chooses_match": true
}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Publish a tournament on Live, or take it off

PATCH/v1/tournaments/{tournamentId}/live-publicationWymaga uwierzytelnienia

Live is the anonymous public scoreboard under /v1/public/*. A tournament is private until a director of the tournament or an administrator of the organization publishes it here; until then Live answers it exactly as it answers an id that does not exist. Taking it off hides it again from the next read.

show_nationalities, when sent, says whether Live and the hall displays show the players' nationalities, for an event such as a junior one where the public needs no more than a name and a club; left out, it stays as it was.

name_style, when sent, says how Live and the hall displays write a side's name (DEV-28): as_entered, every tournament's until a director chooses, shows its display_name, and bwf its players as the BWF prints them, given name then the family name in capitals ("Alex LANIER"), or the family name first where it is written first ("LIANG Wei Keng"), a pair's two joined by " / ". A side with a player whose name nobody split keeps its display_name. Only the name a public screen already showed changes: Live sends no players' names. Left out, it stays as it was.

public_page_qr, when sent, says whether the printed order of play and the hall displays offer the tournament's public page as a QR code, for the people in the hall; off until a director turns it on, and shown by nothing while the page is not published. Left out, it stays as it was.

A change of any of them moves the tournament's revision once and is announced on the tournament aggregate as live_publication_changed; asking for what is already so changes nothing and announces nothing. A referee of the tournament, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • publishedbooleanwymagany

  • show_nationalitiesboolean

    Whether Live and the hall displays show nationalities; left as it was when absent.

  • name_stylestring

    How Live and the hall displays write a side's name (DEV-28): as entered, or the BWF's way, "Alex LANIER" and "LIANG Wei Keng", where every player of the side has a family name.

    as_enteredbwf

  • public_page_qrboolean

    Whether the order of play and the hall displays offer the public page as a QR code; left as it was when absent.

Odpowiedzi

  • 200The tournament with its publication as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed: published is missing or not a JSON boolean,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/live-publication' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "published": true,
  "show_nationalities": true,
  "name_style": "as_entered",
  "public_page_qr": true
}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Close a tournament, or reopen it

PATCH/v1/tournaments/{tournamentId}/closureWymaga uwierzytelnienia

Closing is how a tournament ends (DEV-25). Its status becomes completed, which frees the place it held in the organization's plan, which nothing else does (DEV-706), and it becomes read-only: every write to it (courts, displays, participants, import, matches, schedule, briefing, venue, draws and lots, registration, codes, match commands and taking a scoring session) is refused as tournament_closed until it is reopened. Its Live publication and its staff stay changeable, since neither is the tournament's record. Every court tablet and hall display it admitted is signed out: their credentials are revoked, the codes nobody has used are spent and its setup codes revoked, and a court device's scoring session is released. Reads, the results export and printing are unaffected.

Closing is refused as matches_unfinished while a match is being played or holds a result nobody has confirmed, with details.count. Reopening makes it active again and takes a place in the plan when its dates still hold one, so it is refused as plan_limit_reached when the plan has no room; the devices closing signed out stay signed out.

Either change moves the tournament's revision once and is announced on the tournament aggregate as tournament_closed or tournament_reopened; asking for what is already so changes nothing and announces nothing. A director of the tournament or an administrator of the organization decides it; a referee, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • closedbooleanwymagany

    True to close the tournament, false to reopen it.

Odpowiedzi

  • 200The tournament with its status as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409matches_unfinished: closing while a match is being played or holds a result
  • 422validation_failed: closed is missing or not a JSON boolean. Nothing is
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/closure' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "closed": true
}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Name where a tournament is played, or clear it

PATCH/v1/tournaments/{tournamentId}/venueWymaga uwierzytelnienia

One line of free text, such as a hall and a town, that Control, the hall display and Live show beside the tournament's name. Set by a director of the tournament or an administrator of the organization. null, or a blank name, clears it.

A change moves the tournament's revision once and is announced on the tournament aggregate as venue_changed; naming the venue it already has changes nothing and announces nothing. A referee of the tournament, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • venue_namestring | nullwymagany

    Trimmed; blank or null for none.

Odpowiedzi

  • 200The tournament with its venue as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed under venue_name: the field is missing, not a string or
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/venue' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "venue_name": "string"
}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Correct a tournament's name and dates

PUT/v1/tournaments/{tournamentId}/detailsWymaga uwierzytelnienia

The name and the first and last day, as POST /v1/tournaments took them, all three in every body: a date is null for none, and a body that leaves one out is refused rather than read as a clear. Set by a director of the tournament or an administrator of the organization. The venue's time zone is not among them: every time entered at the venue's clock is stored as the instant it named, so a corrected zone would misname each one.

The dates decide nothing about the organization's plan: a running tournament holds its place until it is closed, and a draft or a closed one holds none, whatever their dates, so no date is refused for the plan. The first day's year is the one an age category counts from, for entries made after the change.

A change moves the tournament's revision once and is announced on the tournament aggregate as details_changed; asking for what is already so changes nothing and announces nothing. A closed tournament refuses it as tournament_closed. A referee of the tournament, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

    Trimmed.

  • starts_onstring | null (date)wymagany

  • ends_onstring | null (date)wymagany

    Not before starts_on.

Odpowiedzi

  • 200The tournament with its name and dates as they now stand.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409tournament_closed: the tournament is closed. Nothing is changed.
  • 422validation_failed under name, starts_on or ends_on: a field is missing, a
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/tournaments/{tournamentId}/details' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "starts_on": "2026-09-27",
  "ends_on": "2026-09-27"
}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Make a new tournament from a tournament's setup

POST/v1/tournaments/{tournamentId}/copyWymaga uwierzytelnienia

A new tournament with the name and dates given and the setup of this one (DEV-42), for running the same event again. The source may be open or closed and of any date; nothing is written to it.

Copied: the Referee's briefing, the venue, the schedule assumptions, and whether Live and the hall displays show nationalities, how they write names and whether they offer the public page as a QR code; the courts by name and order, each open; the hall displays with the courts each shows; every draw as an empty draft of the same definition (format, ruleset, options, entry, age and class rules); and the registration settings, closed, offering the copies of the events the source offered, with the opening, closing and withdrawal times moved by the days between the two first days at the venue's clock, or cleared when either tournament has no first day. Not copied: participants, entries, placements, lots, matches, results, schedules, registrations, the event history, credentials and codes, scoring sessions, staff roles, and Live publication, so the copy is off Live. A consolation draw is made again by its main draw's publication, and a knockout fed by a round robin's groups once those are published, which draws_left_out names; a display's group standings go with them.

For an administrator of the organization only, as creating a tournament is: a director's authority is a grant on the source and holds nothing on a new tournament. The copy is active at revision 1 and announces each row it creates on its own feed, as creating them one by one would. Counted against the organization's plan as a new tournament is, and each court and display as though created one by one, so a source set up under a larger plan is refused rather than copied past the present one. One transaction: a refusal writes nothing.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

    Trimmed.

  • venue_time_zonestring | null

    An IANA time zone, such as Europe/Berlin; absent or null keeps the source's.

  • starts_onstring | null (date)

  • ends_onstring | null (date)

    Not before starts_on.

Odpowiedzi

  • 201The new tournament, and what of the setup came with it.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409plan_limit_reached: the organization's plan has no room for another, and nothing
  • 422validation_failed, with details.validation_errors keyed by field: a missing
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/copy' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "venue_time_zone": "string",
  "starts_on": "2026-09-27",
  "ends_on": "2026-09-27"
}'
201
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    },
    "copied": {
      "courts": 0,
      "displays": 0,
      "draws": 0
    },
    "draws_left_out": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "code": "string",
        "reason": "string"
      }
    ]
  }
}

Set the match length and rest Control's schedule check works from

PATCH/v1/tournaments/{tournamentId}/schedule-assumptionsWymaga uwierzytelnienia

How long a match is assumed to take and how long a player rests between two, in whole minutes: what Control estimates the play left from and warns of a player due twice at once or short of rest by. Assumptions, not rules: nothing is refused for them. Kept with the tournament so every desk working it warns from the same numbers, and read back as Tournament.schedule_assumptions. Set by a director of the tournament or an administrator of the organization; a field left out keeps its value, applied to the row as it stands under its lock.

A change moves the tournament's revision once and is announced on the tournament aggregate as schedule_assumptions_changed; asking for what is already so changes nothing and announces nothing. A referee of the tournament, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • match_minutesinteger

  • rest_minutesinteger

Odpowiedzi

  • 200The tournament with its schedule assumptions as they now stand.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed: neither field is sent, or one is not a whole number in its
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/schedule-assumptions' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "match_minutes": 1,
  "rest_minutes": 0
}'
200
{
  "ok": true,
  "data": {
    "tournament": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "venue_time_zone": "string",
      "venue_name": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "status": "draft",
      "revision": 0,
      "referee_briefing": {
        "call_language": "en",
        "time_clock": true,
        "warm_up_minutes": 1,
        "referee_on_site": true,
        "rally_start_tracking": true,
        "rally_start_required": true,
        "auto_confirm_result": true,
        "overrule_mark": true,
        "result_extras": true,
        "theme": "system",
        "interface_language": "string",
        "announcements": "all",
        "speak_calls": true,
        "input_delay": "off",
        "touch_mode": "native",
        "point_vibration": true,
        "point_tone": true,
        "call_guard": true,
        "keyboard_shortcuts": true,
        "court_diagram": true,
        "scoresheet": true,
        "scoresheet_expand": true,
        "court_chooses_match": true
      },
      "live_published": true,
      "show_nationalities": true,
      "public_page_qr": true,
      "name_style": {},
      "schedule_assumptions": {
        "match_minutes": 1,
        "rest_minutes": 0
      }
    }
  }
}

Add a court to a tournament

POST/v1/tournaments/{tournamentId}/courtsWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization. A court's name is unique within its tournament, because the import places a match by court name and a display labels the court by it; a second Court 1 is refused as a validation error on name, so a form shows it on the field like any other bad name. sort_order is where the court sits in the snapshot and on a display, with ties broken by name. The court is open at revision 1 and is announced as court_created. Counted against the organization's plan, in this tournament.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

  • sort_orderinteger

Odpowiedzi

  • 201The court.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409plan_limit_reached: the organization's plan has no room for another, and nothing
  • 422validation_failed: a missing or over-long name, a sort_order that is not a
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "sort_order": 0
}'
201
{
  "ok": true,
  "data": {
    "court": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "sort_order": 0,
      "status": "open",
      "revision": 0
    }
  }
}

Correct a court's name

PATCH/v1/tournaments/{tournamentId}/courts/{courtId}Wymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization, as creating a court is. The name is the one a court's tablet, the hall displays and Live show, and the one the import places a match by, so it is held to the rules a new court's is: up to 100 characters, trimmed, and none another court of the tournament carries, compared without regard to case; such a name is refused as a validation error on name.

A change moves the court's revision once and is announced on the court aggregate as court_renamed, so the court's tablet, every display showing the court and Live read it again. The name the court already has, to the letter, changes nothing and announces nothing; a change of its case alone is a rename. A referee of the tournament, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • courtIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

Odpowiedzi

  • 200The court as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404not_found: no such tournament in the principal's scope, or no such court in
  • 409tournament_closed: the tournament is closed (DEV-25). Nothing is changed.
  • 422validation_failed under name: the field is missing, not a string, blank or
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts/{courtId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
200
{
  "ok": true,
  "data": {
    "court": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "sort_order": 0,
      "status": "open",
      "revision": 0
    }
  }
}

Remove a court nothing uses

DELETE/v1/tournaments/{tournamentId}/courts/{courtId}Wymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization, as creating a court is (DEV-628): a court added by mistake, which would otherwise stay on the tablets' join screen, every display of all courts, the order of play and Live, and hold a place of the plan's courts per tournament.

A court anything uses is refused with 409 court_in_use, each use in details.uses: matches (a match or a schedule entry is on it, or a match was scored on it), devices (a tablet was paired to it, revoked since or not), displays (a display was chosen to show it) or officials (a rotation of officials serves it, DEV-113). Codes issued for the court that no tablet redeemed go with it. The removal is announced on the court aggregate as court_removed, at the revision after the court's last, so a display of every court and Live read the courts again. A referee of the tournament, a court or display credential and a machine key are refused.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • courtIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The court is gone.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404not_found: no such tournament in the principal's scope, or no such court in
  • 409court_in_use, with details.uses, a list of matches, devices,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts/{courtId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  }
}

List a tournament's hall displays

GET/v1/tournaments/{tournamentId}/displaysWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization, who issue each display's join code and choose what it shows. Ordered by name, each with its projection. A display reads the tournament snapshot, not this list.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The displays.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/displays' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "displays": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "revision": 0,
        "court_scope": "all",
        "court_ids": [
          "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
        ],
        "show_upcoming": true,
        "upcoming_count": 1,
        "standings_draw_ids": [
          "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
        ],
        "show_header": true,
        "show_seeds": true,
        "layout": "cards"
      }
    ]
  }
}

Add a hall display to a tournament

POST/v1/tournaments/{tournamentId}/displaysWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization. A display's name is unique within its tournament, so staff can tell two screens apart when issuing codes; a second Hall is refused as a validation error on name. It shows every court of the tournament and the next four matches on no court until its projection is changed, and is announced as display_created. Counted against the organization's plan, in this tournament.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

Odpowiedzi

  • 201The display.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409plan_limit_reached: the organization's plan has no room for another, and nothing
  • 422validation_failed: a missing or over-long name, or one the tournament's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/displays' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
201
{
  "ok": true,
  "data": {
    "display": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0,
      "court_scope": "all",
      "court_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "show_upcoming": true,
      "upcoming_count": 1,
      "standings_draw_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "show_header": true,
      "show_seeds": true,
      "layout": "cards"
    }
  }
}

Choose what a hall display shows

PATCH/v1/tournaments/{tournamentId}/displays/{displayId}Wymaga uwierzytelnienia

A display's projection: every court of the tournament or only the courts chosen for it, whether and how many of the matches on no court it lists under them, and the group standings of which published round-robin draws it shows. A court added later is not added to a display showing chosen courts. A display chosen no draw shows no standings, which is every display made before draws could be chosen.

The projection bounds what the display's session may read, not only how its board is laid out: a display is an unattended screen in a public hall. So it is set by a director of the tournament or an administrator of the organization, who issue the display's codes, and not by a referee.

A field left out, or null, keeps its value; court_ids and standings_draw_ids are each the whole choice and replace the stored one. The chosen courts are kept while court_scope is all, so switching back finds the last choice. The change is applied to the projection under the display's row lock, so two directors changing different fields both land. A change moves the display's revision once and is announced on the display aggregate as display_projection_changed; a projection equal to the stored one changes nothing and announces nothing.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • displayIdścieżka · string (uuid)wymagany

Treść żądania

  • court_scopestring

    all shows every court of the tournament, one added later included; selected shows only the courts chosen for the display.

    allselected

  • court_idsstring (uuid)[]

    Courts of this tournament, in any order; a court named twice is shown once.

  • show_upcomingboolean

  • upcoming_countinteger

  • standings_draw_idsstring (uuid)[]

    Published round-robin draws of this tournament, in any order; a draw named twice is shown once. The display then reads their standings and their matches on whatever court they are played.

  • show_headerboolean

    Whether the board is headed with its title line: the tournament and its venue, and on a court's scoreboard the court's name before them.

  • show_seedsboolean

    Whether a side's seed is written beside its name.

  • layoutstring

    How a board of several courts is laid out (DEV-654): cards, a card a court in a grid, or list, a band of three lines a court with every game's score in a row and no title line, as a big tournament's screen lists its courts. A board of one court is that court's scoreboard either way. cards unless chosen; a server from before the choice sends none, and the board draws cards.

    cardslist

Odpowiedzi

  • 200The display with its projection as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404not_found: no such tournament in the principal's scope, or no such display in
  • 422validation_failed, with details.validation_errors keyed by field: a
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/displays/{displayId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "court_scope": "all",
  "court_ids": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "show_upcoming": true,
  "upcoming_count": 1,
  "standings_draw_ids": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "show_header": true,
  "show_seeds": true,
  "layout": "cards"
}'
200
{
  "ok": true,
  "data": {
    "display": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0,
      "court_scope": "all",
      "court_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "show_upcoming": true,
      "upcoming_count": 1,
      "standings_draw_ids": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ],
      "show_header": true,
      "show_seeds": true,
      "layout": "cards"
    }
  }
}

List a tournament's directors, referees and umpires

GET/v1/tournaments/{tournamentId}/staffWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization. One entry per role held, so a person holding several appears once for each; directors come first, then referees, then umpires, each role ordered by name. A tournament_umpire is a person who watches the courts' panels, read only, and holds no match authority; the court tablet's umpire is a credential's role and is never granted here. An organization administrator holds no match authority, and is listed here only through a tournament role of their own.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The tournament's staff.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/staff' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "staff": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "email": "string",
        "role": "tournament_director"
      }
    ]
  }
}

Give a person a tournament role

POST/v1/tournaments/{tournamentId}/staffWymaga uwierzytelnienia

An administrator of the organization grants any of the three roles; a director of the tournament grants referee and tournament_umpire. A person may hold several, each granted on its own. The person is named by the verified address their Roundr account registered with, and becomes a member of the organization if they were not one. A person who never signed in has no account, and a suspended member is not reactivated; both are validation errors on email. A repeated grant changes nothing and answers 200 with granted: false.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • emailstringwymagany

  • rolestringwymagany

    tournament_directorrefereetournament_umpire

Odpowiedzi

  • 200The role as granted; granted is false when the person already held it.
  • 201The role as granted; granted is false when the person already held it.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed: a missing address or a role other than the two, under
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/staff' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "role": "tournament_director"
}'
200
{
  "ok": true,
  "data": {
    "member": {
      "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "display_name": "string",
      "email": "string",
      "role": "tournament_director"
    },
    "granted": true
  }
}

Take a tournament role away

DELETE/v1/tournaments/{tournamentId}/staff/{userId}/{role}Wymaga uwierzytelnienia

The same authority as a grant: an administrator removes any role, a director removes referees and umpires. Removing a role the person does not hold answers 200 with revoked: false. The person's sessions pick the change up on their next request, because grants are read on every request.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • userIdścieżka · string (uuid)wymagany

  • roleścieżka · stringwymagany

Odpowiedzi

  • 200Whether a grant was removed.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404The tournament is outside the principal's scope, or the user or role is not one this path names.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/tournaments/{tournamentId}/staff/{userId}/{role}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "revoked": true
  }
}

List a tournament's staff invitations still waiting

GET/v1/tournaments/{tournamentId}/staff-invitationsWymaga uwierzytelnienia

For a director of the tournament or an administrator of the organization (DEV-43). Only invitations nobody has redeemed, withdrawn or let expire, newest first. An invitation is listed by what it grants and whom the staff said it was for; its code was shown once, when it was created, and is never listed.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The waiting invitations.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/staff-invitations' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "invitations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "roles": [
          "tournament_director"
        ],
        "label": "string",
        "created_by_name": "string",
        "created_at": "2026-09-27T10:30:00Z",
        "expires_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Invite someone to a tournament's staff with a one-time link

POST/v1/tournaments/{tournamentId}/staff-invitationsWymaga uwierzytelnienia

For a person who may have no Roundr account yet (DEV-43). The answer carries a link, invitation_url, which the staff send however they like; whoever opens it, signs up or signs in, and accepts it at /v1/staff-invitations/redeem holds roles in this tournament. Nothing is keyed by an address: accounts are never linked by email (DEV-11), and the link is what decides. It works once and for 14 days, and the code in its fragment is shown here and never again; only its keyed digest is kept. An administrator invites to any of the three roles, a director to referee and tournament_umpire. A closed tournament invites nobody (tournament_closed).

With email, Roundr also sends the link to that address, now and once, as a convenience: the address is not stored and decides nothing. email_sent says whether it went; it is false when no mail service is configured, when the sender has had twenty sent within the hour, or when the service refused it, and the link is in the answer either way. It is null when no address was given.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • rolesstring[]wymagany

  • labelstring | null

    Whom it is for, in the staff's own words, for the list of waiting invitations.

  • emailstring | null

    An address Roundr sends the link to. Not stored.

Odpowiedzi

  • 201The invitation, with its link, the one time it exists.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409tournament_closed: the tournament is closed; reopen it to invite anyone.
  • 422validation_failed: no role, or one other than the three, under
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/staff-invitations' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "roles": [
    "tournament_director"
  ],
  "label": "string",
  "email": "string"
}'
201
{
  "ok": true,
  "data": {
    "invitation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "roles": [
        "tournament_director"
      ],
      "label": "string",
      "created_by_name": "string",
      "created_at": "2026-09-27T10:30:00Z",
      "expires_at": "2026-09-27T10:30:00Z"
    },
    "code": "string",
    "invitation_url": "https://example.com",
    "email_sent": true
  }
}

Withdraw a waiting staff invitation

DELETE/v1/tournaments/{tournamentId}/staff-invitations/{invitationId}Wymaga uwierzytelnienia

Its link admits nobody from now. Whoever may invite to every role it carries may withdraw it, so a director withdraws no invitation for a director. A withdrawn invitation is refused as redemption_code_expired, as an expired one is. Allowed on a closed tournament: it gives nobody anything.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • invitationIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200Whether a waiting invitation was withdrawn.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404The tournament is outside the principal's scope, or no invitation of it is waiting under this id.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/tournaments/{tournamentId}/staff-invitations/{invitationId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "revoked": true
  }
}

The organization's administrators

GET/v1/organization/administratorsWymaga uwierzytelnienia

For an administrator of the organization (DEV-626): every administrator by name, a suspended one marked inactive.

Odpowiedzi

  • 200The administrators.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/administrators' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "administrators": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "email": "string",
        "active": true
      }
    ]
  }
}

Make another person an administrator of the organization

POST/v1/organization/administratorsWymaga uwierzytelnienia

For an administrator of the organization (DEV-626). The person is named by the address their Roundr account registered with, as a tournament role is granted; someone who never signed in has no account, and the address is refused. An address finds an account and links nothing. The person is told in their account, and by email where they asked for it, unless they admitted themselves. Admitting an administrator again changes nothing and answers 200.

Treść żądania

  • emailstringwymagany

Odpowiedzi

  • 200Already an administrator; granted is false.
  • 201Made an administrator; granted is true.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 422validation_failed under email: no address, or no Roundr account uses it.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/administrators' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string"
}'
200
{
  "ok": true,
  "data": {
    "administrators": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "email": "string",
        "active": true
      }
    ]
  }
}

Take an administrator's role away

DELETE/v1/organization/administrators/{userId}Wymaga uwierzytelnienia

For an administrator of the organization (DEV-626), themselves included, as long as another active administrator remains: the last one is refused with organization_needs_administrator, so the organization is never left without one. The person stays a member and keeps any tournament role.

Parametry

  • userIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The administrators that remain.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: not an administrator of this organization.
  • 409organization_needs_administrator: the last active administrator.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/organization/administrators/{userId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "administrators": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "display_name": "string",
        "email": "string",
        "active": true
      }
    ]
  }
}

The organization's hostnames

GET/v1/organization/domainsWymaga uwierzytelnienia

For an administrator of the organization. By name, with where each stands and which is primary. No verification token: claiming and proving a hostname is a platform operator's.

Odpowiedzi

  • 200The hostnames, possibly none.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization. The primary host
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/domains' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "domains": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "hostname": "string",
        "kind": "platform_subdomain",
        "status": "pending_verification",
        "sign_in_registered_at": "2026-09-27T10:30:00Z",
        "primary": true
      }
    ]
  }
}

Choose the hostname the organization's links name

POST/v1/organization/domains/{domainId}/primaryWymaga uwierzytelnienia

For an administrator of the organization. The active hostname whose sign-in is registered becomes primary: the join link and QR code of every court, display and setup code issued from then on, and the Live link Control shares, name it, from whichever host they are issued. The one before it is primary for nobody. Another organization's hostname is not found.

Parametry

  • domainIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The hostname, primary.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization. The primary host
  • 404not_found: not a hostname of this organization.
  • 422validation_failed under primary, and nothing changed. details.reason is
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/domains/{domainId}/primary' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "domain": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "hostname": "string",
      "kind": "platform_subdomain",
      "status": "pending_verification",
      "sign_in_registered_at": "2026-09-27T10:30:00Z",
      "primary": true
    }
  }
}

The organization's API keys

GET/v1/organization/integration-keysWymaga uwierzytelnienia

For an administrator of the organization. Newest first: every key still active, and every key revoked or expired in the last 30 days, so what was just ended is still seen. A key's secret is never shown again after it was issued, and its digest never leaves the server.

Odpowiedzi

  • 200The keys, possibly none.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization. A director, a
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/integration-keys' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "keys": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "label": "string",
        "scopes": [
          "tournaments:read"
        ],
        "tournament_id": null,
        "status": "active",
        "created_at": "2026-09-27T10:30:00Z",
        "expires_at": "2026-09-27T10:30:00Z",
        "revoked_at": null,
        "last_used_at": null
      }
    ]
  }
}

Issue an API key

POST/v1/organization/integration-keysWymaga uwierzytelnienia

For an administrator of the organization: a key_ credential for the organization's own system, presented as X-API-Key or a bearer token. scopes says what it may do, and nothing else is ever granted: tournaments:read reads the tournaments, their participants, feeds, matches and results, and tournaments:import loads participants and matches as the CSV import does. A key scores nothing and administers nothing else whatever it holds, and it never issues a key. With tournament_id it sees that tournament alone.

Every key expires, after expires_in_days (90 unless given, 366 at most). An organization holds at most 25 active keys, and at most what its plan allows inside that (DEV-19). The secret is in this response and nowhere else, which is sent Cache-Control: no-store: the server keeps only its digest, so a lost secret is revoked and replaced, never read back.

Treść żądania

  • labelstringwymagany

    What the key is for, as staff will recognize it in the list.

  • scopesIntegrationScope[]wymagany

  • tournament_idone of

    A tournament of the organization, or null for all of them.

    Pola
  • expires_in_daysinteger

Odpowiedzi

  • 201The key, with its one copy of the secret.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization. A director, a
  • 409plan_limit_reached: the organization's plan has no room for another, and nothing
  • 422validation_failed, and nothing was issued: a missing or over-long label, no
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/integration-keys' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "label": "string",
  "scopes": [
    "tournaments:read"
  ],
  "tournament_id": null,
  "expires_in_days": 1
}'
201
{
  "ok": true,
  "data": {
    "key": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "label": "string",
      "scopes": [
        "tournaments:read"
      ],
      "tournament_id": null,
      "status": "active",
      "created_at": "2026-09-27T10:30:00Z",
      "expires_at": "2026-09-27T10:30:00Z",
      "revoked_at": null,
      "last_used_at": null
    },
    "secret": "string"
  }
}

Revoke an API key

DELETE/v1/organization/integration-keys/{keyId}Wymaga uwierzytelnienia

For an administrator of the organization. The key is refused as credential_revoked from its next request. Revoking a key already revoked answers revoked: false. Another organization's key is not found.

Parametry

  • keyIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200Whether this request revoked the key.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization. A director, a
  • 404No such key in the organization, or the id is malformed.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/organization/integration-keys/{keyId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "revoked": true
  }
}

The organization's plan

GET/v1/organization/planWymaga uwierzytelnienia

For an administrator of the organization: the plan it is on, who set it, and how much of each allowance it uses (DEV-19), and billing, what this deployment lets the administrator do about it (DEV-41). Read only: a platform operator sets the plan, or Stripe's webhook does for a subscription; the administrator subscribes through startBillingCheckout and manages it through openBillingPortal. A director, a device and a key are refused.

Odpowiedzi

  • 200The plan.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/plan' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "plan": {
      "plan": "free",
      "source": "default",
      "changed_at": "2026-09-27T10:30:00Z",
      "limits": [
        {
          "limit": "active_tournaments",
          "allowance": 0,
          "used": 0
        }
      ]
    },
    "billing": {
      "available": true,
      "plans_on_sale": [
        "event"
      ],
      "customer": true,
      "subscription": null
    }
  }
}

Subscribe the organization to a paid plan

POST/v1/organization/billing/checkout-sessionWymaga uwierzytelnienia

For an administrator of the organization: open a Stripe-hosted Checkout Session to subscribe the organization to the event or club plan (DEV-40, DEV-41), and return its URL for the client to send the admin to. Stripe collects the card, the billing address and, for a business, its VAT number; the plan is written by the webhook when the payment confirms, not by the return from Checkout, which lands on /settings/plan of the host the request came to, with checkout=complete or checkout=cancelled. The organization is the one the administrator acts for. A director, a device and a key are refused. Exists only where a payment provider is configured; otherwise an operator sets the paid plan and this endpoint is absent.

Treść żądania

  • planstringwymagany

    The plan to subscribe to. Only event and club are sold.

    eventclub

  • localestring

    The admin's interface locale. Checkout, and the line on which the admin agrees to the terms and asks for the subscription to begin at once, are shown in German for a German locale and in English otherwise, the two languages the terms exist in. Absent is English.

Odpowiedzi

  • 200The Checkout Session was opened. Send the admin to checkout_url.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 409billing_refused, with details.reason: subscription_active (the
  • 422No plan, or a plan that is not on sale.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/billing/checkout-session' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "plan": "event",
  "locale": "string"
}'
200
{
  "ok": true,
  "data": {
    "checkout_url": "https://example.com"
  }
}

Manage the organization's subscription

POST/v1/organization/billing/portal-sessionWymaga uwierzytelnienia

For an administrator of the organization: open a session of Stripe's Customer Portal and return its URL (DEV-41). There the administrator cancels the subscription, switches between the plans, changes the card and reads the invoices; what they change reaches the plan through the webhook. The Portal sends them back to /settings/plan of the host the request came to. A director, a device and a key are refused. Exists only where a payment provider is configured.

Odpowiedzi

  • 200The Portal session was opened. Send the admin to portal_url.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 409billing_refused, with details.reason not_a_customer: the organization has never subscribed.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/billing/portal-session' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "portal_url": "https://example.com"
  }
}

The organization's rotations of officials

GET/v1/organization/official-rotationsWymaga uwierzytelnienia

Each rotation of umpires and service judges the organization keeps (DEV-113), with the number of its courts and officials and the tournaments its courts belong to. A rotation is the organization's, so its courts may be two tournaments' played in one hall at once. For an administrator and the directors and referees of its tournaments.

Odpowiedzi

  • 200The rotations, by name.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/official-rotations' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "rotations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "courts": 0,
        "officials": 0,
        "tournaments": [
          "string"
        ]
      }
    ]
  }
}

Start a rotation of officials

POST/v1/organization/official-rotationsWymaga uwierzytelnienia

A new rotation, with no courts and no officials yet. The name is unique among the organization's.

Treść żądania

  • namestringwymagany

Odpowiedzi

  • 201The new rotations board.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 422validation_failed on name: empty, too long, or another rotations.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/official-rotations' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
201
{
  "ok": true,
  "data": {
    "rotation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0
    },
    "courts": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string",
        "has_service_judge": true,
        "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "match": null
      }
    ],
    "umpires": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "service_judges": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "reserve": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "role": "umpire"
      }
    ],
    "officials": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "nationality": "string",
        "umpires": true,
        "judges_service": true,
        "account": true,
        "counts": {}
      }
    ],
    "courts_to_add": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string"
      }
    ]
  }
}

A rotation's board

GET/v1/organization/official-rotations/{rotationId}Wymaga uwierzytelnienia

The board the desk arranges (DEV-113): each court with its umpire and service judge, whether it takes a service judge, and the match its crew serves now (the one in play, or the court's next) with the officials who share a Member with one of its sides; the two queues head first; the reserve; every official with the matches they have umpired or judged by discipline; and the courts the caller may add. The board is not streamed: a desk reads it again every few seconds while it is open.

Parametry

  • rotationIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The board.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 404not_found: no such rotation, or one serving courts only of tournaments the caller does not run.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/official-rotations/{rotationId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "rotation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0
    },
    "courts": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string",
        "has_service_judge": true,
        "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "match": null
      }
    ],
    "umpires": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "service_judges": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "reserve": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "role": "umpire"
      }
    ],
    "officials": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "nationality": "string",
        "umpires": true,
        "judges_service": true,
        "account": true,
        "counts": {}
      }
    ],
    "courts_to_add": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string"
      }
    ]
  }
}

Choose the courts a rotation serves

PUT/v1/organization/official-rotations/{rotationId}/courtsWymaga uwierzytelnienia

The courts, in the board's order, each of one of the organization's tournaments not closed, with whether it takes a service judge. A court is added only by someone who runs its tournament, and a court another rotation serves is refused. An official on a court left out, or in a service judge's seat closed, goes back to the tail of their queue.

Parametry

  • rotationIdścieżka · string (uuid)wymagany

Treść żądania

  • courtsobject[]wymagany

    Pola

Odpowiedzi

  • 200The board as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 404not_found: no such rotation, or one serving courts only of tournaments the caller does not run.
  • 422validation_failed under courts: not a list, a court not the organizations or of a closed tournament, one named twice, or one in another rotation.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/official-rotations/{rotationId}/courts' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "courts": [
    {
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "has_service_judge": true
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "rotation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0
    },
    "courts": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string",
        "has_service_judge": true,
        "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "match": null
      }
    ],
    "umpires": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "service_judges": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "reserve": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "role": "umpire"
      }
    ],
    "officials": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "nationality": "string",
        "umpires": true,
        "judges_service": true,
        "account": true,
        "counts": {}
      }
    ],
    "courts_to_add": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string"
      }
    ]
  }
}

Add an official to a rotation

POST/v1/organization/official-rotations/{rotationId}/officialsWymaga uwierzytelnienia

An umpire, a service judge or both, off the rotation until the desk places them. An official is a name the desk types, or the account at email, whose name is taken unless name is given too; an account is in a rotation once, and is told by push when it is put on a court.

Parametry

  • rotationIdścieżka · string (uuid)wymagany

Treść żądania

  • namestring

  • emailstring

  • nationalitystring | null

  • umpiresbooleanwymagany

  • judges_servicebooleanwymagany

Odpowiedzi

  • 201The board with the official.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 404not_found: no such rotation, or one serving courts only of tournaments the caller does not run.
  • 422validation_failed on name, email (no such account, or in the rotation already), nationality or umpires (neither role taken).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/official-rotations/{rotationId}/officials' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "email": "string",
  "nationality": "string",
  "umpires": true,
  "judges_service": true
}'
201
{
  "ok": true,
  "data": {
    "rotation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0
    },
    "courts": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string",
        "has_service_judge": true,
        "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "match": null
      }
    ],
    "umpires": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "service_judges": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "reserve": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "role": "umpire"
      }
    ],
    "officials": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "nationality": "string",
        "umpires": true,
        "judges_service": true,
        "account": true,
        "counts": {}
      }
    ],
    "courts_to_add": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string"
      }
    ]
  }
}

Correct an official

PATCH/v1/organization/official-rotations/{rotationId}/officials/{officialId}Wymaga uwierzytelnienia

Their name, Member and the roles they take. A role taken away takes them off the rotation where they stood in it.

Parametry

  • rotationIdścieżka · string (uuid)wymagany

  • officialIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

  • nationalitystring | null

  • umpiresbooleanwymagany

  • judges_servicebooleanwymagany

Odpowiedzi

  • 200The board as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 404not_found: no such rotation, or one serving courts only of tournaments the caller does not run.
  • 422validation_failed on name, nationality or umpires.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/organization/official-rotations/{rotationId}/officials/{officialId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "nationality": "string",
  "umpires": true,
  "judges_service": true
}'
200
{
  "ok": true,
  "data": {
    "rotation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0
    },
    "courts": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string",
        "has_service_judge": true,
        "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "match": null
      }
    ],
    "umpires": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "service_judges": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "reserve": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "role": "umpire"
      }
    ],
    "officials": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "nationality": "string",
        "umpires": true,
        "judges_service": true,
        "account": true,
        "counts": {}
      }
    ],
    "courts_to_add": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string"
      }
    ]
  }
}

Arrange a rotation's board

PUT/v1/organization/official-rotations/{rotationId}/arrangementWymaga uwierzytelnienia

The whole board as the desk sees it after a drag (DEV-113): each court's umpire and service judge, the two queues head first, and the reserve. An official it does not name is off the rotation. Sent with the revision it was read at: a board changed since, by another desk or by the rotator's turn when a match ended, is refused with 409 revision_conflict and details.current_revision, and read again. Each court's crew is written on the match it serves at once, so a crew changed on a match in play is that match's.

Parametry

  • rotationIdścieżka · string (uuid)wymagany

Treść żądania

  • revisionintegerwymagany

  • courtsobject[]wymagany

    Pola
  • umpiresstring (uuid)[]wymagany

  • service_judgesstring (uuid)[]wymagany

  • reserveobject[]wymagany

    Pola

Odpowiedzi

  • 200The board as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator, nor a director or referee of one of the organization's tournaments; or a device or a key.
  • 404not_found: no such rotation, or one serving courts only of tournaments the caller does not run.
  • 409revision_conflict: the board changed since it was read; details.current_revision is the one it has.
  • 422validation_failed on the field that cannot stand: an official not the rotations or named twice, a role they do not take, a court not the rotations, or a service judge on a court that takes none.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/official-rotations/{rotationId}/arrangement' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "revision": 0,
  "courts": [
    {
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    }
  ],
  "umpires": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "service_judges": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "reserve": [
    {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "role": "umpire"
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "rotation": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "revision": 0
    },
    "courts": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string",
        "has_service_judge": true,
        "umpire_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "service_judge_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "match": null
      }
    ],
    "umpires": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "service_judges": [
      "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    ],
    "reserve": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "role": "umpire"
      }
    ],
    "officials": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "nationality": "string",
        "umpires": true,
        "judges_service": true,
        "account": true,
        "counts": {}
      }
    ],
    "courts_to_add": [
      {
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_name": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_name": "string"
      }
    ]
  }
}

The organization's player classes

GET/v1/organization/player-classesWymaga uwierzytelnienia

The classes the organization grades players in, strongest first, A to D until an administrator names others (DEV-31). For the organization's staff, who choose a player's class and a draw's classes from it. A device and a key are refused.

Odpowiedzi

  • 200The scale.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/player-classes' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "classes": [
      "string"
    ]
  }
}

Name the organization's player classes

PUT/v1/organization/player-classesWymaga uwierzytelnienia

For an administrator of the organization: one to ten different codes, strongest first. Nothing recorded is rewritten: a class the new scale drops stays on the players and draws that name it, and still counts where a draw admits it.

Treść żądania

  • classesstring[]wymagany

Odpowiedzi

  • 200The scale as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 422validation_failed on classes: not one to ten different codes of one to three letters or digits.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/player-classes' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "classes": [
    "string"
  ]
}'
200
{
  "ok": true,
  "data": {
    "classes": [
      "string"
    ]
  }
}

Rename the organization

PUT/v1/organization/nameWymaga uwierzytelnienia

For an administrator of the organization (DEV-674): the name, trimmed, of 1 to 200 characters, as a new organization's. The slug stays, so no host or link changes. Live, the league pages, Control and the emails read the new name on their next read; a published tournament's poll answers 200 again rather than 304.

Treść żądania

  • namestringwymagany

Odpowiedzi

  • 200The name as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization.
  • 422validation_failed on name: empty once trimmed, or longer than 200 characters.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/name' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
200
{
  "ok": true,
  "data": {
    "name": "string"
  }
}

The organization's memberships of associations, and of its members

GET/v1/organization/membershipsWymaga uwierzytelnienia

Every membership the organization the session acts for is on either side of (DEV-39): the associations it belongs to or has asked to join, and, for an association, the clubs and associations that belong to it. Open ones first, newest first, and the ended ones kept as the record. For the organization's staff; a device and a key are refused.

Odpowiedzi

  • 200The memberships, possibly none.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/memberships' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "memberships": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "association": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        },
        "member": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        },
        "sport": "badminton",
        "member_number": "string",
        "status": "requested",
        "side": "association",
        "awaiting": "association",
        "proposed_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Invite a member, or ask to join an association

POST/v1/organization/membershipsWymaga uwierzytelnienia

For an administrator of the organization, which is one of the two sides: as the association it invites the member (invited), as the member it asks to join (requested). The other side's administrator accepts. Only the association gives a member number, and the association named must be one.

Treść żądania

  • association_idstring (uuid)wymagany

  • member_idstring (uuid)wymagany

    A club, or an association that belongs to a larger one.

  • sportstringwymagany

    A sport Roundr runs. Append-only.

    badminton

  • member_numberstring | null

    The association's number for the member. The association alone sends one.

Odpowiedzi

  • 201The proposed membership.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: the organization is neither side, or the other side is not found.
  • 409membership_refused, with details.reason: not_an_association,
  • 422validation_failed under association_id, member_id, sport or member_number.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/memberships' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "association_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "member_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "sport": "badminton",
  "member_number": "string"
}'
201
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "association": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "member": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "sport": "badminton",
      "member_number": "string",
      "status": "requested",
      "side": "association",
      "awaiting": "association",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Accept an invitation or a request

POST/v1/organization/memberships/{membershipId}/acceptWymaga uwierzytelnienia

For an administrator of the side the membership waits for: the association accepting a request, the member accepting an invitation. The membership is active from then on.

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The membership as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such membership on either side of the organization.
  • 409membership_refused, with details.reason: not_awaiting_you (the other
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/memberships/{membershipId}/accept' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "association": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "member": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "sport": "badminton",
      "member_number": "string",
      "status": "requested",
      "side": "association",
      "awaiting": "association",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

End a membership, or decline or withdraw a proposal

POST/v1/organization/memberships/{membershipId}/endWymaga uwierzytelnienia

For an administrator of either side, answered or not: a club leaving, an association removing a member, or a proposal declined or taken back. The membership is kept as ended; a new one is proposed afresh.

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The membership, ended.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such membership on either side of the organization.
  • 409membership_refused, with details.reason: not_awaiting_you (the other
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/memberships/{membershipId}/end' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "association": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "member": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "sport": "badminton",
      "member_number": "string",
      "status": "requested",
      "side": "association",
      "awaiting": "association",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Number a member

PUT/v1/organization/memberships/{membershipId}/numberWymaga uwierzytelnienia

For an administrator of the association: its number for the member, as its register has it, or null to clear it. Surrounding spaces are dropped, and an empty number clears it too.

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Treść żądania

  • member_numberstring | nullwymagany

Odpowiedzi

  • 200The membership as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such membership on either side of the organization.
  • 409membership_refused, with details.reason: not_awaiting_you (the other
  • 422validation_failed on member_number: more than 20 characters, or not a string.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/memberships/{membershipId}/number' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "member_number": "string"
}'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "association": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "member": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "sport": "badminton",
      "member_number": "string",
      "status": "requested",
      "side": "association",
      "awaiting": "association",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Find an organization by name

GET/v1/organization/directoryWymaga uwierzytelnienia

For an administrator of the organization, to find the other side of a membership (DEV-39). Every word of q appears in the name, in any order. Only active organizations, never the one the session acts for, by name, at most 20. Names are public on Live already, so the answer is nothing a stranger could not read.

Parametry

  • qzapytanie · stringwymagany

  • kindzapytanie · string

Odpowiedzi

  • 200The organizations found, possibly none.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 422validation_failed on q (2 to 100 characters) or kind.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/directory' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "organizations": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      }
    ]
  }
}

The club's members

GET/v1/organization/club-membersWymaga uwierzytelnienia

The people who are members of the club the session acts for, or asked or were invited to be (DEV-39), with the numbers the club keeps. Open ones first, newest first, the ended ones kept as the record. For the club's staff; a device and a key are refused. An association has no members of this kind and reads none.

Odpowiedzi

  • 200The memberships, possibly none.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/club-members' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "memberships": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "club": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "person": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "email": "string"
        },
        "sport": "badminton",
        "member_number": "string",
        "licence_number": "string",
        "status": "requested",
        "side": "club",
        "awaiting": "club",
        "proposed_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Invite a person to the club

POST/v1/organization/club-membersWymaga uwierzytelnienia

For an administrator of the club: the person whose Roundr account uses email is invited (invited) and accepts or declines from their account. Only people with an account for now; one who has none signs in once, which creates it.

Treść żądania

  • emailstringwymagany

  • sportstringwymagany

    A sport Roundr runs. Append-only.

    badminton

  • member_numberstring | null

    The club's own number for the member.

  • licence_numberstring | null

    The member's licence number with the federation, which a league checks later.

Odpowiedzi

  • 201The invitation.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the club, or a device or a key.
  • 409membership_refused, with details.reason: not_a_club (the organization is an association) or already_open.
  • 422validation_failed under email (none, or no account uses it), sport, member_number or licence_number.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/club-members' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "sport": "badminton",
  "member_number": "string",
  "licence_number": "string"
}'
201
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Accept a person's request to join

POST/v1/organization/club-members/{membershipId}/acceptWymaga uwierzytelnienia

For an administrator of the club, on a request the person made.

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The membership as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the club, or a device or a key.
  • 404not_found: no such membership of the club.
  • 409membership_refused, with details.reason: not_awaiting_you (the other side answers) or ended (propose a new one).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/club-members/{membershipId}/accept' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Remove a member, or decline or withdraw a proposal

POST/v1/organization/club-members/{membershipId}/endWymaga uwierzytelnienia

For an administrator of the club, answered or not. The membership is kept as ended.

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The membership, ended.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the club, or a device or a key.
  • 404not_found: no such membership of the club.
  • 409membership_refused, with details.reason: not_awaiting_you (the other side answers) or ended (propose a new one).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/club-members/{membershipId}/end' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

The club's numbers for a member

PUT/v1/organization/club-members/{membershipId}/numbersWymaga uwierzytelnienia

For an administrator of the club: both numbers are replaced, each cleared by null or an empty one, surrounding spaces dropped. Nobody is told.

Parametry

  • membershipIdścieżka · string (uuid)wymagany

Treść żądania

  • member_numberstring | null

    The club's own number for the member.

  • licence_numberstring | null

    The member's licence number with the federation, which a league checks later.

Odpowiedzi

  • 200The membership as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the club, or a device or a key.
  • 404not_found: no such membership of the club.
  • 409membership_refused, with details.reason: not_awaiting_you (the other side answers) or ended (propose a new one).
  • 422validation_failed on member_number or licence_number.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/club-members/{membershipId}/numbers' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "member_number": "string",
  "licence_number": "string"
}'
200
{
  "ok": true,
  "data": {
    "membership": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "club": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "person": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "email": "string"
      },
      "sport": "badminton",
      "member_number": "string",
      "licence_number": "string",
      "status": "requested",
      "side": "club",
      "awaiting": "club",
      "proposed_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "ended_at": "2026-09-27T10:30:00Z"
    }
  }
}

Find a club by name, for the staff

GET/v1/organization/clubsWymaga uwierzytelnienia

For the organization's staff, to name the club a tournament's player stands for (DEV-39): every active club whose name contains every word of q, by name, at most 20, whichever host the search is made on. A device and a key are refused.

Parametry

  • qzapytanie · stringwymagany

Odpowiedzi

  • 200The clubs found, possibly none.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 422validation_failed on q (2 to 100 characters).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/clubs' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "clubs": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

The leagues the organization runs

GET/v1/organization/leaguesWymaga uwierzytelnienia

Every league of the organization the session acts for (DEV-49), newest season first, each with its tie. For the organization's staff; a device and a key are refused.

Odpowiedzi

  • 200The leagues, possibly none.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/leagues' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "leagues": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        },
        "name": "string",
        "sport": "badminton",
        "season": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27",
        "points": {
          "win": 0,
          "draw": 0,
          "loss": 0
        },
        "guest_allowance": 0,
        "entries_open": true,
        "live_published": true,
        "rubbers": [
          {
            "code": "string",
            "ruleset": {
              "id": null,
              "version": null,
              "engine_version": null
            },
            "entry_gender": "men"
          }
        ],
        "created_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Make a league

POST/v1/organization/leaguesWymaga uwierzytelnienia

For an administrator of the organization, an association or a club, on a plan that runs leagues (Club or larger, DEV-48). Its tie is a format preset or rubbers listed in score-sheet order, one of the two. Points default to 2 for a tie won, 1 drawn and 0 lost, the guest allowance to none, and entries to closed.

Treść żądania

  • namestringwymagany

    Once per organization and season.

  • seasonstringwymagany

    Such as 2026/27.

  • starts_onstring | null (date)

  • ends_onstring | null (date)

    Not before starts_on.

  • pointsobject

    Whole numbers from 0 to 10, win above loss and draw between them.

    Pola
  • guest_allowanceinteger

  • entries_openboolean

  • live_publishedboolean

    Publish the league's page on Live (DEV-50); off until it is.

  • formatstring

    obv_8hobby_4

  • rubbersobject[]

    Pola
  • sportstringwymagany

    A sport Roundr runs. Append-only.

    badminton

Odpowiedzi

  • 201The league, with no division and no team yet.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 409league_refused with details.reason name_taken (another league of the
  • 422validation_failed under name, season, sport, starts_on, ends_on, points, guest_allowance, entries_open, format or rubbers.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "season": "string",
  "starts_on": "2026-09-27",
  "ends_on": "2026-09-27",
  "points": {
    "win": 0,
    "draw": 0,
    "loss": 0
  },
  "guest_allowance": 0,
  "entries_open": true,
  "live_published": true,
  "format": "obv_8",
  "rubbers": [
    {
      "code": "string",
      "ruleset_id": "string",
      "ruleset_version": "string",
      "entry_gender": "men"
    }
  ],
  "sport": "badminton"
}'
201
{
  "ok": true,
  "data": {
    "league": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "owner": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "name": "string",
      "sport": "badminton",
      "season": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "points": {
        "win": 0,
        "draw": 0,
        "loss": 0
      },
      "guest_allowance": 0,
      "entries_open": true,
      "live_published": true,
      "rubbers": [
        {
          "code": "string",
          "ruleset": {
            "id": "string",
            "version": "string",
            "engine_version": "string"
          },
          "entry_gender": "men"
        }
      ],
      "created_at": "2026-09-27T10:30:00Z"
    },
    "divisions": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "position": 0
      }
    ],
    "teams": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "league": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "season": "string",
          "owner": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "kind": "association"
          }
        },
        "club": null,
        "name": "string",
        "status": "entered",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "entered_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

A league with its divisions and teams

GET/v1/organization/leagues/{leagueId}Wymaga uwierzytelnienia

For the staff of the organization that runs it. Teams are listed by division in the league's order, entries still to be placed after them, and withdrawn teams last.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The league.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such league of the organization.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/leagues/{leagueId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "league": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "owner": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "name": "string",
      "sport": "badminton",
      "season": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "points": {
        "win": 0,
        "draw": 0,
        "loss": 0
      },
      "guest_allowance": 0,
      "entries_open": true,
      "live_published": true,
      "rubbers": [
        {
          "code": "string",
          "ruleset": {
            "id": "string",
            "version": "string",
            "engine_version": "string"
          },
          "entry_gender": "men"
        }
      ],
      "created_at": "2026-09-27T10:30:00Z"
    },
    "divisions": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "position": 0
      }
    ],
    "teams": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "league": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "season": "string",
          "owner": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "kind": "association"
          }
        },
        "club": null,
        "name": "string",
        "status": "entered",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "entered_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Change a league's settings or its tie

PUT/v1/organization/leagues/{leagueId}Wymaga uwierzytelnienia

For an administrator of the organization that runs it. A field left out keeps its value; a format or rubbers replaces the tie. The sport is the league's from its creation.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Treść żądania

  • namestring

    Once per organization and season.

  • seasonstring

    Such as 2026/27.

  • starts_onstring | null (date)

  • ends_onstring | null (date)

    Not before starts_on.

  • pointsobject

    Whole numbers from 0 to 10, win above loss and draw between them.

    Pola
  • guest_allowanceinteger

  • entries_openboolean

  • live_publishedboolean

    Publish the league's page on Live (DEV-50); off until it is.

  • formatstring

    obv_8hobby_4

  • rubbersobject[]

    Pola

Odpowiedzi

  • 200The league as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such league of the organization.
  • 409league_refused with details.reason name_taken.
  • 422validation_failed under name, season, starts_on, ends_on, points, guest_allowance, entries_open, format or rubbers.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/leagues/{leagueId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "season": "string",
  "starts_on": "2026-09-27",
  "ends_on": "2026-09-27",
  "points": {
    "win": 0,
    "draw": 0,
    "loss": 0
  },
  "guest_allowance": 0,
  "entries_open": true,
  "live_published": true,
  "format": "obv_8",
  "rubbers": [
    {
      "code": "string",
      "ruleset_id": "string",
      "ruleset_version": "string",
      "entry_gender": "men"
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "league": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "owner": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "name": "string",
      "sport": "badminton",
      "season": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "points": {
        "win": 0,
        "draw": 0,
        "loss": 0
      },
      "guest_allowance": 0,
      "entries_open": true,
      "live_published": true,
      "rubbers": [
        {
          "code": "string",
          "ruleset": {
            "id": "string",
            "version": "string",
            "engine_version": "string"
          },
          "entry_gender": "men"
        }
      ],
      "created_at": "2026-09-27T10:30:00Z"
    },
    "divisions": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "position": 0
      }
    ],
    "teams": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "league": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "season": "string",
          "owner": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "kind": "association"
          }
        },
        "club": null,
        "name": "string",
        "status": "entered",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "entered_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Delete a league no team was entered in

DELETE/v1/organization/leagues/{leagueId}Wymaga uwierzytelnienia

For an administrator of the organization that runs it. A league a club has ever entered a team in stays, as the record of who entered it.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200Deleted, with its divisions and tie.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such league of the organization.
  • 409league_refused with details.reason has_teams.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/organization/leagues/{leagueId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "deleted": true
  }
}

Add a division below the league's others

POST/v1/organization/leagues/{leagueId}/divisionsWymaga uwierzytelnienia

For an administrator of the organization that runs the league.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

    Once in the league.

Odpowiedzi

  • 201The division.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such league of the organization.
  • 409league_refused with details.reason name_taken.
  • 422validation_failed under name.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/divisions' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
201
{
  "ok": true,
  "data": {
    "division": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "position": 0
    }
  }
}

Rename a division

PUT/v1/organization/leagues/{leagueId}/divisions/{divisionId}Wymaga uwierzytelnienia

For an administrator of the organization that runs the league.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • divisionIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

    Once in the league.

Odpowiedzi

  • 200The division.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such division of the organization's league.
  • 409league_refused with details.reason name_taken.
  • 422validation_failed under name.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/leagues/{leagueId}/divisions/{divisionId}' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'
200
{
  "ok": true,
  "data": {
    "division": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "name": "string",
      "position": 0
    }
  }
}

Delete a division no team was placed in

DELETE/v1/organization/leagues/{leagueId}/divisions/{divisionId}Wymaga uwierzytelnienia

For an administrator of the organization that runs the league.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • divisionIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200Deleted.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such division of the organization's league.
  • 409league_refused with details.reason has_teams.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/organization/leagues/{leagueId}/divisions/{divisionId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "deleted": true
  }
}

Enter a team by name, for a club that is not on Roundr

POST/v1/organization/leagues/{leagueId}/teamsWymaga uwierzytelnienia

For an administrator of the organization that runs the league (DEV-51). The team has no club (club null), is placed in the division as it is entered, and is kept by the organization: its roster and its line-ups are saved through /v1/organization/teams/{teamId} as a club's own team's are. It has no captains, and it leaves the league through remove.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

  • division_idstring (uuid)wymagany

Odpowiedzi

  • 201The team, placed.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such league of the organization, or division of it.
  • 409league_refused with details.reason name_taken.
  • 422validation_failed under name or division_id.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/teams' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "division_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
}'
201
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    }
  }
}

Place an entered team in a division, or move a placed one

POST/v1/organization/leagues/{leagueId}/teams/{teamId}/placeWymaga uwierzytelnienia

For an administrator of the organization that runs the league: accepting a club's entry by placing it, or moving a team between divisions.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • teamIdścieżka · string (uuid)wymagany

Treść żądania

  • division_idstring (uuid)wymagany

Odpowiedzi

  • 200The team as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such team, or division, of the organization's league.
  • 409league_refused with details.reason withdrawn.
  • 422validation_failed under division_id.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/teams/{teamId}/place' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "division_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
}'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    }
  }
}

Decline an entry, or take a team out of the league

POST/v1/organization/leagues/{leagueId}/teams/{teamId}/removeWymaga uwierzytelnienia

For an administrator of the organization that runs the league. The team is withdrawn and stays as the record; its name may be entered again.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The team as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such team of the organization's league.
  • 409league_refused with details.reason withdrawn.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/teams/{teamId}/remove' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    }
  }
}

A team of the league, with its roster and captains

GET/v1/organization/leagues/{leagueId}/teams/{teamId}Wymaga uwierzytelnienia

For the staff of the organization that runs the league (DEV-49), who read a roster and never write it. A device and a key are refused.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The team.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such team of the organization's league.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/leagues/{leagueId}/teams/{teamId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "players": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "captains": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ],
    "candidates": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

A league's fixtures and match days

GET/v1/organization/leagues/{leagueId}/scheduleWymaga uwierzytelnienia

For the staff of the organization that runs the league (DEV-49): every fixture by division, round and place in the round, and the match days by date, each with the tournament its ties are played in once it is opened.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The schedule.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such league of the organization.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/leagues/{leagueId}/schedule' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Make a division's fixtures

POST/v1/organization/leagues/{leagueId}/divisions/{divisionId}/fixturesWymaga uwierzytelnienia

For an administrator of the organization that runs the league: a double round robin of the division's placed teams, every team meeting every other once at each one's home, replacing the fixtures it had. Refused while any is on a match day, and on a plan without leagues: a club whose plan lapsed plays the fixtures it has (DEV-675).

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • divisionIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The schedule as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such division of the organization's league.
  • 409league_refused with details.reason too_few_teams or fixtures_scheduled; plan_limit_reached with details.limit leagues on a plan without leagues.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/divisions/{divisionId}/fixtures' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Clear a division's fixtures

DELETE/v1/organization/leagues/{leagueId}/divisions/{divisionId}/fixturesWymaga uwierzytelnienia

For an administrator of the organization that runs the league, while none of the division's fixtures is on a match day; its teams may then leave or move.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • divisionIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The schedule as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such division of the organization's league.
  • 409league_refused with details.reason fixtures_scheduled.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/organization/leagues/{leagueId}/divisions/{divisionId}/fixtures' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Add a match day

POST/v1/organization/leagues/{leagueId}/match-daysWymaga uwierzytelnienia

For an administrator of the organization that runs the league, on a plan with leagues. A club whose plan lapsed opens and plays the match days it has, and adds none (DEV-675): each opens as a tournament that holds no plan place (DEV-49).

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Treść żądania

  • namestringwymagany

  • plays_onstring (date)wymagany

  • venue_namestring | null

  • venue_time_zonestringwymagany

    An IANA time zone, which the match day's tournament takes.

Odpowiedzi

  • 201The schedule with the match day.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such league of the organization.
  • 409plan_limit_reached with details.limit leagues: the plan has no leagues.
  • 422validation_failed under name, plays_on, venue_name or venue_time_zone.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/match-days' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "plays_on": "2026-09-27",
  "venue_name": "string",
  "venue_time_zone": "string"
}'
201
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Delete a match day that has not been opened

DELETE/v1/organization/leagues/{leagueId}/match-days/{matchDayId}Wymaga uwierzytelnienia

For an administrator of the organization that runs the league. Its fixtures come off it and wait for another.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • matchDayIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The schedule as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such match day of the organization's league.
  • 409league_refused with details.reason match_day_open.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/organization/leagues/{leagueId}/match-days/{matchDayId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Open a match day

POST/v1/organization/leagues/{leagueId}/match-days/{matchDayId}/openWymaga uwierzytelnienia

For an administrator of the organization that runs the league: makes the draft tournament the match day's ties are played in, named for the league and the day, on its date and at its venue, where the hall is run as in any tournament. It is marked as the league's match day and takes no place against the plan's running tournaments (DEV-49). It opens as the league's last opened match day at the same venue was set up (DEV-54): that tournament's settings, its courts and its hall displays, as far as the plan has room for them, and never its codes, its devices or its place on Live. A match day at another venue, and a league's first, opens with none.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • matchDayIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The schedule, the match day with its tournament_id.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such match day of the organization's league.
  • 409league_refused with details.reason match_day_open or no_fixtures.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/match-days/{matchDayId}/open' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Put a fixture on a match day, or take it off one

PUT/v1/organization/leagues/{leagueId}/fixtures/{fixtureId}/match-dayWymaga uwierzytelnienia

For an administrator of the organization that runs the league. start_time says when the fixture starts on that day, at the venue's clock (DEV-51): left out, the fixture keeps the time it has, and null clears it. A fixture on no match day has no time. match_day_id is always said: null takes the fixture off its match day, and a request that leaves it out is refused, so one that meant only the time cannot lose the day with it.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Treść żądania

  • match_day_idstring | null (uuid)wymagany

  • start_timestring | null

    HH:MM, 24 hours, at the match day's venue.

Odpowiedzi

  • 200The schedule as it now stands.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such fixture or match day of the organization's league.
  • 409league_refused with details.reason tie_started: the tie has started, and its fixture stays on its match day at its time.
  • 422validation_failed under match_day_id or start_time.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/leagues/{leagueId}/fixtures/{fixtureId}/match-day' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "start_time": "string"
}'
200
{
  "ok": true,
  "data": {
    "fixtures": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      }
    ],
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ]
  }
}

Every division's ties and table

GET/v1/organization/leagues/{leagueId}/standingsWymaga uwierzytelnienia

For the staff of the organization that runs the league (DEV-49). Read from the rubbers' matches each time: a tie is decided once every rubber is confirmed, and the table counts decided ties by the league's points, ordered by points, rubber difference, games difference, the ties between the teams still level, then name.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The divisions.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such league of the organization.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/leagues/{leagueId}/standings' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "divisions": [
      {
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "position": 0
        },
        "standings": [
          {
            "team": {
              "id": null,
              "name": null,
              "club": null
            },
            "played": 0,
            "won": 0,
            "drawn": 0,
            "lost": 0,
            "rubbers_for": 0,
            "rubbers_against": 0,
            "games_for": 0,
            "games_against": 0,
            "points": 0
          }
        ],
        "ties": [
          {
            "fixture": {
              "id": null,
              "division": null,
              "round": null,
              "position": null,
              "home": null,
              "away": null,
              "match_day_id": null,
              "start_time": null
            },
            "home_lineup_given": true,
            "away_lineup_given": true,
            "started": true,
            "decided": true,
            "home_rubbers": 0,
            "away_rubbers": 0,
            "rubbers": [
              null
            ]
          }
        ]
      }
    ]
  }
}

A tie with both line-ups

GET/v1/organization/leagues/{leagueId}/fixtures/{fixtureId}/tieWymaga uwierzytelnienia

For the staff of the organization that runs the league.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The tie.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such fixture of the organization's league.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/leagues/{leagueId}/fixtures/{fixtureId}/tie' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tie": {
      "fixture": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      },
      "home_lineup_given": true,
      "away_lineup_given": true,
      "started": true,
      "decided": true,
      "home_rubbers": 0,
      "away_rubbers": 0,
      "rubbers": [
        {
          "code": "string",
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "status": "string",
          "winner": "home",
          "home_games": 0,
          "away_games": 0,
          "not_fielded_by": "home"
        }
      ]
    },
    "home_lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "away_lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ]
  }
}

Start a tie

POST/v1/organization/leagues/{leagueId}/fixtures/{fixtureId}/startWymaga uwierzytelnienia

For an administrator of the organization that runs the league, once the fixture's match day is open and both teams have given their line-up (DEV-49). Each player becomes a player of the match day's tournament, linked to their account and club, each side of a rubber a participant, and each rubber a match, coded D<division>R<round>.<place>-<rubber>, which is scored as every match is. The line-ups, and the league's tie and points, stay as they are from then on. A rubber one side left out of its line-up becomes no match: the tie records which side had no player and counts it for the other (DEV-53). A tie no rubber of which both teams field is refused as nothing_to_play. A match day whose tournament has been closed takes no tie until it is reopened (tournament_closed, DEV-25), and nothing is written; the teams' line-ups are the league's and are still given.

Parametry

  • leagueIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The tie, started.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such fixture of the organization's league.
  • 409league_refused with details.reason match_day_not_open, lineups_missing,
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/leagues/{leagueId}/fixtures/{fixtureId}/start' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tie": {
      "fixture": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      },
      "home_lineup_given": true,
      "away_lineup_given": true,
      "started": true,
      "decided": true,
      "home_rubbers": 0,
      "away_rubbers": 0,
      "rubbers": [
        {
          "code": "string",
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "status": "string",
          "winner": "home",
          "home_games": 0,
          "away_games": 0,
          "not_fielded_by": "home"
        }
      ]
    },
    "home_lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "away_lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ]
  }
}

The club's teams in leagues

GET/v1/organization/teamsWymaga uwierzytelnienia

Every team the organization the session acts for has entered in a league, its own leagues' and others' (DEV-49), open ones first. For the organization's staff; a device and a key are refused.

Odpowiedzi

  • 200The teams, possibly none.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/teams' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "teams": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "league": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "season": "string",
          "owner": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "kind": "association"
          }
        },
        "club": null,
        "name": "string",
        "status": "entered",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "entered_at": "2026-09-27T10:30:00Z",
        "answered_at": "2026-09-27T10:30:00Z",
        "withdrawn_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Enter a team in a league

POST/v1/organization/teamsWymaga uwierzytelnienia

For an administrator of a club on a plan that takes part in leagues (Club or larger, DEV-48), in a league whose entries are open: any club's, or an association's the club is an active member of in the league's sport. The team waits for the league's administrators to place it in a division.

Treść żądania

  • league_idstring (uuid)wymagany

  • namestringwymagany

    The team's name, such as VRC 2, once among the league's open teams.

Odpowiedzi

  • 201The team, entered.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such league.
  • 409league_refused with details.reason not_a_club, entries_closed,
  • 422validation_failed under league_id or name.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/teams' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "league_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "name": "string"
}'
201
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    }
  }
}

Withdraw the club's team

POST/v1/organization/teams/{teamId}/withdrawWymaga uwierzytelnienia

For an administrator of the club whose team it is, entered or placed. The team stays as the record; its name may be entered again.

Parametry

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The team, withdrawn.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such team of the club.
  • 409league_refused with details.reason withdrawn.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/organization/teams/{teamId}/withdraw' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    }
  }
}

One of the club's teams, with its roster and captains

GET/v1/organization/teams/{teamId}Wymaga uwierzytelnienia

For the club's staff (DEV-49), with candidates: the club's active members in the league's sport, whom the roster and the captains are chosen from. A team the organization's own league entered by name is read here too (DEV-51): it has no club, so candidates is empty, and the organization keeps its roster and line-ups through this path and those below it as a club keeps its own team's.

Parametry

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The team.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such team of the club.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/teams/{teamId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "players": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "captains": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ],
    "candidates": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

Replace a team's roster

PUT/v1/organization/teams/{teamId}/rosterWymaga uwierzytelnienia

For an administrator of the club whose team it is (DEV-49). The roster is checked against the league's rule as it is saved: a member of the club in the league's sport is the club's own, anyone else a guest, up to the league's guest_allowance, and a person plays for one team per league. A refusal keeps the roster as it was. On a team without a club (DEV-51), kept by the organization that runs its league, nobody is a guest.

Parametry

  • teamIdścieżka · string (uuid)wymagany

Treść żądania

  • membersstring (uuid)[]

  • guestsstring (email)[]

  • namesstring[]

Odpowiedzi

  • 200The team with its new roster.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such team of the club.
  • 409league_refused with details.reason no_such_account (no account holds a
  • 422validation_failed under members.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/teams/{teamId}/roster' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "members": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ],
  "guests": [
    "[email protected]"
  ],
  "names": [
    "string"
  ]
}'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "players": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "captains": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ],
    "candidates": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

Name a team's captains

PUT/v1/organization/teams/{teamId}/captainsWymaga uwierzytelnienia

For an administrator of the club whose team it is (DEV-49): up to three of the club's active members in the league's sport, replacing those named before. A captain keeps the team's roster from their own account (/v1/me/teams).

Parametry

  • teamIdścieżka · string (uuid)wymagany

Treść żądania

  • user_idsstring (uuid)[]wymagany

Odpowiedzi

  • 200The team with its captains.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such team of the club.
  • 409league_refused with details.reason not_a_club_member or withdrawn.
  • 422validation_failed under user_ids.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/teams/{teamId}/captains' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "user_ids": [
    "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  ]
}'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "players": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "captains": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ],
    "candidates": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      }
    ]
  }
}

A club team's season

GET/v1/organization/teams/{teamId}/seasonWymaga uwierzytelnienia

For the club's staff (DEV-49): the team's league, its match days, and its division's ties and table once it is placed.

Parametry

  • teamIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The season.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such team of the club.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/teams/{teamId}/season' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "team": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "league": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "season": "string",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        }
      },
      "club": null,
      "name": "string",
      "status": "entered",
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string"
      },
      "entered_at": "2026-09-27T10:30:00Z",
      "answered_at": "2026-09-27T10:30:00Z",
      "withdrawn_at": "2026-09-27T10:30:00Z"
    },
    "league": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "owner": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "kind": "association"
      },
      "name": "string",
      "sport": "badminton",
      "season": "string",
      "starts_on": "2026-09-27",
      "ends_on": "2026-09-27",
      "points": {
        "win": 0,
        "draw": 0,
        "loss": 0
      },
      "guest_allowance": 0,
      "entries_open": true,
      "live_published": true,
      "rubbers": [
        {
          "code": "string",
          "ruleset": {
            "id": "string",
            "version": "string",
            "engine_version": "string"
          },
          "entry_gender": "men"
        }
      ],
      "created_at": "2026-09-27T10:30:00Z"
    },
    "match_days": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "plays_on": "2026-09-27",
        "venue_name": "string",
        "venue_time_zone": "string",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      }
    ],
    "table": {
      "division": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "position": 0
      },
      "standings": [
        {
          "team": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string",
            "club": null
          },
          "played": 0,
          "won": 0,
          "drawn": 0,
          "lost": 0,
          "rubbers_for": 0,
          "rubbers_against": 0,
          "games_for": 0,
          "games_against": 0,
          "points": 0
        }
      ],
      "ties": [
        {
          "fixture": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "division": {
              "id": null,
              "name": null
            },
            "round": 0,
            "position": 0,
            "home": {
              "id": null,
              "name": null,
              "club": null
            },
            "away": {
              "id": null,
              "name": null,
              "club": null
            },
            "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "start_time": "string"
          },
          "home_lineup_given": true,
          "away_lineup_given": true,
          "started": true,
          "decided": true,
          "home_rubbers": 0,
          "away_rubbers": 0,
          "rubbers": [
            {
              "code": null,
              "tournament_id": null,
              "match_id": null,
              "status": null,
              "winner": "home",
              "home_games": null,
              "away_games": null,
              "not_fielded_by": "home"
            }
          ]
        }
      ]
    }
  }
}

A club team's line-up for one of its fixtures

GET/v1/organization/teams/{teamId}/fixtures/{fixtureId}/lineupWymaga uwierzytelnienia

For the club's staff: the tie, its rubbers, the roster, the line-up given, and the other side's line-up once the tie has started (opponent, null before). Until then previous is the line-up the team gave last, for another fixture, to fill this one in from.

Parametry

  • teamIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The line-up.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 404not_found: no such fixture of the club's team.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/teams/{teamId}/fixtures/{fixtureId}/lineup' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "tie": {
      "fixture": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      },
      "home_lineup_given": true,
      "away_lineup_given": true,
      "started": true,
      "decided": true,
      "home_rubbers": 0,
      "away_rubbers": 0,
      "rubbers": [
        {
          "code": "string",
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "status": "string",
          "winner": "home",
          "home_games": 0,
          "away_games": 0,
          "not_fielded_by": "home"
        }
      ]
    },
    "roster": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "opponent": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "previous": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "rubbers": [
      {
        "code": "string",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "entry_gender": "men"
      }
    ]
  }
}

Give or change a club team's line-up

PUT/v1/organization/teams/{teamId}/fixtures/{fixtureId}/lineupWymaga uwierzytelnienia

For an administrator of the club, until the tie starts: a player or a pair from the roster for every rubber, each player in two rubbers at most and once in any one. A rubber the team has nobody for is marked not_fielded (DEV-53). new_players are put on the roster by name as the line-up is saved, so a visiting team's sheet is typed in once; a refused line-up leaves the roster as it was.

Parametry

  • teamIdścieżka · string (uuid)wymagany

  • fixtureIdścieżka · string (uuid)wymagany

Treść żądania

  • new_playersstring[]

    Players without an account to put on the roster by name before the line-up is read (DEV-51), after everyone on it. A name the roster holds already changes nothing. Refused as roster_full when the roster would pass forty players.

  • rubbersobject[]wymagany

    Every rubber of the league's tie once, one of them fielded at least.

    Pola

Odpowiedzi

  • 200The line-up.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, or a device or a key.
  • 404not_found: no such fixture of the club's team.
  • 409league_refused with details.reason not_on_roster, plays_too_often, roster_full or tie_started.
  • 422validation_failed under rubbers: every rubber of the tie once, with one player or a pair as its ruleset says or not_fielded and nobody, and one rubber fielded at least. Under new_players: a list of names.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/organization/teams/{teamId}/fixtures/{fixtureId}/lineup' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "new_players": [
    "string"
  ],
  "rubbers": [
    {
      "code": "string",
      "not_fielded": true,
      "players": [
        "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
      ]
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "tie": {
      "fixture": {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "division": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string"
        },
        "round": 0,
        "position": 0,
        "home": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "away": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "club": null
        },
        "match_day_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "start_time": "string"
      },
      "home_lineup_given": true,
      "away_lineup_given": true,
      "started": true,
      "decided": true,
      "home_rubbers": 0,
      "away_rubbers": 0,
      "rubbers": [
        {
          "code": "string",
          "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "status": "string",
          "winner": "home",
          "home_games": 0,
          "away_games": 0,
          "not_fielded_by": "home"
        }
      ]
    },
    "roster": [
      {
        "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "name": "string",
        "guest": true
      }
    ],
    "lineup": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "opponent": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "previous": [
      {
        "code": "string",
        "players": [
          {
            "user_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          }
        ],
        "not_fielded": true
      }
    ],
    "rubbers": [
      {
        "code": "string",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "entry_gender": "men"
      }
    ]
  }
}

Leagues the club may enter a team in now

GET/v1/organization/open-leaguesWymaga uwierzytelnienia

Leagues whose entries are open and that would take the club's: any club's, the club's own among them, and an association's the club is an active member of in the league's sport. For the organization's staff; a device and a key are refused.

Odpowiedzi

  • 200The leagues, possibly none.
  • 401No credential.
  • 403insufficient_scope: a device or a key.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/organization/open-leagues' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "leagues": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "owner": {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "name": "string",
          "kind": "association"
        },
        "name": "string",
        "sport": "badminton",
        "season": "string",
        "starts_on": "2026-09-27",
        "ends_on": "2026-09-27",
        "points": {
          "win": 0,
          "draw": 0,
          "loss": 0
        },
        "guest_allowance": 0,
        "entries_open": true,
        "live_published": true,
        "rubbers": [
          {
            "code": "string",
            "ruleset": {
              "id": null,
              "version": null,
              "engine_version": null
            },
            "entry_gender": "men"
          }
        ],
        "created_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

The participants of a tournament, with their players

GET/v1/tournaments/{tournamentId}/participantsWymaga uwierzytelnienia

Every participant of the tournament by display name, each with its players in position order. Open to staff, a court device and a machine key issued tournaments:read, because a court may be given any match. Not to a display: its snapshot carries only the sides of the matches its projection shows, and every player's name here would undo that. The snapshot carries the same participants without their players; this is the read for a screen that needs the players, or for a client that holds no snapshot.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The participants, possibly none.
  • 401No credential.
  • 403insufficient_scope: a machine key that was not issued tournaments:read,
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/participants' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "participants": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "kind": "single",
        "display_name": "string",
        "external_ref": "string",
        "players": [
          {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "full_name": "string",
            "given_name": "string",
            "family_name": "string",
            "family_name_first": true,
            "position": 1,
            "external_ref": "string",
            "account": {
              "display_name": null
            },
            "association": "string",
            "club": {
              "id": null,
              "name": null
            },
            "nationality": "string",
            "gender": "female",
            "date_of_birth": "2026-09-27",
            "classes": {
              "singles": null,
              "doubles": null,
              "mixed": null
            }
          }
        ],
        "ranking": {
          "position": 1,
          "name": "string",
          "date": "2026-09-27"
        }
      }
    ]
  }
}

Link a player to a Roundr account

PUT/v1/tournaments/{tournamentId}/players/{playerId}/accountWymaga uwierzytelnienia

For an administrator of the organization or a director of the tournament: the player becomes the account registered with the address, replacing any account it named before, as a tournament role is granted by an address. The link authorizes nothing; it is what the account's own view of its results and upcoming matches will join through (DEV-15). One account is one player per tournament, so an address already linked to another player of it is refused. The person must hold an account already, and the answer says when the address holds none.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • playerIdścieżka · string (uuid)wymagany

Treść żądania

  • emailstringwymagany

  • junior_namestring | null

    With a guardian's address, the name that guardian keeps for the junior to link (DEV-36), compared without case, accents or extra spaces. Each such try spends the partner lookup's budgets.

Odpowiedzi

  • 200The participant the player belongs to, as staff now see it.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization, or not a player of it.
  • 422validation_failed on email: not an address, no account uses it, or the
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/tournaments/{tournamentId}/players/{playerId}/account' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string",
  "junior_name": "string"
}'
200
{
  "ok": true,
  "data": {
    "participant": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "kind": "single",
      "display_name": "string",
      "external_ref": "string",
      "players": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "position": 1,
          "external_ref": "string",
          "account": {
            "display_name": "string"
          },
          "association": "string",
          "club": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          },
          "nationality": "string",
          "gender": "female",
          "date_of_birth": "2026-09-27",
          "classes": {
            "singles": null,
            "doubles": null,
            "mixed": null
          }
        }
      ],
      "ranking": {
        "position": 1,
        "name": "string",
        "date": "2026-09-27"
      }
    }
  }
}

Unlink a player from its Roundr account

DELETE/v1/tournaments/{tournamentId}/players/{playerId}/accountWymaga uwierzytelnienia

For an administrator of the organization or a director of the tournament. The player stays; only the account it named is removed. A player that named none is answered the same way.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • playerIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The participant the player belongs to, as staff now see it.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization, or not a player of it.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/tournaments/{tournamentId}/players/{playerId}/account' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "participant": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "kind": "single",
      "display_name": "string",
      "external_ref": "string",
      "players": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "position": 1,
          "external_ref": "string",
          "account": {
            "display_name": "string"
          },
          "association": "string",
          "club": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          },
          "nationality": "string",
          "gender": "female",
          "date_of_birth": "2026-09-27",
          "classes": {
            "singles": null,
            "doubles": null,
            "mixed": null
          }
        }
      ],
      "ranking": {
        "position": 1,
        "name": "string",
        "date": "2026-09-27"
      }
    }
  }
}

Record a player's classes

PUT/v1/tournaments/{tournamentId}/players/{playerId}/classesWymaga uwierzytelnienia

For an administrator of the organization or a director of the tournament: the player's class in each discipline, replacing what was recorded, the import's or the account's (DEV-31). The way to correct a player a registration created, whom the import cannot name again. Every discipline is required, a code or null.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • playerIdścieżka · string (uuid)wymagany

Treść żądania

  • singlesstring | nullwymagany

  • doublesstring | nullwymagany

  • mixedstring | nullwymagany

Odpowiedzi

  • 200The participant the player belongs to, as staff now see it.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization, or not a player of it.
  • 409tournament_closed: the tournament has been closed (DEV-25).
  • 422validation_failed on classes: a discipline missing or unknown, or a value that is not a class code.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/tournaments/{tournamentId}/players/{playerId}/classes' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "singles": "string",
  "doubles": "string",
  "mixed": "string"
}'
200
{
  "ok": true,
  "data": {
    "participant": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "kind": "single",
      "display_name": "string",
      "external_ref": "string",
      "players": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "position": 1,
          "external_ref": "string",
          "account": {
            "display_name": "string"
          },
          "association": "string",
          "club": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          },
          "nationality": "string",
          "gender": "female",
          "date_of_birth": "2026-09-27",
          "classes": {
            "singles": null,
            "doubles": null,
            "mixed": null
          }
        }
      ],
      "ranking": {
        "position": 1,
        "name": "string",
        "date": "2026-09-27"
      }
    }
  }
}

Name the club a player stands for

PUT/v1/tournaments/{tournamentId}/players/{playerId}/clubWymaga uwierzytelnienia

For an administrator of the organization or a director of the tournament: the club on Roundr the player stands for (DEV-39), or null for none. A club named fills the player's association where it has none, since draw separation and Live read that text; one already written stays. The way to name the club of a player a registration created, whom the import cannot name again. An accepted entry, or an account linked to the player, names the account's own club by itself when it belongs to exactly one.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • playerIdścieżka · string (uuid)wymagany

Treść żądania

  • club_idstring | null (uuid)wymagany

Odpowiedzi

  • 200The participant the player belongs to, as staff now see it.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization, or not a player of it.
  • 409tournament_closed: the tournament has been closed (DEV-25).
  • 422validation_failed on club_id: not an id, or not an active club on Roundr.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/tournaments/{tournamentId}/players/{playerId}/club' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "club_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
}'
200
{
  "ok": true,
  "data": {
    "participant": {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "kind": "single",
      "display_name": "string",
      "external_ref": "string",
      "players": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "position": 1,
          "external_ref": "string",
          "account": {
            "display_name": "string"
          },
          "association": "string",
          "club": {
            "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
            "name": "string"
          },
          "nationality": "string",
          "gender": "female",
          "date_of_birth": "2026-09-27",
          "classes": {
            "singles": null,
            "doubles": null,
            "mixed": null
          }
        }
      ],
      "ranking": {
        "position": 1,
        "name": "string",
        "date": "2026-09-27"
      }
    }
  }
}

Read who has checked in at the desk

GET/v1/tournaments/{tournamentId}/check-insWymaga uwierzytelnienia

Every player of the tournament the desk has checked in, taken a check-in back from, or marked away (DEV-44); a player not listed has not checked in. Per player, not per entry: a player in singles and doubles reports once.

For the desk: an administrator of the organization, or a director or the referee of the tournament. Any other person, a court device, a hall display and a machine key are refused once the tournament is found. Live and the hall displays never show check-in, and the tournament feed announces a change as a player_check_in notification to the staff alone; a device, a display and a key see a checkpoint.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The check-ins the desk has recorded.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/check-ins' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "check_ins": [
      {
        "player_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "present": true,
        "checked_in_at": "2026-09-27T10:30:00Z",
        "checked_in_by": {
          "display_name": "string"
        },
        "away_until": "2026-09-27T10:30:00Z",
        "changed_at": "2026-09-27T10:30:00Z",
        "changed_by": {
          "display_name": "string"
        },
        "revision": 0
      }
    ]
  }
}

Check a player in, take it back, or mark them away

PATCH/v1/tournaments/{tournamentId}/players/{playerId}/check-inWymaga uwierzytelnienia

The desk checks a player in (present: true) or takes it back (present: false), and sets the time before which the player is not to be called (away_until, "back at 14:30" or "arriving at 11:00"), or clears it with null (DEV-44). A part left out stays as it is, and the change is applied under the player's lock, so two desk laptops changing different parts both land. Checking in a player already present keeps who took the first check-in and when; taking it back clears both.

A change moves the check-in's own revision and is announced on the tournament feed as player_check_in_changed on the player_check_in aggregate; one that changes nothing writes and announces nothing. It is no match command and never moves match_revision. Nothing is refused for it: Control flags a match whose players have not all checked in, and the desk decides.

For the desk: an administrator of the organization, or a director or the referee of the tournament.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • playerIdścieżka · string (uuid)wymagany

Treść żądania

  • presentboolean

  • away_untilstring | null (date-time)

    An instant with its zone; null for not away.

Odpowiedzi

  • 200The player's check-in as it now stands.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404Not a tournament of the organization, or not a player of it.
  • 409tournament_closed: the tournament has been closed (DEV-25).
  • 422validation_failed on present (not a boolean, or neither part named) or away_until (not an instant with its zone).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/players/{playerId}/check-in' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "present": true,
  "away_until": "2026-09-27T10:30:00Z"
}'
200
{
  "ok": true,
  "data": {
    "check_in": {
      "player_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "present": true,
      "checked_in_at": "2026-09-27T10:30:00Z",
      "checked_in_by": {
        "display_name": "string"
      },
      "away_until": "2026-09-27T10:30:00Z",
      "changed_at": "2026-09-27T10:30:00Z",
      "changed_by": {
        "display_name": "string"
      },
      "revision": 0
    }
  }
}

Load participants and matches from a draw file

POST/v1/tournaments/{tournamentId}/importWymaga uwierzytelnienia

Takes the rows of an entry or draw file the client has already parsed, so the server accepts one JSON shape whatever spreadsheet produced it. Every row is keyed by the external reference the file gives it: a participant, a player or a match whose reference the tournament already holds is updated in place, so a corrected file loads again over the first one instead of beside it. Nothing is deleted; a row missing from a later file stays. An entry already in the tournament, and a player, may be named by id instead, as Control corrects an entry a registration made, which has no reference.

Participants are written first, so a match may name a participant from the same file. A match's sides are participant references, and its court is a court name, matched without regard to case. A match that has been scored keeps its sides, because its history would otherwise name players who never played it; its court and slot still move. A row naming the reference of a knockout draw's match is refused: the draw sets that match's sides.

The import is one transaction, all or nothing. Rows are validated before anything is written, and a reference that names no participant or court, or an id the tournament does not have, is found inside the transaction and rolls the whole import back, so a bad row leaves nothing half applied. Either refusal names its rows under validation_errors, keyed participants[3] or matches[0]. At most 2000 rows in one request, participants and matches together.

For an administrator of the organization, a director of the tournament, or a machine key issued tournaments:import, which is how an organization's own system loads its participants and matches without a person exporting a file.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • participantsImportParticipant[]

    Pola
  • matchesImportMatch[]

    Pola

Odpowiedzi

  • 200Everything was written.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, a director of
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed, and nothing was imported. participants or matches is
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/import' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "participants": [
    {
      "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "external_ref": "string",
      "kind": "single",
      "display_name": "string",
      "players": [
        {
          "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "external_ref": "string",
          "full_name": "string",
          "given_name": "string",
          "family_name": "string",
          "family_name_first": true,
          "association": "string",
          "nationality": "string",
          "gender": "female",
          "date_of_birth": "2026-09-27",
          "classes": {
            "singles": "string",
            "doubles": "string",
            "mixed": "string"
          }
        }
      ],
      "ranking": {
        "position": 1,
        "name": "string",
        "date": "2026-09-27"
      }
    }
  ],
  "matches": [
    {
      "external_ref": "string",
      "ruleset_id": "string",
      "ruleset_version": "string",
      "home_ref": "string",
      "away_ref": "string",
      "court": "string",
      "scheduled_start": "2026-09-27T10:30:00Z",
      "not_before": "2026-09-27T10:30:00Z"
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "participants_imported": 0,
    "matches_created": 0,
    "matches_updated": 0
  }
}

Create one match

POST/v1/tournaments/{tournamentId}/matchesWymaga uwierzytelnienia

The single-match form of the import, for a match added by hand. The ruleset and its version are pinned at creation, together with the engine version the ruleset names, and never change afterwards; a ruleset this deployment does not carry is a validation error. The sides and the court are optional and must belong to the tournament, so a match can exist before the draw is known.

With an external_ref the request is an upsert: a match already holding that reference is answered 200 with created: false, its sides corrected unless it has been scored and its court and slot moved, which is what lets a client retry after a lost response without making a second match. Without one, every request creates a match. A new match is announced as match_created at revision 0. The reference of a knockout draw's match is refused on external_ref: the draw sets that match's sides.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • ruleset_idstringwymagany

    A ruleset this deployment carries, such as badminton.bwf.21x3.

  • ruleset_versionstringwymagany

    The ruleset's version, such as v1.

  • home_participant_idstring | null (uuid)

    A participant of this tournament.

  • away_participant_idstring | null (uuid)

    A participant of this tournament.

  • court_idstring | null (uuid)

    A court of this tournament.

  • external_refstring | null

    The organizer's own key for the match; makes the request an upsert.

  • scheduled_startstring | null (date-time)

  • not_beforestring | null (date-time)

    The earliest the match may start, as an instant, or null for none. Left out, an upsert of an existing match keeps the one it has.

Odpowiedzi

  • 200A match already held external_ref and was updated; none was created.
  • 201The match was created.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 422validation_failed: a ruleset or version this deployment does not carry, under
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/tournaments/{tournamentId}/matches' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "ruleset_id": "string",
  "ruleset_version": "string",
  "home_participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "away_participant_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "external_ref": "string",
  "scheduled_start": "2026-09-27T10:30:00Z",
  "not_before": "2026-09-27T10:30:00Z"
}'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "created": true
  }
}

The tournament's results as CSV

GET/v1/tournaments/{tournamentId}/resultsWymaga uwierzytelnienia

One row per match of the tournament, in creation order, for the organizer's own spreadsheet or a federation upload: the export is how results leave Roundr, so it is a file rather than JSON. For an administrator of the organization, a director or referee of the tournament, or a machine key issued tournaments:read. Every match is included whatever its state; status says which have a result.

The columns are match_id, external_ref, court, home, away, status, games, winner, confirmed_at, draw, round, group and places. games is each game's score as home-away, space separated, such as 21-19 18-21 21-15; winner is home or away once there is a result; confirmed_at is UTC, ISO 8601; status is a match status as GET /v1/matches/{matchId} reports it. external_ref is the reference the import gave the match, so the file joins back onto the organizer's own. draw is the name of the draw the match is in, round its round from 1, group a group match's group as a letter from A, and places the places a play-off match decides between, such as 5-6; all four are empty for a match in no draw. New columns are only ever added after the last, so a reader that takes the columns by position keeps working. A cell without a value is empty. Lines end in CRLF, and a cell holding a comma, a quote or a line break is quoted.

A cell that begins with =, +, -, @, a tab or a carriage return and is not a number is prefixed with an apostrophe, because a participant can be entered under a name that a spreadsheet opening the file would otherwise evaluate as a formula.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The CSV, as an attachment named results.csv.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, nor a director
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/results' \
  -H 'Authorization: Bearer key_...'
200
"string"

The umpire panels scoring the tournament's matches now

GET/v1/tournaments/{tournamentId}/panelsWymaga uwierzytelnienia

One entry per live scoring session: which match is being scored, from which court, by whom, since when, and when the last command arrived. Control draws each beside the match's own state from the snapshot, so a director or referee sees every panel in the hall without walking to it. A released or superseded session is not in use and is not listed.

Ordered as the courts are, by sort_order then name, with a match on no court last. For an administrator of the organization, or a director or referee of the tournament; a court or display device reads its own match, not this.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The panels in use.
  • 401No credential.
  • 403insufficient_scope: not an administrator of the organization, nor a director
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/panels' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "panels": [
      {
        "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "scoring_session_epoch": 0,
        "held_by": "court_session",
        "holder_label": "string",
        "claimed_at": "2026-09-27T10:30:00Z",
        "last_command_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Put a match on a court and in a slot, or take it off

PATCH/v1/matches/{matchId}/assignmentWymaga uwierzytelnienia

Moves the match's schedule entry: its court, its scheduled start, its sequence among the matches on that court and the earliest it may start. The entry's revision moves and match_assignment_changed is announced on the schedule_entry aggregate; match_revision never moves, because that revision counts accepted scoring commands and the undo replay checks the event history against it. A court device learns of a reassignment from the feed, not from a match revision it would otherwise take for a scored command it missed.

The body is the whole assignment, not a set of changed fields: court_id absent or null takes the match off its court, and an absent scheduled_start, not_before or sequence clears it. The court must belong to the match's tournament. For a director of that tournament or an administrator of the organization; a match in a tournament outside the principal's scope is not found, never forbidden.

Parametry

  • matchIdścieżka · string (uuid)wymagany

Treść żądania

  • court_idstring | null (uuid)

    A court of the match's tournament, or null to take the match off its court.

  • scheduled_startstring | null (date-time)

  • sequenceinteger

    The match's place among those queued on the court, from 0.

  • not_beforestring | null (date-time)

    The earliest the match may start, as an instant, or null for none.

Odpowiedzi

  • 200The assignment as written.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such match in the principal's organization, or one in a tournament outside
  • 422validation_failed: a court_id that is not a UUID or not a court of this
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/matches/{matchId}/assignment' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "scheduled_start": "2026-09-27T10:30:00Z",
  "sequence": 0,
  "not_before": "2026-09-27T10:30:00Z"
}'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "scheduled_start": "2026-09-27T10:30:00Z",
    "not_before": "2026-09-27T10:30:00Z",
    "sequence": 0
  }
}

Move a match in the schedule by the parts named

PATCH/v1/matches/{matchId}/scheduleWymaga uwierzytelnienia

Changes the parts of the match's schedule entry the body names, and keeps the rest: court_id, scheduled_start and not_before are cleared by an explicit null, and a part left out is not touched. That is the difference from the assignment, which takes the whole placement and clears what it leaves out: the change is applied to the placement as it stands under the match's row lock, so two directors moving different parts at once both land.

A change moves the entry's revision and announces match_assignment_changed on the schedule_entry aggregate, as an assignment does; one that leaves the placement as it was writes and announces nothing. match_revision never moves. For a director of the match's tournament or an administrator of the organization; a match in a tournament outside the principal's scope is not found, never forbidden.

Parametry

  • matchIdścieżka · string (uuid)wymagany

Treść żądania

  • court_idstring | null (uuid)

    A court of the match's tournament, or null to take the match off its court.

  • scheduled_startstring | null (date-time)

    The start as an instant, or null to clear it.

  • sequenceinteger

    The match's place among those queued on the court, from 0.

  • not_beforestring | null (date-time)

    The earliest the match may start however its court's queue runs, as an instant, or null to clear it. Stored and announced as the start is.

Odpowiedzi

  • 200The placement as it now stands, every part of it.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such match in the principal's organization, or one in a tournament outside
  • 422validation_failed: a court_id that is not a UUID or not a court of this
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/matches/{matchId}/schedule' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "scheduled_start": "2026-09-27T10:30:00Z",
  "sequence": 0,
  "not_before": "2026-09-27T10:30:00Z"
}'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "scheduled_start": "2026-09-27T10:30:00Z",
    "not_before": "2026-09-27T10:30:00Z",
    "sequence": 0
  }
}

Move many of the tournament's matches in the schedule at once

PATCH/v1/tournaments/{tournamentId}/scheduleWymaga uwierzytelnienia

Each change moves one match of the tournament by the parts it names, exactly as PATCH /v1/matches/{matchId}/schedule moves one: a part left out is kept, and court_id, scheduled_start and not_before are cleared by an explicit null. What Control sends when the desk fills its courts from a start time.

One transaction: every match is locked before anything is written, and a change given wrong, or a match that is not the tournament's, leaves every placement as it was. Each change that moves its placement moves that match's schedule entry and announces match_assignment_changed on its schedule_entry aggregate; one that leaves it as it was writes and announces nothing. match_revision never moves. For a director of the tournament or an administrator of the organization.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

Treść żądania

  • changesobject[]wymagany

    One change per match; a match may be named once.

    Pola

Odpowiedzi

  • 200Each match's placement as it now stands, every part of it, in the order of the changes.
  • 401No credential.
  • 403insufficient_scope: the caller is not a director of this tournament or an
  • 404No such tournament in the principal's organization, or one outside the principal's
  • 409tournament_closed: the tournament has been closed (DEV-25).
  • 422validation_failed: changes is not a list of 1 to 1000, or a change names no
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PATCH 'https://api.roundr.com/v1/tournaments/{tournamentId}/schedule' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "changes": [
    {
      "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "scheduled_start": "2026-09-27T10:30:00Z",
      "sequence": 0,
      "not_before": "2026-09-27T10:30:00Z"
    }
  ]
}'
200
{
  "ok": true,
  "data": {
    "placements": [
      {
        "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "scheduled_start": "2026-09-27T10:30:00Z",
        "not_before": "2026-09-27T10:30:00Z",
        "sequence": 0
      }
    ]
  }
}

Matches

The authoritative state of a match

GET/v1/matches/{matchId}Wymaga uwierzytelnienia

The canonical read every client recovers through: the pinned ruleset and engine version, the scoring epoch, and the projection with its revision. A client that does not support the engine version may display the state but cannot score predictively. Visible to principals of the match's organization; a court device sees only the match on its court, a display only a match its projection shows, as its feed does, and anything else is not found.

Parametry

  • matchIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The match.
  • 401No credential.
  • 403insufficient_scope: a machine key that was not issued tournaments:read. It is
  • 404No such match in the principal's organization, or not on this device's court.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/matches/{matchId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "ruleset": {
      "id": "string",
      "version": "string",
      "engine_version": "string"
    },
    "participants": {
      "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
      "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
    },
    "external_ref": "string",
    "scheduled_start": "2026-09-27T10:30:00Z",
    "sequence": 0,
    "not_before": "2026-09-27T10:30:00Z",
    "started_at": "2026-09-27T10:30:00Z",
    "ended_at": "2026-09-27T10:30:00Z",
    "confirmed_at": "2026-09-27T10:30:00Z",
    "officials": null,
    "draw": null,
    "scoring_session_epoch": 0,
    "state": {
      "revision": 0,
      "status": "scheduled",
      "data": {}
    }
  }
}

The canonical events of a match since a revision

GET/v1/matches/{matchId}/eventsWymaga uwierzytelnienia

The event feed a reconciling client lays its retained local tail beside. Every event with a revision above after_revision, in revision then index order, each with the command that produced it, so a device that scored while disconnected can see where its own history and the server's part. Omitting after_revision returns everything the match has produced. revision is the match's current one, so an empty feed says the match has not moved rather than that nothing was read.

Visible to the same principals as the match itself, a display excepted, and read-only: a client never replaces canonical state from it, it reconciles against it and recovers through GET /v1/matches/{matchId}. A display shows a match's state and reconciles nothing, and the history names every command's device and timing, so it is refused even a match it may read.

Parametry

  • matchIdścieżka · string (uuid)wymagany

  • after_revisionzapytanie · integer

    The revision the client scored from. Events up to and including it are the client's own.

Odpowiedzi

  • 200The events after the revision, possibly none.
  • 401No credential.
  • 403insufficient_scope: a display credential, which reads a match's state and not
  • 404No such match in the principal's organization, or not on this device's court.
  • 422validation_failed: after_revision is not a whole number of zero or more.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/matches/{matchId}/events' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "after_revision": 0,
    "revision": 0,
    "events": [
      {
        "revision": 0,
        "index": 0,
        "type": "string",
        "payload": {},
        "command_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "client_timing": {},
        "actor": null,
        "recorded_at": "2026-09-27T10:30:00Z"
      }
    ]
  }
}

Submit one match command

POST/v1/matches/{matchId}/commandsWymaga uwierzytelnienia

The one endpoint every match-changing command goes through. command_id is the idempotency key and is looked up before anything about the match's revision is compared, so a retry after a lost response replays its stored outcome rather than colliding with a revision that has since moved. The same id with a different command is 409 idempotency_key_reused; Idempotency-Key, when sent, equals command_id.

A scoring command needs the caller to hold the match's live scoring session and to carry its epoch; a device fenced by a takeover gets 409 scoring_session_superseded, a stale expected_revision gets 409 revision_conflict, and a command the rules refuse gets 422 invalid_command_for_state. Each of those is a durable outcome, recorded and replayed for the same id, and each carries the current revision and epoch in details. correct_score and reopen_result need no session, only a referee or director. undo_command reverses the latest command still standing, one step at a time as far back as the umpire presses, over every command the umpire enters; never the confirmation, the two repairs or an undo, and never after confirmation. It names that command's command_id as payload.target_command_id, a UUID, or is 422 validation_failed on that field; its CommandUndone event names the target by the same UUID.

record_score_sheet is the result of a match nobody umpired, entered at the desk from the players' paper score sheet (ScoreSheetPayload): the games in order and nothing else. A referee or director sends it, holding the session like any scoring command, and only while the match is scheduled. It is refused with 422 invalid_command_for_state unless every game ends at exactly its score under the match's ruleset and the last game decides the match. The engine derives the winner: the batch is ScoreSheetRecorded, carrying each game with the side that won it, and the MatchEnded a played match ends with, so the result then waits for confirm_result like any other.

record_game is the same result a game at a time, for a match still being played with no umpire (GamePayload): the game in play and its final score, sent as each game ends. A referee or director sends it, holding the session, while the match is scheduled or in_progress. It is refused with 422 invalid_command_for_state for a game other than the one in play, a score no game ends at under the match's ruleset, or one below the points already played in that game. The batch opens with GameRecorded, carrying the side that won the game; the first one also carries MatchStarted, and the one that decides the match the MatchEnded a played match ends with. Each is one command, so the latest is taken back with undo_command.

An accepted command advances the revision exactly once; the response carries the event batch it produced and the state after it.

Parametry

  • matchIdścieżka · string (uuid)wymagany

  • Idempotency-Keynagłówek · string (uuid)

Treść żądania

  • command_idstring (uuid)wymagany

    Client-generated UUIDv7; the idempotency key.

  • client_instance_idstringwymagany

    The installation's stable identifier, kept across reauthentication.

  • expected_revisioninteger | null

    The revision the client scored from. Required for a scoring command; null only for correct_score and reopen_result.

  • scoring_session_epochintegerwymagany

  • typestringwymagany

    A MatchCommandType value.

  • payloadobject

    The command's own fields; for record_score_sheet, a ScoreSheetPayload, and for record_game, a GamePayload.

  • client_timingobject | null

    When the device says the command happened, for the scoresheet and its statistics: authored_at, and for a rally the press that started it and, for a rally entered again after an undo, when it originally ended; for a command that settles a hold, when play was held. Stored with the receipt in UTC with milliseconds and returned with the command's events. Never read by the rules and not part of the fingerprint, so a retry stamped again is still the same command.

    Pola

Odpowiedzi

  • 200Accepted, now or on an earlier delivery of the same command.
  • 401No credential.
  • 403insufficient_scope: the command is outside the principal's authority, or the
  • 404No such match in the principal's organization, or not on this device's court.
  • 409revision_conflict, scoring_session_superseded or idempotency_key_reused.
  • 422validation_failed for a malformed envelope, or invalid_command_for_state for
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/matches/{matchId}/commands' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "command_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
  "client_instance_id": "string",
  "expected_revision": 0,
  "scoring_session_epoch": 0,
  "type": "string",
  "payload": {},
  "client_timing": {
    "authored_at": "2026-09-27T10:30:00Z",
    "rally_started_at": "2026-09-27T10:30:00Z",
    "rally_ended_at": "2026-09-27T10:30:00Z",
    "held_from": "2026-09-27T10:30:00Z"
  }
}'
200
{
  "ok": true,
  "data": {
    "command_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "outcome": "accepted",
    "replayed": true,
    "revision": 0,
    "events": [
      {
        "type": "string",
        "payload": {},
        "index": 0
      }
    ],
    "state": {
      "revision": 0,
      "status": "scheduled",
      "data": {}
    },
    "scoring_session_epoch": 0
  }
}

Claim a match's scoring session, or take it over

POST/v1/matches/{matchId}/scoring-sessionWymaga uwierzytelnienia

A court device claims the match assigned to its court, which opens the one live scoring session under the next epoch; claiming again from the same device returns it unchanged. A device cannot take a match another device holds. A referee or tournament director takes the session over, which fences the former holder: its queued commands are refused as superseded and kept for reconciliation. Every scoring command then carries the epoch returned here.

Parametry

  • matchIdścieżka · string (uuid)wymagany

Treść żądania

  • client_instance_idstring

    The installation claiming, for the audit trail.

Odpowiedzi

  • 200The live session.
  • 401No credential.
  • 403Neither the court's own device nor a referee or director of the tournament.
  • 404No such match in the principal's organization, or not on this device's court.
  • 409scoring_session_held: another device holds the match. tournament_closed: the
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X POST 'https://api.roundr.com/v1/matches/{matchId}/scoring-session' \
  -H 'Authorization: Bearer key_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_instance_id": "string"
}'
200
{
  "ok": true,
  "data": {
    "scoring_session_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "scoring_session_epoch": 0,
    "held_by": "court_session"
  }
}

Release a match's scoring session so the court's device can claim it

DELETE/v1/matches/{matchId}/scoring-sessionWymaga uwierzytelnienia

A referee or tournament director ends the live scoring session without opening another, for a holder that will never score again, such as a tablet that rejoined its court under a new credential while its old one still held the match. The match moves to the next epoch with nobody holding it, so the former holder is fenced at once, exactly as by a takeover: its queued commands are refused as superseded and kept for reconciliation. The court's device then claims the match under a new epoch. Releasing a match nobody holds changes nothing and answers released: false, so a repeated request does not move the epoch again.

Parametry

  • matchIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The match's scoring session is released, or nobody held it.
  • 401No credential.
  • 403Not a referee or director of the tournament.
  • 404No such match in the principal's organization, or not on this device's court.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/matches/{matchId}/scoring-session' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "released": true,
    "scoring_session_epoch": 0
  }
}

The matches a court's tablet may take

GET/v1/tournaments/{tournamentId}/courts/{courtId}/open-matchesWymaga uwierzytelnienia

For a court's tablet whose umpire chooses the match (DEV-58), on a match day with no desk putting matches on courts: the tournament's matches that wait for a court, each nothing has been played in, on no court and with both sides known, and the names of their sides. choosing is the Referee's briefing (court_chooses_match); with it off, or the tournament closed, the list is empty, so a tablet learns from this one read whether to offer a list at all.

The court's own device alone: a court session reads it for the court and the tournament it is bound to. No notification says that a waiting match was taken by another court, so a tablet showing the list reads it again while it does.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • courtIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The matches that wait for a court.
  • 401No credential.
  • 403Not a court's device. Staff place a match through the schedule.
  • 404No such court of that tournament for this device: a court session is bound to one
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts/{courtId}/open-matches' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "choosing": true,
    "matches": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "tournament_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "ruleset": {
          "id": "string",
          "version": "string",
          "engine_version": "string"
        },
        "participants": {
          "home": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
          "away": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
        },
        "external_ref": "string",
        "scheduled_start": "2026-09-27T10:30:00Z",
        "sequence": 0,
        "not_before": "2026-09-27T10:30:00Z",
        "started_at": "2026-09-27T10:30:00Z",
        "ended_at": "2026-09-27T10:30:00Z",
        "confirmed_at": "2026-09-27T10:30:00Z",
        "officials": null,
        "draw": null,
        "scoring_session_epoch": 0,
        "state": {
          "revision": 0,
          "status": "scheduled",
          "data": {}
        }
      }
    ],
    "participants": [
      {
        "id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
        "kind": "single",
        "display_name": "string",
        "external_ref": "string",
        "players": [
          {
            "full_name": "string",
            "given_name": "string",
            "family_name": "string",
            "family_name_first": true,
            "position": 1,
            "nationality": "string"
          }
        ]
      }
    ]
  }
}

Take a waiting match to the court

PUT/v1/tournaments/{tournamentId}/courts/{courtId}/matches/{matchId}Wymaga uwierzytelnienia

The court's tablet takes one of the matches open-matches lists (DEV-58). The match keeps its start and its place in the schedule and gains the court, announced as match_assignment_changed like any assignment, so from here it is a match on the court as one the desk placed is: the tablet claims it and scores it. Decided under the match's row lock: of two courts taking one match, the second is answered 404, and reads the list again. Taking a match already on this court changes nothing, so a request sent again after a lost answer is safe.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • courtIdścieżka · string (uuid)wymagany

  • matchIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The match is on the court.
  • 401No credential.
  • 403Not a court's device, or a tournament whose briefing gives its courts their
  • 404No such court for this device, or no such match waiting for a court: not the
  • 409tournament_closed: the tournament is closed (DEV-25).
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X PUT 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts/{courtId}/matches/{matchId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  }
}

Give a match on the court back before it starts

DELETE/v1/tournaments/{tournamentId}/courts/{courtId}/matches/{matchId}Wymaga uwierzytelnienia

For a match chosen by mistake: the court's tablet gives back a match on its court that nothing has been played in, which waits for a court again. The tablet's claim on it is released with the move, as when the desk moves a match. A match that has begun stays on its court and is the desk's to move. Giving back a match that waits already changes nothing.

Parametry

  • tournamentIdścieżka · string (uuid)wymagany

  • courtIdścieżka · string (uuid)wymagany

  • matchIdścieżka · string (uuid)wymagany

Odpowiedzi

  • 200The match waits for a court.
  • 401No credential.
  • 403Not a court's device, or a tournament whose briefing gives its courts their
  • 404No such court for this device, or no such match on it.
  • 409tournament_closed: the tournament is closed (DEV-25).
  • 422validation_failed on match_id: play has begun in the match.
  • 429rate_limited: the signed-in user, device or machine key has spent its budget
Przykład
curl -X DELETE 'https://api.roundr.com/v1/tournaments/{tournamentId}/courts/{courtId}/matches/{matchId}' \
  -H 'Authorization: Bearer key_...'
200
{
  "ok": true,
  "data": {
    "match_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f",
    "court_id": "0192f3a4-7b1c-7d2e-9f40-5a6b7c8d9e0f"
  }
}