Skip to main content

Ranked matchmaking API

Ranked matchmaking pairs eligible players and creates a live match after both accept a proposal. The API supplies queue state, seasonal ratings, standings, and each participant's settlement. Clients cannot select an opponent, rating, season, or result.

See Ranked competition for eligibility, search ranges, cooldowns, rating calculations, and season rules. Live PvP covers the battle connection after matching; Territories covers optional zone claims and influence feedback.

Access and queue routes​

All routes require bearer authentication and an active player account. Successful responses return the objects described below directly. Errors use the shared API format.

Routes below begin with /api/v1 and return 200 on success.

MethodRouteRequest and result
POST/ranked/queueSend { deckId } to join; returns your queue state. Optional territoryClaim is described in the territory contract.
GET/ranked/queueRead your queue state without renewing its lease.
POST/ranked/queue/heartbeatRenew an unexpired searching lease; no body is required.
DELETE/ranked/queueLeave searching or decline your pending proposal; returns the resolved queue state.
POST/ranked/proposals/:proposalId/acceptAccept your proposal; no body is required.
POST/ranked/proposals/:proposalId/declineDecline your proposal; no body is required.

Joining uses the gameplay quota; other ranked requests use the general request quota. A deck ID must identify the caller's valid saved deck. Extra join-body fields are rejected.

Queue state and deadlines​

FieldsMeaning
statusidle, searching, proposed, matched, cancelled, expired, restricted, or invalid_deck.
queueEntryId, seasonId, joinedAtQueue identity, season, and original join time.
leaseExpiresAt, searchRangeSearching lease deadline and current rating range.
proposalId, acceptanceDeadline, acceptedPending proposal, its deadline, and whether you have accepted.
matchIdThe committed live match ID after matching.

Unavailable values are null. Proposals hide the opponent's name, deck, and rating. A proposed pair is not yet a match.

While searching, heartbeat at least every 10 seconds to maintain the 30-second lease. GET requests do not extend it, and a heartbeat cannot revive an expired entry. Stop heartbeats when leaving search or receiving a proposal.

A proposal gives both players 20 seconds to accept. Acceptance does not extend the deadline. If only 1 player accepts, no match starts. Decline or expiry can return an eligible accepting player to searching with their original join time; the other player may enter the policy's cooldown. Render the returned state rather than assuming a proposal always ends in a match.

Once status is matched, open matchId through the live API. Cancelling a queue does not cancel a match that has already committed. Use live resignation when conceding an active battle.

Rating and season reads​

RouteReturned object
GET /api/v1/ranked/meseason, rating, wins, losses, settledMatchCount, placementMatchesRemaining, and provisional.
GET /api/v1/ranked/matches/:matchId/settlementYour match outcome, rating change, and optional territory result.
GET /api/v1/ranked/seasons/current{ season }; null when no season is active or closing.
GET /api/v1/ranked/standingsCurrent-season { season, entries, nextCursor }.
GET /api/v1/ranked/seasons/:seasonId/standingsClosed-season { season, entries, nextCursor }.

Season objects include seasonId, name, status, policyVersion, activatedAt, activeEndsAt, and closedAt. A closing season can still be read, while new queue entries require an active season. Profile rating can be null when no seasonal rating exists.

Settlement includes matchId, seasonId, status: pending|settled, completionReason, outcome, ratingBefore, ratingAfter, appliedDelta, settledAt, and territory. Fields awaiting settlement can be null. A missing match and another player's settlement return a neutral 404 RANKED_MATCH_UNAVAILABLE. Read territory using the contribution contract.

Only ranked live matches have ranked settlement. A completed battle is not permission to calculate or write a rating locally; completion and settlement commit together on the server.

Standings pagination and privacy​

Use limit from 1–100 (default 25) and the returned opaque cursor. Entries contain playerName, rank, rating, wins, losses, and settledMatchCount. nextCursor: null marks the end.

Current standings hold competitive values stable for a 10-minute traversal. An invalid, foreign, or expired cursor returns 400 RANKED_CURSOR_INVALID; restart from the first page. Names resolve from current account records on each page, and unavailable accounts are omitted. Closed-season competitive values are fixed, while display names can change and personal entries can be removed by account deletion.

Provisional ratings remain private until the player has completed the required placements. Standings do not expose private queue candidates or decks.

Conflicts and recovery​

Ranked commands use the queue or proposal identity rather than a caller-supplied submission UUID. Rejoining the same active selection returns the existing entry; changing the deck or territory selection conflicts. Repeating acceptance for a matched proposal returns its committed match ID.

After a timeout or lost response, read /ranked/queue before deciding what to submit next. A cancellation racing with proposal resolution returns the resolved state; it cannot undo an already created match.

ResponseCaller action
409 RANKED_STATE_CONFLICTRead queue state before changing the selection.
409 RANKED_DECK_INVALIDChoose a valid saved deck.
409 RANKED_COOLDOWNWait before rejoining; follow the competition policy.
409 RANKED_ALREADY_PLAYINGReturn to the existing active battle.
409 RANKED_UNAVAILABLERefresh season availability before joining.
403 RANKED_RESTRICTEDShow the safe access message; repeated joining cannot bypass the restriction.
404 RANKED_PROPOSAL_UNAVAILABLERefresh queue state rather than acting on the old proposal.
503 GAMEPLAY_COORDINATION_UNAVAILABLEKeep current state, use a bounded retry delay, and refresh before continuing.

Temporary service failures do not extend leases or proposal deadlines.

AI declaration​

Rewritten with assistance from Codex[GPT-6], using ranked route schemas, queue handling, and read projections. Earlier versions also used Codex[GPT-5] and Codex-CLI[GPT-5].