Slots

GET /api/v1/slots/ Auth required

List public slots

Cursor-paginated list of published slots. Default order: -created_at. With ?updated_since: order switches to (updated_at, id) ASC for forward-sync. With ?ordering=-release_date|release_date: order switches to release-date mode. With ?ordering=-captured_at|captured_at: order switches to capture-date mode (matches the public listing default order). Use /slots/ids/ for tombstone reconcile (removed slots do not appear in deltas). ETag/304 support via If-None-Match.

Parameters

Name In Type Required Description Example
If-None-Match header string optional Opaque ETag value from a previous response to this same endpoint. When it matches the current ETag, the server returns 304 Not Modified with no body instead of re-sending the full payload.
cursor query string optional Opaque pagination cursor from a previous response's next/previous link.
feature query string optional Feature slug (exact match). A slot may carry several features.
game_category query string optional Game category, exact match. 400 on any value outside the enum. Also filters GET /api/v1/demand/, where it doubles as a cut axis (?by=game_category). Allowed: crash · instant_win · live · other · scratch · table · unknown · video_slot
has_bonus_buy query string optional 'true' or 'false'. Any other value returns 400.
jackpot_type query string optional Jackpot type (none/fixed/progressive/pooled/unknown) Allowed: fixed · none · pooled · progressive · unknown
max_win_max query integer optional max_win <= this value (multiplier of stake, positive integer). Also filters GET /api/v1/demand/ — same catalogue filter.
max_win_min query integer optional max_win >= this value (multiplier of stake, positive integer). Also filters GET /api/v1/demand/ — same catalogue filter.
mechanic query string optional Bet mechanic (lines/ways/cluster/megaways/scatter_pays) Allowed: cluster · lines · megaways · scatter_pays · variable_ways · ways
ordering query string optional Whitelist: '-release_date' (newest first) or 'release_date' (oldest first). Slots with release_date IS NULL sort to the end for '-release_date' and to the start for 'release_date'. '-captured_at' (most recently captured from a live demo first) or 'captured_at' (oldest/never-captured first) — matches the public listing's default order. Any other value → 400. Ignored when ?updated_since is present (sync order wins). Note on backward paging: cursor position is derived from the sort field alone, so walking back with `previous` through the trailing block of items that share the same sort value (those with no release date, or never captured) can skip entries. Forward paging with `next` is always complete, and neither ?updated_since sync nor the /ids/ reconcile is affected. Walk forward when you need the full set. Allowed: -captured_at · -release_date · captured_at · release_date
page_size query integer optional Number of results per page. Default 20, maximum 100 — same limits as the rest of the public API. An operator-configured limit may lower the maximum.
provider query string optional Provider slug (exact match).
released_after query string(date) optional ISO date (YYYY-MM-DD). release_date >= this value. Slots with release_date IS NULL are excluded. 400 on invalid format.
released_before query string(date) optional ISO date (YYYY-MM-DD). release_date <= this value — INCLUSIVE, the named day is part of the range. Note that ?published_before, ?posted_before and ?established_before on other endpoints are EXCLUSIVE. Slots with release_date IS NULL are excluded. 400 on invalid format.
rtp_max query number(double) optional rtp_default <= this value (percent, decimal, e.g. 96.5). Also filters GET /api/v1/demand/ — same catalogue filter.
rtp_min query number(double) optional rtp_default >= this value (percent, decimal, e.g. 96.5). Also filters GET /api/v1/demand/ — same catalogue filter.
search query string optional Case-insensitive substring search over slot name + aliases. Empty/whitespace-only value is a no-op (does not narrow results). Soft-clipped to 100 characters (not a 400).
series query string optional Series slug (exact match). A slot belongs to at most one series.
theme query string optional Theme slug (exact match). A slot may carry several themes.
updated_since query string(date-time) optional ISO-8601 datetime. Returns only slots whose content changed at or after this moment. When present, results are ordered by (updated_at, id) ASC — forward through time. Without this param the default order (-created_at, -id) is preserved. 400 on invalid format. Known limitation: cross-object renames (provider/studio/series name changes) do NOT appear in this delta — use /slots/ids/ for tombstone reconcile.
volatility query string optional Volatility (low/med_low/medium/med_high/high/very_high) Allowed: high · low · med_high · med_low · medium · very_high
curl \
  -H "Authorization: Token <YOUR_TOKEN>" \
  "https://i-gaming.tools/api/v1/slots/"
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://i-gaming.tools/api/v1/slots/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token <YOUR_TOKEN>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch("https://i-gaming.tools/api/v1/slots/", {
  method: "GET",
  headers: {
  "Authorization": "Token <YOUR_TOKEN>"
}
});
const data = await response.json();
console.log(data);
import requests

