speedrun.io API

High-performance speedrun.com mirror and native v1 API — faster responses, better availability, richer data.

Free for non-commercial use. /src and /v1 data are licensed under CC-BY-NC 4.0 — see the Data License for full terms. By using this API you agree to the Terms of Service.

Jump to

Namespaces

SRC Mirror Live CC-BY-NC 4.0

A faithful, high-performance mirror of the speedrun.com public API. Responses are carbon copies of the upstream JSON. No fields added, removed, or transformed. Use as a high-performance, low latency alternative.

The API is live. Full endpoint documentation is undergoing final updates over the next week.

Native v1 Pending CC-BY-NC 4.0

A restructured, normalized schema with fat trimmed and speedrun.io-specific fields added: run statistics, aggregate run analytics, leaderboard snapshots, and daily differential feeds. Public access with the same IP-based rate limits as /src.

🔒 Currently in developer preview. Full public docs will be posted here at release.

Developer Access Preview

Want early access to the native /v1 namespace and other features before they're public? Leave your email and we'll reach out as new previews open up.

Release Notes & Current Status

Authentication

/src Public — no authentication required
/v1 Public with IP-based rate limits. Bearer token authentication will be available at a future date.

Rate Limits

Limit 100 requests / minute
Window 60-second fixed window
Scope Per IP address
Exceeded Returns 429 with Retry-After header
Abuse detection 5 rate-limit hits within 1 hour → blacklisted for 1 hour

Caching

Gametypes, platforms, regions 30 days
Games, series 7 days
Categories, levels, variables, users, runs (single) 1 day
Runs (list), leaderboards 5 minutes

Cache duration is deliberately kept well under how often each resource type is actually re-scraped from speedrun.com, so the cache is never the limiting factor on data freshness.

Response Format

All responses use application/json. Successful responses wrap the payload in a top-level data field alongside a status code.

{
  "status": 200,
  "data": { ... }
}

Error responses use a nested error object with a code and human-readable msg. Request metadata (request ID, timing, URI) is returned in response headers, not the body. This keeps successful response bodies pure, cacheable data.

{
  "status": 400,
  "error": { "code": "BAD_REQUEST", "msg": "invalid id: must be 8 characters" }
}
400Invalid input (malformed ID, bad or unsupported parameter)
403Path doesn't exist, unsupported endpoint
404Valid request, record not found
404Content too large, specific to embedding
429Rate limit exceeded
500Internal server error
501Endpoint is planned but not yet implemented — see Current Status

Additional status codes apply to the /v1 namespace and will be documented alongside its public release.

Request Headers

HeaderRequiredDescription
User-AgentOptional, recommendedIdentify your application (e.g. my-app/1.2.0). Not enforced, but including it helps us reach out and help debug your integration, specifically if something looks off on our end. An unidentified client is much harder to trace through logs.

Response Headers

HeaderScopeDescription
X-SRIO-Request-IDAlwaysUUID for this request
X-SRIO-PerfAlwaysHandler execution time in milliseconds
X-SRIO-TimestampAlwaysUnix timestamp of request start
X-SRIO-URIAlwaysRequest URI including query string
X-SRIO-SRCRef200 responses onlymirrored — response is a carbon copy of speedrun.com. generated — assembled by speedrun.io
X-RateLimit-LimitAlways (non-exempt)Configured request limit (default 100/min)
X-RateLimit-RemainingAlways (non-exempt)Remaining requests in window
X-RateLimit-ResetAlways (non-exempt)Unix timestamp when window resets
X-RateLimit-MethodAlwaysAlways ip — rate limiting is IP-scoped
X-RateLimit-NamespaceAlwayssrc on this namespace
X-RateLimit-ExemptExempt IPs only"true" for whitelisted IPs
Retry-After429 responses onlySeconds until retry is allowed

Health Check

GET /src/health returns 200 with {"status":"ok"} when all dependencies are reachable, or 503 with {"status":"degraded","unhealthy":[...]} naming which one isn't. No authentication or rate limiting applies.

IDs

speedrun.com uses base36-encoded IDs for all records, always exactly 8 characters (e.g. 02q8o4p2). The /src namespace enforces this width strictly. An ID with fewer than 8 characters or extra padding is not a valid ID and returns 400. This matches speedrun.com's own behavior for canonical lookups, not a stricter-than-upstream restriction. The games endpoint allows an exception for the "abbreviation" field (e.g. sm64, celeste) and returns a 302 redirect when appropriate, as per the original API specification.

The /v1 namespace uses independently generated speedrun.io IDs — source IDs are not used in /v1 endpoint URIs. A dedicated mapping endpoint for resolving a /src ID to its corresponding /v1 ID is planned; details will be published here once finalized.

Support

Until we have a formal ticket system in place, feel free to email any questions, issues, feature requests or general feedback to [email protected].