Fantasy Sports
Callback Introduction
In this system, callbacks are secure, server-to-server HTTPS POST requests sent from the fantasy sports platform to the client’s wallet API. These callbacks notify the wallet system of specific actions, such as placing a bet, refunding a bet, or settling payouts.
Each callback serves a unique purpose, but they all follow the same fundamental communication pattern:
- Request Structure: The fantasy platform sends a structured JSON payload to the client’s server endpoint via a POST request, containing details about the action being requested (e.g., user information, tournament details, transaction amounts).
- Authorization: To secure the communication, an authorization header with a bearer token is included. This token is signed and includes specific roles (e.g.,
user
oradmin
) to distinguish between types of actions. - HTTPS & Security: All callbacks are sent over HTTPS, and the client’s server must support the latest stable version of TLS to ensure secure transmission. Any necessary IP whitelisting on the client’s end should be configured to allow our staging and production server IPs. Clients can obtain these IP addresses by contacting their Key Account Manager (KAM) or project leader from the Scouts team.
- Response Handling: After receiving a callback, the client’s server processes the request and responds with an HTTP status code. A 200 OK response confirms successful processing, while other status codes signal errors or issues with the request.
These callbacks ensure that the wallet system accurately tracks user transactions and maintains consistency between the fantasy platform and the client’s wallet. Proper implementation of each callback helps prevent issues like double charges, incorrect payouts, or missed entries in tournaments.
Place Bet Callback
The Place Bet callback is triggered whenever a user attempts to enter one or more tournaments on the fantasy sports platform. This callback informs the wallet system to either deduct funds or register free entries based on ticket validation. The client must implement this endpoint to process and respond to place bet requests.
Endpoint Example
The callback is a server-to-server HTTP POST request to:
//{your_server}/bets
https:
Request Structure
Each request is in JSON format and can contain multiple bets in a single array. The payload includes user information, tournament details, and bet data. This structure supports both paid and free-to-play tournaments. For free-to-play tournaments, the buy-in (amount
) and rake can be set to 0.0
, while the overdraw
field may contain a prize pool value for payouts.
Headers
- Authorization:
Bearer <client-name> <JWT token>
- The token format varies based on the context:
- User token: When placing a bet directly, this token includes
role: 'user'
. - Admin token: For server-to-server calls, this token includes
role: 'admin'
.
- User token: When placing a bet directly, this token includes
- For more information about token structure, see the authentication section.
- The token format varies based on the context:
Request Body Example
"headers": {
"authorization": "Bearer customer {user_token}"
},
"body": {
"bets": [
{
"user": {
"client": "string", // Platform identifier
"uid": "string", // Unique user ID
"name": "string", // Username
"ip": "string" // User's IP address
},
"pool": {
"client": "string", // Platform identifier
"game": "string", // Game type (e.g., "fantasy" or "micro")
"uid": "integer", // Unique tournament ID
"currency": "string", // Tournament base currency
"overdraw": "decimal number", // Guaranteed prize pool amount / Freeroll prize
"category": "string", // Tournament type (e.g., admin_created, hidden)
"amount": "decimal number" // Tournament buy-in, set to 0.0 if free-to-play
},
"bet": {
"uid": "integer", // Unique ID of the fantasy team (actual bet ID)
"uuid": "string", // Unique identifier for the request (sanity check only)
"base_amount": "decimal number", // Buy-in in tournament's base currency (0.0 for free-to-play)
"amount": "decimal number", // Total buy-in amount (0.0 for free-to-play)
"rake": "decimal number", // Entry fee (set to 0.0 for free-to-play)
"currency": "string", // Currency of the bet (user’s currency)
"ticket": "string (optional)" // Ticket token if applicable (see ticket section)
}
}
]
}
}
{
Field Descriptions
User: Details of the user placing the bet.
- client (string): Identifier for the platform (white label name).
- uid (string): Unique user ID.
- name (string): Username.
- ip (string): User's IP address.
Pool: Information about the tournament.
- client (string): Platform identifier.
- game (string): Game type (e.g., "fantasy").
- uid (integer): Unique tournament ID.
- currency (string): Tournament base currency.
- overdraw (decimal number): Guaranteed prize pool amount. This can be a positive number even if the tournament is free-to-play.
- category (string): Type of tournament (e.g., admin_created, hidden).
- amount (decimal number): Buy-in amount. For free-to-play tournaments, set to
0.0
.
Bet: Information about the user's entry.
- uid (integer): Unique fantasy team ID, representing the bet ID. Used for idempotency and should not allow duplicates within the same tournament.
- uuid (string): Unique identifier for the request, primarily for sanity checks on potential duplicate submissions.
- base_amount (decimal number): Buy-in amount in the pool's base currency. For free-to-play, set to
0.0
. - amount (decimal number): Total buy-in amount,
0.0
for free-to-play. - rake (decimal number): Fee taken for entry. Set to
0.0
for free-to-play tournaments. - currency (string): Currency of the bet (user’s currency).
- ticket (string, optional): JWT ticket token for free entry, if applicable.
Idempotency and Request Validation
UUID: The
uuid
field provides a unique identifier for the request to assist with sanity checks. While it helps detect potential duplicate submissions, it is not the primary source of idempotency.Bet ID:
bet.uid
andpool.game
together serve as the primary source of idempotency in the system. Duplicatebet.uid
values within the samepool.game
should not be processed more than once. If duplicates are received, the system should return a successful status without reprocessing.
Refund Bet Callback
The Refund Bet callback is used to reverse the buy-ins for one or more fantasy teams within a specified tournament. This request is initiated from our platform to the client’s wallet API to ensure that users are refunded appropriately for their bets. This callback can include multiple refunds, covering all teams in a tournament or just a subset.
Endpoint and Authorization
- Endpoint: This callback is sent as a server-to-server HTTPS POST request to:
//{your_server}/bets/cancel
https: - Authorization: The request uses an admin_token in the
Authorization
header, formatted asBearer customer {admin_token}
. This token is a short-lived JWT generated by our system and should be verified for authenticity.
Idempotency and Reliability
Idempotency: This endpoint relies on the
bet.uid
andpool.game
to detect duplicate refund requests. Theuuid
included here is for reference to the original place bet request and serves as a sanity check but does not determine idempotency.Retries: These server-to-server callbacks may be retried if any issues arise. If any of the bets in the array fail to be refunded, the client should respond with an error for the entire callback. In such cases, the platform will retry the callback with the full set of bets. This retry mechanism requires the client’s system to ensure that each refund request is processed only once, preventing duplicate refunds.
Request Structure
The request payload contains details about the tournaments and associated bets being refunded. Multiple tournaments and/or bets can be included in a single request.
Headers
"authorization": "Bearer customer {admin_token}"
}
{
Request Body Example
{
"pools": [
{
"pool": {
"client": "string", // Name of white label, not necessarily the client's own
"status": "string", // Status of the tournament (e.g., "waiting", "cancelled")
"game": "string", // Game type, should be "fantasy"
"
uid": "integer", // Unique ID of the tournament
"currency": "string", // Tournament's base currency
"category": "string", // Tournament type (e.g., "admin_created")
"overdraw": "number" // Guaranteed prize pool amount / Freeroll prize
},
"bets": [
{
"user": {
"client": "string", // Name of white label, unique to client
"uid": "string", // Unique user ID
"name": "string" // Username
},
"bet": {
"uid": "integer", // Unique ID of the fantasy team (actual bet ID)
"amount": "number", // Buy-in amount
"rake": "number", // Entry fee
"currency": "string", // Bet currency
"base_amount": "number", // Buy-in in tournament’s base currency
"uuid": "string" // Unique identifier for the request, referenced from place-bet request
}
}
]
}
]
}
Field Descriptions
Pool: Information about the tournament.
- client (string): Platform identifier for the tournament; may not match the client’s own name.
- status (string): Current status of the tournament. Valid statuses are:
waiting
: Tournament has not started.in_progress
: Tournament is currently running.pending_confirmation
: Tournament has ended, but results are not yet verified.closed
: Tournament has ended successfully.cancelled
: Tournament has been cancelled.
- game (string): Type of game, should be
"fantasy"
. - uid (integer): Unique tournament ID.
- currency (string): Base currency of the tournament.
- category (string): Type of tournament (e.g.,
"admin_created"
). - overdraw (number): Guaranteed prize pool or freeroll prize.
Bets: Data about the user’s entry and refund information.
- User:
- client (string): White label name, unique to the client.
- uid (string): Unique ID for the user.
- name (string): Username of the user.
- Bet:
- uid (integer): Unique ID for the fantasy team (bet ID), used with
pool.game
for idempotency. - amount (number): Buy-in amount for the bet.
- rake (number): Entry fee associated with the bet.
- currency (string): Currency of the bet.
- base_amount (number): Buy-in amount in the tournament’s base currency.
- uuid (string): Reference to the original place-bet request.
- uid (integer): Unique ID for the fantasy team (bet ID), used with
- User:
Response Handling
- Success: If the refund is successfully processed, respond with HTTP 200 OK.
- Failure: If any of the refunds in the array fail, the client should respond with an error for the entire callback. This signals the platform to retry the callback with the full set of bets. In such cases, respond with an appropriate error code (e.g., HTTP 400 Bad Request or HTTP 404 Not Found) and include a descriptive error message in the following format:
"error": "Descriptive error message" }
{
Refund Tournament Callback (Optional)
The Refund Tournament callback is an optional endpoint specifically for cases where an entire tournament is cancelled, triggering refunds for all entries (bets) within that tournament. This callback closely mirrors the Refund Bet callback, with a few key differences:
- Trigger Condition: This callback is triggered only when a tournament is cancelled (status: "cancelled"). It is designed to handle full tournament refunds.
- Flexible Bet Count: To future-proof this callback, it can accept both single and multiple bets, similar to Refund Bet. This flexibility ensures it can handle individual or batch refunds within a cancelled tournament, allowing for potential expanded use cases.
- Single or Separate Endpoint: Clients can choose to:
- Use only the Refund Bet callback to handle both individual and full tournament refunds in one endpoint.
- Set up Refund Tournament as a separate endpoint to distinguish full tournament cancellations from single bet refunds.
Idempotency and Reliability
Idempotency: The Refund Tournament callback must be idempotent, as retries may occur if server issues or timeouts arise. Each uuid serves as a unique identifier, ensuring each refund request is processed only once.
Retries: If any of the refunds in the array fail, the client should respond with an error for the entire callback. This approach prompts the platform to retry with the full set of bets.
Response Handling
- Success: If all refunds are processed successfully, respond with HTTP 200 OK.
- Failure: If any refunds fail, respond with an appropriate error code (e.g., HTTP 400 Bad Request) and an error message:
json { "error": "Descriptive error message" }
This optional callback offers flexibility for clients who want to manage full tournament refunds separately from single-bet refunds, providing future-proofing for handling individual and batch refunds in cancelled tournaments.
Settle Bet Callback
The Settle Bet callback sends all participants in a tournament, regardless of whether they received payouts. This callback processes results for the tournament and settles the appropriate winnings for each user.
Endpoint and Authorization
- Endpoint: This callback is sent as a server-to-server HTTPS POST request to:
//{your_server}/winners
https: - Authorization: The request uses an admin_token in the
Authorization
header, formatted asBearer customer {admin_token}
. This token is a short-lived JWT generated by our system and should be verified for authenticity.
Idempotency and Reliability
Idempotency: The Settle Bet callback relies on
bet.uid
andpool.game
to ensure that payouts are processed only once for each user’s entry. This idempotency is crucial, as retries may occur if the initial callback fails or encounters network issues. Eachbet.uid
in apool.game
context should be processed only once.Retries: If any payout fails, the entire request should be rejected, prompting a retry with the full set of participants. The client’s system should be idempotent to prevent duplicate payouts if the same request is resent.
Request Structure
Each request includes details about the tournament and the users involved, along with information about the user’s bet, rank, and payout.
Headers
"authorization": "Bearer customer {admin_token}"
}
{
Request Body Example
"pools": [
{
"pool": {
"client": "string", // Platform identifier
"game": "string", // Game type (e.g., "fantasy")
"uid": "integer", // Unique tournament ID
"currency": "string", // Tournament base currency
"overdraw": "decimal string", // Total prize pool payout
"category": "string", // Tournament type (e.g., "admin_created")
"status": "string", // Status of the tournament (e.g., "waiting", "in_progress", "closed", "cancelled")
"cost": "decimal number", // Entry cost for the pool
"amount": "decimal number", // Amount associated with the pool
"gameType": "string", // Type of game variation (e.g., "universal_six")
"overlay": "boolean", // Indicates if there’s an overlay in prize distribution
"guaranteed": "boolean", // True if the prize is guaranteed
"distribution": "string", // Prize distribution type (e.g., "normal")
"estimatedEndTime": "string" // Expected end time in ISO8601 format
},
"bets": [
{
"user": {
"client": "string", // Platform identifier
"uid": "string", // User ID
"name": "string", // Username
"ip": "string" // User’s IP address
},
"bet": {
"uid": "integer", // Bet ID, unique to this bet
"currency": "string", // Currency of the payout
"amount": "decimal number", // Bet amount
"odds": "decimal number", // Betting odds
"rake": "decimal number", // Entry fee
"payout": "decimal string", // Amount won, 0 if no winnings
"base_payout": "decimal string", // Payout in tournament’s base currency
"rank": "integer", // User's rank in the tournament
"score": "decimal number", // Score achieved
"uuid": "string", // Unique identifier, used for sanity checks only. References create-bet request.
"secrets": { // Optional secrets associated with the bet.
}
}
}
]
}
]
}
{
Field Descriptions
Pool: Information about the tournament.
- client (string): Identifier for the platform.
- game (string): Game type (e.g.,
"fantasy"
). - uid (integer): Unique tournament ID.
- currency (string): Tournament base currency.
- overdraw (decimal string): Total prize pool payout, represented as string.
Bets: Details about each participant’s entry.
- User:
- client (string): Platform identifier.
- uid (string): Unique user ID.
- name (string): Username.
- Bet:
- uid (integer): Unique ID for the user’s bet, combined with
pool.game
for idempotency. - currency (string): Currency for the payout.
- amount (decimal number): Original bet amount.
- odds (decimal number): Betting odds.
- rake (decimal number): Always 0 for this game.
- payout (decimal string): Payout amount, or
0
if the user did not win. - base_payout (decimal string): Same as
payout
. - rank (integer): Final rank in the tournament.
- score (decimal number): Score achieved by the user.
- uuid (string): Unique identifier for sanity checks (not used for idempotency). Will be the same as the original create-bet request.
- uid (integer): Unique ID for the user’s bet, combined with
- User:
Response Handling
- Success: If all payouts are processed correctly, respond with HTTP 200 OK.
- Failure: If any part of the payout process fails, respond with an error for the entire callback. This will trigger a retry with the full set of participants. Return an error response code, such as HTTP 400 Bad Request, and include a descriptive error message:
"error": "Descriptive error message" }
{