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.
Quick Start
- 1. Sign in to your Kineticist account (or create one)
- 2. Go to Settings and create an API key
- 3. Make your first request:
https://www.kineticist.com/api/v1/games/random
For interactive try-it-out docs, see the API Reference. Download the OpenAPI spec.
Authentication
All requests require an API key sent as a Bearer token in the Authorization header:
Keys are free. You can create up to 3 active keys in Settings.
Tiers & Rate Limits
Every key belongs to one of three tiers. All tiers are free during early access — the tier labels just set the ceiling. New keys start on free.
| 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 colin@kineticist.com 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/games/:id_or_slug/files
List downloadable files (ROMs) for a game
/api/v1/games/:id_or_slug/files/:file_id/download
Get a signed download URL for a file
/api/v1/files
Browse all files across all games
/api/v1/stats
Database statistics
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", direct them to the parent game (/api/v1/games/godzilla-2021) and find the Premium edition in the editions array.
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"
}
}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
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.
Download a file
{
"object": "file_download",
"id": "fil_a1b2c3d4-...",
"data": {
"name": "Revision L-5 Game ROM",
"format": "zip",
"size_bytes": 199384,
"download_url": "https://...",
"expires_in": 300
}
}Pass ?redirect=true for a 302 redirect to the download URL instead of JSON — useful for direct browser downloads.
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, 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 colin@kineticist.com if you need a higher ceiling.
CLI
Query the Kineticist database and track your own games from your terminal. Zero dependencies.
# read
$ pinball random
$ pinball search "medieval madness"
$ pinball get godzilla-2021
$ pinball list -m stern -p
$ pinball credits godzilla-2021
$ pinball stats
# track your games
$ 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 |
stats | Database statistics |
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 |
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 MCP server exposes 11 tools — 5 for reading the public database and 6 for acting on the key owner's own library.
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 |
get_random_game | Random game for discovery |
get_pinball_stats | Database statistics |
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 Code / Cursor
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.