headers = {
    "Authorization": "Token <YOUR_TOKEN>"
}
response = requests.get("https://i-gaming.tools/api/v1/slots/", headers=headers)

print(response.json())

Response fields

next string(uri) | null Absolute URL of the next page, or null on the last page.
previous string(uri) | null Absolute URL of the previous page, or null on the first page.
results array[object]
Example response
{
  "next": "https://i-gaming.tools/api/v1/slots/?cursor=cD00ODY%3D",
  "previous": "https://i-gaming.tools/api/v1/slots/?cursor=cj0xJnA9NDg3",
  "results": [
    {
      "slug": "example-slot-title",
      "name": "Example Slot Title",
      "provider": {
        "slug": "example-provider",
        "name": "Example Provider"
      },
      "game_category": "video_slot",
      "game_subtype": null,
      "rtp_default": "96.50",
      "volatility": "high",
      "max_win": 5000,
      "mechanic": "ways",
      "mechanic_value": 243,
      "release_date": "2026-01-15",
      "release_date_precision": "day",
      "thumbnail_url": "https://cdn.i-gaming.tools/slots/example-slot-title.webp",
      "thumbnail": {
        "url": "https://cdn.i-gaming.tools/slots/example-slot-title.webp",
        "key": "slots/example-slot-title.webp",
        "version": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
      },
      "volume_12m": 12000,
      "trend": "growing",
      "demo_url": null,
      "updated_at": "2026-08-01T09:30:00Z"
    }
  ]
}
GET /api/v1/slots/ids/ Auth required

Reconcile — all public slot slugs

Cursor-paginated list of ALL public slot slugs for tombstone diff. Results are plain strings, not objects. Decrements quota once per request. REQUIRED for unpublish/compliance detection: ?updated_since delta does NOT include removed slots. Compare this set with your own copy and tombstone the slugs that are gone. X-Sync-Timestamp is included in the response header.

Parameters

Name In Type Required Description Example
cursor query string optional Opaque pagination cursor from a previous response's next/previous link.
page_size query integer optional Number of results per page. Default 20, maximum 100 — same limits as the rest of the public API. An operator-configured limit may lower the maximum.
curl \
  -H "Authorization: Token <YOUR_TOKEN>" \
  "https://i-gaming.tools/api/v1/slots/ids/"
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://i-gaming.tools/api/v1/slots/ids/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token <YOUR_TOKEN>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch("https://i-gaming.tools/api/v1/slots/ids/", {
  method: "GET",
  headers: {
  "Authorization": "Token <YOUR_TOKEN>"
}
});
const data = await response.json();
console.log(data);
import requests

headers = {
    "Authorization": "Token <YOUR_TOKEN>"
}
response = requests.get("https://i-gaming.tools/api/v1/slots/ids/", headers=headers)

print(response.json())

Response fields

next string(uri) | null
previous string(uri) | null
results array[string]
GET /api/v1/slots/{slug}/ Auth required

Get slot detail

Full slot profile: data (RTP/volatility/layout/mechanics), spec_sheet (symbols/modes/palette/accessibility), assets (screenshots/icon). ETag/304: pass If-None-Match to skip the heavy response on unchanged content.

