Steam Tracker API
Frontend integration guide · Production
https://steam.datagame.dev
Quick facts
- No API key for reads · CORS enabled · JSON · Unix timestamps (seconds)
- CCU every 15 minutes · Catalog/prices ~weekly
- IDs are Steam app IDs (e.g. Marathon =
3065800)
Tracked games
| Game | App ID | Try |
|---|---|---|
| Marathon | 3065800 |
/api/games/3065800 |
| Apex Legends | 1172470 |
/api/games/1172470 |
| Modern Warfare 4 | 4435490 |
/api/games/4435490 |
Live list: GET /api/games
Endpoints
Health
GET /api/health
{ "status": "ok", "timestamp": 1785886604 }
List games cache 60s
GET /api/games
Each item includes catalog summary fields + latest: { captured_at, player_count } (or null).
Game detail recommended
GET /api/games/:id
{
"game": { "id": "3065800", "name": "Marathon", "header_image": "...", "screenshots": [...], "store_url": "..." },
"latest": { "captured_at": 1785886470, "player_count": 4033 },
"prices": [
{ "region": "us", "currency": "USD", "final_price": 3999, "formatted_final": "$39.99", "discount_percent": 0 }
]
}
final_price is minor units (cents). Prefer formatted_final for display. Regions: us, gb, de.
CCU history (charts) cache 5m
GET /api/games/:id/history?from=&to=
from / to optional Unix seconds.
{
"app_id": "3065800",
"history": [
{ "captured_at": 1772135136, "player_count": 142237 },
{ "captured_at": 1785886470, "player_count": 4033 }
]
}
Price history sparse
GET /api/games/:id/prices?region=&from=&to=
Written on catalog refresh (~weekly), not every 15 minutes.
Copy-paste helpers
const API_BASE = "https://steam.datagame.dev";
async function getSteamStats(appId) {
const res = await fetch(`${API_BASE}/api/games/${appId}`);
if (res.status === 404) return null;
if (!res.ok) throw new Error("Steam API failed");
const data = await res.json();
return {
players: data.latest?.player_count ?? 0,
lastUpdated: data.latest?.captured_at ?? null,
headerImage: data.game.header_image,
prices: data.prices ?? [],
storeUrl: data.game.store_url,
};
}
async function getCcuHistory(appId, days = 7) {
const from = Math.floor(Date.now() / 1000) - days * 24 * 60 * 60;
const { history } = await fetch(
`${API_BASE}/api/games/${appId}/history?from=${from}`
).then((r) => r.json());
return history.map((p) => ({
x: new Date(p.captured_at * 1000),
y: p.player_count,
}));
}
Errors
| Status | Meaning |
|---|---|
200 | OK |
400 | Bad from/to |
404 | Game not tracked |
5xx | Retry |
{ "error": "Game not found" }
More detail
Full Markdown (TypeScript types, field notes):
docs/frontend-api.md in the
tool-steamtracker repo.