Deadlock Research
verifiednote 0011build 66792026-08-16apinetworkecosystemopenapitooling

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).

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

hostroleverified
api.deadlock-api.comThe API. Spec at /openapi.json, interactive docs at /docs, GraphQL playground at /v1/graphqlspec fetched (HTTP 200, 368,506 B); 30 endpoint groups probed below
assets.deadlock-api.comLegacy. 301s into api.deadlock-api.com (root → /docs)curl -I → 301
assets-bucket.deadlock-api.comCDN holding the actual asset files the /v1/assets/{fonts,icons,images,sounds} indexes point atindex entry radiance-bold.otf → HEAD 200, font/otf, 69,988 B
s3-cache.deadlock-api.comS3-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.comReact front end: analytics pages, /data-dumps, /streamkit, patron infoHTTP 200; links extracted from the served HTML
streamkit.deadlock-api.com301 → deadlock-api.com/streamkitcurl -I → 301
data.deadlock-api.comdoes not existDNS 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):

groupopsgroupops
Analytics20Ranks (assets)3
Players12SQL3
Matches10Misc Entities (assets)2
Custom Matches6NPC Units (assets)2
MMR (all deprecated)6Steam Info (assets)2
Items (assets)5Internal2
Assets Bucket4Info2
Commands (streamkit)4Steam2
Leaderboard4Client Versions (assets)1
Demo4Colors (assets)1
Servers4Generic Data (assets)1
Accolades (assets)3Loot Tables (assets)1
Build Tags (assets)3Map (assets)1
Heroes (assets)3Ranked Seasons (assets)1
Patches3Builds1
GraphQL1

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:

groupproberesult
Info/v1/info200, keys fetched_matches_per_day, table_sizes, …
Players/v1/players/112724001/rank200, keys badge, rank, subrank, last_match
Matches/v1/matches/99570153/salts200, same shape note 0010 recorded
Leaderboard/v1/leaderboard/Europe/1200, 9 entries — hero-board size unchanged since 0010
Analytics/v1/analytics/scoreboards/heroes?sort_by=wins&limit=3200, list[38] of {rank, hero_id, value, matches}
Builds/v1/builds?limit=1200, list[1], keys hero_build, num_favorites, …
Patches/v2/patches200, list[30] of forum/RSS-shaped notes (title, pub_date, link)
MMR/v1/players/mmr?account_ids=112724001200 but the whole group is marked deprecated in the spec
Steam/v1/players/steam?account_ids=112724001200, persona/avatar profile
SQL/v1/sql/tables200, 12 queryable tables
Demo/v1/matches/demo/schema200, 5,082,540 B — by far the largest response
Servers/v1/servers200, keys servers
Commands/v1/commands/variables/available200, 42 streamkit variables
Custom Matches/v1/matches/custom/0/match-id404 on a dummy id, as expected; POSTs not exercised
Heroes (assets)/v1/assets/heroes/by-name/inferno200, codename-keyed hero record
Items (assets)/v1/assets/items/upgrade_ammo_scavenger200, item record with image, weapon_info
Ranks (assets)/v1/assets/ranks200, 12 tiers with badge image URLs
Client Versions/v1/assets/client-versions200, 804 known versions
Steam Info (assets)/v1/assets/steam-info200 — matches local build exactly (below)
Map (assets)/v1/assets/map200, radius, objective_positions, zipline_paths
Colors (assets)/v1/assets/colors200, Panorama palette
Generic Data/v1/assets/generic-data200, generic_data.vdata parse
Loot Tables/v1/assets/loot-tables200, per-slot tier tables
Accolades (assets)/v1/assets/accolades200, list[31]
Build Tags (assets)/v1/assets/build-tags200, list[14]
Ranked Seasons/v1/assets/ranked-seasons200, list[1]
Misc Entities/v1/assets/misc-entities200, list[91]
NPC Units (assets)/v1/assets/npc-units200, list[58]
Assets Bucket/v1/assets/fonts200, name → assets-bucket.deadlock-api.com URL map
GraphQL/v1/graphql200, HTML playground (the POST query side was not exercised)
Internalunverified: 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:

repolicenserole
deadlock-apiMITthe monorepo: API, website, ingestion tools, live-events
deadlock-api-assetsMITthe former standalone assets API (now absorbed)
deadlock-api-ingestMITcrowd-sourced salt ingestion (note 0010)
valveprotos-pyMITPython protobuf bindings
hasteBSD-3-Clausereplay/demo parser
valveprotos-rsBSD-3-ClauseRust protobuf bindings
DeadlockStatsGPL-3.0their Android app (Google Play)
openapi-clientsnone declaredauto-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

6. The rest of the ecosystem

serviceprobe 2026-08-16public API?
statlocker.gg200none found (not searched beyond front page)
tracklock.gg200/api and /openapi.json both 404 — no documented surface
deadlocktracker.gg200none found (liveness only)
deadlocklabs.gg403 to curl (bot filter, note 0010)reported to sit on "the public Deadlock API pipeline"
tracker.gg/deadlockreported 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

Open questions

Sources