Parameters

Name In Type Required Description Example
If-None-Match header string optional Opaque ETag value from a previous response to this same endpoint. When it matches the current ETag, the server returns 304 Not Modified with no body instead of re-sending the full payload.
slug path string required URL-friendly unique identifier of the slot.
curl \
  -H "Authorization: Token <YOUR_TOKEN>" \
  "https://i-gaming.tools/api/v1/slots/{slug}/"
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://i-gaming.tools/api/v1/slots/{slug}/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token <YOUR_TOKEN>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch("https://i-gaming.tools/api/v1/slots/{slug}/", {
  method: "GET",
  headers: {
  "Authorization": "Token <YOUR_TOKEN>"
}
});
const data = await response.json();
console.log(data);
import requests

headers = {
    "Authorization": "Token <YOUR_TOKEN>"
}
response = requests.get("https://i-gaming.tools/api/v1/slots/{slug}/", headers=headers)

print(response.json())

Response fields

data object Verified, editorially curated structured data for this slot. Decimal values (rtp, bets, payouts) are strings. provably_fair, bets_per_round and has_auto_cashout appear only when game_category is "crash"; game_subtype, blackjack_payout and side_bets only when it is "table".
spec_sheet object Unverified specification block, as extracted from the source. source is the constant "extracted, unverified"; raw is the extracted text or null; updated_at is when the extraction was last written.
assets object Media assets: screenshots (with key/version), logo, palette, demo embed info.
Example response
{
  "data": {
    "slug": "example-slot-title",
    "name": "Example Slot Title",
    "provider": {
      "slug": "example-provider",
      "name": "Example Provider"
    },
    "game_category": "video_slot",
    "rtp_default": "96.50",
    "volatility": "high",
    "max_win": 5000,
    "mechanic": "ways",
    "mechanic_value": 243,
    "reels": 5,
    "rows": 3,
    "release_date": "2026-01-15",
    "release_date_precision": "day",
    "status": "active",
    "studio": null,
    "series": null,
    "order_in_series": null,
    "licensed_brand": null,
    "rtp_variants": [
      {
        "rtp": "96.50",
        "variant": "default",
        "condition_note": "",
        "is_default": true
      }
    ],
    "min_bet": "0.20",
    "max_bet": "100.00",
    "currency": "EUR",
    "payline_direction": "ltr",
    "jackpot_type": "none",
    "jackpot_tiers": [],
    "has_bonus_buy": "yes",
    "bonus_buy_cost": "100.00",
    "bonus_buys": [
      {
        "label": "Free Spins",
        "cost": "100.00",
        "effect": "Awards 10 free spins",
        "is_default": true
      }
    ],
    "has_autoplay": "yes",
    "mobile_adapted": "yes",
    "ante_bet_cost": null,
    "themes": [
      {
        "slug": "fishing",
        "name": "Fishing"
      }
    ],
    "features": [
      {
        "slug": "free-spins",
        "name": "Free spins"
      }
    ],
    "aliases": [],
    "provider_ref": "",
    "symbols": [],
    "modes": [],
    "accessibility_notes": [],
    "coverage_notes": [],
    "coverage_gap_count": 0,
    "captured_at": "2026-02-01T10:00:00Z",
    "capture_method": "Live demo capture (headless browser) & OCR verification",
    "counts": {
      "symbols": 0,
      "screenshots": 1,
      "modes": 0,
      "palette": 0
    }
  },
  "spec_sheet": {
    "source": "extracted, unverified",
    "raw": "RTP 96.5% · Max win 5000x · 5 reels",
    "updated_at": "2026-02-02T08:15:00Z"
  },
  "assets": {
    "screenshots": [
      {
        "type": "preview",
        "device": "desktop",
        "page": "base_game",
        "order": 0,
        "width": 1280,
        "height": 720,
        "note": "",
        "url": "https://cdn.i-gaming.tools/slots/example-slot-title/preview.webp",
        "srcset": "",
        "key": "slots/example-slot-title/preview.webp",
        "version": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
      }
    ],
    "logo_url": "https://cdn.i-gaming.tools/slots/example-slot-title/logo.webp",
    "logo": {
      "url": "https://cdn.i-gaming.tools/slots/example-slot-title/logo.webp",
      "key": "slots/example-slot-title/logo.webp",
      "version": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    },
    "palette": [],
    "demo": {
      "available": true,
      "page_url": "https://i-gaming.tools/all-slots/example-slot-title/",
      "embed_url": "https://demo.i-gaming.tools/iframe/example-slot-title/"
    }
  }
}
GET /api/v1/slots/{slug}/demand/ Auth required

