Notell API Docs
Русский

Features

Free spins

Free spins are spins you give a player at a fixed bet. They are played in the game's own client and cost the player nothing. Use the methods below to grant them from your back office or CRM.

  • Available for games with free_spins: true in /games/health (1009 of 1010 games).
  • All methods are POST https://notell-api.com/gameActions.do with a method field. They need partner, api_key and an allowlisted IP.
  • The optional Idempotency-Key header is supported by every method on this page (Conventions). Common errors (UNAUTHORIZED, IP_NOT_ALLOWED, INVALID_IDEMPOTENCY_KEY, IDEMPOTENCY_CONFLICT, RATE_LIMITED) are listed in Errors and not repeated in the tables below.
  • The legacy methods freespins_set, freespins_delete and freespins_get without an id answer METHOD_RETIRED.
  • Free spins are not available in demo mode.

How free spins work#

active --last spin settled--> used
active --expires_at passed--> expired     (unused spins are dropped)
active --freespins_cancel---> cancelled
  • A player can hold several grants per game. The grant that expires first is played first (ties: the older one first). A grant applies only to the same player_id and the same currency it was created for.
  • While a grant is active the player can play only the free spins in that game. Paid spins, ante bets and bonus buys are refused (FREE_SPINS_ACTIVE) until the grant is used up, expires or is cancelled.
  • A round that already started when its grant expires or is cancelled finishes and is credited normally; the grant is finished only after it.
  • Free-spin rounds go through the same RTP logic as paid rounds and count in the player's adaptive RTP window with their nominal bet (RTP).
  • bet and the project bet limits are checked when the grant is created, and again when a spin is played.

Wallet callbacks of a grant#

Every free-spin round sends a bet with amount 0 and meta.is_freespins: true. Your wallet must accept the zero bet (Wallet callbacks).

The wins of a grant are held and paid once. Winning rounds are not sent to your wallet one by one. When the last round of the grant has settled, the platform sends one win for the whole amount and only then the freespins_finished summary. The win is sent only if the total is above zero. Its transaction is stable across retries, and it is repeated until you answer ok.

json
{
  "method": "win",
  "player_id": "player-1024",
  "amount": 23.5,
  "meta": {
    "symbol": "gates-of-olympus",
    "time": 1803295800,
    "transaction": "e8a2b6c4-1d3f-4a57-9b0e-6c7d2f1a3e55",
    "round_id": "b2a74c1e-5d90-4f3a-8c21-0e9b7a6d4f12",
    "session_id": "9d0c3f7e-2b1a-4c58-a6d3-7e4f1b0c9a28",
    "is_freespins": true,
    "freespins": {
      "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4",
      "external_id": "spring-promo-1",
      "nominal_bet": 1,
      "total_win": 23.5,
      "final_credit": true
    }
  },
  "api_key": "YOUR_API_KEY"
}

meta.round_id is the last settled round of the grant. The player's balance in the game is updated locally while the spins are played; your wallet is credited by this one win. Then the summary is sent.

Summary callback#

When a grant finishes (used, expired or cancelled) the platform sends exactly one freespins_finished callback to your wallet URL and repeats it until you answer ok (delays of 10 s × 2<sup>attempts</sup>, at most 1 hour). A grant with unsettled rounds waits for them first.

json
{
  "method": "freespins_finished",
  "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4",
  "external_id": "spring-promo-1",
  "player_id": "player-1024",
  "currency": "EUR",
  "game": "gates-of-olympus",
  "status": "used",
  "total": 10,
  "played": 10,
  "bet": "1.00",
  "total_win": "23.50",
  "finished_at": "2027-02-15T12:30:00.000Z",
  "api_key": "YOUR_API_KEY"
}

Use it to close the promotion on your side. The money has already been credited by the final win above.

freespins_create#

POST/gameActions.domethodfreespins_create

Creates a grant for one player in one game.

Request#

curl
curl -s -X POST https://notell-api.com/gameActions.do \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: spring-promo-1-player-1024' \
  -d '{
    "method": "freespins_create",
    "partner": "demo-casino",
    "api_key": "YOUR_API_KEY",
    "player_id": "player-1024",
    "currency": "EUR",
    "symbol": "gates-of-olympus",
    "count": 10,
    "bet": "1.00",
    "external_id": "spring-promo-1",
    "meta": {"campaign": "spring"}
  }'
