---
title: "Check a team in for a tournament"
method: POST
path: "/tournaments/{identifier}/participants/{participantId}/check-in"
tags: ["Tournament Entry"]
---

# Check a team in for a tournament

`POST /tournaments/{identifier}/participants/{participantId}/check-in`

Confirms that a team you lead is present for a tournament that is about to start. The participant must be APPROVED; a PENDING application or a withdrawn, removed, or disqualified row answers 400 error_invalid_input.

SAFE TO RETRY. This endpoint is idempotent by effect: calling it again re-stamps the check-in timestamp and answers 200. There is no 'already checked in' conflict response, so a retry after a dropped connection is always safe. The consequence is that checkedInAt is the time of your LAST successful call, not your first - read it back from GET /tournaments/{identifier}/me rather than assuming it is stable.

The check-in window opens checkInOpensMinutesBefore minutes ahead of startsAt; outside it the request answers 400 error_check_in_closed. When the tournament has checkInRequired set to false there is no window and the call simply succeeds, so an integration can call this unconditionally without first branching on the flag.

Authority comes from the participant: you must be the captain, co-captain, or organization owner of the team it belongs to. A participantId from a different tournament answers 404 error_tournament_not_found. Requires the tournaments actor check_in capability - a narrower grant than entry, and deliberately not covered by it.

## Path parameters

- `identifier` string, required — Tournament slug.
- `participantId` string, required — Tournament participant ID.

## Response `200`

The team is checked in.

- TournamentWriteAck — Acknowledgement returned by the tournament write endpoints whose backing operation has nothing to return - the organizer writes (endpoints 22-34), the team roster writes (40, 41), and the competitor self actions that neither mint nor resolve a row (38, 39, 44, 45, 47). Endpoints that mint a row answer with that row's id instead, and the two respond endpoints (42, 46) answer with the decision they recorded.
  - `success` true, required — Always true; failures are error responses.
  - `timestamp` string, required — Response generation time (ISO 8601).

## Other responses

- `400` — Bad request (invalid body, cursor, limit, or date).
- `401` — Missing or invalid API key.
- `403` — API key lacks the required permission.
- `404` — Resource not found.
- `429` — Rate limited.
- `500` — Internal server error.

---

[API](https://skmtc.net/teambattles/apis/teambattles-api.md) · [All operations](https://skmtc.net/teambattles/apis/teambattles-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/teambattles/teambattles-api/revisions/2ffe8fb53b7d/schema)
