Overview
StoryStats API
The StoryStats API turns major sports events into narrated insights. Pregame previews, live event-driven updates, and postgame recaps, all through a single REST interface.
Broad sports coverage
StoryStats is built for major professional, college, global, and tournament sports.
OpenAPI 3.0 spec
AI-agent friendlyThe full machine-readable spec is the source of truth for every endpoint, parameter, and response shape. Drop it into Cursor, Claude Code, or any codegen pipeline.
Base URL
All endpoints live under a single base URL. Every successful response is JSON.
https://api.balldontlie.ioAuthentication
Every request must include your API key in the Authorization header using the Bearer scheme. Your API keys are provisioned during onboarding and managed from your account dashboard.
Authorization: Bearer YOUR_API_KEYRate limits
Limits are per API key and configured during onboarding. Your plan can be shaped around traffic, sport coverage, and endpoint usage.
| Account | Limit | Scope |
|---|---|---|
| Provisioned | Set during onboarding | Per API key |
| Custom | Custom throughput | Configured by account requirements |
Rate-limit responses use HTTP 429. Contact us if your expected traffic changes materially.
Typical workflow
Story endpoints require a game ID. Start by listing games for a date, then use the returned IDs to fetch stories.
- List games for a date to get game IDs.
- Fetch the pregame story within 1 hour of the scheduled start.
- Poll live stories during the game for event-driven updates.
- Fetch the postgame story once the game is final.
Story availability
Stories are generated on a schedule. If you request one before it's ready, the API returns 404.
| Phase | When available | If not ready |
|---|---|---|
| Pregame | Within 1 hour before scheduled start | 404 |
| Live | After the game starts (first checkpoint at end of period 1) | Empty data: [] |
| Postgame | Immediately after the game goes final | 404 |
Error responses
4xx errors return a JSON body with a single error field. The 429 rate-limit response is plain text.
| Status | When | Body |
|---|---|---|
| 400 | Validation failed (invalid sport, missing date, bad timezone, invalid audience or tone). | {"error": "Invalid sport."} |
| 401 | Missing or invalid Authorization header. | {"error": "Authentication required. Provide an API key via the Authorization header."} |
| 404 | Game does not exist for that sport, or the requested story has not been generated yet. | {"error": "Game not found"} {"error": "Story not yet generated for this game"} |
| 429 | Rate limit exceeded. Body is plain text, not JSON. | Too many requests, please try again later. |
| 500 | Unexpected server error. Safe to retry with backoff. | {"error": "Internal server error"} |
Reference examples
Every endpoint is scoped to a sport path parameter. The examples below show the shared games and stories interface using common sport slugs such as nba, mlb, nhl.
Next steps
Head to the Quickstart for a hello-world request, or jump into the API examples for the shared games and stories interface.