Slot demand snapshot

Per-slot search-demand aggregate: volume_12m/prev_12m/yoy_pct/trend + 24-point sparkline, derived from the provider demand snapshot. Graceful nulls when the provider has no demand snapshot yet. ETag/304 via If-None-Match (seed=computed_at, mirrors provider /demand/). See the `months` parameter for the trailing-window override.

Parameters

Name In Type Required Description Example
If-None-Match header string optional Opaque ETag value from a previous response to this same endpoint. When it matches the current ETag, the server returns 304 Not Modified with no body instead of re-sending the full payload.
months query string optional Number of trailing months to include in months/totals/markets[].values. Integer values are clamped to [1, 60] (0/negative/huge values do not error, they clamp). 'all' returns the full stored history (60 months). Omitting the parameter defaults to 12 months (pre-existing behaviour, byte-identical response shape). A non-numeric, non-"all" value returns 400. Note: per-market `volume_12m` always sums exactly the requested window — with `?months=all` it is NOT a 12-month sum despite the field name (the name is historical and kept for backward compatibility).
slug path string required URL-friendly unique identifier of the slot.
curl \
  -H "Authorization: Token <YOUR_TOKEN>" \
  "https://i-gaming.tools/api/v1/slots/{slug}/demand/"
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://i-gaming.tools/api/v1/slots/{slug}/demand/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token <YOUR_TOKEN>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch("https://i-gaming.tools/api/v1/slots/{slug}/demand/", {
  method: "GET",
  headers: {
  "Authorization": "Token <YOUR_TOKEN>"
}
});
const data = await response.json();
console.log(data);
import requests

headers = {
    "Authorization": "Token <YOUR_TOKEN>"
}
response = requests.get("https://i-gaming.tools/api/v1/slots/{slug}/demand/", headers=headers)

print(response.json())

Response fields

computed_at string(date-time) | null
volume_12m integer | null
prev_12m integer | null
yoy_pct number(double) | null
trend string
sparkline array[integer]
months array[string]
totals array[integer]
markets array[object]
Example response
{
  "computed_at": "2026-08-01T03:15:00Z",
  "volume_12m": 12000,
  "prev_12m": 9000,
  "yoy_pct": 33.3,
  "trend": "growing",
  "sparkline": [
    700,
    720,
    740,
    760,
    780,
    800,
    820,
    840,
    860,
    880,
    900,
    920,
    940,
    960,
    980,
    1000,
    1020,
    1040,
    1060,
    1080,
    1100,
    1120,
    1140,
    1160
  ],
  "months": [
    "2026-07",
    "2026-06",
    "2026-05"
  ],
  "totals": [
    1160,
    1140,
    1120
  ],
  "markets": [
    {
      "country": "Brazil",
      "country_iso": "BR",
      "flag": "🇧🇷",
      "values": [
        640,
        620,
        600
      ],
      "mom_delta": 20,
      "volume_12m": 7000,
      "trend": "growing"
    },
    {
      "country": "Canada",
      "country_iso": "CA",
      "flag": "🇨🇦",
      "values": [
        520,
        520,
        520
      ],
      "mom_delta": 0,
      "volume_12m": 5000,
      "trend": "flat"
    }
  ]
}