JSON
{
  "method": "freespins_create",
  "partner": "demo-casino",
  "api_key": "YOUR_API_KEY",
  "player_id": "player-1024",
  "currency": "EUR",
  "symbol": "gates-of-olympus",
  "count": 10,
  "bet": "1.00",
  "external_id": "spring-promo-1",
  "meta": {"campaign": "spring"}
}
FieldTypeRequiredDescription
methodstringyes"freespins_create".
partner, api_keystringyesYour project id and API key.
player_idstringyesYour player id, 1–128 printable ASCII characters without spaces.
currencystringyesAny of the 157 supported ISO 4217 codes (Currencies). The grant can be played only in this currency.
symbolstringyesGame id with free_spins: true.
countintegeryesNumber of spins, 1–1000.
betmoneyyesTotal bet of one spin as a decimal string. It must equal one of the game's bets in its base mode, and lie within the bet limits of the project, the game and the player.
expires_atstringnoISO 8601 date-time with a zone. From 1 hour to 30 days after the call. Default: now + 7 days.
external_idstringnoYour id, unique within the project, 1–128 printable ASCII characters without spaces. Lets you read or cancel the grant without storing ours.
metaobjectnoFree JSON object up to 4096 bytes. It is stored with the grant but not returned by the read methods.

Response#

json
{
  "status": "ok",
  "grant": {
    "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4",
    "external_id": "spring-promo-1",
    "player_id": "player-1024",
    "currency": "EUR",
    "symbol": "gates-of-olympus",
    "provider": "pragmatic",
    "total": 10,
    "remaining": 10,
    "played": 0,
    "bet": "1.00",
    "total_win": "0.00",
    "status": "active",
    "created_at": "2027-02-15T10:00:00.000Z",
    "expires_at": "2027-02-28T12:00:00.000Z",
    "finished_at": null
  }
}
FieldTypeDescription
grant.grant_idstringId of the grant (UUID).
grant.external_idstring or nullYour id, if you sent one.
grant.player_id, grant.currency, grant.symbolstringWhom, in which currency, in which game.
grant.providerstringpragmatic, endorphina or nolimitcity.
grant.total, grant.remaining, grant.playedintegerSpins granted, left and already played.
grant.betmoneyBet per spin.
grant.total_winmoneySum of the wins of the grant's settled rounds so far.
grant.statusenumactive, used, expired or cancelled.
grant.created_at, grant.expires_atstringISO 8601, UTC.
grant.finished_atstring or nullnull until the grant is finished.

Errors#

CodeHTTPWhen
INVALID_REQUEST400A field is missing, has the wrong type or format, currency is not supported, or meta is too large.
GAME_NOT_FOUND404symbol is not a catalog game.
FREE_SPINS_UNSUPPORTED400The game's provider does not support operator free spins.
INVALID_COUNT400count is not an integer from 1 to 1000.
INVALID_FREE_SPIN_BET400bet is not a string, or is not a bet of the game's base mode.
INVALID_EXPIRY400expires_at has no zone, or is less than 1 hour or more than 30 days ahead.
DUPLICATE_EXTERNAL_ID409A grant with this external_id already exists in the project.
PROJECT_BET_LIMIT400bet is outside the project, per-game or player limit for the currency.
PROJECT_GAME_DISABLED400The game or its provider is switched off for the project.
CURRENCY_REQUIRED400The project has no stake range for this currency.
GAME_MODE_DISABLED400The base mode of the game is switched off for the project.

freespins_get#

POST/gameActions.domethodfreespins_get

Returns one grant by grant_id or by your external_id.

Request#

curl
curl -s -X POST https://notell-api.com/gameActions.do \
  -H 'Content-Type: application/json' \
  -d '{"method":"freespins_get","partner":"demo-casino","api_key":"YOUR_API_KEY","external_id":"spring-promo-1"}'
JSON
{
  "method": "freespins_get",
  "partner": "demo-casino",
  "api_key": "YOUR_API_KEY",
  "external_id": "spring-promo-1"
}
FieldTypeRequiredDescription
grant_idstringexactly one of grant_id / external_idGrant id (UUID).
external_idstringexactly one of grant_id / external_idYour id.

Response#

