---
title: "Join a match by name (or by an existing personal token)"
method: POST
path: "/api/v1/matches/{code}/join"
tags: ["matches"]
---

# Join a match by name (or by an existing personal token)

`POST /api/v1/matches/{code}/join`

## Request

- Base URL: `https://kicksma.sh`
- URL: `https://kicksma.sh/api/v1/matches/{code}/join`
- Auth: one of:
  - none
  - HTTP bearer

Outcomes: joined, waitlisted, already_in, full, or requested when the player's level is outside the match's range, or declared but unconfirmed on a match that takes confirmed levels only (the organizer approves on the match page; a coach's or the club's confirmation seats the player). A player who already played a finished, scored match with the organizer is never held by that organizer's range. A place the organizer holds for the same name ("Danny") refuses the join with 409 name_held, and nothing is written: if it is that person, they take the place on the match page; if not, they join with a fuller name, such as a last name. A name given without a token that a player in the match (seated or waiting) already carries refuses the join with 409 name_seated, and nothing is written: if it is that player, call again with their personal token; if not, join with a fuller name.

## Path parameters

- `code` string, required

## Request body

- JoinMatch
  - `code` string, required: The 4-character match code from the link, e.g. kicksma.sh/AB12 → AB12.
  - `name` string: Required unless token is given.
  - `token` string: Personal token of an existing player.
  - `email` string, email: Optional. Sends a calendar invite that updates itself.
  - `level` number: Needed once when the match has a level range and the player has no level yet.
  - `partner` string: A fixed-pairs tournament only: the partner's first name. Their spot is reserved with its own invite link (partner.inviteUrl in the answer), which the partner opens to claim it. Omit to join alone: the player is listed as needing a partner. A player already in alone may call again with a partner.

## Response `200`

Result

- JoinMatchResult
  - `outcome` 'joined' | 'waitlisted' | 'already_in' | 'full' | 'requested'
  - `match` Match: Exactly what the public match page shows. First names and levels only; never emails, phones, tokens or manage links.
    - `code` string, required
    - `url` string, required
    - `type` 'match' | 'tournament', required
    - `format` 'americano' | 'mexicano' | 'king' | 'null', nullable: Tournaments only.
    - `fixedPairs` boolean, nullable: Tournaments only: two partners play every round together instead of rotating.
    - `pairs` object[], nullable: A fixed-pairs tournament's list as pairs, in order: two first names each, or one name that needs a partner. Null otherwise.
      - `names` string[]
      - `partnerNeeded` boolean
    - `title` string, nullable
    - `status` 'open' | 'full' | 'cancelled' | 'past', required
    - `startsAt` string, date-time, required
    - `endsAt` string, date-time: startsAt plus durationMinutes.
    - `durationMinutes` 60 | 90 | 120: How long the organiser booked the court, in minutes. The calendar invitation ends here too.
    - `tz` string, required
    - `venue` object, nullable
      - `name` string
      - `slug` string, nullable
      - `mapUrl` string, nullable
      - `court` string, nullable
      - `boardUrl` string, nullable
    - `capacity` integer, required
    - `players` object[], required
      - `name` string
      - `level` number, nullable
      - `organizer` boolean
      - `status` 'joined' | 'confirmed' | 'invited'
    - `spotsLeft` integer, required
    - `waitlist` integer
    - `whenFull` 'waitlist' | 'closed'
    - `level` object, nullable
      - `min` number, nullable
      - `max` number, nullable
      - `preset` string, nullable: bronze, silver, gold, platinum or custom
      - `verifiedOnly` boolean: Only levels confirmed by an organizer, a coach or the club walk in; declared levels inside the range ask to join.
    - `category` 'men' | 'women' | 'mixed' | 'null', nullable: Who the match is for; null for anyone. Information only: nobody is checked when they join.
    - `ageMin` 35 | 45 | 55 | null, nullable: An age tag, read as 35+, 45+ or 55+; null for any age. Information only.
    - `group` object, nullable
      - `code` string
      - `name` string
      - `url` string
    - `listed` boolean
    - `bookingUrl` string, nullable
    - `courtBooked` object, nullable: A player booked the court in the club's own app and said so. Null while not booked and on a cancelled match. Kicksmash never books or takes a payment.
      - `at` string, date-time
      - `by` string, nullable: The booker's first name; null when the booker no longer holds a seat or their account is gone.
    - `cost` string, nullable: What each player pays, free text.
    - `note` string, nullable
    - `result` object, nullable
      - `sets` object[]
        - `a` integer
        - `b` integer
      - `teamA` string[]
      - `teamB` string[]
      - `winner` 'a' | 'b' | 'draw': Sets can be empty when only the winner was recorded.
      - `confirmed` boolean
    - `createdAt` string, date-time
  - `player` object
    - `name` string
    - `personalToken` string
    - `personalUrl` string
  - `partner` object, nullable: A fixed-pairs tournament joined with a partner: the partner's name and the link that claims their reserved spot. Private to whoever named them.
    - `name` string
    - `inviteUrl` string
  - `group` object, nullable: The match's group, and whether the player is a member now. A seat never makes a member of a group that asks to join: member stays false and the player asks on the group page.
    - `code` string
    - `url` string
    - `askToJoin` boolean
    - `member` boolean
  - `next` string

## Other responses

- `404`: No such match
- `409`: A place is held for this name (name_held), a player in the match has this name (name_seated), or the match is over or called off
- `422`: Invalid request; the message names the field
- `429`: Rate limited; the hint says how to get more room

---

[API](https://skmtc.dev/kicksma/apis/kicksmash-api.md) · [All operations](https://skmtc.dev/kicksma/apis/kicksmash-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kicksma/apis/kicksmash-api/revisions/8ae952aa0f19?raw)
