The full programmatic API surface around Deadlock
Question
Beyond the match-history and leaderboard slice covered in note 0010: what is the complete live programmatic surface around Deadlock in 2026 — every service, its machine-readable spec, its endpoint groups, auth and rate-limit tiers, and each project's license?
Summary
All network claims below come from single HTTP calls made on 2026-08-16. Nothing in this note is a Valve product; the entire surface is community-run, tolerated-but- unendorsed, and can break without notice (note 0010 records the September 2024 throttling incident).
- The surface has consolidated onto one platform: the deadlock-api.com family, all open source under MIT (deadlock-api/deadlock-api). The formerly separate assets API is folded into the main host.
- One OpenAPI spec exists:
https://api.deadlock-api.com/openapi.json— OpenAPI 3.1.0,info.title"Deadlock API",info.version0.1.0,info.licenseMIT, 116 paths / 117 operations / 31 tag groups, 206 component schemas (368,506 bytes fetched). - 30 of the 31 groups were verified live with one GET each — 29 returned 200 with the documented shape; the Custom Matches GET needs a real lobby id and 404s on a dummy, as expected. The Internal group is POST-only and was not exercised.
- The family is five hosts:
api.(the API),assets.(legacy, 301 intoapi.),assets-bucket.(CDN for actual asset files),s3-cache.(daily database dumps, Parquet + SQL), anddeadlock-api.com(website;streamkit.301s into it). There is nodata.host (NXDOMAIN). A sixth piece, the Live Events SSE server, is shipped as a self-hosted Docker image rather than a hosted endpoint. - The API's per-version asset endpoints agree exactly with the local install:
/v1/assets/steam-inforeportsclient_version6679,source_revision10912166,version_date"Aug 14 2026" — the same valuestools/find_game.pyprints. - Everything tested works keyless. An optional key (
X-API-KEYheader orapi_keyquery, the spec's two security schemes) raises per-endpoint limits. - No other community service publishes an API: statlocker.gg, tracklock.gg and deadlocktracker.gg are alive (HTTP 200) but expose no spec or documented developer surface (verified for tracklock; others liveness-only).
This note feeds the site's static API reference at /api/, generated by tools/build_api.py from a committed snapshot of the spec (tools/fetch_openapi.py). MIT licensing is what permits committing the snapshot.
Findings
1. The deadlock-api.com family, host by host
| host | role | verified |
|---|---|---|
api.deadlock-api.com | The API. Spec at /openapi.json, interactive docs at /docs, GraphQL playground at /v1/graphql | spec fetched (HTTP 200, 368,506 B); 30 endpoint groups probed below |
assets.deadlock-api.com | Legacy. 301s into api.deadlock-api.com (root → /docs) | curl -I → 301 |
assets-bucket.deadlock-api.com | CDN holding the actual asset files the /v1/assets/{fonts,icons,images,sounds} indexes point at | index entry radiance-bold.otf → HEAD 200, font/otf, 69,988 B |
s3-cache.deadlock-api.com | S3-compatible bucket with daily database dumps under /db-snapshot/ — per-table .parquet + .sql schema files | ?list-type=2 listing returned real objects, LastModified 2026-08-16 (same day) |
deadlock-api.com | React front end: analytics pages, /data-dumps, /streamkit, patron info | HTTP 200; links extracted from the served HTML |
streamkit.deadlock-api.com | 301 → deadlock-api.com/streamkit | curl -I → 301 |
data.deadlock-api.com | does not exist | DNS NXDOMAIN |
The Live Events API (real-time entity updates from live matches over SSE) is distributed as a Docker image (ghcr.io/deadlock-api/deadlock-live-events) you run yourself, optionally with an API key for higher upstream limits — per the monorepo's live-events/README.md (reported, not run). Hosted live-match access exists inside the main API instead (/v1/matches/demo/live/query SSE, /v1/matches/live/urls).
2. The spec
$ curl -s -o openapi.json -w "%{http_code} %{size_download}\n" https://api.deadlock-api.com/openapi.json
200 368506
openapi 3.1.0 | title "Deadlock API" | version 0.1.0 | license MIT
116 paths, 117 operations, 31 tags, 206 component schemas
servers: [https://api.deadlock-api.com]
securitySchemes: api_key_header (X-API-KEY), api_key_query (api_key)
The 31 tag groups, with operation counts (all from the fetched spec):
| group | ops | group | ops |
|---|---|---|---|
| Analytics | 20 | Ranks (assets) | 3 |
| Players | 12 | SQL | 3 |
| Matches | 10 | Misc Entities (assets) | 2 |
| Custom Matches | 6 | NPC Units (assets) | 2 |
| MMR (all deprecated) | 6 | Steam Info (assets) | 2 |
| Items (assets) | 5 | Internal | 2 |
| Assets Bucket | 4 | Info | 2 |
| Commands (streamkit) | 4 | Steam | 2 |
| Leaderboard | 4 | Client Versions (assets) | 1 |
| Demo | 4 | Colors (assets) | 1 |
| Servers | 4 | Generic Data (assets) | 1 |
| Accolades (assets) | 3 | Loot Tables (assets) | 1 |
| Build Tags (assets) | 3 | Map (assets) | 1 |
| Heroes (assets) | 3 | Ranked Seasons (assets) | 1 |
| Patches | 3 | Builds | 1 |
| GraphQL | 1 |
Half the surface is the absorbed assets API: 17 of the 31 groups sit under /v1/assets/… and serve parsed game data per client version — the same heroes, items, ranks, map and generic-data content this repo derives locally from the VPKs.
3. One live probe per group
One GET per group, 0.5 s apart, User-Agent identifying this research note (probe_groups.py, reproduced below). Status / size / shape, all on 2026-08-16:
| group | probe | result |
|---|---|---|
| Info | /v1/info | 200, keys fetched_matches_per_day, table_sizes, … |
| Players | /v1/players/112724001/rank | 200, keys badge, rank, subrank, last_match |
| Matches | /v1/matches/99570153/salts | 200, same shape note 0010 recorded |
| Leaderboard | /v1/leaderboard/Europe/1 | 200, 9 entries — hero-board size unchanged since 0010 |
| Analytics | /v1/analytics/scoreboards/heroes?sort_by=wins&limit=3 | 200, list[38] of {rank, hero_id, value, matches} |
| Builds | /v1/builds?limit=1 | 200, list[1], keys hero_build, num_favorites, … |
| Patches | /v2/patches | 200, list[30] of forum/RSS-shaped notes (title, pub_date, link) |
| MMR | /v1/players/mmr?account_ids=112724001 | 200 but the whole group is marked deprecated in the spec |
| Steam | /v1/players/steam?account_ids=112724001 | 200, persona/avatar profile |
| SQL | /v1/sql/tables | 200, 12 queryable tables |
| Demo | /v1/matches/demo/schema | 200, 5,082,540 B — by far the largest response |
| Servers | /v1/servers | 200, keys servers |
| Commands | /v1/commands/variables/available | 200, 42 streamkit variables |
| Custom Matches | /v1/matches/custom/0/match-id | 404 on a dummy id, as expected; POSTs not exercised |
| Heroes (assets) | /v1/assets/heroes/by-name/inferno | 200, codename-keyed hero record |
| Items (assets) | /v1/assets/items/upgrade_ammo_scavenger | 200, item record with image, weapon_info |
| Ranks (assets) | /v1/assets/ranks | 200, 12 tiers with badge image URLs |
| Client Versions | /v1/assets/client-versions | 200, 804 known versions |
| Steam Info (assets) | /v1/assets/steam-info | 200 — matches local build exactly (below) |
| Map (assets) | /v1/assets/map | 200, radius, objective_positions, zipline_paths |
| Colors (assets) | /v1/assets/colors | 200, Panorama palette |
| Generic Data | /v1/assets/generic-data | 200, generic_data.vdata parse |
| Loot Tables | /v1/assets/loot-tables | 200, per-slot tier tables |
| Accolades (assets) | /v1/assets/accolades | 200, list[31] |
| Build Tags (assets) | /v1/assets/build-tags | 200, list[14] |
| Ranked Seasons | /v1/assets/ranked-seasons | 200, list[1] |
| Misc Entities | /v1/assets/misc-entities | 200, list[91] |
| NPC Units (assets) | /v1/assets/npc-units | 200, list[58] |
| Assets Bucket | /v1/assets/fonts | 200, name → assets-bucket.deadlock-api.com URL map |
| GraphQL | /v1/graphql | 200, HTML playground (the POST query side was not exercised) |
| Internal | — | unverified: POST-only (/v1/feedback, salts ingest) |
The build cross-check, verbatim:
$ curl -s https://api.deadlock-api.com/v1/assets/steam-info
{"client_version": 6679, "server_version": 6679, "product_name": "citadel",
"app_id": 1422450, "server_app_id": 1422460, "tools_app_id": 211,
"source_revision": 10912166, "version_date": "Aug 14 2026", ...}
$ python tools/find_game.py
ClientVersion 6679
SourceRevision 10912166
VersionDate Aug 14 2026
4. Licenses
From the GitHub org listing (api.github.com/orgs/deadlock-api/repos, 2026-08-16), license field as reported by GitHub:
| repo | license | role |
|---|---|---|
| deadlock-api | MIT | the monorepo: API, website, ingestion tools, live-events |
| deadlock-api-assets | MIT | the former standalone assets API (now absorbed) |
| deadlock-api-ingest | MIT | crowd-sourced salt ingestion (note 0010) |
| valveprotos-py | MIT | Python protobuf bindings |
| haste | BSD-3-Clause | replay/demo parser |
| valveprotos-rs | BSD-3-Clause | Rust protobuf bindings |
| DeadlockStats | GPL-3.0 | their Android app (Google Play) |
| openapi-clients | none declared | auto-generated API clients |
The spec itself also declares MIT in info.license. Inferred: committing a snapshot of openapi.json to this repo is permitted (MIT requires only attribution, which the snapshot's meta sidecar and the rendered page carry). The openapi-clients repo has no license and is treated as not redistributable.
5. Auth and rate-limit tiers
- Two optional security schemes:
api_key_header(X-API-KEY) andapi_key_query(api_key). Every probe in §3 ran keyless. - Keys raise per-endpoint limits; they are obtained via the project's Discord (reported, note 0010).
- Limits are documented per endpoint in the spec's description fields, not enforced globally. Representative figures (spec self-documentation, not empirically probed — same caveat as 0010): cached reads 100 req/s per IP; Steam-sourced fetches 3 req/h keyless / 300 req/h with key; analytics pool 200 req/min per IP.
- The website adds a Patron tier (from $1.50/month) for prioritized data fetching — a funding mechanism, not an API auth tier (reported, deadlock-api.com).
6. The rest of the ecosystem
| service | probe 2026-08-16 | public API? |
|---|---|---|
| statlocker.gg | 200 | none found (not searched beyond front page) |
| tracklock.gg | 200 | /api and /openapi.json both 404 — no documented surface |
| deadlocktracker.gg | 200 | none found (liveness only) |
| deadlocklabs.gg | 403 to curl (bot filter, note 0010) | reported to sit on "the public Deadlock API pipeline" |
| tracker.gg/deadlock | reported alive (search result; not probed) | Tracker Network has a partner API program; Deadlock coverage unverified |
The official Valve surface is unchanged from note 0010: the only Web API interface for app 1422450 is IGCVersion_1422450; real data flows over the Game Coordinator protobufs. Not re-verified here — see 0010 for the calls.
Reproduce
python tools/find_game.py # ClientVersion 6679
# The family
curl -s -o openapi.json -w "%{http_code} %{size_download}\n" "https://api.deadlock-api.com/openapi.json"
python -c "import json; d=json.load(open('openapi.json', encoding='utf-8')); \
print(d['openapi'], d['info']['version'], d['info']['license'], len(d['paths']))"
curl -sI "https://assets.deadlock-api.com/" # 301 -> api.../docs
curl -sI "https://streamkit.deadlock-api.com/" # 301 -> deadlock-api.com/streamkit
curl -s "https://s3-cache.deadlock-api.com/db-snapshot/?list-type=2&max-keys=5"
curl -sI "https://assets-bucket.deadlock-api.com/assets-api-res/fonts/radiance-bold.otf" | head -3
curl -sI "https://data.deadlock-api.com/" # could not resolve host
# Build agreement
curl -s "https://api.deadlock-api.com/v1/assets/steam-info"
# One probe per group (0.5s apart, ~30 requests total -- do not loop this)
# The full probe table in Findings #3 comes from a script doing exactly one GET per
# row; spot-check any single row like so:
curl -s "https://api.deadlock-api.com/v1/sql/tables"
curl -s "https://api.deadlock-api.com/v1/assets/client-versions" | python -c "import json,sys; print(len(json.load(sys.stdin)))"
# Licenses
curl -s "https://api.github.com/orgs/deadlock-api/repos?per_page=100" | \
python -c "import json,sys; [print(r['name'], (r['license'] or {}).get('spdx_id')) for r in json.load(sys.stdin)]"
# Ecosystem liveness
curl -s -o /dev/null -w "%{http_code}\n" "https://tracklock.gg/api" # 404 -- no API surface
# The committed snapshot this repo renders at /api/
python tools/fetch_openapi.py # refresh tools/data/openapi/
python tools/build_site.py # re-render site/api/
python tools/test_api.py # invariants against the snapshot
Counts (client versions, patch notes, board entries) drift with live data; the hosts, status codes, spec version and license fields are the claims.
Gotchas
- Fetch the spec from
api., notassets.— the legacy host's redirect string-rewrites paths and mangles unknown ones (assets.deadlock-api.com/openapi.json→ 301 →/v1/assetsenapi.json→ 404). /v1/matches/demo/schemais a 5 MB response. Do not fetch it casually, and do not render it whole into a page./v1/graphqlanswers GET with an HTML playground; the JSON API is POST on the same path. A naive "is it JSON" check misreads the group as broken.- The whole MMR group still answers 200 but is deprecated in the spec ("Valve reports a single account-wide rank"); do not build on it.
- 17 of the 31 groups are
/v1/assets/…game-data mirrors. They are the service's parse of the same files this repo derives locally — convenient, but a second-hand source by this repo's rules; anything load-bearing should still be re-derived from the local install (AGENTS.md rule 1). - The
Custom Matchesgroup is mostly POST lobby management; its one GET requires a realparty_id. Nothing there is verifiable without creating a lobby. - Carry-over from 0010 still applies: leaderboard regions are capitalized path values,
account_idis the 32-bit SteamID3, and the community layer can break whenever Valve tightens limits.
Open questions
- POST endpoints unexercised: Internal (
/v1/feedback, salts ingest), Custom Matches lobby management, server status/metrics ingest, the GraphQL POST side, and/v1/sqlGET /v1/sql?query=…itself (only/v1/sql/tableswas called). - Rate limits not empirically probed — all figures are the spec's own documentation.
- Live Events self-host image not run; hosted SSE (
/v1/matches/demo/live/query) not connected to. - Database dumps verified only as a bucket listing; no dump was downloaded or its schema inspected.
- tracker.gg's Deadlock coverage (and whether their partner API exposes it) not checked; statlocker/deadlocktracker checked for liveness only, not exhaustively for hidden APIs.
- Whether the absorbed assets endpoints (
/v1/assets/…) always track the live client version or can lag a patch was not tested (only the same-day agreement above).
Sources
- api.deadlock-api.com/openapi.json — fetched and parsed 2026-08-16 (verified; snapshot committed under
tools/data/openapi/). - deadlock-api/deadlock-api monorepo README and
live-events/README.md— structure and Live Events distribution (reported). - GitHub org repo listing — license fields (verified via API call).
- deadlock-api.com and its
/data-dumpspage — website features, patron tier, dump formats (reported via fetch). - Note 0010 — the match-history/leaderboard deep dive, the GC protobuf layer, and the Valve-stance caveats this note inherits.