Developer API
Early AccessKineticist API
REST API, command-line tool, and MCP server for AI agents. 1,700+ games with edition pricing, design team credits, images, OPDB cross-references, and community ratings.
On this page
Quick Start
- 1. Catalog reads need no key. Try one:
- 2. Sign in to your Kineticist account (or create one), then go to Settings and create an API key
- 3. Send it as a Bearer token to reach
/meendpoints and file downloads:
https://www.kineticist.com/api/v1/me/state
For interactive try-it-out docs, see the API Reference. Download the OpenAPI spec.
Authentication
Catalog reads (games, credits, file listings, random, stats, where to play, search, page and what's new) work without a key, at 60 requests a minute and 2,000 a day per IP, inside a site-wide daily ceiling. With a key you get your own tier's limits (see below), and every /me endpoint needs one, sent as a Bearer token in the Authorization header:
Keys are free. You can create up to 20 active keys in Settings.
Tiers & Rate Limits
Every account belongs to one of three tiers. All tiers are free during early access — the tier labels just set the ceiling. New accounts start on free. Limits apply to your account, not to each key: all of your keys share one per-second, per-minute and daily budget, so a second key doesn’t add quota.
| Tier | Burst (per second) | Per minute | Per day |
|---|---|---|---|
free | 10 | 60 | 1,000 |
builder | 20 | 120 | 5,000 |
partner | 30 | 200 | 25,000 |
Daily limits reset at midnight UTC. Every response includes rate limit headers: X-RateLimit-Tier, X-RateLimit-Remaining-Day, X-RateLimit-Remaining-Minute, and X-RateLimit-Reset.
Need a higher ceiling? Email [email protected] with a short note about what you're building. Upgrades are free during early access.
Endpoints
Read endpoints return public game data. Write endpoints act on the API key owner's own library (play logs, ownership, wishlist, fun scores).
Read
/api/v1/games
List games with filtering, sorting, and pagination
/api/v1/games/:id_or_slug
Get a game by slug, UUID, or OPDB ID. Editions always included.
/api/v1/games/:id_or_slug/credits
Design team credits
/api/v1/games/:id_or_slug/tags
Game tags
/api/v1/games/:id_or_slug/trims
Editions/trims (also on detail)
/api/v1/games/random
Random game with full detail
/api/v1/games/batch?ids=...
Up to 50 games by ID
/api/v1/machines
List individual machines with filtering, sorting, and pagination
/api/v1/machines/:id_or_slug
Get one machine by slug, UUID, or OPDB machine ID. 301s on a renamed slug.
/api/v1/games/:id_or_slug/files
List downloadable files (ROMs) for a game
/api/v1/games/:id_or_slug/files/:file_id
Get a signed download URL for a file (?redirect=true for a 302)
/api/v1/machines/:id_or_slug/files
List the files linked to one machine. 301s on a renamed slug.
/api/v1/files
Browse all files across all games
/api/v1/stats
Database statistics
/api/v1/where-to-play?place=:postal_or_city
Venues near a postal code or city; add game=:name to only list venues with that game (country defaults to us)
/api/v1/search?q=:text
Search games, articles, venues, manufacturers, people, mods, Hype Index entries, and creators; type narrows to one kind
/api/v1/page?url=:kineticist_link
Read a Kineticist page as markdown by its link. Members-only news halves are never returned.
/api/v1/whats-new?days=7
Recent news, creator videos and podcasts, and Hype Index moves (days clamped to 1-30)
Your library
/api/v1/me/state?gameId=:uuid
Read your state for one game: ownership, wishlist, plays, fun score, favorite
/api/v1/me/actions
Log plays, toggle ownership, toggle wishlist, set fun score, undo last play, and more — see Your Library below
Full request/response examples for every endpoint in the interactive API reference.
Games & Editions
Pinball games often ship in multiple editions — Pro, Premium, LE, etc. In the Kineticist database, a game is the parent title (e.g. "Godzilla") and editions are the variants (Pro, Premium, LE, 70th Anniversary). Each edition has its own MSRP, production run, and specs.
Editions are always included on game detail responses — no extra request needed. Pricing lives on editions, not on the game itself. List responses include an editions_count field so you can see at a glance which games have multiple variants. Where available, editions also include manufacture_date, model_number, and mpu (CPU board type).
There are no separate pages for editions. If someone searches for "Godzilla Premium" on the website, direct them to the parent game (/games/pinball/godzilla-2021). In the API, though, every edition is also addressable on its own — see Machines below.
Machines
A machine is one physical title — the addressable unit beneath a game. It is the same record the game detail response returns inside editions, addressed directly instead of nested, and it carries the same trm_ ID.
Use it when your user has to pick the exact machine in front of them. For a modern release the machines under a game really are its editions (Pokémon → Pro, Premium, LE). For an older electromechanical they often are not: El Dorado's machines include Solar City, Lucky Strike, and Target Alpha — different titles that shared a Gottlieb wedgehead chassis and were grouped upstream. Grouping them under one game page is the right call for reading about them; it is the wrong call for a "what did you play?" picker, which is what this resource is for.
Machines have no page on the website — links.web points at the parent game's page, because that is where the coverage lives. Filter the list with game_slug, game_id, q, manufacturer, or year. Look one up by machine slug, trm_ ID, or raw OPDB machine ID (leading G included — unlike a game's OPDB group ID, which is bare).
Machines redirect. This is the one v1 endpoint that answers a renamed slug with a 301 and a Location header instead of a 404 — so a cached machine slug keeps working after an editor renames it. Follow the redirect and store the new slug. IDs never redirect; a miss on one is a real 404. Agents can also fetch /api/markdown/machines/:slug for the same record as token-efficient markdown.
Filtering & Sorting
The /api/v1/games endpoint supports these query parameters:
| Parameter | Description |
|---|---|
manufacturer | Filter by manufacturer slug or name (fuzzy match, e.g. stern). Only matches game manufacturers, not mod-only companies. |
in_production | true or false |
year_from / year_to | Filter by manufacture year range |
game_type | Filter by type (e.g. solid_state) |
q | Text search by game name (fuzzy, 2+ characters) |
sort | Sort field. Prefix with - for descending. Options: name, first_manufacture_year, average_fun_score, ratings_count |
limit | Results per page (1-100, default 25) |
offset | Skip N results (max 10,000) |
fields | Comma-separated fields for sparse responses (e.g. name,slug,average_fun_score) |
include | Inline optional sub-resources on detail: credits (editions and tags are always included) |
Response Format
Game Detail
{
"object": "game",
"id": "gm_44587386-0321-5463-89a6-0df400c1c7d4",
"data": {
"name": "Godzilla",
"slug": "godzilla-2021",
"first_manufacture_year": 2021,
"in_production": true,
"average_fun_score": 89,
"ratings_count": 81,
"manufacturer": { "id": "mfr_...", "name": "Stern Pinball Inc.", "slug": "stern-pinball-inc" },
"editions_count": 4,
"editions": [
{ "id": "trm_...", "name": "Godzilla (Pro)", "trim_level": "Pro", "msrp": "6899", ... }
],
"tags": [ { "id": "tag_...", "name": "Licensed", "slug": "licensed" } ],
"images": { "flyers": [...], "tutorial": [...], "other": [...] }
},
"links": {
"self": "/api/v1/games/godzilla-2021",
"credits": "/api/v1/games/godzilla-2021/credits",
"web": "https://www.kineticist.com/games/pinball/godzilla-2021"
}
}average_fun_score is the raw average of every reader rating, returned whatever ratings_count is. On kineticist.com a fun score shows only once a game has 5 or more ratings; to match the site, check ratings_count before displaying it.
List responses return the same fields minus editions, tags, and images, but include editions_count and pagination links.
Errors
{
"error": {
"type": "rate_limit_error",
"code": "daily_limit_exceeded",
"message": "Daily request limit of 1,000 exceeded. Resets at midnight UTC.",
"hint": "You're tilting! Step away from the machine and come back tomorrow.",
"doc_url": "https://www.kineticist.com/docs/api/errors#daily_limit_exceeded"
}
}Error types: invalid_request_error, authentication_error, rate_limit_error, not_found_error, api_error
A 503 with code temporarily_unavailable means our database hiccuped, not that the data is missing: wait for the Retry-After seconds and try again. A 404 or an empty list always means the data really isn't there.
Every code, what it means, and what to do about it is on the error codes page.
Object IDs
All IDs are type-prefixed UUIDs. You can pass either the prefixed or raw UUID — both work. Responses always include the prefix.
| Type | Prefix | Example |
|---|---|---|
| Game | gm_ | gm_550e8400-e29b-... |
| Manufacturer | mfr_ | mfr_7c9e6679-... |
| Person | prs_ | prs_a1b2c3d4-... |
| Tag | tag_ | tag_f2a3b4c5-... |
| Edition | trm_ | trm_e0f1a2b3-... |
| File | fil_ | fil_d4e5f6a7-... |
Example Queries
Stern games currently in production
Highest rated games of the 90s
Search for a game
Get a random game with full details
Get a game with design credits in one call
Look up a game by OPDB ID
Works with both OPDB group IDs (weeP) and full machine IDs (GweeP-MW95j). Machine IDs resolve to the parent game.
Files
ROMs, service manuals, schematics, parts lists, and instruction cards. List files for a specific game, browse all files across the catalog, or get a signed download URL. Downloads require authentication. Signed URLs expire after 5 minutes.
List files for a game
Filter by format (zip, bin, pdf, txt) or file_type (rom, parts_list, manual, schematic, instruction_card). Supports standard limit/offset pagination.
Every file carries a description (one line saying what sets it apart, such as the edition, print or language; null when the title says it all), a language (ISO 639-1 code, null for English) and a machines array naming the machines it is for. machines is always present and is empty when the file applies to the whole game. Each entry is { id, slug, name, manufacturer, relationship }. relationship is also_made_as when the machine's own manufacturer differs from the game's (the game page's “Also made as” split), otherwise edition.
{
"id": "fil_a1b2c3d4-...",
"name": "Fire Action ROM",
"description": "Taito's Brazilian edition",
"file_type": "rom",
"format": "zip",
"size_bytes": 199384,
"download_count": 42,
"language": null,
"machines": [
{
"id": "trm_692760a3-...",
"slug": "firepower-fire-action",
"name": "Fire Action",
"manufacturer": { "id": "mfr_c1aee15e-...", "name": "Stern Pinball Inc.", "slug": "stern-pinball-inc" },
"relationship": "also_made_as"
}
],
"created_at": "2026-04-04T10:00:00Z"
}Add machine (machine slug, trm_ ID, or UUID) to keep only that machine's files. An unknown machine, or one that belongs to a different game, returns an empty list, not an error. The filter does not trim a file's own machines array.
List files for a machine
Pulls one machine's files out of its game, for example Fire Action's files without the rest of Firepower's. Same file shape as above, same format, file_type, limit, and offset parameters. Files that apply to the whole game and are not linked to a machine are not included. A renamed machine slug answers 301 with a Location header pointing at the new path.
Download a file
{
"object": "file_download",
"id": "fil_a1b2c3d4-...",
"data": {
"name": "Revision L-5 Game ROM",
"description": null,
"format": "zip",
"size_bytes": 199384,
"download_url": "https://...",
"expires_in": 300,
"machines": []
}
}Pass ?redirect=true for a 302 redirect to the download URL instead of JSON — useful for direct browser downloads.
A file removed as a duplicate of another file on the same game answers 301 with a Location header pointing at the copy that replaced it, so old file IDs keep working.
Browse all files
Sorted by download count (most popular first). Each file includes a nested game object with the parent game's name, slug, and year. Filter by game (slug), format, file_type, machine, year_from, and year_to.
Your Library
Read and write the API key owner's own game data — play logs, ownership, wishlist, fun scores, favorites. The CLI and MCP server wrap these same endpoints.
Read your state for a game
{
"gameId": "44587386-0321-5463-89a6-0df400c1c7d4",
"owned": true,
"wantToPlay": false,
"wantToOwn": false,
"favorite": true,
"playCount": 12,
"latestPlayAt": "2026-04-12",
"funScore": 87
}Pass the raw UUID (without the gm_ prefix). Agents typically call this after a write to verify the mutation landed.
Write actions
All writes go through one endpoint. Pick a handler and send its fields in the same JSON body.
{
"handler": "logPlay",
"gameId": "44587386-0321-5463-89a6-0df400c1c7d4",
"playedAt": "2026-04-17",
"locationText": "Pin Museum",
"note": "cleared wizard mode",
"score": 2350000
}| Handler | Fields |
|---|---|
logPlay | gameId, playedAt (ISO date), dateKnown (false if you played but don't remember when), locationId, locationText, note, score, isReplay |
updatePlayLog | playLogId, plus the same optional fields as logPlay |
deletePlayLog | playLogId |
undoLastPlay | gameId — removes your most recent play for that game |
toggleOwnership | gameId, action (own | disown), removalReason, removedAt |
updateOwnershipDetails | gameId, purchasePrice, purchaseSource, tradeDetail, trimId, salePrice |
toggleWant | gameId, wantType (play | own) |
updateFunScore | gameId, score (0–100) |
deleteFunScore | gameId |
Writes are available on every tier. They count against the same daily quota as reads, so heavy batch imports will burn through a free key quickly — email [email protected] if you need a higher ceiling.
CLI
Query the Kineticist database, find places to play and read the site from your terminal, with no key. Add a key to track your own games. Zero dependencies.
$ pinball random
$ pinball search "medieval madness"
$ pinball get godzilla-2021
$ pinball list -m stern -p
$ pinball credits godzilla-2021
$ pinball stats
$ pinball where 60622 --game godzilla-2021
$ pinball find "steve ritchie"
$ pinball news
# track your games (needs a key)
$ export KINETICIST_API_KEY=ki_live_...
$ pinball play godzilla-2021 --location "Pin Museum"
$ pinball own godzilla-2021
$ pinball want godzilla-2021 play
$ pinball rate godzilla-2021 87
$ pinball state godzilla-2021
$ pinball undo godzilla-2021
Read commands
| Command | Description |
|---|---|
random | Random game with full details and credits |
get <slug|opdb_id> | Full game details by slug or OPDB ID |
search <query> | Search for games by name |
list [options] | List with filters: -m manufacturer, -p in production, --from/--to year, -s sort |
credits <slug> | Design team credits |
files <slug> | Manuals, schematics and other files, with the machines each covers |
stats | Database statistics |
where <place> | Places to play near a postal code or city. --game for venues with a machine, --country for postal codes outside the US |
find <query> | Search everything on Kineticist: games, news, places, people, manufacturers, mods, creators. --type to narrow |
read <url|path> | Read any Kineticist page as text |
news [--days n] | Recent news, creator videos and Hype Index moves |
Track your games
| Command | Description |
|---|---|
play <slug> [flags] | Log a play. Flags: --date YYYY-MM-DD, --unknown, --location, --note, --score, --replay |
own <slug> [--remove] | Mark as owned or no longer owned. With --remove: --reason sold|traded|other, --removed-at |
want <slug> play|own | Toggle want-to-play or want-to-own |
rate <slug> <1-100> | Set your fun score |
undo <slug> | Remove your most recent play |
follow <creator-slug> | Follow or unfollow a creator |
state <slug> | Show your state for a game (ownership, wishlist, plays, fun score) |
Install globally:
MCP Server (AI Agents)
Connect the Kineticist database to AI agents like Claude, ChatGPT, Cursor, and other tools that support the Model Context Protocol. The read tools need no key. The library tools act on the key owner's own library, so they need a Kineticist API key.
Setup for Claude, ChatGPT, Cursor and Codex is on one page.
Read tools
| Tool | Description |
|---|---|
search_pinball_games | Search and filter games with natural language |
get_game_details | Full game info with editions, images, and description |
get_game_credits | Design team for a game |
list_game_files | Game files grouped by machine, optionally for one machine |
get_random_game | Random game for discovery |
get_pinball_stats | Database statistics |
where_to_play | Venues near a postal code or city, optionally only those with a given game |
search | Search games, news, places to play, people, manufacturers, mods, Hype Index entries and creators |
get | Read any Kineticist page by its link; news as headline, summary and link |
whats_new | Latest news and the Hype Index top 10 and climbers |
Your library tools
| Tool | Description |
|---|---|
kineticist_get_my_state | Read your state for a game: ownership, wishlist, plays, fun score, favorite |
kineticist_log_play | Log a play with optional date, location, note, score, replay flag |
kineticist_toggle_ownership | Mark as owned or no longer owned |
kineticist_toggle_want | Toggle want-to-play or want-to-own |
kineticist_set_fun_score | Set the key owner's fun score (0–100) |
kineticist_undo_last_play | Remove the most recent play for a game |
Add to Claude or ChatGPT (no key)
Add a custom connector (Claude: Settings → Connectors; ChatGPT: Settings → Plugins) with the server URL https://www.kineticist.com/api/mcp and no authentication. You get the read tools, limited to 60 calls a minute and 2,000 a day per IP.
Add to Claude Code / Cursor (with your key)
Once configured, your AI agent can answer questions like "What Stern games are in production?" or "Who designed Medieval Madness?" using live Kineticist data.
Images
Image URLs returned by the API (e.g. image_url, editions[].image_url) point directly to media.kineticist.com and can be hotlinked, embedded, or displayed in your application.
For heavy usage, we recommend caching images locally or behind your own CDN to keep your app fast and avoid unnecessary bandwidth on both sides.
Terms of Use & Attribution
By using the Kineticist API you agree to the following:
Attribution Required
Any application, website, or service that displays Kineticist data to end users must include visible attribution with a link back to kineticist.com. Use one of these formats:
Attribution must be visible on every page or screen that displays Kineticist data. Footer placement is fine. Hidden or invisible attribution does not count.
Permitted Uses
- - Building apps, tools, or websites that reference pinball game data
- - Tournament software, collection trackers, and community tools
- - Editorial and journalistic use with attribution
- - Academic research and personal projects
Don't scrape the full database to build a competing product or strip the attribution link. We reserve the right to revoke keys that violate these terms.