> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vatic.trading/llms.txt
> Use this file to discover all available pages before exploring further.

# Games and platforms

> Every game in a window, and which platforms offer markets for it.

The Game Graph answers two questions with one stable id per game:

1. **Which games are on, and where can I find markets for each?** Every game lists the platforms that offer it, including games offered by only one platform.
2. **How do I stream the order books of a game across platforms?** One call returns the identifiers and the exact subscribe messages.

All endpoints need an API key (`x-api-key` or `Authorization: Bearer`). Responses are JSON, keyset-paginated, and carry `ETag` so a repeated request can be answered with `304`.

## Every game of a weekend, with its platforms

```bash theme={null}
# Saturday and Sunday in Mexico City
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.vatic.trading/api/v1/games?day=2026-10-10&days=2&tz=America/Mexico_City&include=platforms,coverage&limit=200"
```

```json theme={null}
{
  "data": [{
    "id": "espn:401874764",
    "league": "ita.1",
    "status": "scheduled",
    "home": { "id": "soccer:espn:104", "name": "Cagliari" },
    "away": { "id": "soccer:espn:111", "name": "Juventus" },
    "time": { "kickoff_at": "2026-10-11T18:45:00.000Z", "est_end_at": "2026-10-11T20:45:00.000Z" },
    "platforms": [
      { "source": "polymarket", "confidence": "exact", "events": 9, "markets_stored": 132 },
      { "source": "predictfun", "confidence": "exact", "events": 7, "markets_stored": 76 }
    ],
    "coverage": [
      { "source": "hyperliquid", "status": "not_listed", "checked_at": "2026-10-10T16:11:39.000Z" },
      { "source": "polymarket", "status": "listed", "checked_at": "2026-10-10T16:36:50.000Z" }
    ]
  }],
  "next_cursor": null,
  "meta": { "as_of": "2026-10-10T16:50:28.076Z", "venues_checked": ["hyperliquid", "limitless", "polymarket", "predictfun"], "total": 46 }
}
```

`day` + `tz` returns a viewer-local day (daylight-saving days are 23 or 25 hours long); use `from` / `to` for an explicit UTC window.

## Reading `platforms` and `coverage` correctly

A platform that is missing from `platforms` does **not** automatically mean "not offered".

| `coverage.status` | Meaning |
| - | - |
| `listed` | We found markets for the game on that platform. |
| `not_listed` | A scan of that league and window succeeded in the last 6 hours and the game was not there. Platforms often create games only a few days ahead, so read it with `checked_at`. |
| `not_checked` | No recent successful scan covers the game (past games, a stalled scan). |

`meta.venues_checked` lists the platforms we integrate. A game offered only on a platform outside that list will not show it.

## Markets that can be compared

`GET /api/v1/games/{id}/markets` gives each market a canonical meaning:

| `canonical.key` | Outcomes |
| - | - |
| `1x2` | `home`, `draw`, `away` (each its own binary market) |
| `moneyline` | `home`, `away` |
| `total:<line>` | `over`, `under` |
| `spread:<home line>` | `home`, `away`, always from the home team's point of view |
| `btts` | `yes`, `no` |
| `null` | unclassified: listed with its order book key but never compared across platforms |

Only markets with the same `(key, period, includes_overtime)` are comparable. `includes_overtime: null` means the rules did not say.

## Stream every order book of a game

```bash theme={null}
curl -H "x-api-key: YOUR_API_KEY" "https://api.vatic.trading/api/v1/games/espn:401879264/streams"
```

For each platform the answer has the WebSocket `url`, the `refs` (token ids, coins, slugs, market ids), and the `subscribe` messages to send. Open **one socket per platform**, not one per outcome.

* Platforms with `book_semantics: yes_book_only_derive_no` publish only the YES book of a market. The NO side is derived: price `1 - p`, bids and asks swapped.
* Where `socket.auth` is set, use **your own** API key with that platform.
* Frames are either full book snapshots or level deltas (`frames` describes which). Replace or apply them to a local book per ref.

## Rate limits and caching

Limits apply per API key (not per IP) and are reported in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. Past the limit you get `429` with `Retry-After`. Data refreshes about every 15 seconds on our side, so polling faster than that returns the same answer: send `If-None-Match` and a `304` costs almost nothing.

## Errors

Every error has the same shape:

```json theme={null}
{ "error": "human readable message", "code": "bad_request", "hint": "optional" }
```

`code` is one of `bad_request`, `unauthorized`, `forbidden`, `not_found`, `method_not_allowed`, `rate_limited`, `unavailable`, `internal`.

## Acting on an outcome: the `trade` object

Every outcome in `/games/{id}/markets` and `/games/{id}/streams` carries a `trade` object with what a frontend needs to build an order on that venue. Vatic gives information only; it never places or signs orders.

| Venue | What identifies the outcome | Also included |
| - | - | - |
| Polymarket | `instrument.token_id` (the CLOB token, which is also the CTF position id), `condition_id`, `neg_risk` | tick size, minimum size, fee schedule, the CLOB V2 exchange address for that market, pUSD collateral |
| Hyperliquid | `instrument.asset` (`100000000 + 10*outcome + side`), `coin` (`#<n>`), `token_name` (`+<n>`) | the order action shape; tick and lot size are not stored |
| Limitless | `instrument.market_slug`, `token_id` (YES and NO have their own), `side` | exchange (the EIP-712 verifying contract), adapter, collateral token, chain 8453 |
| Predict.fun | `instrument.market_id`, `token_id` (the outcome's on-chain id), `is_neg_risk`, `is_yield_bearing`, `fee_rate_bps` | the exchange contract that follows from those flags, chain 56 |

`complement` is the opposite outcome of the same market, `tradable` says whether the venue is accepting orders now, and `caveats` lists what is not stored or not verified. Fields a venue does not give us are `null`, never guessed.

```bash theme={null}
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.vatic.trading/api/v1/games/espn:401878773/markets?canonical_key=1x2&limit=20"
```

## Data you may not see yet

Each source of data carries a `redistributable` flag (`yes`, `no`, `unknown`). Keys only receive data that is cleared for redistribution. When games exist that are not yet cleared, `meta.withheld` says how many.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.