Skip to content

Integration Flow

This is the whole happy path. Your backend submits a ticket, IVK Match forms a match and pushes it to you, you provision a server and tell the player where to go.

One rule underpins all of it: IVK Match never talks to your players, and your players never talk to IVK Match. Your backend is always in the middle. That keeps authentication, anti-cheat, skill lookup, and rate limiting where they already live.

The diagrams name operations by their gRPC name (CreateTicket, CancelTicket, and so on). Each is equally available as an HTTP/JSON call and the flows are identical either way; see Matchmaking API § Two transports, one API.

sequenceDiagram
    autonumber
    actor P as Player
    participant GB as Your Backend
    participant IM as IVK Match
    participant OR as Orchestrator
    participant GS as Game Server

    P->>GB: queue_matchmaking(playlist, party)
    Note over GB: Look up MMR, measure/read latencies,<br/>resolve platform + crossplay prefs
    GB->>GB: ticket_id = uuid4()
    GB->>IM: CreateTicket(ticket_id, queue_id, ruleset_ids,<br/>engine_input, metadata)
    IM-->>GB: ticket_id (ack, ticket is in the pool)
    GB-->>P: queued (ticket_id)

    Note over IM: Every tick (default 1s) the engine improves<br/>the matches it is assembling from the pool

    IM->>IM: match formed, tickets leave the pool
    IM->>GB: outcome: match.created<br/>{ match_id, tickets[metadata], engine_output }
    Note over GB: Decode engine_output →<br/>teams + host.preferred

    GB->>OR: CreateGameServer(host=preferred, match_id, players)
    OR->>GS: start
    GS-->>OR: ready (address, port)
    OR-->>GB: server { address, port }

    GB->>GB: persist session(match_id → server, players)
    GB-->>P: game_found { match_id, address, port, team }
    P->>GS: connect

Step 2: enrich before you submit. IVK Match knows nothing about your players. Everything the engine needs goes in engine_input: player IDs, MMR, per-host latencies, and the attributes your queue’s attr_filter names. Everything you want back goes in metadata.

Step 4: you own the ticket ID. Generate a UUID before calling. If the call times out, retry with the same ID; it cannot create a duplicate.

Step 5: the ack is not a match. CreateTicket returns when the ticket is durably pooled. Show the player a queue state, not a match.

Step 8: the outcome is the match. By the time match.created reaches you, those tickets have already left the pool. That is a commitment: those players are no longer matchmaking. If you cannot honour it, you have to compensate actively. See When provisioning fails.

Step 9: host.preferred drives placement. The latency map keys you supplied in engine_input come back as engine_output.host.preferred, with every mutually-acceptable alternative in host.acceptable. If those keys are your provisioning layer’s own region or pool identifiers, this step is a direct pass-through with no translation layer.

Step 10: provisioning is yours. The orchestrator API, its authentication, and its retry policy all stay on your side.

Step 13: correlate via match_id. Match.id is a UUID and the natural session key. It is also the value a game server will later need for backfill requests.

PhaseTypicalDriven by
CreateTicket round tripsingle-digit msNetwork
Waiting in queueseconds to minutesPopulation, wait_time, ruleset strictness
Match formed → outcome deliveredtens of msSink; webhook adds one HTTP round trip
Server provisioningsecondsOrchestrator; usually the dominant term after queue wait
Notify playermsYour own push channel

Queue wait and server provisioning dominate. At tick_rate_secs: 1 the engine contributes at most one second of scheduling latency.

Each of these needs handling before you ship:

CaseGuide
The player backs out, and races a match being formedCancel a search
A match is real but no server can be hadWhen provisioning fails
Nobody was found, or the queue changed under a playerTimeouts and removals
A running match has open slotsBackfill

Every state a ticket can be in is in the ticket lifecycle reference. When you are ready to ship, work through the production checklist.