Match links and provisional matches
Every prop says whether it is tied to a match. A match that books list before our schedule has it gets a provisional id that stays valid forever.
Linked and pending props
Every prop row carries match_link, which is linked or pending. A linked row has a kr_match_id and match_link_reason: null. A pending row has no kr_match_id yet and explains why in match_link_reason, in plain English. A pending row is never dropped. It is returned like any other row, and it links on its own as soon as our schedule, or a second book, confirms the match. You do not need to re-request it.
{
"player_name": "nicx",
"stat_type": "CS2_KILLS_MAPS_1_2",
"team": "Marsborne",
"opponent": "Overtake Sector",
"event_time": "2026-10-02T00:00:00.000Z",
"kr_match_id": null,
"match_link": "pending",
"match_link_reason": "This match is not on our schedule yet. It links once a schedule source or a second book confirms it.",
"resolution_status": "unresolved"
}{
"player_name": "nicx",
"stat_type": "CS2_KILLS_MAPS_1_2",
"team": "Marsborne",
"opponent": "Overtake Sector",
"kr_match_id": "kr_cs2_marsborne-vs-overtake-sector-02-10-2026",
"match_link": "linked",
"match_link_reason": null
}The machine-readable codes are still in match_link_reasons and resolution_unresolved. A prop never reports resolution_status: ok without a kr_match_id.
Provisional matches
When two or more books list the same two teams at about the same time and our schedule does not have the match yet, KashRock creates a provisional match with its own kr_match_id. It is marked status_source: book, and confidence is the number of books that agree. One book alone never creates a match: its props stay pending until a schedule source or a second book confirms the match.
{
"source": "kashrock",
"match": {
"kr_match_id": "kr_cs2_alpha-vs-beta-03-10-2026",
"status": "not_started",
"status_source": "book",
"confidence": 2
}
}Ids never stop working
A provisional id is permanent. It is never deleted, and it resolves on every route that takes a match id: the match itself, boxscore, betting lines, lines history, prep, player board, tournament maps, veto, and every live route. Anything you stored keeps working.
- The schedule confirms the match. The id resolves to the official match.
- The match was wrong, and a correct match exists. The id is served as the correct match, and the response carries an
X-Match-Redirected-Fromheader with the id you asked for. A slug stays a slug and akr_id stays akr_id. - The match never happens. The route answers
200withavailable: falseandreason: provisional_retired. It is never a 404.
{
"source": "kashrock",
"kr_match_id": "kr_cs2_alpha-vs-beta-03-10-2026",
"match": null,
"available": false,
"reason": "provisional_retired",
"message": "This match was listed before our schedule confirmed it and did not go ahead as listed."
}