# Promotions
Promotion tools may not be available in all jurisdictions. Before implementing this functionality, please consult your RubyPlay account manager for further details.
The Gaming Platform (GP) can create campaigns with defined start and end dates (based on time zone), predefined players, games, currencies, campaign prices, and more.
## API Rate Limiting
The API implements a three-tier rate limiting system:
### Global Rate Limits
- **All methods** (GET, POST, PUT, PATCH, DELETE): 500 requests/second
- **GET methods only**: 1000 requests/second
### Per Endpoint Per User Rate Limits
- **Campaign participant addition** (`/campaign/*/participant` POST): 130 requests/second
- **Campaign creation** (`/campaign` POST): 60 requests/second
- **All other endpoints**: 60 requests/second
### Per Endpoint Rate Limits
- **Campaign participant addition** (`/campaign/*/participant` POST): 270 requests/second
- **Campaign creation** (`/campaign` POST): 135 requests/second
These limits represent general guidelines and may be further restricted in extreme cases to safeguard stable operations for all customers.
We recommend implementing dynamic throttling or retry mechanisms in your integration to gracefully handle rate limiting and related changes.
If you expect higher volumes, please contact support to discuss capacity planning.
## Promotion Limits and Recommendations
The following limits apply to campaign creation and management:
| Parameter | Limit | Notes |
| --- | --- | --- |
| `name` | 255 characters | Campaign name |
| `externalCampaignId` | 512 characters | Operator-defined campaign ID |
| `requestId` | 36 characters | Idempotency key |
| `rulesUrl` | 2048 characters | URL with campaign rules |
| `betNumber` | 1500 | Maximum free rounds/features per player |
| CSV import (Back Office) | 50,000 rows | Maximum players per CSV import |
Recommendations
- Use the `requestId` parameter for idempotency to safely retry failed requests
- For large player lists, use the batch participant endpoint instead of individual additions
- Set realistic campaign durations - campaigns shorter than 24 hours are not typical business scenarios
## Brand-Level Configuration
As part of our promotional tools (Free Rounds and Awarded Features), we provide the following additional configurations related to what is displayed on pop-ups/counter. These options can be enabled or disabled on request at the brand level from the RubyPlay side:
* **Show/Hide Value of Promotion** (default: **Show**)
* **Show/Hide Final Winning Value** (default: **Show**)
* **Show/Hide Campaign/Feature Player Expiry Time** (default: **Hide**)
* **Show/Hide Play Later Button** (default: **Show**)
* **Show/Hide Bet Value (Awarded Feature only)** (default: **Hide**)
* **Show/Hide Opt-Out Button and Function** (default: **Hide**)
Opt-Out Function
The opt-out function is **not enabled by default**. In regulated markets if this needs to be handled on RubyPlay side, it should be requested.
Also note that no information is provided regarding this through integration.
## Type of Round based on debit/credit request body
(described in the [Rubyplay Seamless Wallet API](/content/integration/seamless-wallet-api/general/overview#type-of-round-based-on-debitcredit-request-body))
## Important Note
The legacy URL format (`/api/v1/freeround/campaign/...`) is still supported for backward compatibility. However, we ****strongly recommend**** using the new unified format:
`/api/v1/campaign/...`
This ensures consistency across all campaign types and simplifies integration.
## Campaign Creation Flow
The following diagram illustrates the primary flow for creating and managing promotional campaigns:
```mermaid
sequenceDiagram
participant Operator
participant RubyPlay API
participant Player
Note over Operator,Player: Campaign Setup Phase
Operator->>RubyPlay API: Get Games (retrieve available games and bet sizes)
RubyPlay API-->>Operator: Game list with bets, buy feature multipliers
Operator->>RubyPlay API: Create Campaign (type, games, bet, players, dates)
RubyPlay API-->>Operator: Campaign created (campaignId)
opt Add more participants
Operator->>RubyPlay API: Add Participants (campaignId, playerIds)
RubyPlay API-->>Operator: Participants added
end
Note over Operator,Player: Campaign Active Phase
Player->>RubyPlay API: Launch game
RubyPlay API-->>Player: Display promotion popup
Player->>RubyPlay API: Accept promotion
loop For each free round/feature
Player->>RubyPlay API: Play round
RubyPlay API->>Operator: Debit request (freeRounds=true)
Operator-->>RubyPlay API: Debit response
RubyPlay API->>Operator: Credit request (winnings)
Operator-->>RubyPlay API: Credit response
RubyPlay API-->>Player: Round result
end
RubyPlay API-->>Player: Promotion completed
```
## Awarded Feature Campaign Creation
When creating an **Awarded Feature** campaign, the `bet` value must represent the **total cost of the buy feature** (base bet × price multiplier), not the base bet alone.
There are three approaches to determine the correct bet value:
### Approach 1: Using Awarded Feature Configurations Endpoint (Recommended)
This is the simplest approach. The endpoint returns pre-calculated feature costs that can be used directly.
```mermaid
sequenceDiagram
participant Operator
participant RubyPlay API
Operator->>RubyPlay API: GET /api/v1/awarded-feature-configurations
?gameId=rp_140¤cyCode=EUR
RubyPlay API-->>Operator: Available configurations with feature costs
Note over Operator: Response example:
{ "gameId": "rp_140", "bet": 50.0, "currencyCode": "EUR" }
Operator->>RubyPlay API: POST /api/v1/campaign
{ type: "AWARDED_FEATURE", gameIds: ["rp_140"],
bet: 50, currencyCode: "EUR", ... }
RubyPlay API-->>Operator: Campaign created
```
**Example Request:**
```bash
GET /api/v1/awarded-feature-configurations?gameId=rp_140¤cyCode=EUR
```
**Example Response:**
```json
{
"content": [
{ "gameId": "rp_140", "bet": 5.0, "currencyCode": "EUR" },
{ "gameId": "rp_140", "bet": 7.5, "currencyCode": "EUR" },
{ "gameId": "rp_140", "bet": 50.0, "currencyCode": "EUR" },
{ "gameId": "rp_140", "bet": 100.0, "currencyCode": "EUR" }
]
}
```
### Approach 2: Using Get Games Endpoint with Multiplier Calculation
If you prefer to calculate the feature cost yourself, retrieve the game's buy feature multiplier from the Get Games endpoint and multiply it by the base bet.
```mermaid
sequenceDiagram
participant Operator
participant RubyPlay API
Operator->>RubyPlay API: GET /api/v1/game?gameId=rp_140
RubyPlay API-->>Operator: Game configuration with buyFeatures
Note over Operator: Response includes:
buyFeatures: [{ buyFeatureType: "freespin",
priceMultiplier: 50 }]
betSizes: { EUR: [0.1, 0.2, 0.5, 1.0, 2.0] }
Note over Operator: Calculate: 1.0 EUR × 50 = 50 EUR
Operator->>RubyPlay API: POST /api/v1/campaign
{ type: "AWARDED_FEATURE", gameIds: ["rp_140"],
bet: 50, currencyCode: "EUR", ... }
RubyPlay API-->>Operator: Campaign created
```
**Calculation Formula:**
```
Feature Cost = Base Bet × Price Multiplier
Example: 1.0 EUR × 50 = 50 EUR
```
### Approach 3: Using Pre-stored Information
If you have already stored game information (bet sizes and multipliers) in your system, you can calculate the feature cost directly without additional API calls.
```mermaid
sequenceDiagram
participant Operator System
participant Operator
participant RubyPlay API
Operator System-->>Operator: Retrieve stored game data
(betSizes, priceMultiplier)
Note over Operator: Stored data:
rp_140: multiplier=50, bets=[0.1, 0.5, 1.0, 2.0]
Note over Operator: Calculate: 1.0 EUR × 50 = 50 EUR
Operator->>RubyPlay API: POST /api/v1/campaign
{ type: "AWARDED_FEATURE", gameIds: ["rp_140"],
bet: 50, currencyCode: "EUR", ... }
RubyPlay API-->>Operator: Campaign created
```
Important
For **Awarded Feature** campaigns, always use the **total feature cost** (base bet × multiplier) in the `bet` field.
For example, if you want to award a feature with a 1 EUR base bet on a game with a 50× multiplier, the `bet` value should be **50 EUR**, not 1 EUR.