Payout API
Once a tournament ends, based on the result (that may need an optional manual approve from the back-office), the winners are credited with the prizes. This happens in the form of a series of API calls from Gamity’s server to the client’s server. Winnings are sent one by one in separate calls, one for each player. The following API must be implemented by the client.
Example cash payout request
POST [YOUR-SERVER-ENDPOINT] HTTP/1.1
Content-Type: application/json
X-API-Key: [ask from Codemodity]
{
"payoutId": "100200",
"payoutRef": "0e17e833-a4db-41d0-83d1-adb539631864",
"brandId": "brand-1",
"playerId": "player-12345",
"amount": 10.25,
"currency": "USD",
"type": "CASH",
"promoName": "Demo_Tournament",
"promoRef": "8d308790-55db-11ed-bdc3-0242ac120002",
"metadata": {
"lastGameId": "GAME-ID-123"
}
}In case of cash payouts:
currency: The player’s last known currency (the currency most recently used in the tournament).amount: The tournament prize converted into the player’s currency. This value is not rounded to decimals for any currency.
Example free round request
POST [YOUR-SERVER-ENDPOINT] HTTP/1.1
Content-Type: application/json
X-API-Key: [ask from Codemodity]
{
"payoutId": "100200",
"payoutRef": "0e17e833-a4db-41d0-83d1-adb539631864",
"brandId": "brand-1",
"playerId": "player-12345",
"amount": 2,
"currency": "USD",
"type": "FREEROUND",
"numberOfRounds": 10,
"freeroundGameId": "GAME-ID-123",
"validHours": 24,
"promoName": "Demo_Tournament",
"promoRef": "8d308790-55db-11ed-bdc3-0242ac120002",
"metadata": {
"lastGameId": "GAME-ID-123"
}
}In case of free round payouts:
currency: The base currency of the tournament (the currency in which the prizes are defined).amount: The unit value of a single free round (unconverted).numberOfRounds: The total number of awarded free rounds.- Example:
100 × 0.2 EURworth of free rounds for the game defined by thefreeroundGameIdfield.
Request header
| Header | Type | Mandatory? | Description |
|---|---|---|---|
X-API-Key | string | Yes | All requests must be authorized with an API key sent in the X-API-Key header. |
Request body
| Field | Type | Mandatory? | Description |
|---|---|---|---|
payoutId | string (format: number) | No | Internal identifier in Gamity’s system for the participant’s win. This ID remains the same across multiple retry attempts for the same win. |
payoutRef | string (format: UUID) | Yes | Unique reference for a single payout attempt. Gamity will generate a new, unique UUID for every API call, including retries of a previously failed payout. Your system must use this reference to implement idempotency and prevent duplicate credits for the same attempt. |
brandId | string | Yes | The unique ID of the brand the player belongs to (e.g., HAPPYLUKE). brandId and playerId together must be unique. |
playerId | string | Yes | The ID of the player in your brand/PAM system. brandId and playerId together must be unique. |
amount | decimal | Yes | The prize amount. For CASH, this is the full awarded amount. For FREEROUND, this is the unit value of a single free round. |
currency | string | Yes | Currency code of the amount. |
type | string (enum) | Yes | Type of the prize. Currently CASH and FREEROUND are supported. |
numberOfRounds | integer | No | The number of free rounds awarded to the player. Required if type is FREEROUND. |
freeroundGameId | string | No | The game ID for which the player receives the free round prize. Required if type is FREEROUND. |
validHours | integer | No | The expiration of the free round prize in hours. Required if type is FREEROUND. |
promoName | string | No | Human-friendly name of the tournament that the payout relates to. Not guaranteed to be unique. |
promoRef | string (UUID) | No | Unique reference of the tournament that the payout relates to. |
metadata | object | No | This field is optional. If you require additional data to process the payout, please discuss with Codemodity. Supported fields: - lastGameId (string): game ID of the last transaction that a player was scored from. |
Response and Error Handling
Idempotency
Your endpoint must be idempotent. Gamity may send the same request multiple times due to network issues. To prevent duplicate credits, your system must store the payoutRef of each successful request. If a new request arrives with a payoutRef you have already processed, you must not credit the player again and should return a 200 OK response with the original transaction ID.
Response Codes and Retry Logic
Gamity’s automated retry system uses your API’s HTTP status codes to determine its behavior. It is critical that you return the correct status code for each scenario.
| Status Code Range | Description | Gamity’s Action |
|---|---|---|
200 (Success) | OK. The payout was successfully processed. | No Retry. The payout is considered complete. |
429 (Too Many Requests) | Retryable Client Error. Your system is temporarily rate-limiting requests. | Automatic Retry. Gamity will wait for a 5-minute backoff period and then try again. |
4xx (Other Client Errors) | Permanent Client Error. The request is invalid and will likely never succeed without a change. Examples: 400 Bad Request (e.g., player not found, currency mismatch), 401 Unauthorized. | No Automatic Retry. The payout is immediately flagged for manual intervention by an administrator. |
5xx (Server Errors) | Temporary Server Error. Your server encountered an unexpected issue (500, 503, etc.). | Automatic Retry. Gamity will wait for a 5-minute backoff period and then try again. |
| Request Timeout | Gamity’s request to your endpoint times out after 30 seconds. | Automatic Retry. This is treated as a temporary network or server issue. Gamity will wait and try again. |
Summary of Client Responsibilities:
- Return a
2xxcode only for a successful, completed transaction. - Return a specific
4xxcode for permanent errors that require a human to investigate. - Return a
5xxcode for any unexpected internal errors on your server.
Response Body
Response body in case of success
Your success response should return a unique transaction identifier for the credit operation.
{
"transactionId": "4bba536-69a5-42b4-a66f-678bb61ae3f8"
}| Field | Type | Mandatory? | Description |
|---|---|---|---|
| transactionId | string | Yes | Your system’s unique identifier for the successful transaction. |
Response body in case of error
{
"error": {
"code": "string", // e.g. "PLAYER_NOT_FOUND"
"message": "string" // e.g. "Player with ID player-12345 is not found"
}
}There are no predefined error codes or messages; these are left to your discretion. Gamity will store and display the message to administrators to help investigate payout issues.
Test scenarios
This is a high risk endpoint. Implementing the security measures below are mandatory.
- Idempotency: The endpoint must be idempotent using the payoutRef field. Sending a request again with the same payoutRef must not result in a duplicate transaction.
- IP Allowlisting: The endpoint should have restricted access. Only IPs provided by Codemodity should be on the allowlist; all others should be blocked.
- Authentication: The X-API-Key must be checked on every request. Requests with an invalid or missing API key should be rejected with a 401 Unauthorized status.
- Data Validation: Your system is responsible for all business-level validation, such as detecting if a player’s currency has changed or if an account is blocked.