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=12345678Response 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": ""
}**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
- Template ID: The
template_idin the request is the unique assignment ID your platform generated during the /assign request - 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
- HTTP Response Codes:
- Return HTTP 200 even when returning
completedorexpiredstatus - Use HTTP 404 only when the bonus doesn’t exist
- Return HTTP 200 even when returning
- Player Protection: Ensure no active game rounds are using the bonus before cancellation
- Audit Trail: Keep records of cancellation attempts, even unsuccessful ones
- Immediate Effect: Successful cancellations should take effect immediately
Business Rules
-
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
-
Refunds: Cancellation does not imply refund - it only stops future usage
-
Notification: Consider notifying the player that their bonus has been canceled
Best Practices
- Transaction Safety: Use database transactions to ensure atomic updates
- Concurrent Access: Handle race conditions if player is actively using the bonus
- Audit Logging: Log all cancellation requests with timestamp and reason
- Status Consistency: Ensure status is consistently updated across all systems
- Error Messages: Provide clear error messages for different failure scenarios