The same {"status": "ok", "grant": {…}} as in freespins_create, with current remaining, played, total_win and status.

json
{
  "status": "ok",
  "grant": {
    "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4",
    "external_id": "spring-promo-1",
    "player_id": "player-1024",
    "currency": "EUR",
    "symbol": "gates-of-olympus",
    "provider": "pragmatic",
    "total": 10,
    "remaining": 6,
    "played": 4,
    "bet": "1.00",
    "total_win": "7.20",
    "status": "active",
    "created_at": "2027-02-15T10:00:00.000Z",
    "expires_at": "2027-02-28T12:00:00.000Z",
    "finished_at": null
  }
}

Errors#

CodeHTTPWhen
INVALID_REQUEST400Both or neither of grant_id and external_id were sent, or the value is malformed.
GRANT_NOT_FOUND404No such grant in your project.
METHOD_RETIRED400Neither grant_id nor external_id was sent (the retired no-id form).

freespins_list#

POST/gameActions.domethodfreespins_list

Lists grants of your project, newest first, at most 200.

Request#

curl
curl -s -X POST https://notell-api.com/gameActions.do \
  -H 'Content-Type: application/json' \
  -d '{"method":"freespins_list","partner":"demo-casino","api_key":"YOUR_API_KEY","player_id":"player-1024","status":"active"}'
JSON
{
  "method": "freespins_list",
  "partner": "demo-casino",
  "api_key": "YOUR_API_KEY",
  "player_id": "player-1024",
  "status": "active"
}
FieldTypeRequiredDescription
player_idstringnoOnly grants of this player.
symbolstringnoOnly grants for this game.
currencystringnoOnly grants in this currency.
statusstringnoactive, used, expired or cancelled. Other values return an empty list.

Response#

json
{
  "status": "ok",
  "grants": [
    {
      "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4",
      "external_id": "spring-promo-1",
      "player_id": "player-1024",
      "currency": "EUR",
      "symbol": "gates-of-olympus",
      "provider": "pragmatic",
      "total": 10,
      "remaining": 6,
      "played": 4,
      "bet": "1.00",
      "total_win": "7.20",
      "status": "active",
      "created_at": "2027-02-15T10:00:00.000Z",
      "expires_at": "2027-02-28T12:00:00.000Z",
      "finished_at": null
    }
  ]
}
FieldTypeDescription
grantsarray<object>Grant objects, see freespins_create. Empty when nothing matches.

Errors#

CodeHTTPWhen
INVALID_REQUEST400A filter has the wrong type.

freespins_cancel#

POST/gameActions.domethodfreespins_cancel

Cancels an active grant: the unused spins are dropped. Repeating the call returns the same grant. A grant that is not active or has no spins left is returned unchanged.

Request#

curl
curl -s -X POST https://notell-api.com/gameActions.do \
  -H 'Content-Type: application/json' \
  -d '{"method":"freespins_cancel","partner":"demo-casino","api_key":"YOUR_API_KEY","grant_id":"7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4"}'
JSON
{
  "method": "freespins_cancel",
  "partner": "demo-casino",
  "api_key": "YOUR_API_KEY",
  "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4"
}
FieldTypeRequiredDescription
grant_idstringexactly one of grant_id / external_idGrant id (UUID).
external_idstringexactly one of grant_id / external_idYour id.

Response#

json
{
  "status": "ok",
  "grant": {
    "grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4",
    "external_id": "spring-promo-1",
    "player_id": "player-1024",
    "currency": "EUR",
    "symbol": "gates-of-olympus",
    "provider": "pragmatic",
    "total": 10,
    "remaining": 6,
    "played": 4,
    "bet": "1.00",
    "total_win": "7.20",
    "status": "cancelled",
    "created_at": "2027-02-15T10:00:00.000Z",
    "expires_at": "2027-02-28T12:00:00.000Z",
    "finished_at": "2027-02-17T09:15:00.000Z"
  }
}

finished_at is set, and the summary is queued, as soon as no round of the grant is unsettled: at once, or after a round that was in progress has settled (until then it is null).

Errors#

CodeHTTPWhen
INVALID_REQUEST400Both or neither of grant_id and external_id were sent.
GRANT_NOT_FOUND404No such grant in your project.

See also#

Documentation for operators and integrators.TEST_ONLY platform: non-withdrawable units, no real payments.