TANITARDevelopers
GuidesTournaments

Enrollment and check-in

Teams and rosters, enrollments and the waitlist, check-in and its close, free-agent requests, and marking a match ready.

Your integration enrolls players (or teams), confirms them, checks them in and marks them ready for their matches. Every route on this page needs tournaments:mutate, except match readiness, which acts for an entrant and needs participants:mutate. All of them require an Idempotency-Key.

Entrant identity

Wherever a route takes an identity (or a team owner), it is an object:

FieldMeaning
modesaas for a player known to Tanitar, opaque for a player you identify yourself. Must be one of the tournament's identityModes.
principalIdThe Tanitar player id, for saas.
externalIdYour stable identifier, for opaque (up to 128 characters).
displayNameOptional, up to 120 characters.
seed, metadataOptional.

Teams

Team tournaments enroll teams. A team belongs to an organization and has an owner and members.

RouteWhat it does
POST /teamsCreates a team: organizationId, name, slug (lowercase, hyphens), owner identity.
GET /teams/:teamIdReads a team (tournaments:read).
PATCH /teams/:teamIdChanges name or slug.
POST /teams/:teamId/membersAdds a member: identity. The same identity cannot be added twice (TEAM_MEMBER_DUPLICATE).
DELETE /teams/:teamIdArchives the team. Refused with TEAM_HAS_ACTIVE_ENROLLMENTS while it has a pending, confirmed or waitlisted enrollment.

There is no route that lists teams; keep the teamId you get back from POST /teams.

Enroll

POST /enrollments enrolls one entrant in a published tournament while its registration window is open.

FieldMeaning
tournamentIdThe tournament.
entrantTypesolo or team; must match the tournament's participantMode.
identityThe player, for solo.
teamIdThe team, for team. It must belong to the tournament's organization and have between capacity.teamSize and teamSize + maxSubstitutes members.
attributesOptional string map, checked against the tournament's eligibility rules.
curl -X POST "$TOURNAMENT_API_URL/enrollments" \
  -H "Authorization: Bearer $TANITAR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"tournamentId":"trn_0190f1c2-7a3b-7c4d-8e5f-6a7b8c9d0e1f","entrantType":"solo","identity":{"mode":"opaque","externalId":"player-8812","displayName":"Nova"},"attributes":{"country":"FR"}}'

Eligibility

A tournament's eligibility object can restrict who enrolls:

  • whitelistOnly with a whitelist of identities;
  • allowedCountries, matched against the enrollment's attributes.country;
  • requirements, a list of attribute names that must be present.

An enrollment that fails a rule is refused with 422 ENROLLMENT_INELIGIBLE.

Enrollment states

StateMeaning
pendingEnrolled, not yet confirmed.
confirmedCounts toward the tournament and is seeded into stages.
waitlistedThe tournament was full and the waitlist had room; carries a waitlistPosition.
withdrawnWithdrawn by you.
no_showDid not check in before check-in closed.
rejectedRefused.
RouteWhat it does
POST /enrollments/:enrollmentId/confirmpending to confirmed.
POST /enrollments/:enrollmentId/withdrawpending or confirmed to withdrawn.
DELETE /enrollments/:enrollmentIdSame as withdraw.
PATCH /enrollments/:enrollmentIdReplaces attributes.
GET /tournaments/:slug/entrantsLists the tournament's entrants with their status, seed and check-in state (tournaments:read; cursor, limit).

The waitlist

When a tournament with waitlist.enabled and a waitlist.maxSize is full, a new enrollment is waitlisted instead of refused. Without a waitlist, or once the waitlist is also full, the request is refused with 409 TOURNAMENT_CAPACITY_FULL (TOURNAMENT_TEAM_CAPACITY_FULL when a team tournament has reached maxTeams).

Promotion is automatic. There is no promote call:

  • when an active enrollment is withdrawn while registration is still open, the first waitlisted entrant becomes pending;
  • when check-in closes, waitlisted entrants fill the places left by no-shows, in waitlist order, with their check-in waived.

Each promotion publishes tournament.enrollment.promoted.

Team rosters

A team enrollment copies the team's members into a roster. The owner's place is accepted; every other member's invitation is pending until you record their answer while registration is open:

  • POST /enrollments/:enrollmentId/roster/:rosterMemberId/accept
  • POST /enrollments/:enrollmentId/roster/:rosterMemberId/reject

Answering an invitation that is not pending is refused with ENROLLMENT_STATE_INVALID. The roster locks once every member has accepted.

Check-in

When the tournament has checkIn.enabled, each entrant checks in during the check-in window with POST /enrollments/:enrollmentId/check-in. Checking in confirms a pending enrollment. Outside the window the call is refused with TOURNAMENT_CHECK_IN_CLOSED. Reminders are published as tournament.enrollment.check-in-reminder-requested at each lifecyclePolicy.checkInReminderOffsetsMinutes before check-in closes, so you can notify your players.

Close check-in

Check-in closes on its own at checkIn.closesAt. To close it earlier, call POST /tournaments/:slug/check-in/close; it answers with the tournament. Closing check-in:

  1. marks every pending or confirmed entrant that has not checked in as no_show;
  2. promotes waitlisted entrants into the freed places, in order;
  3. records that check-in close was processed: the tournament can now start, and registration can no longer be reopened.

Free agents

In a published team tournament, a player without a team can ask to be picked up.

RouteWhat it does
POST /free-agent-requestsCreates a request: tournamentId, identity. One per identity per tournament (FREE_AGENT_DUPLICATE).
DELETE /free-agent-requests/:requestIdWithdraws a pending request.

Requests publish tournament.free-agent.requested and tournament.free-agent.withdrawn, which your own matchmaking can consume.

Match readiness

Once the tournament is in_progress, each entrant in a ready match signals that they are present with POST /matches/:matchId/ready (participants:mutate):

FieldMeaning
enrollmentIdThe entrant that is ready. It must occupy a slot in the match.
expectedRevisionThe match's current readiness revision (0 before anyone is ready).

Marking an entrant ready twice is harmless. When every occupant is ready the match becomes playing. A stale expectedRevision is refused with 409 MATCH_READINESS_STALE.

If the tournament sets lifecyclePolicy.matchForfeitTimeoutMinutes, a forfeit deadline starts when the match becomes ready. See Forfeits.

You can also start a ready match yourself, without waiting for readiness, with PATCH /matches/:matchId and "status": "playing". The same route edits label, scheduledAt, notes and liveEntries (live scores) under an expectedRevision equal to the match's revision. GET /matches/:matchId reads a match.

Errors you will see

errorCodeMeaning
TOURNAMENT_REGISTRATION_CLOSEDThe tournament is not published or the registration window is not open.
ENROLLMENT_ENTRANT_TYPE_INVALIDentrantType does not match the tournament.
ENROLLMENT_IDENTITY_INVALIDMissing identity, or a mode the tournament does not accept.
ENROLLMENT_DUPLICATEThat entrant is already enrolled.
TEAM_ROSTER_INVALIDThe team size does not fit the tournament.
ENROLLMENT_STATE_INVALIDThe transition is not allowed from the current state.
ENROLLMENT_CONCURRENT_MODIFICATIONAnother write won; read again and retry.
MATCH_NOT_READYThe tournament is not in progress or the match is not ready.
MATCH_OCCUPANT_REQUIREDThe enrollment does not occupy the match.

On this page