Groove Game Provider Integration API

Game Provider Integration API

Welcome to Groove Technologies Integration

Groove Technology is a leading game aggregation platform that connects game providers with casino operators worldwide. As a game provider, integrating with Groove allows you to distribute your games to numerous casino operators through a single integration point.

This documentation describes the APIs that you, as a game provider, must implement to integrate your games with the Groove aggregation platform. Once integrated, your games will be available to all casino operators using the Groove platform.

Info

**Provider-Side Implementation**: This documentation specifies the endpoints and methods that must be implemented on your (game provider's) infrastructure. Groove will call these endpoints to launch games and process transactions.

🎮 What You Need to Implement

1. Game Launch

Groove → Your Platform

  • Receive game launch requests from Groove
  • Generate game sessions for players
  • Return game URLs for player redirection
  • Handle device detection and reality checks

2. Transaction APIs

Your Games → Groove → Casino Wallet

  • GetAccount: Validate player sessions from Groove
  • GetBalance: Retrieve player balance from Groove
  • Wager: Process bet requests through Groove
  • Result: Process win/loss results through Groove
  • Rollback: Handle transaction corrections
  • Jackpot: Process jackpot wins

3. Free Round Bonus API

Groove → Your Platform

  • Receive and create bonus templates
  • Assign bonuses to specific players
  • Track bonus usage and expiration
  • Support multi-currency with automatic conversion
Section Description
Getting Started Initial setup and requirements
API Reference Complete API documentation
Error Codes Response codes reference
Examples Integration examples
FAQ Frequently asked questions

🔑 Integration Benefits

  • ✅ Single Integration - Reach multiple casino operators through Groove
  • ✅ Wide Distribution - Your games available to all Groove partner casinos
  • ✅ Multi-Currency - Automatic currency conversion handled by Groove
  • ✅ Standardized API - One integration standard for all operators
  • ✅ Transaction Management - Groove handles wallet operations with casinos
  • ✅ Comprehensive Support - Full gaming lifecycle and bonus management

📊 Integration Flow

graph LR A[Player] --> B[Casino Operator] B --> C[Groove Platform] C --> D[Your Game Provider API] D --> E[Your Game Server] style D fill:#f9f,stroke:#333,stroke-width:4px style E fill:#f9f,stroke:#333,stroke-width:4px

Data Flow:

  1. Player requests game from Casino
  2. Casino sends request to Groove
  3. Groove calls your Game Launch API
  4. Your system generates session and returns game URL
  5. Player is redirected to your game
  6. Your game communicates with Groove for transactions

🚀 Integration Steps

  1. Prepare Your Infrastructure

    • Set up API endpoints on your servers
    • Implement secure session management
    • Configure game servers for Groove integration
  2. Implement Required APIs

    • Game Launch: Handle game start requests from Groove
    • Transaction API: Connect to Groove for wallet operations
    • Bonus API (optional): Support free rounds functionality
  3. Testing Phase

    • Test with Groove’s staging environment
    • Validate all transaction types
    • Ensure proper error handling
    • Test currency conversions
  4. Certification & Go Live

    • Complete Groove certification process
    • Deploy to production environment
    • Monitor integration performance
    • Provide game assets to Groove

📞 Support

For technical assistance during integration:

  • Documentation: This site
  • Response Time: Within 24 hours
  • During integration: Contact Groove via the integration main communication chanel(slack/teams).

Groove Technologies - Powering Casino Innovation

Subsections of Groove Game Provider Integration API

Game Launch API

Overview

When a player wants to play your game from a casino operator, Groove sends a game launch request to your platform. Your system must process this request, create a game session, and return a URL where the player will be redirected to play your game.

Start Game Process Flow

The game launch process follows these steps:

sequenceDiagram participant Player participant Casino participant Groove participant YourAPI as Your Game Provider API participant YourGame as Your Game Server Player->>Casino: Select game to play Casino->>Groove: Request game launch Groove->>YourAPI: Forward launch request with player data YourAPI->>YourAPI: Create game session YourAPI-->>Groove: Return game URL Groove-->>Casino: Return redirect URL Casino->>Player: Redirect to game Player->>YourGame: Start playing

Process Steps:

  1. Player selects your game in the casino lobby
  2. Casino sends game launch request to Groove
  3. Groove forwards the request to your Game Launch API endpoint
  4. Your system creates a session and returns the game URL
  5. Player is redirected to your game server

Start Game Request

Groove will send a game launch request to your platform with player and session information. Your system must process this request and return a URL where the player can access the game.

Request Details (From Groove to Your Platform)

  • Endpoint: https://{your_domain}/game/ (or your specified endpoint)
  • Method: GET
  • Content-Type: URL encoded parameters
Warning

All parameters sent by Groove will be URL encoded. Your system must decode them properly.

Request Parameters

Required Parameters

Parameter Data Type Description Example
accountid String(60) [0-9a-zA-Z] Account ID 5179068
country String Country code (ISO 3166-1 alpha-2) IL, UK, US
historyUrl String(50) URL for viewing player’s gaming history (regulatory requirement) http://casino.com/history
homeurl String(50) Page URL that the player is redirected to after exiting the game
Note: If empty, the home button should not be displayed in your game (prevents iframe-in-iframe issues)
http://www.somecasino.com
is_test_account Boolean Indicates if the player is a test player (excluded from reports) false (regular), true (test)
license String Country that has gaming jurisdiction Curacao, Malta, UK
nogscurrency String Currency code EUR, USD, GBP
nogsgameid String Groove game ID
Note: Can contain letters and special characters
80102, game_123, slot-abc
nogslang String Language code en_US
nogsmode String Game mode demo, real
nogsoperatorid String Groove ID for the casino 11
sessionid String(64) Session ID ${nogsoperatorid}_99d71938-d598c2es

Optional Parameters

Parameter Data Type Description Example
device_type String Device currently used by the player desktop, mobile
exitUrl String Exit URL http://myhomepage.com
rc_url String Reality check URL https://realitycheckapp.groovegaming.com
realityCheckElapsed Integer Reality Check Elapsed time in minutes 10
realityCheckInterval Integer Reality Check Interval in minutes 15
Info

**Note**: Some games are not available on mobile devices. Always specify the `device_type` parameter when known.

Request Example (What You’ll Receive)

GET /game/?accountid=5179068&country=UK&historyUrl=http%3A%2F%2Fcasino.com%2Fhistory&homeurl=http%3A%2F%2Fwww.somecasino.com&is_test_account=false&license=UK&nogscurrency=EUR&nogsgameid=80102&nogslang=en_US&nogsmode=real&nogsoperatorid=11&sessionid=11_99d71938-d598c2es HTTP/1.1
Host: {your_domain}

Processing the Request (Your Implementation)

Your platform must:

  1. Process the incoming parameters from Groove
  2. Create a game session in your system
  3. Store the session information for use in transaction callbacks
  4. Return a redirect to your game URL (HTTP 302)

**Critical for Transactions**: When making transaction callbacks to Groove, you must use the latest game session for the combination of: - `nogsoperatorid` (operator ID) - `accountid` (player account ID) - `nogscurrency` (currency) This ensures Groove can properly identify and process the transaction.

Response (What You Must Return)

Success Response

  • Status Code: 302 Found
  • Behavior: Your system must redirect to the actual game URL where the player can start playing
  • Location Header: Must contain the full URL to your game

Error Response

If you cannot launch the game, return an error response:

{
    "errMsg": "general_error"
}

Error Handling

Common error scenarios:

Error Description Solution
general_error Generic error occurred Check all required parameters are present and valid
Missing parameters Required parameter not provided Ensure all required parameters are included
Invalid game ID Game ID doesn’t exist Verify the nogsgameid is correct
Invalid session Session has expired or is invalid Generate a new session

Reality Check Feature

For jurisdictions requiring reality check functionality:

  1. Include realityCheckInterval - the interval in minutes for reality checks
  2. Include realityCheckElapsed - time already elapsed in the current session
  3. Provide rc_url - URL for the reality check application

The game will automatically prompt players at the specified intervals.

Implementation Best Practices

  1. Validate all incoming parameters from Groove before processing
  2. Store session information securely for later transaction validation
  3. Implement proper error handling for invalid or expired sessions
  4. Support both demo and real modes in your game
  5. Handle device detection to serve appropriate game versions
  6. Maintain session mapping between Groove session IDs and your internal sessions
  7. Use HTTPS for all endpoints
  8. Handle empty homeurl - If homeurl is empty, hide the home button in your game UI to prevent iframe-in-iframe issues

Next Steps

After successfully launching a game, your game will need to communicate with Groove through the Transaction API for:

  • Validating player sessions (GetAccount)
  • Retrieving player balances (GetBalance)
  • Processing bets (Wager)
  • Reporting results (Result)

Continue to Transaction APIs →

Transaction API

Overview

The Transaction API enables your games to communicate with Groove for all wallet and gaming operations. Your game sends transaction requests to Groove, which then handles the actual wallet operations with the casino operators.

This standardized API allows your games to work with any casino operator connected to Groove without needing individual integrations.

Transaction Flow

When a player starts your game:

  1. Your game calls Groove’s GetAccount endpoint to validate the session
  2. Your game calls Groove’s GetBalance to retrieve the player’s current balance
  3. During gameplay, your game sends Wager requests to Groove when players bet
  4. Your game sends Result requests to report wins or losses
  5. If needed, your game can send Rollback requests to correct transactions

API Configuration

  • Groove Transaction Endpoint: {GrooveEndpoint}/groove (Groove will provide this)
  • Request Method: GET
  • Response Format: JSON
  • Authentication: HMAC-SHA256 signature in Authorization header ( see Signature Validation)

Transaction Sequence Diagram

sequenceDiagram participant YourGame as Your Game participant Groove participant Casino participant Wallet as Casino Wallet Note over YourGame,Wallet: Session Validation YourGame->>Groove: GetAccount Request Groove->>Casino: Validate Session Casino-->>Groove: Player Details Groove-->>YourGame: Account Validated Note over YourGame,Wallet: Balance Check YourGame->>Groove: GetBalance Request Groove->>Wallet: Get Balance Wallet-->>Groove: Current Balance Groove-->>YourGame: Balance Response Note over YourGame,Wallet: Bet Processing YourGame->>Groove: Wager Request Groove->>Wallet: Deduct Bet Wallet-->>Groove: Updated Balance Groove-->>YourGame: Wager Confirmed Note over YourGame,Wallet: Win Processing YourGame->>Groove: Result Request Groove->>Wallet: Credit Win Wallet-->>Groove: Updated Balance Groove-->>YourGame: Result Confirmed

Transaction Types

Authentication & Session Management (Your Game → Groove)

  • GetAccount - Validate player session and get player details
  • GetBalance - Retrieve current player balance

Core Gaming Transactions (Your Game → Groove)

  • Wager - Process a bet when player places a wager
  • Result - Report the outcome of a game round
  • Wager and Result - Process bet and result in a single transaction

Correction & Special Transactions (Your Game → Groove)

  • Rollback - Cancel or reverse a previous transaction
  • Jackpot - Report a jackpot win to Groove

Security (Groove → Your Game)

Implementation Requirements for Your Game

Making Requests to Groove

  • All requests from your game to Groove use GET method with URL parameters
  • Session ID from game launch must be included in all transactions
  • Transaction IDs must be unique for each transaction
  • Handle timeouts appropriately (recommended 30 second timeout)

Handling Groove Responses

  • Check response codes - 200 means success, others indicate errors
  • Store transaction IDs for potential rollback scenarios
  • Retry logic should respect idempotency (use same transaction ID)
  • Balance updates should be reflected in your game UI immediately

Balance Management

For CMA-compliant games, additional fields are required:

  • game_mode: Combined real and bonus modes (1 = Real, 2 = Bonus)
  • order: Type of order (cash_money, bonus_money)
  • Separate tracking of real_balance and bonus_balance

Error Handling

Standard Response Structure

{
    "code": 200,
    "status": "Success",
    "apiversion": "1.2",
    // Additional fields based on transaction type
}

Error Response Structure

{
    "code": 1,
    "status": "Technical error",
    "message": "Technical error",
    "apiversion": "1.2"
}

Common Error Codes

Code Status Description
200 Success Transaction processed successfully
1 Technical error Generic technical error
102 Wager not found Wager transaction not found
110 Operation not allowed Operation cannot be performed
400 Transaction parameter mismatch Essential fields mismatch
409 Round closed or transaction ID exists Round already closed
1000 Not logged on Session invalid (not for result/rollback)
1006 Out of money Insufficient funds
1019 Gaming limit Loss or bet limit exceeded
1035 Account blocked Player account is blocked

Best Practices for Game Providers

  1. Session Management: Store the Groove session ID from game launch and use it for all transactions
  2. Unique Transaction IDs: Generate unique IDs for each wager and result to enable proper tracking
  3. Error Handling: Implement comprehensive error handling for all Groove responses
  4. Balance Synchronization: Always update your game UI based on balance returned by Groove
  5. Logging: Maintain detailed logs of all transactions for debugging and reconciliation
  6. Timeout Handling: Implement appropriate timeouts and retry logic
  7. Currency Precision: Always use decimal format with maximum of two decimal places

Security Considerations

  • Implement HMAC-SHA256 signature validation for all incoming requests ( see Signature Validation)
  • Use HTTPS for all communications
  • Validate session tokens properly
  • Implement rate limiting to prevent abuse
  • Log all transactions for audit purposes
  • Store Access Keys securely (never in code)

Integration Steps for Your Game

  1. Implement session validation - Call GetAccount when game loads
  2. Add balance retrieval - Call GetBalance to show player’s funds
  3. Process bets - Send Wager requests when players place bets
  4. Report results - Send Result requests after each game round
  5. Handle corrections - Implement Rollback for error scenarios
  6. Support jackpots - Send Jackpot requests for special wins

Continue to GetAccount API →

Subsections of Transaction API

GetAccount

GetAccount

Returns player details, such as unique ID, currency, and language.

Responsibilities of the casino platform

The casino platform must confirm the validity of incoming game sessions and account IDs and return the user data relevant for the session. If a retry or rollback request is sent regarding a request that the casino already responded to, the account ID that is returned must be unique per player, and identical.

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
apiversion String Required The API version that will be used
Example: 1.2
device String Required The device currently used by the player
Valid values: desktop or mobile
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
request String Required Request method name
Example: getaccount

Request Example

/groove?request=getaccount&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&apiversion=1.2

Response Parameters

Parameter Data Type Mandatory Description
accountid String Required Account ID generated by the casino
Example: 5179068
apiversion String Required The version of the API being used
Example: 1.2
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
city String(32) Required The city where the player logged in
Examples: London, Tel Aviv
code Integer Required Response code (See Appendix)
Example: 200
country String Required Country code (ISO 3166-1 alpha-2)
Examples: IL, UK, US
currency String Required Currency code (ISO)
Example: EUR
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
gamesessionid String(64) Required The ID for the game session
Example: 11_99d71938-c2d9-4844-b950-d598c2es
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
status String Required The status of the response
Example: Success
Info

For Fugaso GP, the following cryptocurrencies are available: BTC, LTC, DOG, ETH, BCH

Response Example

Success Response

{
  "code": 200,
  "status": "Success",
  "accountid": 8877,
  "city": "aaa",
  "country": "IL",
  "currency": "EUR",
  "gamesessionid": "aaaaa",
  "real_balance": 100,
  "bonus_balance": 50,
  "game_mode": 1,
  "order": "cash_money, bonus_money",
  "apiversion": "1.2"
}

Error Codes

Code Status Message
1 Technical error Technical error
1000 Not logged on Not logged on
1003 Authentication failed Authentication failed

GetBalance

GetBalance

Returns the current balance in the specific player account.

Responsibilities of the casino platform

The casino platform must confirm the validity of the incoming game session ID and that it is connected to the given account ID. The casino platform must also return the player’s current balance, both the bonus balance and the real balance.

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
apiversion String Required The API version that will be used
Example: 1.2
device String Required The device currently used by the player
Valid values: desktop or mobile
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
nogsgameid String Required Groove game ID
Note: Can contain letters and special characters
Example: 80102, game_123, slot-abc
request String Required Request method name
Example: getbalance

Request Example

/groove?request=getbalance&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&nogsgameid=80102&apiversion=1.2

Response Parameters

Parameter Data Type Mandatory Description
apiversion String Required The version of the API being used
Example: 1.2
balance Decimal (32,10) Required The total balance amount (real + bonus)
Examples: 500, 140.25
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
code Integer Required Response code
Example: 200
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
status String Required The status of the response
Example: Success

Response Examples

Success Response

{
    "code": 200,
    "status": "Success",
    "balance": 100,
    "bonus_balance": 50,
    "real_balance": 50,
    "game_mode": 1,
    "order": "cash_money, bonus_money",
    "apiversion": "1.2"
}

Error Response

{
    "code": 1,
    "status": "Technical error",
    "message": "Technical error",
    "apiversion": "1.2"
}

Error Codes

Code Status Message
1 Technical error Technical error

Wager

Wager

The Wager method wagers, or bets, for a player and updates the player’s wallet balance on the casino’s platform. Idempotency must be provided.

Responsibilities of the casino platform

The casino platform must:

  • Confirm that the incoming game session ID is valid and is connected with the given account ID. If this validation fails, refuse the wager.
  • Check that the transaction can be approved. Checks should include:
    • Sufficient funds are available
    • The player is within responsible gaming limits
  • Determine whether the transactions have already been processed or not
  • Check if a request with the same transactionid has been performed before:
    • If any of the essential fields transactionid, accountid, or betamount mismatch, the error Transaction parameter mismatch is returned
    • If there are no mismatches, the original response with the status 200 Success - duplicate request is returned. The only values that may change are the balance related parameters, since the player’s balance may have changed
  • In order to handle future Result and Rollback calls, you must store the following parameters: gamesessionid, accountid, roundid, transactionid and betamount

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
apiversion String Required The API version that will be used
Example: 1.2
betamount Decimal (32,10) Required The wager amount (total of real and bonus money)
Note: Must be 0 for free round transactions when frbid is provided
Examples: 2, 0.4, 0.01 (regular), 0 (free rounds)
device String Required The device currently used by the player
Valid values: desktop, mobile
frbid String(255) Optional* Free Round Bonus ID - Must be the templateId from FRB assign response
*Required for free round transactions
Example: 123abc456 (the templateId from assign response)
gameid String Required Groove game ID
Note: Can contain letters and special characters
Example: 80102, game_123, slot-abc
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
request String Required Request method name
Example: wager
roundid String(255) Required Round ID
Example: 802d1812c32686748f2afbcacfcc82114cf
transactionid String(255) Required Transaction ID
Example: 7617edd0924c11e7abb2865556898ad0

Request Examples

Regular Wager (No Free Rounds)

/groove?request=wager&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&betamount=10.0&roundid=nc8n4nd87&transactionid=trx_id

Free Round Wager

/groove?request=wager&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&betamount=0&roundid=nc8n4nd87&transactionid=trx_id&frbid=123abc456

**Free Round Transactions:** - `betamount` must be `0` when using free rounds - `frbid` must be the `templateId` from the FRB assign response - The same template can be assigned multiple times to the same player

Response Parameters

Parameter Data Type Mandatory Description
accounttransactionid String(50) Required The casino’s internal transaction ID
Example: 7617edd0924c11e7abb2865556898ad0
apiversion String Required The version of the API being used
Example: 1.2
balance Decimal (32,10) Required The total balance amount after the wager
Examples: 500, 140.25
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
bonusmoneybet Decimal (32,10) Required The bonus amount used in the bet
If casino doesn’t work with bonuses, value must be 0
code Integer Required Response code
Example: 200
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
realmoneybet Decimal (32,10) Required The real money amount used in the bet
status String Required The status of the response
Example: Success
Warning

The sum of `bonusmoneybet` and `realmoneybet` must equal the `betamount` sent by the provider.

Response Example

Success Response

{
    "code": 200,
    "status": "Success",
    "accounttransactionid": "aaaaaaa",
    "balance": 100,
    "bonusmoneybet": 0,
    "realmoneybet": 10,
    "bonus_balance": 50,
    "real_balance": 50,
    "game_mode": 1,
    "order": "cash_money, bonus_money",
    "apiversion": "1.2"
}

Error Codes

Code Status Message
1 Technical error Technical error
110 Operation not allowed Reasons include:
• Wager amount is less than 0
• User with specified accountId not found
• AccountId doesn’t match sessionId
400 Transaction operator mismatch Transaction operator mismatch
409 Round closed or transaction ID exists Round closed or transaction ID exists
1000 Not logged on Not logged on
1006 Out of money Out of money
1019 Gaming limit Loss limit exceeded or Overall bet limit exceeded
1035 Account blocked Account blocked

Result

Result

The game server uses this method to inform that the wager round is complete. The result 0 indicates that the player lost. Idempotency must be provided.

Info

**Note:** - Result requests may be received after the player goes offline - Result requests may be received without a prior wager request for FRB (free round bonus) and tournament auto-payout - For FRB results without a prior wager, the result represents the win from the free round

Responsibilities of the casino platform

The casino platform must:

  • Confirm that the incoming game session ID is valid and is connected with the given account ID
  • Check if a request with the same transactionid has been performed before:
    • If any of the essential fields transactionid, accountid, or betamount mismatch, the error Transaction parameter mismatch is returned
    • If there are no mismatches, the original response with the status 200 Success - duplicate request is returned. The only values that may change are the balance related parameters, since the player’s balance may have changed
  • Confirm that the incoming accountid and roundid match up with a previously placed wager. If this confirmation fails, refuse the result
  • A result must be accepted even if the game session has expired, since a result can be reported by the game server later. Groove provides the game session for you as information in this call
  • The only expected return code for a valid result call is success. All other return codes are unexpected and will result in the result attempt being resent. Return code 1000 Not logged on is never a valid response to a result call. The casino platform must accept the result even if the session has expired

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
apiversion String Required The API version that will be used
Example: 1.2
device String Required The device currently used by the player
Valid values: desktop, mobile
frbid String(255) Optional* Free Round Bonus ID - Must be the templateId from FRB assign response
*Required for free round result transactions
Example: 123abc456 (the templateId from assign response)
gameid String Required Groove game ID
Note: Can contain letters and special characters
Example: 80102, game_123, slot-abc
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
gamestatus String Required Game Status
Valid values: completed, pending
request String Required Request method name
Example: result
result Decimal (32,10) Required The amount of money won by the player
If player did not win, value must be 0
Example: 2.25
roundid String(255) Required Round ID
Example: 802d1812c32686748f2afbcacfcc82114cf
transactionid String(255) Required Transaction ID
Example: 7617edd0924c11e7abb2865556898ad0

Request Examples

Regular Result (After Wager)

/groove?request=result&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&result=10.0&roundid=nc8n4nd87&transactionid=trx_id&gamestatus=completed

Free Round Result (No Prior Wager)

/groove?request=result&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&result=10.0&roundid=nc8n4nd87&transactionid=trx_id&gamestatus=completed&frbid=123abc456

**Free Round Result without Wager:** - Can be sent without a prior wager request - Must include `frbid` (the templateId from assign response) - The `result` amount represents the total win from the free round

Response Parameters

Parameter Data Type Mandatory Description
apiversion String Required The version of the API being used
Example: 1.2
balance Decimal (32,10) Required The total balance amount after the result
Examples: 500, 140.25
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
bonusWin Decimal (32,10) Required The bonus amount won
If casino doesn’t work with bonuses, value must be 0
code Integer Required Response code
Example: 200
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
realMoneyWin Decimal (32,10) Required The real money amount won
status String Required The status of the response
Example: Success
walletTx String(50) Required The wallet transaction ID
Example: de73550e-0612-4a1b-8a0d-a5a3745b
Warning

The sum of `bonusWin` and `realMoneyWin` must equal the `result` amount sent by the provider.

Response Example

Success Response

{
    "code": 200,
    "status": "Success",
    "walletTx": "aaaaaaa",
    "balance": 100,
    "bonusWin": 0,
    "realMoneyWin": 10,
    "bonus_balance": 50,
    "real_balance": 50,
    "game_mode": 1,
    "order": "cash_money, bonus_money",
    "apiversion": "1.2"
}

Error Codes

Code Status Message
1 Technical error Technical error
110 Operation not allowed Reasons include:
• Result amount is less than 0
• User with specified accountId not found
• AccountId doesn’t match sessionId
• Game status is not pending or completed
400 Transaction operator mismatch Transaction operator mismatch
409 Round closed or transaction ID exists Round closed or transaction ID exists
1000 Not logged on Not logged on

Rollback

Rollback

This method either rolls back a wager or a wager that did not result in a result. For example, if a player places a wager and the Result request fails, you can send a Rollback request to roll back the original wager.

Responsibilities of the casino platform

The casino platform must confirm that the incoming accountid, roundid, and transactionid are identical to the latest wager in the game round and not included in a result that has been issued for the relevant game round.

The casino platform may, but is not required to, verify that the bet amount in the relevant wager request is identical to the rollback amount.

Info

**Note:** The rollback amount is not mandatory and can be null.

The casino platform must refuse the rollback if any of these assertions fail.

  • Check if a request with the same transactionid has been performed before:
    • If any of the essential fields transactionid, accountid, or betamount mismatch, the error Transaction parameter mismatch is returned
    • If there are no mismatches, the original response with the status 200 Success - duplicate request is returned. The only values that may change are the balance related parameters, since the player’s balance may have changed
  • A rollback can be issued by the game server later. Therefore, a rollback must be accepted even if the game session has expired. Groove provides the game session for you as information in this call
  • The only expected return code for a valid rollback call is 0 success
  • If no matching wager is found, the code 102 Wager not found is returned
  • If the rollback is incorrect, code 110 Operation not allowed is returned
  • Return code 1000 Not logged on is never a valid response to a rollback call. The casino platform must accept the rollback even if the session has expired
  • All other return codes result in a resending of the rollback attempt
  • The Casino must refund the player only if a successful wager was found. Do not refund the player in the case of a failed wager or any other error

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
apiversion String Required The API version that will be used
Example: 1.2
device String Required The device currently used by the player
Valid values: desktop, mobile
gameid String Required Groove game ID
Note: Can contain letters and special characters
Example: 80102, game_123, slot-abc
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
request String Required Request method name
Example: rollback
rollbackamount Decimal (32,10) Optional The betamount in the Wager request that you want to rollback
Example: 0.10
In some cases rollback amount can be 0, then rollback amount should be taken from original wager
roundid String(255) Optional Each casino needs to handle the rollback by transactionId, although sometimes the roundId is sent as well
Example: 802d1812c32686748f2afbcacfcc82114cf
transactionid String(255) Required Transaction ID
Example: 7617edd0924c11e7abb2865556898ad0

Request Example

/groove?request=rollback&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&rollbackamount=10.0&roundid=nc8n4nd87&transactionid=trx_id

Response Parameters

Parameter Data Type Mandatory Description
accounttransactionid String(50) Required The casino’s internal transaction ID
Example: 7617edd0924c11e7abb2865556898ad0
apiversion String Required The version of the API being used
Example: 1.2
balance Decimal (32,10) Required The total balance amount after the rollback
Examples: 500, 140.25
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
code Integer Required Response code
Example: 200
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
status String Required The status of the response
Example: Success

Response Example

Success Response

{
    "code": 200,
    "status": "Success",
    "accounttransactionid": "aaaaaaa",
    "balance": 100,
    "bonus_balance": 50,
    "real_balance": 50,
    "game_mode": 1,
    "order": "cash_money, bonus_money",
    "apiversion": "1.2"
}

Error Codes

Code Status Description
1 Technical error Technical error
102 Wager not found Reasons include:
• A wager with the given transactionId is not found
• The roundId in the rollback request is not the same as the roundId of a wager with the specified transactionId
110 Operation not allowed Reasons include:
• A win request was already received for the given wager

Wager And Result

Wager And Result

Places a wager and sets the result amount at the same time. Idempotency must be provided, which means equal requests should only be processed once. If a request is duplicated, that is, the requests have the same transactionid, the original response must be sent with the status 200, Success - duplicate request status.

Responsibilities of the casino platform

The same as in the separate Wager and Result requests.

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
apiversion String Required The API version that will be used
Example: 1.2
betamount Decimal (32,10) Required The wager amount (total of real and bonus money)
Note: Must be 0 for free round transactions when frbid is provided
Examples: 2, 0.4, 0.01 (regular), 0 (free rounds)
device String Required The device currently used by the player
Valid values: desktop, mobile
frbid String Optional* Free Round Bonus ID - Must be the templateId from FRB assign response
*Required for free round transactions
Example: 123abc456 (the templateId from assign response)
Note: The FRB result can be sent without a separate wager
gameid String Required Groove game ID
Note: Can contain letters and special characters
Example: 80102, game_123, slot-abc
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
gamestatus String Required Game Status
Valid values: completed, pending
request String Required Request method name
Example: wagerAndResult
result Decimal (32,10) Required The amount of money won by the player
Example: 2.25
roundid String(255) Required Round ID
Example: 802d1812c32686748f2afbcacfcc82114cf
transactionid String(255) Required Transaction ID
Example: 7617edd0924c11e7abb2865556898ad0

Request Examples

Regular Wager and Result (No Free Rounds)

/groove?request=wagerAndResult&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&result=10.0&betamount=5.0&roundid=nc8n4nd87&transactionid=trx_id&gamestatus=completed

Free Round Wager and Result

/groove?request=wagerAndResult&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&result=10.0&betamount=0&roundid=nc8n4nd87&transactionid=trx_id&gamestatus=completed&frbid=123abc456

**Free Round Transactions:** - `betamount` must be `0` when using free rounds - `frbid` must be the `templateId` from the FRB assign response - The `result` amount represents the win from the free round

Response Parameters

Parameter Data Type Mandatory Description
apiversion String Required The version of the API being used
Example: 1.2
balance Decimal (32,10) Required The total balance amount after the transaction
Examples: 500, 140.25
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
bonusmoneybet Decimal (32,10) Required The bonus amount used in the bet
If casino doesn’t work with bonuses, value must be 0
bonusWin Decimal (32,10) Required The bonus amount won
If casino doesn’t work with bonuses, value must be 0
code Integer Required Response code
Example: 200
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
realmoneybet Decimal (32,10) Required The real money amount used in the bet
realmoneyWin Decimal (32,10) Required The real money amount won
status String Required The status of the response
Example: Success
walletTx String(50) Required The wallet transaction ID
Example: de73550e-0612-4a1b-8a0d-a5a3745b
Warning

- The sum of `bonusmoneybet` and `realmoneybet` must equal the `betamount` sent by the provider - The sum of `bonusWin` and `realmoneyWin` must equal the `result` amount sent by the provider

Response Example

Success Response

{
  "code": 200,
  "status": "Success",
  "walletTx": "aaaaaaa",
  "balance": 100,
  "bonusWin": 0,
  "realmoneyWin": 0,
  "bonusmoneybet": 0,
  "realmoneybet": 5,
  "bonus_balance": 50,
  "real_balance": 50,
  "game_mode": 1,
  "order": "cash_money, bonus_money",
  "apiversion": "1.2"
}

Error Codes

The error codes are the same that are used in separate Wager and Result requests.

Jackpot

Jackpot

Groove Gaming sends this request as a Result call when the player wins a jackpot. Idempotency must be provided, which means the same request should only be processed once. If a request is duplicated, the original response must be sent with status 200, Success - duplicate request status.

Request Parameters

Parameter Data Type Mandatory Description
accountid String(60) [0-9a-zA-Z] Required Account ID
Example: 5179068
amount Decimal (32,10) Required The jackpot win amount
Example: 2000
apiversion String Required The API version that will be used
Example: 1.2
gameid String Required Groove game ID
Note: Can contain letters and special characters
Example: 80102, game_123, slot-abc
gamesessionid String(64) Required The game session id from the start game
Example: 11_99d71938-c2d9-4844-b950-d598c2es
gamestatus String Required Game Status
Valid values: completed, pending
request String Required Request method name
Example: jackpot
roundid String(255) Required Round ID
Example: 802d1812c32686748f2afbcacfcc82114cf
transactionid String(255) Required Transaction ID
Example: 7617edd0924c11e7abb2865556898ad0

Request Example

/groove?request=jackpot&gamesessionid=123_jdhdujdk&accountid=111&device=desktop&gameid=80102&apiversion=1.2&amount=2000.0&roundid=nc8n4nd87&transactionid=trx_id&gamestatus=completed

Response Parameters

Parameter Data Type Mandatory Description
apiversion String Required The version of the API being used
Example: 1.2
balance Decimal (32,10) Required The total balance amount after the jackpot
Examples: 500, 140.25
bonus_balance Decimal (32,10) Optional The player’s bonus balance
Example: 50.0
bonusWin Decimal (32,10) Required The bonus amount won from jackpot
If casino doesn’t work with bonuses, value must be 0
code Integer Required Response code
Example: 200
game_mode Integer Optional* Combined real and bonus modes
1 = Real mode
2 = Bonus mode
*Required for CMA-compliant games
order String Optional* The type of order
Valid values: cash_money, bonus_money
*Required for CMA-compliant games
real_balance Decimal (32,10) Required The player’s real balance
Example: 100.0
realmoneyWin Decimal (32,10) Required The real money amount won from jackpot
status String Required The status of the response
Example: Success
walletTx String(50) Required The wallet transaction ID
Example: de73550e-0612-4a1b-8a0d-a5a3745b
Warning

The sum of `bonusWin` and `realmoneyWin` must equal the `amount` sent by the provider.

Response Example

Success Response

{
    "code": 200,
    "status": "Success",
    "walletTx": "aaaaaaa",
    "balance": 2100,
    "bonusWin": 0,
    "realMoneyWin": 2000,
    "bonus_balance": 50,
    "real_balance": 2050,
    "game_mode": 1,
    "order": "cash_money, bonus_money",
    "apiversion": "1.2"
}

Error Codes

Code Status Message
1 Technical error Technical error
110 Operation not allowed Reasons include:
• The result amount is less than 0
• A user with the specified accountId cannot be found
• Game status is not pending or completed
400 Transaction operator mismatch Transaction operator mismatch

Signature Validation

Signature Validation

Overview

For enhanced security, Groove can sign transaction API requests using HMAC-SHA256. Your platform should validate these signatures to ensure requests are authentic and haven’t been tampered with.

Prerequisites

Before validating signatures, you’ll need:

  1. Access Key Value: Provided by Groove during integration setup
  2. Secret: Base64 decoded version of the Access Key Value
Secret = base64_decode(<Access Key Value>)

Note: The Access Key is a pseudo-random HS512 secret provided by Groove.

Authorization Header

Each signed request from Groove includes an Authorization header with the following format:

Authorization: HMAC-SHA256 Signature={Signature}

Header Syntax

Component Description Required
HMAC-SHA256 Authorization scheme Optional (but recommended to verify)
Signature Base64 encoded HMAC-SHA256 hash Required

Signature Calculation

The signature is calculated using:

Signature = base64_encode(HMACSHA256(Path-And-Query, Secret))

Where:

  • Path-And-Query: The canonical representation of the request path and query string
  • Secret: The base64 decoded Access Key Value

Path-And-Query Format

The Path-And-Query is the concatenation of:

  1. The request’s absolute URI path
  2. The query string (including the ?)

Example

For a request to:

https://your-domain.com/groove?request=getbalance&gamesessionid=123&accountid=456

The Path-And-Query would be:

/groove?request=getbalance&gamesessionid=123&accountid=456

Implementation Example

PHP Implementation

function validateGrooveSignature($request, $accessKeyValue) {
    // Get the Authorization header
    $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
    
    // Extract signature from header
    if (!preg_match('/HMAC-SHA256\s+Signature=(.+)/', $authHeader, $matches)) {
        return false;
    }
    
    $providedSignature = $matches[1];
    
    // Decode the secret
    $secret = base64_decode($accessKeyValue);
    
    // Build Path-And-Query
    $pathAndQuery = $_SERVER['REQUEST_URI'];
    
    // Calculate expected signature
    $hash = hash_hmac('sha256', $pathAndQuery, $secret, true);
    $expectedSignature = base64_encode($hash);
    
    // Compare signatures (constant-time comparison)
    return hash_equals($expectedSignature, $providedSignature);
}

// Usage
$accessKeyValue = "your_base64_access_key_from_groove";
if (validateGrooveSignature($_REQUEST, $accessKeyValue)) {
    // Process the valid request
    processTransaction();
} else {
    // Reject invalid signature
    http_response_code(401);
    echo json_encode([
        "code" => 401,
        "status" => "Unauthorized",
        "message" => "Invalid signature"
    ]);
}

Node.js Implementation

const crypto = require('crypto');

function validateGrooveSignature(req, accessKeyValue) {
    // Get the Authorization header
    const authHeader = req.headers['authorization'] || '';
    
    // Extract signature from header
    const match = authHeader.match(/HMAC-SHA256\s+Signature=(.+)/);
    if (!match) {
        return false;
    }
    
    const providedSignature = match[1];
    
    // Decode the secret
    const secret = Buffer.from(accessKeyValue, 'base64');
    
    // Build Path-And-Query
    const pathAndQuery = req.originalUrl;
    
    // Calculate expected signature
    const hash = crypto
        .createHmac('sha256', secret)
        .update(pathAndQuery)
        .digest('base64');
    
    // Compare signatures (constant-time comparison)
    return crypto.timingSafeEqual(
        Buffer.from(hash),
        Buffer.from(providedSignature)
    );
}

// Usage in Express.js
app.get('/groove', (req, res) => {
    const accessKeyValue = process.env.GROOVE_ACCESS_KEY;
    
    if (!validateGrooveSignature(req, accessKeyValue)) {
        return res.status(401).json({
            code: 401,
            status: "Unauthorized",
            message: "Invalid signature"
        });
    }
    
    // Process valid request
    processTransaction(req, res);
});

Python Implementation

import hmac
import hashlib
import base64
from flask import request, jsonify

def validate_groove_signature(access_key_value):
    # Get the Authorization header
    auth_header = request.headers.get('Authorization', '')
    
    # Extract signature from header
    import re
    match = re.search(r'HMAC-SHA256\s+Signature=(.+)', auth_header)
    if not match:
        return False
    
    provided_signature = match.group(1)
    
    # Decode the secret
    secret = base64.b64decode(access_key_value)
    
    # Build Path-And-Query
    path_and_query = request.full_path
    if path_and_query.endswith('?'):
        path_and_query = path_and_query[:-1]
    
    # Calculate expected signature
    hash_obj = hmac.new(
        secret,
        path_and_query.encode('utf-8'),
        hashlib.sha256
    )
    expected_signature = base64.b64encode(hash_obj.digest()).decode('utf-8')
    
    # Compare signatures (constant-time comparison)
    return hmac.compare_digest(expected_signature, provided_signature)

# Usage in Flask
@app.route('/groove')
def handle_groove_request():
    access_key_value = os.environ.get('GROOVE_ACCESS_KEY')
    
    if not validate_groove_signature(access_key_value):
        return jsonify({
            'code': 401,
            'status': 'Unauthorized',
            'message': 'Invalid signature'
        }), 401
    
    # Process valid request
    return process_transaction()

Testing Signature Validation

Test Example

Given:

  • Access Key Value: dGVzdF9zZWNyZXRfa2V5XzEyMw==
  • Request URL: /groove?request=getbalance&accountid=123
  • Expected Path-And-Query: /groove?request=getbalance&accountid=123

Steps:

  1. Decode secret: base64_decode("dGVzdF9zZWNyZXRfa2V5XzEyMw==")
  2. Calculate HMAC-SHA256 of Path-And-Query with secret
  3. Base64 encode the hash
  4. Compare with provided signature

Security Best Practices

  1. Always validate signatures in production environments
  2. Use constant-time comparison to prevent timing attacks
  3. Store Access Key securely (environment variables, secure vault)
  4. Log validation failures for security monitoring
  5. Reject requests with invalid or missing signatures
  6. Rotate Access Keys periodically as per security policy
  7. Use HTTPS for all communications

Common Issues and Solutions

Issue 1: Signature Mismatch

Cause: Incorrect Path-And-Query construction Solution: Ensure you’re using the exact request URI including all query parameters

Issue 2: Encoding Problems

Cause: Incorrect base64 decoding of Access Key Solution: Verify the Access Key is properly base64 decoded before use

Issue 3: Missing Authorization Header

Cause: Header not properly forwarded by proxy/load balancer Solution: Configure your infrastructure to forward Authorization headers

Issue 4: Query Parameter Order

Cause: Parameters reordered by framework Solution: Use the raw request URI as received, not reconstructed

Response for Invalid Signatures

When signature validation fails, return:

{
    "code": 401,
    "status": "Unauthorized",
    "message": "Invalid signature",
    "apiversion": "1.2"
}

Integration Checklist

  • Receive Access Key Value from Groove
  • Implement signature validation in your chosen language
  • Test with sample requests from Groove
  • Handle both signed and unsigned requests (during transition)
  • Configure proper error responses
  • Set up monitoring for validation failures
  • Document your validation endpoint

Note on Optional Implementation

While signature validation is highly recommended for production environments, it may be optional during initial integration and testing phases. Coordinate with Groove to determine when signature validation should be enabled for your integration.

Free Round Bonus API

Overview

The Free Round Bonus (FRB) API enables your game platform to receive and process free spin bonus requests from Groove. When casino operators want to offer free spins to their players on your games, Groove sends requests to your FRB API endpoints.

Through this API, your platform will:

  • Receive bonus template creation requests from Groove
  • Process player bonus assignments sent by Groove
  • Track and validate free round usage during gameplay
  • Support multi-currency with automatic conversion from EUR base

Integration Flow

sequenceDiagram participant Casino as Casino Operator participant Groove participant YourAPI as Your FRB API participant YourGame as Your Game Server participant Player Note over Casino,YourAPI: Template Creation Casino->>Groove: Create bonus campaign Groove->>YourAPI: POST /create (bonus template) YourAPI-->>Groove: Template ID response Note over Casino,YourAPI: Bonus Assignment Casino->>Groove: Assign bonus to players Groove->>YourAPI: POST /assign (player list) YourAPI-->>Groove: Assignment confirmation Note over Player,YourGame: Free Round Usage Player->>YourGame: Play free rounds YourGame->>Groove: Wager with frbid Groove-->>YourGame: Transaction response

API Endpoints (Your Implementation)

Your platform must implement these endpoints to receive FRB requests from Groove:

1. Create Bonus Template

Method: POST
Endpoint: https://{your_domain}/frb/create (or your specified endpoint)
Purpose: Receive and process bonus template creation requests from Groove
Direction: Groove → Your Platform

2. Assign Bonus to Players

Method: POST
Endpoint: https://{your_domain}/frb/assign (or your specified endpoint)
Purpose: Receive and process bonus assignment requests from Groove
Direction: Groove → Your Platform

3. Get FRB Status

Method: GET
Endpoint: https://{your_domain}/frb/{version}/bonus
Purpose: Provide status information for a specific bonus assignment
Direction: Groove → Your Platform

4. Cancel FRB

Method: DELETE
Endpoint: https://{your_domain}/frb/{version}/bonus
Purpose: Cancel an active bonus assignment for a player
Direction: Groove → Your Platform

Key Features

Bonus Template Assignment and Currency Conversion

When Groove sends you bonus assignments:

  • Base Currency: All templates use EUR as the base currency
  • Automatic Conversion: Your system should convert EUR amounts to each player’s currency
  • Multiple Assignments: The same template can be assigned to multiple players
  • Currency Alignment: Each player receives the bonus in their account currency
  • Exchange Rates: Use current rates to convert from EUR to player currencies

Request/Response Format

  • Content-Type: application/json; charset=UTF-8
  • Method: POST for all FRB endpoints
  • All dates/times in UTC format
  • Currency codes in ISO3 format
  • Country codes in ISO3 format

Implementation Requirements for Your Platform

  1. Idempotency: Handle duplicate requests from Groove properly - return same response
  2. Template Storage: Store template IDs when Groove creates them
  3. Currency Conversion: Convert EUR base amounts to player currencies
  4. Bulk Processing: Handle multiple player assignments in single request
  5. Error Responses: Return appropriate error codes to Groove
  6. Session Validation: Validate Groove session IDs in bonus requests
  7. Audit Trail: Log all bonus operations from Groove

Error Response Format

All error responses follow this structure:

{
    "status": "Error Type",
    "code": 400,
    "templateId": null,
    "exceptionResponses": "Error description"
}

Common Error Codes

Code Status Description
200 Success Request processed successfully
400 General Error Invalid parameters or request
443 Wrong Game ID Game ID is not valid
444 Wrong Player ID Player ID is not valid
449 Invalid Parameters Parameter validation failed
500 Internal Error Server error occurred

Best Practices for Your Implementation

  1. Request Validation: Validate all parameters from Groove before processing
  2. Template Management: Store template details when Groove creates them
  3. Partial Success: Return detailed status for each player in bulk assignments
  4. Audit Logging: Log all incoming requests from Groove
  5. Currency Precision: Maintain proper decimal precision in conversions
  6. Expiry Handling: Track and enforce bonus expiration dates
  7. Duplicate Handling: Return original response for duplicate requests from Groove
  8. Session Security: Always validate Groove session tokens

Integration with Game Transactions

When a player uses free rounds in your game:

  1. Your game checks if the player has active free rounds
  2. Your game sends wager request to Groove with:
    • frbid: The unique assignment ID your platform generated in the assign response
    • betamount: Must be 0 (zero) for free round transactions
  3. Groove validates the bonus and processes the transaction
  4. Your game decrements the free round count after successful wager
Warning

**Important Transaction Rules for Free Rounds:** - **frbid**: Must be the unique `templateId` that YOUR PLATFORM generates and returns in the assign response - **betamount**: Must always be `0` for free round wagers - **Unique Assignment IDs**: Each assignment must return a new unique templateId, even for the same bonus template - **Multiple Grants**: The same template can be assigned multiple times to the same player - each with its own unique assignment ID

Integration Steps

  1. Set up FRB endpoints on your servers to receive Groove requests
  2. Implement template storage to save bonus templates from Groove
  3. Add assignment logic to process player bonus assignments
  4. Implement status tracking to provide real-time bonus status
  5. Add cancellation support to handle bonus cancellations
  6. Integrate with your games to track free round usage
  7. Test with Groove using their staging environment
  8. Monitor and log all FRB operations for reconciliation

API Documentation

Subsections of Free Round Bonus API

Create Bonus

Create Bonus Template

This endpoint receives bonus template creation requests from Groove. When casino operators want to set up free spin campaigns for your games, Groove sends the template details to your platform.

Request Details (From Groove to Your Platform)

  • Method: POST
  • Endpoint: https://{your_domain}/frb/create (or your specified endpoint)
  • Content-Type: application/json; charset=UTF-8
  • Direction: Groove → Your Platform

Request Parameters (What You’ll Receive from Groove)

Parameter Type Mandatory Description
providerName string Yes Provider’s name
operatorId int Yes Operator’s ID
transactionId string Yes Transaction’s ID
numberOfRounds int Yes Amount of free bets
availableFromDate string Yes Date and time from which the bonus becomes available in UTC
Format: YYYY-MM-DD HH:MM:SS
availableDuration int Yes How long the rounds will be available (in days)
expirationDate string Yes Date and time until which the bonus is available in UTC
Format: YYYY-MM-DD HH:MM:SS
balanceTypeId int Yes Defines if the money goes to bonus/real
messageFirstLine string Yes Text message 1
messageSecondLine string Yes Text message 2
offerName string Yes Name of the offer
gameInfoList array Yes Array with the game details
gameInfoList.gameId string Yes Identifies specific game
gameInfoList.betAmount decimal Yes Bet value for each free bet

Request Example

{
    "providerName": "Provider Name",
    "operatorId": 11,
    "transactionId": "292c8dbb-e00d-4807-a754-0b9ae5297c1j",
    "numberOfRounds": 10,
    "availableFromDate": "2023-06-19 14:56:56",
    "availableDuration": 90,
    "expirationDate": "2025-01-15 11:24:38",
    "balanceTypeId": 1,
    "messageFirstLine": "You got a Free Round Bonus",
    "messageSecondLine": "It's your lucky day",
    "offerName": "2e10691304314db08244f8c730055af73781878195",
    "gameInfoList": [
        {
            "gameId": "provider_game_id",
            "betAmount": 1
        }
    ]
}

Response Examples

Success Response

{
    "status": "Success",
    "code": 200,
    "templateId": "123456789",
    "exceptionResponses": null
}

Error Responses

General Error

{
    "status": "General Error",
    "code": 400,
    "templateId": null,
    "exceptionResponses": "Invalid Parameters"
}

Wrong Game ID

{
    "status": "Wrong Game ID",
    "code": 443,
    "templateId": null,
    "exceptionResponses": "Game id 123 is not valid"
}

Invalid Parameters

{
    "status": "Invalid Parameters",
    "code": 449,
    "templateId": null,
    "exceptionResponses": "Expiration Date is already Expired"
}

Internal Error

{
    "status": "Internal Error",
    "code": 500,
    "templateId": null,
    "exceptionResponses": null
}

Alternative Internal Error format:

{
    "status": "Internal Error",
    "errorCode": 500,
    "description": "Wrong info received"
}

Implementation Requirements

  1. Template ID Generation: Your system must generate and return a unique templateId in the response
  2. Storage: Store the template details for future player assignments from Groove
  3. Currency: All bet amounts are in EUR - convert when assigning to players
  4. Multi-Game Support: A template can include multiple games from your portfolio
  5. Offer Tracking: Store the offerName as a unique identifier from Groove
  6. Date Validation: Verify expiration date is after available from date
  7. Idempotency: If Groove resends the same transactionId, return the original response

Processing the Request (Your Implementation)

// Example of how to process the incoming request from Groove
app.post('/frb/create', (req, res) => {
    const {
        providerName,
        operatorId,
        transactionId,
        numberOfRounds,
        gameInfoList,
        expirationDate,
        // ... other parameters
    } = req.body;
    
    // Validate the request
    if (!validateGameIds(gameInfoList)) {
        return res.status(443).json({
            status: "Wrong Game ID",
            code: 443,
            templateId: null,
            exceptionResponses: "Invalid game ID provided"
        });
    }
    
    // Generate unique template ID
    const templateId = generateUniqueTemplateId();
    
    // Store template in your database
    storeTemplate({
        templateId,
        transactionId,
        operatorId,
        gameInfoList,
        // ... other fields
    });
    
    // Return success response to Groove
    res.json({
        status: "Success",
        code: 200,
        templateId: templateId,
        exceptionResponses: null
    });
});

Validation Checklist

When processing requests from Groove, validate:

  • ✅ All required fields are present in the request
  • ✅ Game IDs match games available on your platform
  • ✅ Dates are in correct UTC format (YYYY-MM-DD HH:MM:SS)
  • ✅ Expiration date is after available from date
  • ✅ Bet amounts are positive numbers
  • ✅ Transaction ID hasn’t been processed before (idempotency check)

Assign Bonus

Assign Bonus to Players

This endpoint receives player bonus assignment requests from Groove. When casino operators want to grant free spins to specific players on your games, Groove sends the assignment details to your platform.

Request Details (From Groove to Your Platform)

  • Method: POST
  • Endpoint: https://{your_domain}/frb/assign (or your specified endpoint)
  • Content-Type: application/json; charset=UTF-8
  • Direction: Groove → Your Platform

Request Parameters (What You’ll Receive from Groove)

Parameter Type Mandatory Description
templateId string Yes Template’s ID (from create response)
providerName string Yes Provider’s name
operatorId int Yes Operator’s ID
transactionId string Yes Transaction’s ID
numberOfRounds int Yes Amount of free bets
availableFromDate string Yes Date and time from which the bonus becomes available in UTC
availableDuration int Yes How long the rounds will be available (in days)
expirationDate string Yes Date and time until which the bonus is available in UTC
balanceTypeId int Yes Defines if the money goes to bonus/real
messageFirstLine string Yes Text message 1
messageSecondLine string Yes Text message 2
offerName string Yes Name of the offer
gameInfoList array Yes Array with the game details
gameInfoList.gameId string Yes Identifies specific game
gameInfoList.betAmount decimal Yes Bet value for each free bet
players array Yes Array with the player details
players.playerId string Yes Player’s ID on operator’s side
players.playerCurrency string Yes Player’s currency in ISO3 format
players.playerCountry string Yes Player’s country in ISO3 format

Request Example

{
    "templateId": "fe06efeb-b7fd-4249-a58d-717226507d5f",
    "providerName": "Provider Name",
    "operatorId": 11,
    "transactionId": "292c8dbb-e00d-4807-a754-0b9ae5297c1j",
    "numberOfRounds": 10,
    "availableFromDate": "2023-06-19 14:56:56",
    "availableDuration": 90,
    "expirationDate": "2025-01-15 11:24:38",
    "balanceTypeId": 1,
    "messageFirstLine": "You got a Free Round Bonus",
    "messageSecondLine": "It's your lucky day",
    "offerName": "2e10691304314db08244f8c730055af73781878195",
    "gameInfoList": [
        {
            "gameId": "provider_game_id",
            "betAmount": 1
        }
    ],
    "players": [
        {
            "playerId": "12345678",
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ]
}

Response Examples

Success Response

{
    "code": 200,
    "status": "Success",
    "templateId": "assign_unique_456xyz",  // Unique ID for THIS assignment (different from create templateId)
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        },
        {
            "playerId": 793918408,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": null
}

**IMPORTANT - Unique Assignment IDs**: - Each `/assign` request must return a **unique templateId** in the response - This is different from the templateId received in the `/create` request - The unique assignment templateId allows casinos to track different bonus triggers (e.g., registration bonus vs deposit bonus) - This unique assignment templateId will be used as the `frbid` parameter in transaction requests - Example: Same bonus template assigned twice to same player should return two different templateIds

Partially Success Response

When some players are assigned successfully but others fail:

{
    "code": 200,
    "status": "Partially Succeeded",
    "templateId": "123abc456",
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": null
}

Error Responses

General Error

{
    "status": "General Error",
    "code": 400,
    "templateId": null,
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": "Invalid Parameters"
}

Wrong Game ID

{
    "status": "Wrong Game ID",
    "code": 443,
    "templateId": null,
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": "Game id 123 is not valid"
}

Wrong Player ID

{
    "status": "Wrong Player Id",
    "code": 444,
    "templateId": null,
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": ""
}

Internal Error

{
    "status": "Internal Error",
    "code": 500,
    "templateId": null,
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": null
}

Implementation Requirements

  1. Template Validation: Verify the templateId in the request matches a template previously created by Groove
  2. Generate Unique Assignment ID: Create a new unique templateId for each assignment (different from the create templateId)
  3. Currency Conversion: Your system must convert bet amounts from EUR to each player’s currency
  4. Bet Value Mapping: After currency conversion, use the closest bet value supported by your game for that currency
  5. Bulk Processing: Handle multiple player assignments in a single request from Groove
  6. Partial Success Handling: Support partial success - some players may succeed while others fail
  7. Player Validation: Check if player IDs from Groove exist in your system
  8. Assignment Tracking: Store each unique assignment with its generated templateId for transaction reference
  9. Idempotency: If Groove resends the same transactionId, return the original response with the same unique templateId

Processing the Request (Your Implementation)

// Example of how to process the incoming assignment request from Groove
app.post('/frb/assign', (req, res) => {
    const {
        templateId,
        transactionId,
        players,
        gameInfoList,
        // ... other parameters
    } = req.body;
    
    // Check if template exists (created earlier by Groove)
    const template = getTemplate(templateId);
    if (!template) {
        return res.status(400).json({
            status: "General Error",
            code: 400,
            templateId: null,
            players: players,
            exceptionResponses: "Template not found"
        });
    }
    
    // Generate a UNIQUE assignment ID for this specific assignment
    // This is different from the templateId in the request
    const uniqueAssignmentId = generateUniqueAssignmentId();
    // Example: "assign_" + uuid() or "assign_" + timestamp + "_" + randomId
    
    // Process each player
    const successfulPlayers = [];
    const failedPlayers = [];
    
    for (const player of players) {
        // Validate player exists in your system
        if (!validatePlayer(player.playerId)) {
            failedPlayers.push(player);
            continue;
        }
        
        // Convert EUR bet amounts to player's currency
        // and map to closest supported bet value
        const convertedBets = convertBetAmounts(
            gameInfoList,
            player.playerCurrency
        );
        
        // Map to closest supported bet values for the game
        const supportedBets = mapToSupportedBetValues(
            convertedBets,
            player.playerCurrency
        );
        
        // Assign bonus to player with the unique assignment ID
        assignBonusToPlayer({
            playerId: player.playerId,
            originalTemplateId: templateId,  // Store original for reference
            assignmentId: uniqueAssignmentId,  // Unique ID for this assignment
            convertedBets: supportedBets,
            expirationDate: req.body.expirationDate
        });
        
        successfulPlayers.push(player);
    }
    
    // Return appropriate response to Groove with UNIQUE assignment ID
    if (successfulPlayers.length === players.length) {
        res.json({
            code: 200,
            status: "Success",
            templateId: uniqueAssignmentId,  // Return the UNIQUE assignment ID
            players: successfulPlayers,
            exceptionResponses: null
        });
    } else if (successfulPlayers.length > 0) {
        res.json({
            code: 200,
            status: "Partially Succeeded",
            templateId: uniqueAssignmentId,  // Return the UNIQUE assignment ID
            players: successfulPlayers,
            exceptionResponses: null
        });
    } else {
        res.status(444).json({
            status: "Wrong Player Id",
            code: 444,
            templateId: null,
            players: failedPlayers,
            exceptionResponses: "No valid players found"
        });
    }
});

Validation Checklist

When processing assignment requests from Groove:

  • ✅ Template ID exists in your system (from previous create request)
  • ✅ All player IDs are validated against your player database
  • ✅ Currency codes are in ISO3 format and supported
  • ✅ Bet amounts are converted from EUR to player currencies
  • ✅ Transaction ID hasn’t been processed before (idempotency)
  • ✅ Expiration date hasn’t passed

Parameter Mismatch Handling

If the assignment parameters from Groove don’t match the stored template (except availableFromDate), return an error response:

{
    "status": "General Error",
    "code": 400,
    "templateId": null,
    "players": [...],
    "exceptionResponses": "Transaction parameter mismatch"
}

Currency Conversion Example

When Groove sends a template with EUR bet amounts, convert for each player:

Template (EUR) Player Currency Converted Amount
1.00 EUR USD 1.10 USD
1.00 EUR GBP 0.85 GBP
1.00 EUR EUR 1.00 EUR

Important: After converting the EUR amount to the player’s currency, use the closest bet value supported by your game for that currency. For example, if the conversion results in 1.13 USD but your game only supports 1.00 or 1.25 USD bets, use the closest supported value.

Get FRB Status

Get FRB Status

This endpoint allows Groove to query the status of a specific free round bonus assignment for a player on your platform.

Request Details (From Groove to Your Platform)

  • Method: GET
  • Endpoint: https://{your_domain}/frb/{version}/bonus?operator_id={operator_id}&template_id={template_id}&player_id={player_id}
  • Direction: Groove → Your Platform

Request Parameters (What You’ll Receive from Groove)

Parameter Type Mandatory Description
version String Yes The API version. Currently supports 1.0
Example: 1.0
operator_id Integer Yes Groove operator ID
Example: 11
template_id String Yes The unique assignment ID (the one your platform generated during /assign)
Example: assign_456xyz
player_id String Yes The player ID
Example: 12345678

Request Example

GET /frb/1.0/bonus?operator_id=11&template_id=assign_456xyz&player_id=12345678

Response Parameters (What You Must Return)

Parameter Type Mandatory Description
player_id String Yes The player ID from the request
player_currency String Yes Player’s currency in ISO3 format
operator_id Integer Yes The operator ID from the request
provider_id Integer Yes Your provider ID
status String Yes Current status of the bonus (see Status Index below)
template_id String Yes The assignment ID from the request
left_rounds Integer Conditional* Number of rounds remaining
*Required if status is active
total_rounds Integer Conditional* Total number of rounds originally granted
*Required if status is active
expiration_date String Yes Expiration date in ISO 8601 format
Example: 2025-02-11T12:00:00Z
games Array Conditional* List of games for this bonus
*Required if status is active
games.game_id String Yes Game identifier
games.bet_amount Array Yes Available bet amounts in player’s currency
games.currency String Yes Currency for the bet amounts
error_message String No Error description (empty string if no error)

Available Statuses

All FRB endpoints must use these exact status values:

Status Value Description
"active" The FRB is active and can be used by the player
"canceled" The FRB has been canceled by the operator
"expired" The FRB has passed its expiration date
"completed" The player has used all available rounds

**Note**: These are the only valid status values. Always use lowercase and return them as strings.

Response Examples

Success Response - Active Bonus

{
    "player_id": "12345678",
    "player_currency": "EUR",
    "operator_id": 11,
    "provider_id": 123,
    "status": "active",
    "template_id": "assign_456xyz",
    "left_rounds": 10,
    "total_rounds": 50,
    "expiration_date": "2025-02-11T12:00:00Z",
    "games": [
        {
            "game_id": "game001",
            "bet_amount": [1.0, 2.0],
            "currency": "EUR"
        },
        {
            "game_id": "game002",
            "bet_amount": [1.0, 2.0],
            "currency": "EUR"
        }
    ],
    "error_message": ""
}

Success Response - Completed Bonus

{
    "player_id": "12345678",
    "player_currency": "EUR",
    "operator_id": 11,
    "provider_id": 123,
    "status": "completed",
    "template_id": "assign_456xyz",
    "left_rounds": 0,
    "total_rounds": 50,
    "expiration_date": "2025-02-11T12:00:00Z",
    "games": [],
    "error_message": ""
}

Error Response

{
    "player_id": "12345678",
    "player_currency": "EUR",
    "operator_id": 11,
    "provider_id": 123,
    "template_id": "assign_456xyz",
    "expiration_date": "2025-02-11T12:00:00Z",
    "error_message": "Bonus not found"
}

HTTP Response Codes

Code Status Description
200 Success FRB status retrieved successfully
400 Bad Request Invalid parameters
403 Forbidden Access denied
500 Internal Server Error Server error occurred

Implementation Example

app.get('/frb/:version/bonus', (req, res) => {
    const { operator_id, template_id, player_id } = req.query;
    const { version } = req.params;
    
    // Validate parameters
    if (!operator_id || !template_id || !player_id) {
        return res.status(400).json({
            player_id: player_id || "",
            player_currency: "",
            operator_id: parseInt(operator_id) || 0,
            provider_id: 123,
            template_id: template_id || "",
            expiration_date: "",
            error_message: "Missing required parameters"
        });
    }
    
    // Look up the bonus assignment
    const assignment = getAssignment(template_id, player_id);
    
    if (!assignment) {
        return res.status(404).json({
            player_id: player_id,
            player_currency: "EUR",
            operator_id: parseInt(operator_id),
            provider_id: 123,
            template_id: template_id,
            expiration_date: "",
            error_message: "Bonus not found"
        });
    }
    
    // Determine status
    let status = 'active';
    if (assignment.canceled) {
        status = 'canceled';
    } else if (new Date(assignment.expiration_date) < new Date()) {
        status = 'expired';
    } else if (assignment.left_rounds === 0) {
        status = 'completed';
    }
    
    // Build response
    res.json({
        player_id: player_id,
        player_currency: assignment.player_currency,
        operator_id: parseInt(operator_id),
        provider_id: 123,
        status: status,
        template_id: template_id,
        left_rounds: assignment.left_rounds,
        total_rounds: assignment.total_rounds,
        expiration_date: assignment.expiration_date,
        games: status === 'active' ? assignment.games : [],
        error_message: ""
    });
});

Important Notes

  1. Template ID: The template_id in the request is the unique assignment ID your platform generated during the /assign request
  2. Status Logic: Determine status based on cancellation, expiration, and remaining rounds
  3. Games Array: Only include games array when status is active
  4. Bet Amounts: Return the converted bet amounts in the player’s currency
  5. Error Handling: Always return a structured response even for errors

Best Practices

  1. Cache Assignment Data: Keep assignment data readily available for quick status checks
  2. Track Round Usage: Accurately track remaining rounds as players use them
  3. Update Status: Automatically update status based on expiration and usage
  4. Validate Operator: Ensure the operator_id matches the assignment
  5. Log Requests: Keep audit logs of all status check requests

Cancel FRB

Cancel FRB

This endpoint allows Groove to cancel an active free round bonus assignment for a player on your platform.

Request Details (From Groove to Your Platform)

  • Method: DELETE
  • Endpoint: https://{your_domain}/frb/{version}/bonus?operator_id={operator_id}&template_id={template_id}&player_id={player_id}
  • Direction: Groove → Your Platform

Request Parameters (What You’ll Receive from Groove)

Parameter Type Mandatory Description
version String Yes The API version. Currently supports 1.0
Example: 1.0
operator_id Integer Yes Groove operator ID
Example: 11
template_id String Yes The unique assignment ID (the one your platform generated during /assign)
Example: assign_456xyz
player_id String Yes The player ID
Example: 12345678

Request Example

DELETE /frb/1.0/bonus?operator_id=11&template_id=assign_456xyz&player_id=12345678

Response Parameters (What You Must Return)

The response structure is identical to the Get FRB Status endpoint, but should reflect the actual status of the bonus.

**Critical**: Always return the ACTUAL status of the bonus, not necessarily "canceled": - If the bonus was already `completed`, return status: `"completed"` - If the bonus was already `expired`, return status: `"expired"` - If the bonus was already `canceled`, return status: `"canceled"` - Only return status: `"canceled"` if the cancellation was actually performed

Parameter Type Mandatory Description
player_id String Yes The player ID from the request
player_currency String Yes Player’s currency in ISO3 format
operator_id Integer Yes The operator ID from the request
provider_id Integer Yes Your provider ID
status String Yes The ACTUAL status of the bonus (see Available Statuses below)
template_id String Yes The assignment ID from the request
left_rounds Integer Yes Number of rounds remaining (0 if completed)
total_rounds Integer Yes Total number of rounds originally granted
expiration_date String Yes Original expiration date in ISO 8601 format
games Array No Empty array for non-active statuses
error_message String No Error description (empty string if successful)

Available Statuses

All FRB endpoints must use these exact status values:

Status Value Description
"active" The FRB is active and can be used by the player
"canceled" The FRB has been canceled by the operator
"expired" The FRB has passed its expiration date
"completed" The player has used all available rounds

Response Examples

Success Response - Bonus Canceled

{
    "player_id": "12345678",
    "player_currency": "EUR",
    "operator_id": 11,
    "provider_id": 123,
    "status": "canceled",
    "template_id": "assign_456xyz",
    "left_rounds": 10,
    "total_rounds": 50,
    "expiration_date": "2025-02-11T12:00:00Z",
    "games": [],
    "error_message": ""
}

Error Response - Bonus Not Found

{
    "player_id": "12345678",
    "player_currency": "EUR",
    "operator_id": 11,
    "provider_id": 123,
    "template_id": "assign_456xyz",
    "expiration_date": "",
    "error_message": "Bonus not found"
}

Response - Already Completed (Cannot Cancel)

{
    "player_id": "12345678",
    "player_currency": "EUR",
    "operator_id": 11,
    "provider_id": 123,
    "status": "completed",
    "template_id": "assign_456xyz",
    "left_rounds": 0,
    "total_rounds": 50,
    "expiration_date": "2025-02-11T12:00:00Z",
    "games": [],
    "error_message": ""
}
Info

**Note**: When a cancellation is requested for an already completed bonus, return HTTP 200 with status: `"completed"` to indicate the actual state. The error_message can be empty or contain an informational message.

HTTP Response Codes

Code Status Description
200 Success FRB canceled successfully
400 Bad Request Invalid parameters or bonus cannot be canceled
403 Forbidden Access denied
404 Not Found Bonus assignment not found
500 Internal Server Error Server error occurred

Implementation Example

app.delete('/frb/:version/bonus', (req, res) => {
    const { operator_id, template_id, player_id } = req.query;
    const { version } = req.params;
    
    // Validate parameters
    if (!operator_id || !template_id || !player_id) {
        return res.status(400).json({
            player_id: player_id || "",
            player_currency: "",
            operator_id: parseInt(operator_id) || 0,
            provider_id: 123,
            template_id: template_id || "",
            expiration_date: "",
            error_message: "Missing required parameters"
        });
    }
    
    // Look up the bonus assignment
    const assignment = getAssignment(template_id, player_id);
    
    if (!assignment) {
        return res.status(404).json({
            player_id: player_id,
            player_currency: "EUR",
            operator_id: parseInt(operator_id),
            provider_id: 123,
            template_id: template_id,
            expiration_date: "",
            error_message: "Bonus not found"
        });
    }
    
    // Check current status and respond accordingly
    if (assignment.status === 'completed') {
        // Return the actual status (completed) - cannot cancel
        return res.json({
            player_id: player_id,
            player_currency: assignment.player_currency,
            operator_id: parseInt(operator_id),
            provider_id: 123,
            status: "completed",  // Return ACTUAL status
            template_id: template_id,
            left_rounds: 0,
            total_rounds: assignment.total_rounds,
            expiration_date: assignment.expiration_date,
            games: [],
            error_message: ""
        });
    }
    
    if (assignment.status === 'expired') {
        // Return the actual status (expired) - can still mark as canceled for records
        return res.json({
            player_id: player_id,
            player_currency: assignment.player_currency,
            operator_id: parseInt(operator_id),
            provider_id: 123,
            status: "expired",  // Return ACTUAL status
            template_id: template_id,
            left_rounds: assignment.left_rounds,
            total_rounds: assignment.total_rounds,
            expiration_date: assignment.expiration_date,
            games: [],
            error_message: ""
        });
    }
    
    if (assignment.status === 'canceled') {
        // Already canceled - return current status
        return res.json({
            player_id: player_id,
            player_currency: assignment.player_currency,
            operator_id: parseInt(operator_id),
            provider_id: 123,
            status: "canceled",  // Already canceled
            template_id: template_id,
            left_rounds: assignment.left_rounds,
            total_rounds: assignment.total_rounds,
            expiration_date: assignment.expiration_date,
            games: [],
            error_message: ""
        });
    }
    
    // Cancel the bonus
    cancelAssignment(template_id, player_id);
    
    // Return success response
    res.json({
        player_id: player_id,
        player_currency: assignment.player_currency,
        operator_id: parseInt(operator_id),
        provider_id: 123,
        status: "canceled",
        template_id: template_id,
        left_rounds: assignment.left_rounds,
        total_rounds: assignment.total_rounds,
        expiration_date: assignment.expiration_date,
        games: [],
        error_message: ""
    });
});

Important Notes

  1. Template ID: The template_id in the request is the unique assignment ID your platform generated during the /assign request
  2. Status Response Rules:
    • ALWAYS return the ACTUAL status of the bonus, not the requested action
    • If bonus is completed, return status: "completed" (not "canceled")
    • If bonus is expired, return status: "expired" (not "canceled")
    • If bonus is already canceled, return status: "canceled"
    • Only return "canceled" if you actually performed the cancellation
  3. HTTP Response Codes:
    • Return HTTP 200 even when returning completed or expired status
    • Use HTTP 404 only when the bonus doesn’t exist
  4. Player Protection: Ensure no active game rounds are using the bonus before cancellation
  5. Audit Trail: Keep records of cancellation attempts, even unsuccessful ones
  6. Immediate Effect: Successful cancellations should take effect immediately

Business Rules

  1. Active Games: If a player is currently in a game round using this bonus, handle appropriately:

    • Option 1: Prevent cancellation until round completes
    • Option 2: Allow cancellation but let current round complete
    • Document your approach for Groove
  2. Refunds: Cancellation does not imply refund - it only stops future usage

  3. Notification: Consider notifying the player that their bonus has been canceled

Best Practices

  1. Transaction Safety: Use database transactions to ensure atomic updates
  2. Concurrent Access: Handle race conditions if player is actively using the bonus
  3. Audit Logging: Log all cancellation requests with timestamp and reason
  4. Status Consistency: Ensure status is consistently updated across all systems
  5. Error Messages: Provide clear error messages for different failure scenarios

FAQ

Frequently Asked Questions

Template Creation & Assignment Flow

Will Groove send an /assign request without first sending a /create request?

Answer: No. Groove will always send a /create request first, and your platform must respond with a templateId. Groove then uses this templateId in subsequent /assign requests.

How do template IDs flow through the FRB process?

Answer: The template ID flow works as follows:

  1. Create: Groove sends create request → Your platform responds with templateId (e.g., “template_123”)
  2. Assign: Groove sends assign request with templateId: "template_123" → Your platform generates and returns a NEW unique templateId (e.g., “assign_456”)
  3. Transaction: Your game sends wager/result with frbid: "assign_456" (the unique assignment ID, not the original template ID)

This allows the same bonus template to be assigned multiple times with unique tracking for each assignment.

Why does Groove send similar data in both create and assign requests?

Answer: Both requests contain similar data for consistency and validation purposes. Your platform can ignore any fields that aren’t relevant to your processing logic.

What should we do if Groove sends an /assign request with different parameters than the original /create request for the same offerName?

Answer: This situation is a mismatch so error should be returned:

{
    "status": "General Error",
    "code": 400,
    "templateId": null,
    "players": [
        {
            "playerId": 793918407,
            "playerCurrency": "EUR",
            "playerCountry": "IRL"
        }
    ],
    "exceptionResponses": "Transaction parameter mismatch"
}

Date & Time Management

Can availableFromDate, availableDuration, and expirationDate be different for POST /create and POST /assign?

Answer:

  • expirationDate - must be the same for both create and assign requests
  • availableDuration - must be the same for both create and assign requests
  • availableFromDate - can be different for both create and assign requests

Are dates in requests in UTC format?

Answer: Correct, all dates are in UTC format.

What does availableDuration mean in Groove’s requests?

Answer: It specifies how many days the free rounds will be available to the player after the availableFromDate.

How does expirationDate relate to availableFromDate in Groove’s requests?

Answer: The expirationDate can be independent of availableFromDate. It represents the final date when the bonus expires, regardless of when it became available.

Duplicate Handling

How should we handle duplicate offerName values from Groove?

Answer: For /create requests from Groove with duplicate offerName, this is an error - return:

{
    "status": "General Error",
    "code": 400,
    "templateId": null,
    "exceptionResponses": "OfferName already exist"
}

For /assign requests, duplicate offerName is normal - it means Groove is assigning the same template to different players, or the same player is receiving the template multiple times.

Game & Player Management

Will Groove send multiple games in the gameInfoList?

Answer: Yes, Groove can send multiple games in a single template. If the list contains only one game, the bonus applies to that specific game. If multiple games are included, the bonus can be used on any of those games.

Will Groove send multiple players in a single /assign request?

Answer: Yes, Groove can send multiple players in the players array for bulk assignments. Your platform should process each player and return appropriate success/failure status for each.

Transaction Integration

What should our game send as frbid when making wager requests to Groove?

Answer: The frbid must be the unique templateId that YOUR PLATFORM generates and returns in the assign response. This is NOT the templateId from the create request or from Groove’s assign request - it’s a new unique ID you generate for each assignment.

What exactly should our game use as the frbid when sending wager requests to Groove?

Answer: The frbid must be the unique templateId that your platform generates and returns in the assign response. Each assignment gets a new unique ID, even when the same bonus template is assigned multiple times to the same player. This allows casinos to differentiate between bonuses triggered by different events (registration, deposit, etc.).

What bet amount should our game send in wager requests for free rounds?

Answer: The betamount parameter must always be 0 (zero) for free round transactions. The actual bet value for the free round is already defined in the FRB template and converted to the player’s currency during assignment.

If a round starts before expirationDate but finishes after, should our game still send the result to Groove?

Answer: Yes, your game should send the result request to Groove. As long as the round started before the expirationDate, it’s valid.

Implementation Details

Currency Conversion

When Groove sends bonus assignments, your platform must convert the EUR base amounts to each player’s currency. This ensures players receive equivalent value in their account currency.

Multiple Assignments from Groove

  • Groove may assign the same template to multiple players
  • Groove may assign the same template to the same player multiple times
  • Each assignment must generate a NEW unique templateId in your response
  • Your platform tracks each assignment with its unique ID (e.g., remaining rounds per assignment)
  • When a player has multiple active assignments, each has its own unique assignment ID for transactions
  • This allows casinos to differentiate bonuses by trigger event (registration vs deposit vs promotion)

Best Practices for Handling Groove Requests

  1. Validate that template exists when Groove sends /assign requests
  2. Check if players exist in your system before assignment
  3. Return specific error codes to help Groove understand issues
  4. Support partial success when Groove sends multiple players
  5. Log all requests from Groove for reconciliation

Testing Your FRB Implementation

  1. Test receiving single and multiple player assignments from Groove
  2. Verify EUR to player currency conversion accuracy
  3. Test edge cases with date validations
  4. Ensure proper error responses are returned to Groove
  5. Test idempotency - return same response if Groove resends requests

Appendix - Transaction Response Status Codes

This section contains reference information for response codes used throughout the Transaction API.

Success Codes

Code Status Description
200 Success Transaction processed successfully
200 Success - duplicate request Request with same transaction ID was already processed

Error Codes

Code Status Description Applicable Endpoints
1 Technical error Generic technical error All
102 Wager not found Wager with given transactionId not found Rollback
110 Operation not allowed Operation cannot be performed due to business rules Wager, Result, Rollback
400 Transaction parameter mismatch Essential fields mismatch (transactionid, accountid, betamount) Wager, Result, Rollback
409 Round closed or transaction ID exists Round already closed or transaction ID already used Wager, Result
443 Wrong Game ID Game ID is not valid FRB Create/Assign
444 Wrong Player Id Player ID is not valid FRB Assign
449 Invalid Parameters Request parameters are invalid FRB Create/Assign
500 Internal Error Internal server error FRB Create/Assign
1000 Not logged on Session invalid or expired GetAccount, GetBalance, Wager
1003 Authentication failed Authentication failed GetAccount
1006 Out of money Insufficient funds Wager
1019 Gaming limit Loss limit exceeded or Overall bet limit exceeded Wager
1035 Account blocked Player account is blocked Wager

Operation Not Allowed Details

Code 110 (Operation not allowed) can occur for various reasons:

For Wager:

  • The wager amount is less than 0
  • A user with the specified accountId cannot be found
  • The accountId is not identical to the sessionId that was created

For Result:

  • The result amount is less than 0
  • A user with the specified accountId cannot be found
  • The accountId is not identical to the sessionId that was created
  • Game status is not pending or completed

For Rollback:

  • A win request was already received for the given wager

Important Notes

  1. Success - duplicate request: When a request with the same transaction ID is received again, the original response should be returned with status 200. Balance-related parameters may differ as the player’s balance may have changed.

  2. Session Expiry: Result and Rollback requests must be accepted even if the game session has expired. Return code 1000 (Not logged on) is never a valid response to result or rollback calls.

  3. Idempotency: All transaction endpoints must provide idempotency to ensure duplicate requests are handled properly.