API documentation
Clean JSON over HTTPS. Authenticate with X-API-Key: <your key>
(or ?api_key=). Get a key. Markets use ISO codes; UK is accepted as an alias for GB.
GET /api/availability
The core lookup: which tracked operators host this game, plus the closest alternatives at operators that don't.
GET /api/availability?game=starburst&market=GB
GET /api/availability?game=Big%20Bass%20Splash&market=UK&alternatives=false
{
"query": "starburst",
"market": "GB",
"game": { "title": "Starburst", "slug": "starburst", "provider": "NetEnt", "asset_id": "a1_..." },
"availability_status": "available",
"results": [
{
"operator": "playojo",
"operator_name": "PlayOJO",
"market": "GB",
"available": true,
"confidence": "api_seen",
"match_quality": "exact",
"casino_title": "Starburst",
"source": "PlayOJO extract_playojo_api.js",
"last_checked": "2026-06-01"
}
],
"alternatives_by_operator": {
"midnite": [
{ "title": "Starburst XXXtreme", "slug": "starburst-xxxtreme",
"provider": "NetEnt", "available": true, "reason": "name_family" }
]
}
}
POST /api/verdicts
Bulk availability verdicts for keywords / search terms — built for PPC workflows (e.g. a Google Ads Script labelling keywords by partner coverage). Max 200 terms per call.
POST /api/verdicts
{ "market": "GB",
"partners": ["playojo", "midnite"],
"terms": ["big bass splash", "hand of anubis demo", "random gibberish"] }
{
"market": "GB",
"partner_scope": ["midnite", "playojo"],
"verdicts": [
{
"term": "big bass splash",
"resolved": true,
"game": { "title": "Big Bass Splash", "slug": "big-bass-splash", "provider": "Pragmatic Play" },
"coverage": { "hosting": ["midnite", "playojo"], "count": 2, "of": 2, "ratio": 1 },
"suggested_action": "route",
"last_checked": "2026-06-01"
},
{
"term": "random gibberish",
"resolved": false,
"suggested_action": "unresolved"
}
]
}
suggested_action taxonomy:
route — hosted by ≥1 of your partners ·
reroute_or_bid_down — game exists at tracked casinos but none of your partners (closest
alternatives at your partners are included) ·
availability_unknown — game known, not seen in any tracked lobby ·
unresolved — no game entity matched the term.
Verdicts cover the availability dimension only; relevance/competitor classification is a separate module.
Common PPC modifiers around the game name ("… slot", "… demo", "… free spins") are stripped automatically
when a term doesn't resolve as-is; the response then carries resolved_term for transparency.
Single-term convenience: GET /api/verdicts?term=big+bass+splash&market=GB
Google Ads Script — keyword labelling
The paste-and-go integration: a Google Ads Script that runs inside your own account
(no account access granted to us), sends your enabled keywords to /api/verdicts,
and labels each one with its availability verdict:
LL: route (4/5) game hosted by 4 of your 5 partners — bid confidently
LL: not-at-partners game exists at tracked casinos, none of yours — reroute or bid down
LL: unknown game known, not seen in tracked lobbies
LL: unresolved no game matched — review for relevance
You then drive automated rules or bid adjustments off the labels. The script only ever applies
labels — it never pauses, negatives, or changes bids, and it ships in shadow mode
(DRY_RUN = true) so your first runs just report.
Download the script — paste into
Tools & settings → Scripts, set API_URL + API_KEY, Preview, then schedule daily.
Partner scoping
API keys can carry your partner list — every availability answer, coverage ratio and
alternative is then computed against your casinos, not all tracked operators. Unscoped keys can pass
?partners=playojo,midnite (or a partners array in POST bodies) per request.
Scoped responses include a partner_scope field.
GET /api/search
GET /api/search?q=big+bass&market=GB&limit=10
Token search over the full catalogue; each hit includes available_at operator slugs and availability_status.
GET /api/games/:slug
GET /api/games/big-bass-splash
Full game record: stats (RTP, reels, max win…) plus every availability edge across markets.
GET /api/operators · GET /api/operators/:slug
GET /api/operators?market=GB
Coverage per operator: lobby game count, matched count, capture method, last checked.
GET /api/status no key needed
GET /api/status
Dataset freshness and per-operator capture provenance — poll it to decide when to re-sync.
Errors
{ "error": { "code": "unknown_market", "message": "Unknown market \"SE\". Covered markets: GB (alias: UK=GB)." } }
Codes: unauthorized (401), bad_query / missing_game / unknown_market (400), game_not_found / operator_not_found / not_found (404).