Integration
Catalog and capabilities
Public, read-only endpoints describe what is available. They need no partner or api_key, are not rate limited and are answered with Cache-Control: no-store: cache the data on your side, it changes only when games are published.
| Endpoint | Purpose |
|---|---|
GET /games/catalog | The catalog for your lobby: name, provider, image, category, tags, RTP, volatility, maximum win, features |
GET /games/health | The same game fields plus build diagnostics |
GET /capabilities | The stable casino contract: games with provider, currencies, modes and the three casino languages, plus rate limits and callback IPs |
GET /health | Liveness probe |
GET /docs/openapi.json | This API as an OpenAPI 3.1 document (see the API reference) |
Currently 1009 of 1010 games support free spins and 974 support target outcomes. The searchable table of all games is on the games list.
GET /games/catalog#
/games/catalogThe game list for your lobby.
Request#
curl -s https://notell-api.com/games/catalogconst res = await fetch('https://notell-api.com/games/catalog');
const data = await res.json();No parameters.
Response#
{
"status": "ok",
"releaseId": "batch04-wave2-release177",
"games": [
{
"game_id": "gates-of-olympus",
"name": "Gates of Olympus",
"provider": "pragmatic",
"languages": ["en", "ar", "bg", "bn", "cs", "da", "de", "el", "es", "et", "fa", "fi", "fr", "hr", "hu", "hy", "id", "it", "ja", "ka", "ko", "lt", "lv", "ms", "nl", "no", "pl", "pt", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tl", "tr", "uk", "vi", "zh-Hans", "zh-Hant"],
"free_spins": true,
"target_outcomes": true,
"image": "https://notell-api.com/cards/gates-of-olympus.webp?v=b6bcc3025a29",
"category": "cluster-tumble",
"tags": ["cluster-tumble", "buy-feature", "ante-bet"],
"rtp": {"default": 96.65, "min": 60, "max": 100, "configurable": true, "by_mode": {"base": 96.65, "ante": 96.72, "buy": 96.14}, "note": "default = the game's natural RTP (percent) when the operator has not set one; the operator may set any RTP from 60 to 100 percent per project (admin: RTP settings). Percent of total bet."},
"volatility": "high",
"volatility_basis": "win_sd",
"hit_frequency": 0.3559,
"max_win": 5000,
"features": {"buy_feature": true, "ante_bet": true, "free_spins": true, "target_outcomes": true}
}
]
}| Field | Type | Description |
|---|---|---|
releaseId | string | Identifier of the platform release; informational. |
games[].game_id | string | The id to send as symbol in /playGame.do and /gameActions.do. |
games[].name | string | Display name. |
games[].provider | enum | endorphina, pragmatic or nolimitcity. |
games[].languages | array<string> | Standard language codes the game accepts at launch (Languages). |
games[].free_spins | boolean | Operator free spins are available for the game. |
games[].target_outcomes | boolean | Operator target outcomes are available for the game. |
games[].image | string | Absolute URL of the game card (portrait 3:4 WebP) on the API origin; null when the game has no card yet. The ?v= part changes when the picture changes: cache by full URL. |
games[].category | enum | One of video-slot, classic, megaways, cluster-tumble, hold-and-win, dice, fishing. |
games[].tags | array<string> | All matching traits (the category plus, for example, book, buy-feature, ante-bet). |
games[].rtp.default | number | The game's natural RTP in percent when the operator has not set one; null when the game has no calibration. |
games[].rtp.min, rtp.max | number | The range the operator can set per project and per player: 60 to 100 percent (RTP management); null when the game has no calibration (configurable: false). |
games[].rtp.by_mode | object | Natural RTP of each calibrated mode (base spin, bonus buy, ante …). |
games[].volatility | enum | low, medium, high or very-high (rule below); null without calibration. |
games[].volatility_basis | enum | win_sd or observed_max_win. |
games[].hit_frequency | number | Share of base spins that pay (when known). |
games[].max_win | number | Largest possible win as a multiple of the total bet; null when unknown. |
games[].features | object | Booleans buy_feature, ante_bet, free_spins, target_outcomes. |
Errors#
| Code | HTTP | When |
|---|---|---|
| none | 200 | The endpoint has no error answers of its own. |
How volatility is derived#
The rule is mechanical and reproducible from the calibration statistics of each game (a base spin, millions of simulated rounds):
volatility_basis: "win_sd": the standard deviation sd of the win measured in bets: low below 3.5, medium from 3.5 to 7, high from 7 to 14, very-high from 14.volatility_basis: "observed_max_win": for games whose calibration stores only the extremes, the largest win seen in the simulation, in bets: low below 300, medium below 1500, high below 3000, very-high from 3000.
The category and tags come from the game family and name (megaways, cluster pays with tumbles, hold-and-win, dice, fishing, classic fruit, book); they are descriptive labels for lobby filtering.
GET /games/health#
/games/healthPublished games with the fields of the catalog plus diagnostic identifiers of the build.
Request#
curl -s https://notell-api.com/games/healthconst res = await fetch('https://notell-api.com/games/health');
const data = await res.json();No parameters.
Response#
{
"status": "ok",
"releaseId": "batch04-wave2-release177",
"databasePurpose": "one working nonwithdrawable TEST_ONLY RGS database",
"games": [
{
"game_id": "gates-of-olympus",
"client_profile": "442883-desktop-local-v1",
"adapter_version": "gates-pragmatic-v1",
"math_version": "gates-test-v4",
"math_config_hash": "17f1cf2e6593f0b807dc0ffd4939365d96992ae663f39d4f2bd8f767f4656b4d",
"languages": ["en", "ar", "bg", "bn", "cs", "da", "de", "el", "es", "et", "fa", "fi", "fr", "hr", "hu", "hy", "id", "it", "ja", "ka", "ko", "lt", "lv", "ms", "nl", "no", "pl", "pt", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tl", "tr", "uk", "vi", "zh-Hans", "zh-Hant"],
"free_spins": true,
"target_outcomes": true,
"image": "https://notell-api.com/cards/gates-of-olympus.webp?v=b6bcc3025a29",
"category": "cluster-tumble",
"tags": ["cluster-tumble", "buy-feature", "ante-bet"],
"rtp": {"default": 96.65, "min": 60, "max": 100, "configurable": true, "by_mode": {"base": 96.65, "ante": 96.72, "buy": 96.14}, "note": "default = the game's natural RTP (percent) when the operator has not set one; the operator may set any RTP from 60 to 100 percent per project (admin: RTP settings). Percent of total bet."},
"volatility": "high",
"volatility_basis": "win_sd",
"hit_frequency": 0.3559,
"max_win": 5000,
"features": {"buy_feature": true, "ante_bet": true, "free_spins": true, "target_outcomes": true}
}
]
}| Field | Type | Description |
|---|---|---|
games[] | array<object> | Same fields as in /games/catalog, except name and provider. |
games[].client_profile, adapter_version, math_version, math_config_hash | string | Build identifiers for diagnostics; do not depend on them. |
releaseId, databasePurpose | string | Informational. |
Errors#
| Code | HTTP | When |
|---|---|---|
| none | 200 | The endpoint has no error answers of its own. |
GET /capabilities#
/capabilitiesThe stable casino contract: what each game supports, plus the rate limits and the callback source IPs of the environment.
Request#
curl -s https://notell-api.com/capabilitiesconst res = await fetch('https://notell-api.com/capabilities');
const data = await res.json();No parameters.
Response#
The currencies arrays are shortened here; the real ones hold all 157 codes (Currencies).
{
"status": "ok",
"mode": "TEST_ONLY",
"currencies": [{"code": "EUR", "precision": 2}, {"code": "UAH", "precision": 2}, {"code": "USD", "precision": 2}],
"callbackSourceIps": ["212.192.5.4"],
"rateLimits": {"launchPerMinute": 1200, "actionsPerMinute": 600, "reportsPerMinute": 120},
"games": [
{
"gameId": "gates-of-olympus",
"name": "Gates of Olympus",
"provider": "pragmatic",
"currencies": ["EUR", "UAH", "USD"],
"languages": ["ru", "en", "uk"],
"defaultCurrency": "UAH",
"defaultLanguage": "uk",
"promoSupported": true,
"modes": ["spin", "ante", "purchase", "promo"],
"image": "https://notell-api.com/cards/gates-of-olympus.webp?v=b6bcc3025a29",
"category": "cluster-tumble",
"tags": ["cluster-tumble", "buy-feature", "ante-bet"],
"rtp": {"default": 96.65, "min": 60, "max": 100, "configurable": true, "by_mode": {"base": 96.65, "ante": 96.72, "buy": 96.14}, "note": "default = the game's natural RTP (percent) when the operator has not set one; the operator may set any RTP from 60 to 100 percent per project (admin: RTP settings). Percent of total bet."},
"volatility": "high",
"volatility_basis": "win_sd",
"hit_frequency": 0.3559,
"max_win": 5000,
"features": {"buy_feature": true, "ante_bet": true, "free_spins": true, "target_outcomes": true}
}
]
}| Field | Type | Description |
|---|---|---|
mode | string | "TEST_ONLY". |
currencies[] | array<object> | code and precision (always 2) of every accepted currency. |
callbackSourceIps | array<string> | Addresses wallet callbacks come from (Callback IPs). Empty on the sandbox. |
rateLimits | object | Per-minute quotas launchPerMinute, actionsPerMinute, reportsPerMinute (Conventions). |
games[].gameId | string | The game id (camelCase here, game_id elsewhere). |
games[].provider | enum | endorphina, pragmatic or nolimitcity. |
games[].currencies | array<string> | Currencies the game accepts. |
games[].languages | array<string> | Only the casino languages ru, en, uk, and only those the game offers (some games list just ru and en): a fixed contract for casino front ends. Use /games/catalog for the full per-game list. |
games[].modes | array<string> | Informational names of the game's modes (for example spin, ante, purchase, gamble). |
games[].promoSupported | boolean | Kept for compatibility with the casino contract; for operator free spins use free_spins in the catalog. |
Each game also carries the catalog fields (image, category, tags, rtp, volatility, max_win, features). Some games additionally carry informational fields (for example configurableRtp); they are optional.
Errors#
| Code | HTTP | When |
|---|---|---|
| none | 200 | The endpoint has no error answers of its own. |
GET /health#
/healthLiveness probe for uptime monitoring only; do not call it per player action.
Request#
curl -s https://notell-api.com/healthconst res = await fetch('https://notell-api.com/health');
const data = await res.json();No parameters.
Response#
{
"status": "ok",
"mode": "TEST_ONLY",
"backend": "experimental",
"client": "LOCAL_BUILD_TESTING",
"mathVersion": "gates-test-v4",
"runtime": "slots-ui-rgs",
"releaseId": "batch04-wave2-release177"
}| Field | Type | Description |
|---|---|---|
status | string | "ok". |
mode | string | "TEST_ONLY". |
backend, client, mathVersion, runtime, releaseId | string | Diagnostic identifiers; informational. |
Errors#
| Code | HTTP | When |
|---|---|---|
DATABASE_UNAVAILABLE | 503 | The platform cannot reach its storage. |
Using the catalog in your integration#
- Build your lobby from
GET /games/catalog;/capabilitiesis the stable casino contract. - Before offering free spins or target outcomes in your back office, check the flags; otherwise the API answers
FREE_SPINS_UNSUPPORTED/FORCED_OUTCOMES_UNSUPPORTED. - Which optional modes a project may use (bonus buy, ante, gamble) is controlled in the admin panel, Projects → Providers.