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: truein/games/health(1009 of 1010 games). - All methods are
POST https://notell-api.com/gameActions.dowith amethodfield. They needpartner,api_keyand an allowlisted IP. - The optional
Idempotency-Keyheader 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_deleteandfreespins_getwithout an id answerMETHOD_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_idand the samecurrencyit 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).
betand 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.
{
"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.
{
"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#
/gameActions.domethodfreespins_createCreates a grant for one player in one game.
Request#
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"}
}'{
"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"}
}| Field | Type | Required | Description |
|---|---|---|---|
method | string | yes | "freespins_create". |
partner, api_key | string | yes | Your project id and API key. |
player_id | string | yes | Your player id, 1–128 printable ASCII characters without spaces. |
currency | string | yes | Any of the 157 supported ISO 4217 codes (Currencies). The grant can be played only in this currency. |
symbol | string | yes | Game id with free_spins: true. |
count | integer | yes | Number of spins, 1–1000. |
bet | money | yes | Total 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_at | string | no | ISO 8601 date-time with a zone. From 1 hour to 30 days after the call. Default: now + 7 days. |
external_id | string | no | Your id, unique within the project, 1–128 printable ASCII characters without spaces. Lets you read or cancel the grant without storing ours. |
meta | object | no | Free JSON object up to 4096 bytes. It is stored with the grant but not returned by the read methods. |
Response#
{
"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
}
}| Field | Type | Description |
|---|---|---|
grant.grant_id | string | Id of the grant (UUID). |
grant.external_id | string or null | Your id, if you sent one. |
grant.player_id, grant.currency, grant.symbol | string | Whom, in which currency, in which game. |
grant.provider | string | pragmatic, endorphina or nolimitcity. |
grant.total, grant.remaining, grant.played | integer | Spins granted, left and already played. |
grant.bet | money | Bet per spin. |
grant.total_win | money | Sum of the wins of the grant's settled rounds so far. |
grant.status | enum | active, used, expired or cancelled. |
grant.created_at, grant.expires_at | string | ISO 8601, UTC. |
grant.finished_at | string or null | null until the grant is finished. |
Errors#
| Code | HTTP | When |
|---|---|---|
INVALID_REQUEST | 400 | A field is missing, has the wrong type or format, currency is not supported, or meta is too large. |
GAME_NOT_FOUND | 404 | symbol is not a catalog game. |
FREE_SPINS_UNSUPPORTED | 400 | The game's provider does not support operator free spins. |
INVALID_COUNT | 400 | count is not an integer from 1 to 1000. |
INVALID_FREE_SPIN_BET | 400 | bet is not a string, or is not a bet of the game's base mode. |
INVALID_EXPIRY | 400 | expires_at has no zone, or is less than 1 hour or more than 30 days ahead. |
DUPLICATE_EXTERNAL_ID | 409 | A grant with this external_id already exists in the project. |
PROJECT_BET_LIMIT | 400 | bet is outside the project, per-game or player limit for the currency. |
PROJECT_GAME_DISABLED | 400 | The game or its provider is switched off for the project. |
CURRENCY_REQUIRED | 400 | The project has no stake range for this currency. |
GAME_MODE_DISABLED | 400 | The base mode of the game is switched off for the project. |
freespins_get#
/gameActions.domethodfreespins_getReturns one grant by grant_id or by your external_id.
Request#
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"}'{
"method": "freespins_get",
"partner": "demo-casino",
"api_key": "YOUR_API_KEY",
"external_id": "spring-promo-1"
}| Field | Type | Required | Description |
|---|---|---|---|
grant_id | string | exactly one of grant_id / external_id | Grant id (UUID). |
external_id | string | exactly one of grant_id / external_id | Your id. |
Response#
The same {"status": "ok", "grant": {…}} as in freespins_create, with current remaining, played, total_win and status.
{
"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#
| Code | HTTP | When |
|---|---|---|
INVALID_REQUEST | 400 | Both or neither of grant_id and external_id were sent, or the value is malformed. |
GRANT_NOT_FOUND | 404 | No such grant in your project. |
METHOD_RETIRED | 400 | Neither grant_id nor external_id was sent (the retired no-id form). |
freespins_list#
/gameActions.domethodfreespins_listLists grants of your project, newest first, at most 200.
Request#
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"}'{
"method": "freespins_list",
"partner": "demo-casino",
"api_key": "YOUR_API_KEY",
"player_id": "player-1024",
"status": "active"
}| Field | Type | Required | Description |
|---|---|---|---|
player_id | string | no | Only grants of this player. |
symbol | string | no | Only grants for this game. |
currency | string | no | Only grants in this currency. |
status | string | no | active, used, expired or cancelled. Other values return an empty list. |
Response#
{
"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
}
]
}| Field | Type | Description |
|---|---|---|
grants | array<object> | Grant objects, see freespins_create. Empty when nothing matches. |
Errors#
| Code | HTTP | When |
|---|---|---|
INVALID_REQUEST | 400 | A filter has the wrong type. |
freespins_cancel#
/gameActions.domethodfreespins_cancelCancels 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 -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"}'{
"method": "freespins_cancel",
"partner": "demo-casino",
"api_key": "YOUR_API_KEY",
"grant_id": "7b1c0e52-4f6a-4d8e-9a31-2c5e8f90b1d4"
}| Field | Type | Required | Description |
|---|---|---|---|
grant_id | string | exactly one of grant_id / external_id | Grant id (UUID). |
external_id | string | exactly one of grant_id / external_id | Your id. |
Response#
{
"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#
| Code | HTTP | When |
|---|---|---|
INVALID_REQUEST | 400 | Both or neither of grant_id and external_id were sent. |
GRANT_NOT_FOUND | 404 | No such grant in your project. |
See also#
- Wallet callbacks: the zero
bet, the finalwinandfreespins_finished. - Bet limits and Currencies.
- Admin: the same grants can be managed in the admin panel.