<!-- source: docs/api/2_capi/campaign/getmycampaigns.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/getmycampaigns -->

# GetMyCampaigns

Returns the list of campaigns the current player is participating in, including their assigned scenario, campaign details, and engagement metrics.

| Service | Operation |
| ------- | --------- |
| campaign | GET_MY_CAMPAIGNS |

## Method Parameters
Parameter | Description
--------- | -----------
optionsJson | Optional JSON parameter (reserved for future use).

## Usage

**C#:**

```csharp
string optionsJson = "{}";
SuccessCallback successCallback = (response, cbObject) =>
{
    Debug.Log(string.Format("Success | {0}", response));
};
FailureCallback failureCallback = (status, code, error, cbObject) =>
{
    Debug.Log(string.Format("Failed | {0}  {1}  {2}", status, code, error));
};

_bc.CampaignService.GetMyCampaigns(optionsJson, successCallback, failureCallback);
```

**C++:**

```cpp
const char *optionsJson = "{}";
_bc.getCampaignService().getMyCampaigns(optionsJson, this);
```

**Obj-C:**

```objectivec
NSString *optionsJson = @"{}";
BCCompletionBlock successBlock; // define callback
BCErrorCompletionBlock failureBlock; // define callback
[[_bc campaignService] getMyCampaigns:
                  optionsJson:optionsJson
              completionBlock:successBlock
         errorCompletionBlock:failureBlock
                     cbObject:nil]
```

**Java:**

```java
String optionsJson = "{}";
this; // implements IServerCallback
_bc.getCampaignService.getMyCampaigns(optionsJson, this);

public void serverCallback(ServiceName serviceName, ServiceOperation serviceOperation, JSONObject jsonData)
{
    System.out.print(String.format("Success | %s", jsonData.toString()));
}
public void serverError(ServiceName serviceName, ServiceOperation serviceOperation, int statusCode, int reasonCode, String jsonError)
{
    System.out.print(String.format("Failed | %d %d %s", statusCode,  reasonCode, jsonError.toString()));
}
```

**JavaScript:**

```javascript
var optionsJson = {};
_bc.campaign.getMyCampaigns(optionsJson, result =>
{
  var status = result.status;
  console.log(status + " : " + JSON.stringify(result, null, 2));
});
```

**Dart:**

```dart
var optionsJson = {};
ServerResponse result = await _bc.campaignService.getMyCampaigns(optionsJson:optionsJson);

if (result.statusCode == 200) {
    print("Success");
} else {
    print("Failed ${result.error['status_message'] ?? result.error}");
}
```

**Roblox:**

```lua
local optionsJson = {}
local callback = function(success, response)
    if success then
        print("Success")
    else
        print("Failed | " .. tostring(response.status_message))
    end
end
_bc.campaign:getMyCampaigns(optionsJson, callback)
```

**GDScript:**

```gdscript
var options_json = {}

var result = await _bc.campaign_service.get_my_campaigns(options_json)

if result.status == 200:
	print("Success")
else:
	print("Failed: %s" % result.status_message)
```

**Lua:**

```lua
local optionsJson = {}

local callback = function(success, response)
    if success then
        print("Success")
    else
        print("Failed | " .. tostring(response.status_message))
    end
end

_bc.campaign:getMyCampaigns(optionsJson, callback)
```

**Cloud Code:**

```cfscript
var optionsJson = {};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.getMyCampaigns(optionsJson);
```

**Raw:**

```r
{
    "service":"campaign",
    "operation":"GET_MY_CAMPAIGNS",
    "data":{
        "optionsJson":{}
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaigns": [
            {
                "campaignCode": "holiday2026",
                "scenarioCode": "b",
                "createdAt": 1714000000000,
                "updatedAt": 1714000000000,
                "originalStartedAt": 1714000000000,
                "originalEndsAt": 1716591999000,
                "expireAtIso": 1724367999000,
                "loginCount": 12,
                "logouts": 11,
                "timePlayed": 7200000,
                "avgPlayTime": 600000,
                "numPurchases": 2,
                "amtSpent": 499,
                "version": 3,
                "purpose": "Summer Sale A/B Test",
                "campaignJson": {
                    "theme": "summer"
                },
                "startAt": 1714000000000,
                "endAt": 1716591999000,
                "targetType": "SEGMENT",
                "segmentCode": "premium_users",
                "description": "50% off bundle variant",
                "scenarioJson": {
                    "discount": "50%"
                },
                "overrides": {
                    "globalProperties": {
                        "free_currency_bonus": {
                            "name": "free_currency_bonus",
                            "value": "200"
                        }
                    },
                    "cashProducts": {
                        "coinbundle10": {
                            "itemId": "coinbundle10",
                            "priceId": 1
                        }
                    },
                    "items": {
                        "sword_01": {
                            "defId": "sword_01",
                            "buyPrice": {
                                "coins": 50
                            }
                        }
                    }
                }
            }
        ]
    },
    "status": 200
}
```
</details>

<details>
<summary>Common Error Code</summary>

### Status Codes
Code | Name | Description
---- | ---- | -----------
40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.

</details>


---

<!-- source: docs/api/2_capi/campaign/index.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign -->

# Campaign

**Campaign** is a LiveOps service that enables no-code A/B testing and feature flagging. Game operators can create time-bounded campaigns that modify game behavior for targeted player segments - without deploying new code.

### How It Works

A **Campaign** defines:
- **Schedule** — a `startAt` / `endAt` window
- **Trigger** — evaluated on `LOGIN` or `REGISTRATION`
- **Target** — either `ALL` players or a specific player `SEGMENT`
- **Scenarios** — traffic-split experiment groups (e.g. control vs. variants), each with configurable **overrides**

Each scenario can override **Global Properties**, **Cash Product prices**, and **Item/Bundle definitions**. The control scenario (code `"_"`) always has empty overrides — it represents the baseline experience.

Players are enrolled on their first qualifying login/registration during the campaign window and are assigned to a scenario based on weighted distribution. Participation metrics (login count, time played, purchases, spend) are tracked automatically.

### Scenario Weights (Traffic %)

You control traffic allocation by setting a **weight** (0–100) for each scenario. Weights are integers and **must sum to 100**.

**Example — 50/25/25 split:**

| Scenario | Weight | Traffic |
|---|---|---|
| `"_"` (control — no changes) | 50 | 50% |
| `"A"` (double coins) | 25 | 25% |
| `"B"` (half-price sale) | 25 | 25% |

```json
{
  "campaignCode": "holiday2026",
  "version": 3,
  "scenarios": [
    { "scenarioCode": "_", "weight": 50 },
    { "scenarioCode": "A", "weight": 25 },
    { "scenarioCode": "B", "weight": 25 }
  ]
}
```

**Validation rules:**
- The control scenario `"_"` must always be present
- All referenced scenarios must already exist in the campaign
- Weights must sum to exactly 100

**Default behavior:**
- **On campaign create** — only `"_"` exists with weight 100 (all traffic sees baseline)
- **When adding a new scenario** — its weight starts at **0** until you redistribute via [SysUpdateCampaignScenarioWeights](/api/capi/campaign/sysupdatecampaignscenarioweights)
- **When deleting a scenario** — its weight is automatically reassigned to `"_"` (control absorbs freed traffic)

### The Control Scenario (`"_"`)

Every campaign auto-creates a control scenario with **no overrides** — it is the scientific control group.

Key facts:
- **Auto-created** when the campaign is created — you never create it manually
- **Cannot be deleted** independently — you must delete the entire campaign
- **Required by validation** — every campaign must include `"_"` with a weight
- **Absorbs freed weight** — when a variant scenario is deleted, its traffic share rolls back to control

The control scenario is what you measure your variants against. If variant `"A"` drives 20% more purchases than `"_"`, you know the change works.

### API Summary

- [GetMyCampaigns](/api/capi/campaign/getmycampaigns) - Returns the list of campaigns the current player is participating in, including their assigned scenario and campaign details.
- [SysTriggerCampaignForUser](/api/capi/campaign/systriggercampaignforuser) - Triggers a campaign scenario for a specific player, bypassing normal eligibility constraints. Player must be flagged as a tester.
- [SysRemoveCampaignForUser](/api/capi/campaign/sysremovecampaignforuser) - Removes a player's participation in a specific campaign.
- [SysRemoveAllCampaignsForUser](/api/capi/campaign/sysremoveallcampaignsforuser) - Removes a player's participation in all campaigns.
- [SysCreateCampaign](/api/capi/campaign/syscreatecampaign) - Creates a new campaign. A control scenario is automatically created alongside the campaign.
- [SysReadCampaign](/api/capi/campaign/sysreadcampaign) - Reads a campaign's full configuration, optionally including the details of every scenario.
- [SysUpdateCampaign](/api/capi/campaign/sysupdatecampaign) - Updates some or all of a campaign's configuration fields.
- [SysDeleteCampaign](/api/capi/campaign/sysdeletecampaign) - Deletes a campaign along with all of its scenarios, participation records and metrics.
- [SysEnableCampaign](/api/capi/campaign/sysenablecampaign) - Enables or disables a campaign without changing any other fields.
- [SysGetCampaignPage](/api/capi/campaign/sysgetcampaignpage) - Returns a filtered, sorted page of the app's campaigns.
- [SysGetCampaignPageOffset](/api/capi/campaign/sysgetcampaignpageoffset) - Returns another page of campaigns using the context from a previous page request.
- [SysCreateScenario](/api/capi/campaign/syscreatescenario) - Creates a new variant scenario under a campaign.
- [SysReadScenario](/api/capi/campaign/sysreadscenario) - Reads a campaign scenario's full configuration.
- [SysUpdateScenario](/api/capi/campaign/sysupdatescenario) - Updates some or all of a variant scenario's configuration fields.
- [SysDeleteScenario](/api/capi/campaign/sysdeletescenario) - Deletes a variant scenario and moves its weight to the control scenario.
- [SysUpdateCampaignScenarioWeights](/api/capi/campaign/sysupdatecampaignscenarioweights) - Sets the traffic split between a campaign's scenarios.
- [SysUpdateCampaignJson](/api/capi/campaign/sysupdatecampaignjson) - Updates only the free-form `campaignJson` custom payload on a campaign.
- [SysUpdateScenarioJson](/api/capi/campaign/sysupdatescenariojson) - Updates only the free-form `scenarioJson` custom payload on a campaign scenario.


---

<!-- source: docs/api/2_capi/campaign/syscreatecampaign.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/syscreatecampaign -->

# SysCreateCampaign

Creates a new campaign. The campaign code must be unique for the app. The control scenario (`"_"`) is created automatically alongside the campaign with a weight of 100, so all traffic sees the baseline experience until you add variant scenarios and redistribute the weights.

New campaigns are created **disabled** by default. Pass `"enabled": true` in `configJson` to activate the campaign immediately.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_CREATE_CAMPAIGN |

## Method Parameters

| Parameter    | Description                                                                                                                                  |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| campaignCode | Unique code for the new campaign. Must be 1–15 characters, using only uppercase letters, digits, underscores (`_`) and hyphens (`-`).        |
| configJson   | The campaign configuration. See the table below for the supported fields. `scenarios` cannot be specified — the control scenario is created automatically. |

### configJson Fields

| Field        | Required | Description                                                                                                                                              |
| ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name         | Yes      | Display name of the campaign.                                                                                                                            |
| startAt      | Yes      | Start of the campaign window, in UTC epoch milliseconds. Must be before `endAt`.                                                                         |
| endAt        | Yes      | End of the campaign window, in UTC epoch milliseconds. Cannot be in the past. The campaign duration cannot exceed the app's maximum campaign length (90 days by default). |
| trigger      | Yes      | When players are evaluated for enrollment: `LOGIN` (every login during the campaign window) or `REGISTRATION` (first registration only).               |
| target       | Yes      | Which players are eligible. `{ "type": "ALL" }` targets all players. `{ "type": "SEGMENT", "segmentCode": "..." }` targets a specific player segment, which must already exist. |
| purpose      | No       | A description of what the campaign is evaluating.                                                                                                        |
| category     | No       | Free-form category used to organize campaigns.                                                                                                           |
| enabled      | No       | Whether the campaign is active. Defaults to `false`.                                                                                                     |
| campaignJson | No       | Free-form custom payload returned to every player enrolled in the campaign. Maximum serialized size is governed by an application property (50 KB by default). |
| abGoalType   | No       | The overall goal of the A/B test. One of `revenue`, `engagement`, `retention` or `conversion`.                                                          |
| abConfidence | No       | Confidence level used for A/B significance testing. One of `80`, `85`, `90`, `95` or `99`. Defaults to `95` when not set.                               |
| notes        | No       | Developer assessment notes (markdown). Maximum 16,384 characters.                                                                                       |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var configJson = {
    "name": "Summer 2026",
    "purpose": "Evaluating impact of themes and summer sale on spenders",
    "trigger": "LOGIN",
    "startAt": 1811808000000,
    "endAt": 1814227200000,
    "target": {
        "type": "SEGMENT",
        "segmentCode": "spenders"
    },
    "campaignJson": {
        "customFieldA": "summer",
        "customFieldB": 1,
        "customFieldC": true
    },
    "abGoalType": "revenue",
    "enabled": false
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysCreateCampaign(campaignCode, configJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_CREATE_CAMPAIGN",
    "data": {
        "campaignCode": "SUMMER2026",
        "configJson": {
            "name": "Summer 2026",
            "purpose": "Evaluating impact of themes and summer sale on spenders",
            "trigger": "LOGIN",
            "startAt": 1811808000000,
            "endAt": 1814227200000,
            "target": {
                "type": "SEGMENT",
                "segmentCode": "spenders"
            },
            "campaignJson": {
                "customFieldA": "summer",
                "customFieldB": 1,
                "customFieldC": true
            },
            "abGoalType": "revenue",
            "enabled": false
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "name": "Summer 2026",
        "purpose": "Evaluating impact of themes and summer sale on spenders",
        "category": null,
        "enabled": false,
        "startAt": 1811808000000,
        "endAt": 1814227200000,
        "trigger": "LOGIN",
        "target": {
            "type": "SEGMENT",
            "segmentCode": "spenders"
        },
        "scenarios": [
            {
                "scenarioCode": "_",
                "weight": 100
            }
        ],
        "campaignJson": {
            "customFieldA": "summer",
            "customFieldB": 1,
            "customFieldC": true
        },
        "abGoalType": "revenue",
        "abConfidence": null,
        "notes": null,
        "version": 1,
        "createdAt": 1811721600000,
        "updatedAt": 1811721600000
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                                                                                                  |
| ----- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 40358 | MISSING_REQUIRED_PARAMETER            | `campaignCode` or `configJson` was not specified.                                                                                                                                           |
| 40660 | INVALID_PARAMETER_VALUE               | The campaign configuration is invalid — for example, a campaign with this `campaignCode` already exists, the code is badly formatted, a required field is missing, `startAt`/`endAt` are invalid, the target segment does not exist, or `scenarios` was specified. The error message describes the specific problem. |
| 41064 | CAMPAIGN_JSON_TOO_LARGE               | The serialized `campaignJson` exceeds the maximum size allowed for the app.                                                                                                                 |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                                                                                                          |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.                                                                                      |

</details>


---

<!-- source: docs/api/2_capi/campaign/syscreatescenario.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/syscreatescenario -->

# SysCreateScenario

Creates a new variant scenario under the specified campaign. The scenario code is assigned automatically, using the next available letter from `A` to `Z`, so a campaign can have at most 26 variant scenarios. The campaign must not have ended.

A new scenario is not part of the campaign's traffic split until you give it a weight with [SysUpdateCampaignScenarioWeights](/api/capi/campaign/sysupdatecampaignscenarioweights) — until then, no players are assigned to it.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_CREATE_SCENARIO |

## Method Parameters

| Parameter    | Description                                                                                                                                                                                                                      |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code to create the scenario under.                                                                                                                                                                                  |
| configJson   | The scenario configuration. Supported fields are `description` (string), `overrides` (see below — at least one override is required) and `scenarioJson` (free-form custom payload returned to players assigned to the scenario). |

### Scenario Overrides

`overrides` holds up to three maps. Each one is keyed by the identifier of the thing being overridden, and every scenario must contain at least one override.

| Map              | Key                      | Value fields                                                                                                                                                                  |
| ---------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| globalProperties | Global property name     | `name` (must match the key) and `value` (string). The property must already exist, cannot be marked as secret, and the override value must differ from its current value.   |
| cashProducts     | Cash product `itemId`    | `itemId` (must match the key), `priceId` (the price point to use), `notForSale` (hide the product) and `showAsListPrice` (show the regular price as a strikethrough list price). |
| items            | Item definition `defId`  | `defId` (must match the key), `buyPrice` (map of currency to amount), `buyPriceDisabled` (item cannot be bought) and `showAsListPrice` (show the regular price as a list price). |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var configJson = {
    "description": "Beach",
    "overrides": {
        "globalProperties": {
            "xpMultiplier": {
                "name": "xpMultiplier",
                "value": "2"
            },
            "ThemeJson": {
                "name": "ThemeJson",
                "value": "{\"season\":\"Summer\",\"extra\":\"Beach\"}"
            }
        },
        "cashProducts": {
            "coinBundle10": {
                "itemId": "coinBundle10",
                "notForSale": false,
                "priceId": 1,
                "showAsListPrice": false
            }
        },
        "items": {
            "beachHat": {
                "defId": "beachHat",
                "buyPriceDisabled": false,
                "buyPrice": {
                    "coin": 200
                },
                "showAsListPrice": false
            },
            "summerHat": {
                "defId": "summerHat",
                "buyPriceDisabled": true,
                "buyPrice": null,
                "showAsListPrice": false
            }
        }
    },
    "scenarioJson": {
        "customField1": "beach"
    }
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysCreateScenario(campaignCode, configJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_CREATE_SCENARIO",
    "data": {
        "campaignCode": "SUMMER2026",
        "configJson": {
            "description": "Beach",
            "overrides": {
                "globalProperties": {
                    "xpMultiplier": {
                        "name": "xpMultiplier",
                        "value": "2"
                    },
                    "ThemeJson": {
                        "name": "ThemeJson",
                        "value": "{\"season\":\"Summer\",\"extra\":\"Beach\"}"
                    }
                },
                "cashProducts": {
                    "coinBundle10": {
                        "itemId": "coinBundle10",
                        "notForSale": false,
                        "priceId": 1,
                        "showAsListPrice": false
                    }
                },
                "items": {
                    "beachHat": {
                        "defId": "beachHat",
                        "buyPriceDisabled": false,
                        "buyPrice": {
                            "coin": 200
                        },
                        "showAsListPrice": false
                    },
                    "summerHat": {
                        "defId": "summerHat",
                        "buyPriceDisabled": true,
                        "buyPrice": null,
                        "showAsListPrice": false
                    }
                }
            },
            "scenarioJson": {
                "customField1": "beach"
            }
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A",
        "scenarioCampaignCode": "SUMMER2026:A",
        "description": "Beach",
        "overrides": {
            "globalProperties": {
                "xpMultiplier": {
                    "name": "xpMultiplier",
                    "value": "2"
                },
                "ThemeJson": {
                    "name": "ThemeJson",
                    "value": "{\"season\":\"Summer\",\"extra\":\"Beach\"}"
                }
            },
            "cashProducts": {
                "coinBundle10": {
                    "itemId": "coinBundle10",
                    "notForSale": false,
                    "priceId": 1,
                    "showAsListPrice": false
                }
            },
            "items": {
                "beachHat": {
                    "defId": "beachHat",
                    "buyPriceDisabled": false,
                    "buyPrice": {
                        "coin": 200
                    },
                    "showAsListPrice": false
                },
                "summerHat": {
                    "defId": "summerHat",
                    "buyPriceDisabled": true,
                    "buyPrice": null,
                    "showAsListPrice": false
                }
            }
        },
        "scenarioJson": {
            "customField1": "beach"
        },
        "version": 1,
        "createdAt": 1811725200000,
        "updatedAt": 1811725200000
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                                                                                                                               |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                                                                                                                                      |
| 40001 | INVALID_REQUEST                       | The campaign has ended and can no longer be modified.                                                                                                                                                                     |
| 40001 | INVALID_REQUEST                       | All 26 scenario codes (`A`–`Z`) are already in use for the campaign.                                                                                                                                                      |
| 40660 | INVALID_PARAMETER_VALUE               | The scenario configuration is invalid — for example, no overrides were specified, or an override refers to a global property, cash product or item that does not exist. The error message describes the specific problem. |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                                                                                                                                        |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.                                                                                                                    |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysdeletecampaign.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysdeletecampaign -->

# SysDeleteCampaign

Deletes a campaign, along with all of its scenarios, player participation records and collected metrics. This cannot be undone.

If the campaign is in progress (enabled and within its `startAt`/`endAt` window) and has an active A/B split — that is, the control scenario does not hold 100% of the weight — you must pass `force` as `true` to delete it.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_DELETE_CAMPAIGN |

## Method Parameters

| Parameter    | Description                                                                                                                      |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code to delete.                                                                                                     |
| version      | Version of the campaign being deleted. Pass `-1` to delete regardless of the current version.                                    |
| force        | If `true`, allows deleting an in-progress campaign whose control scenario does not hold 100% of the weight. Defaults to `false`. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var version = -1;
var force = false;
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysDeleteCampaign(campaignCode, version, force);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_DELETE_CAMPAIGN",
    "data": {
        "campaignCode": "SUMMER2026",
        "version": -1,
        "force": false
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026"
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                 |
| ----- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                        |
| 41062 | CAMPAIGN_VERSION_MISMATCH             | The specified `version` no longer matches the campaign — it was updated by someone else. Re-read and retry. |
| 41054 | CAMPAIGN_UPDATE_ERROR                 | The campaign is in progress with active scenario weight allocations. Pass `force` as `true` to delete it.   |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                          |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.      |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysdeletescenario.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysdeletescenario -->

# SysDeleteScenario

Deletes a variant scenario from a campaign, along with its player participation records and collected metrics. Any weight the scenario held is moved to the control scenario (`_`). The control scenario itself cannot be deleted — delete the campaign instead. The campaign must not have ended.

If the campaign is in progress (enabled and within its `startAt`/`endAt` window) and the scenario has a weight above 0, you must pass `force` as `true` to delete it.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_DELETE_SCENARIO |

## Method Parameters

| Parameter    | Description                                                                                                             |
| ------------ | ----------------------------------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code that owns the scenario.                                                                               |
| scenarioCode | The scenario code to delete — for example `A` or `B`. The control scenario (`_`) cannot be deleted.                     |
| version      | Version of the scenario being deleted. Pass `-1` to delete regardless of the current version.                           |
| force        | If `true`, allows deleting a scenario that has weight allocated while the campaign is in progress. Defaults to `false`. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var scenarioCode = "A";
var version = -1;
var force = false;
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysDeleteScenario(campaignCode, scenarioCode, version, force);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_DELETE_SCENARIO",
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A",
        "version": -1,
        "force": false
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A"
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                 |
| ----- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No scenario exists for the specified `campaignCode` and `scenarioCode`.                                     |
| 40001 | INVALID_REQUEST                       | The campaign has ended and can no longer be modified.                                                       |
| 41063 | CAMPAIGN_SCENARIO_VERSION_MISMATCH    | The specified `version` no longer matches the scenario — it was updated by someone else. Re-read and retry. |
| 40660 | INVALID_PARAMETER_VALUE               | `scenarioCode` is the control scenario (`_`), which cannot be deleted.                                      |
| 41054 | CAMPAIGN_UPDATE_ERROR                 | The scenario has weight allocated while the campaign is in progress. Pass `force` as `true` to delete it.   |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                          |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.      |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysenablecampaign.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysenablecampaign -->

# SysEnableCampaign

Enables or disables a campaign. Only the `enabled` flag is changed — all other campaign fields are left untouched. The campaign must not have ended.

The campaign configuration is re-validated before it is enabled, so a campaign that has become invalid (for example, because its target segment was deleted) cannot be enabled until it is fixed.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_ENABLE_CAMPAIGN |

## Method Parameters

| Parameter    | Description                                           |
| ------------ | ----------------------------------------------------- |
| campaignCode | The campaign code to enable or disable.               |
| enable       | `true` to enable the campaign, `false` to disable it. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var enable = true;
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysEnableCampaign(campaignCode, enable);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_ENABLE_CAMPAIGN",
    "data": {
        "campaignCode": "SUMMER2026",
        "enable": true
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "enabled": true,
        "version": 2,
        "updatedAt": 1811725200000
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                                         |
| ----- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                                                |
| 40001 | INVALID_REQUEST                       | The campaign has ended and can no longer be modified.                                                                               |
| 41055 | INVALID_CAMPAIGN_CONFIGURATION        | The campaign configuration is no longer valid and the campaign cannot be enabled. The error message describes the specific problem. |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                                                  |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.                              |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysgetcampaignpage.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysgetcampaignpage -->

# SysGetCampaignPage

Returns a page of the app's campaigns, filtered and sorted using the provided context. The response includes an encoded `context` string that you can pass to [SysGetCampaignPageOffset](/api/capi/campaign/sysgetcampaignpageoffset) to fetch the pages before or after it.

A single page returns at most 100 campaigns by default.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_GET_CAMPAIGN_PAGE |

## Method Parameters

| Parameter | Description                                                                                                                                                                                                                                                                                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| context   | The JSON context for the page request. Supports `pagination` (`rowsPerPage`, `pageNumber`), `searchCriteria` (any simple campaign field, or dot-notation into `target`, `scenarios` or `campaignJson`) and `sortCriteria` (field name mapped to `1` for ascending or `-1` for descending). |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var context = {
    "pagination": {
        "rowsPerPage": 10,
        "pageNumber": 1
    },
    "searchCriteria": {
        "enabled": true,
        "endAt": {
            "$gt": 1811808000000
        },
        "target.type": "SEGMENT"
    },
    "sortCriteria": {
        "createdAt": -1
    }
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysGetCampaignPage(context);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_GET_CAMPAIGN_PAGE",
    "data": {
        "context": {
            "pagination": {
                "rowsPerPage": 10,
                "pageNumber": 1
            },
            "searchCriteria": {
                "enabled": true,
                "endAt": {
                    "$gt": 1811808000000
                },
                "target.type": "SEGMENT"
            },
            "sortCriteria": {
                "createdAt": -1
            }
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "context": "eyJzZWFyY2hDcml0ZXJpYSI6eyJlbmFibGVkIjp0cnVlfSwic29ydENyaXRlcmlhIjp7ImNyZWF0ZWRBdCI6LTF9LCJwYWdpbmF0aW9uIjp7InJvd3NQZXJQYWdlIjoxMCwicGFnZU51bWJlciI6MX19",
        "results": {
            "count": 11,
            "page": 1,
            "items": [
                {
                    "campaignCode": "SUMMER2026",
                    "name": "Summer 2026",
                    "purpose": "Evaluating impact of themes and summer sale on spenders",
                    "category": null,
                    "enabled": true,
                    "startAt": 1811808000000,
                    "endAt": 1814227200000,
                    "trigger": "LOGIN",
                    "target": {
                        "type": "SEGMENT",
                        "segmentCode": "spenders"
                    },
                    "scenarios": [
                        {
                            "scenarioCode": "_",
                            "weight": 100
                        }
                    ],
                    "campaignJson": {
                        "customFieldA": "summer",
                        "customFieldB": 1,
                        "customFieldC": true
                    },
                    "abGoalType": "revenue",
                    "abConfidence": null,
                    "notes": null,
                    "version": 1,
                    "createdAt": 1811721600000,
                    "updatedAt": 1811721600000
                }
            ],
            "moreAfter": true,
            "moreBefore": false
        }
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                            |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| 40358 | MISSING_REQUIRED_PARAMETER            | `context` was not specified.                                                                           |
| 40660 | INVALID_PARAMETER_VALUE               | `searchCriteria` or `sortCriteria` refers to a field that cannot be queried.                           |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                     |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysgetcampaignpageoffset.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysgetcampaignpageoffset -->

# SysGetCampaignPageOffset

Returns another page of campaigns, using the encoded context string returned by a previous call to [SysGetCampaignPage](/api/capi/campaign/sysgetcampaignpage) or to this method.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_GET_CAMPAIGN_PAGE_OFFSET |

## Method Parameters

| Parameter  | Description                                                                                                                                              |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| context    | The encoded context string returned by a previous call to SysGetCampaignPage or SysGetCampaignPageOffset.                                                |
| pageOffset | The positive or negative page offset to fetch, relative to the last page retrieved with this context. Pages before the first page return the first page. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var context = "eyJzZWFyY2hDcml0ZXJpYSI6eyJlbmFibGVkIjp0cnVlfSwic29ydENyaXRlcmlhIjp7ImNyZWF0ZWRBdCI6LTF9LCJwYWdpbmF0aW9uIjp7InJvd3NQZXJQYWdlIjoxMCwicGFnZU51bWJlciI6MX19";
var pageOffset = 1;
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysGetCampaignPageOffset(context, pageOffset);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_GET_CAMPAIGN_PAGE_OFFSET",
    "data": {
        "context": "eyJzZWFyY2hDcml0ZXJpYSI6eyJlbmFibGVkIjp0cnVlfSwic29ydENyaXRlcmlhIjp7ImNyZWF0ZWRBdCI6LTF9LCJwYWdpbmF0aW9uIjp7InJvd3NQZXJQYWdlIjoxMCwicGFnZU51bWJlciI6MX19",
        "pageOffset": 1
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "context": "eyJzZWFyY2hDcml0ZXJpYSI6eyJlbmFibGVkIjp0cnVlfSwic29ydENyaXRlcmlhIjp7ImNyZWF0ZWRBdCI6LTF9LCJwYWdpbmF0aW9uIjp7InJvd3NQZXJQYWdlIjoxMCwicGFnZU51bWJlciI6MX19",
        "results": {
            "count": 11,
            "page": 2,
            "items": [
                {
                    "campaignCode": "SPRING2027",
                    "name": "Spring 2027",
                    "purpose": "Evaluating impact of themes and summer sale on spenders",
                    "category": null,
                    "enabled": true,
                    "startAt": 1811808000000,
                    "endAt": 1814227200000,
                    "trigger": "LOGIN",
                    "target": {
                        "type": "SEGMENT",
                        "segmentCode": "spenders"
                    },
                    "scenarios": [
                        {
                            "scenarioCode": "_",
                            "weight": 100
                        }
                    ],
                    "campaignJson": {
                        "customFieldA": "summer",
                        "customFieldB": 1,
                        "customFieldC": true
                    },
                    "abGoalType": "revenue",
                    "abConfidence": null,
                    "notes": null,
                    "version": 1,
                    "createdAt": 1811721600000,
                    "updatedAt": 1811721600000
                }
            ],
            "moreAfter": false,
            "moreBefore": true
        }
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                            |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| 40358 | MISSING_REQUIRED_PARAMETER            | `context` or `pageOffset` was not specified.                                                           |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                     |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysreadcampaign.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysreadcampaign -->

# SysReadCampaign

Reads a campaign by campaign code and returns the full campaign configuration. Optionally includes the full configuration of every scenario in the campaign.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_READ_CAMPAIGN |

## Method Parameters

| Parameter              | Description                                                                                                                                                                    |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| campaignCode           | The campaign code to read.                                                                                                                                                     |
| includeScenarioDetails | If `true`, the response includes a `scenarioDetails` array with the full configuration of every scenario in the campaign, including the control scenario. Defaults to `false`. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var includeScenarioDetails = true;
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysReadCampaign(campaignCode, includeScenarioDetails);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_READ_CAMPAIGN",
    "data": {
        "campaignCode": "SUMMER2026",
        "includeScenarioDetails": true
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "name": "Summer 2026",
        "purpose": "Evaluating impact of themes and summer sale on spenders",
        "category": null,
        "enabled": false,
        "startAt": 1811808000000,
        "endAt": 1814227200000,
        "trigger": "LOGIN",
        "target": {
            "type": "SEGMENT",
            "segmentCode": "spenders"
        },
        "scenarios": [
            {
                "scenarioCode": "_",
                "weight": 100
            }
        ],
        "campaignJson": {
            "customFieldA": "summer",
            "customFieldB": 1,
            "customFieldC": true
        },
        "abGoalType": "revenue",
        "abConfidence": null,
        "notes": null,
        "version": 1,
        "createdAt": 1811721600000,
        "updatedAt": 1811721600000,
        "scenarioDetails": [
            {
                "campaignCode": "SUMMER2026",
                "scenarioCode": "_",
                "scenarioCampaignCode": "SUMMER2026:_",
                "description": "Control — no changes",
                "overrides": {
                    "globalProperties": {},
                    "cashProducts": {},
                    "items": {}
                },
                "scenarioJson": null,
                "version": 1,
                "createdAt": 1811721600000,
                "updatedAt": 1811721600000
            },
            {
                "campaignCode": "SUMMER2026",
                "scenarioCode": "A",
                "scenarioCampaignCode": "SUMMER2026:A",
                "description": "Beach",
                "overrides": {
                    "globalProperties": {
                        "xpMultiplier": {
                            "name": "xpMultiplier",
                            "value": "2"
                        },
                        "ThemeJson": {
                            "name": "ThemeJson",
                            "value": "{\"season\":\"Summer\",\"extra\":\"Beach\"}"
                        }
                    },
                    "cashProducts": {
                        "coinBundle10": {
                            "itemId": "coinBundle10",
                            "notForSale": false,
                            "priceId": 1,
                            "showAsListPrice": false
                        }
                    },
                    "items": {
                        "beachHat": {
                            "defId": "beachHat",
                            "buyPriceDisabled": false,
                            "buyPrice": {
                                "coin": 200
                            },
                            "showAsListPrice": false
                        },
                        "summerHat": {
                            "defId": "summerHat",
                            "buyPriceDisabled": true,
                            "buyPrice": null,
                            "showAsListPrice": false
                        }
                    }
                },
                "scenarioJson": {
                    "customField1": "beach"
                },
                "version": 1,
                "createdAt": 1811725200000,
                "updatedAt": 1811725200000
            }
        ]
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                            |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                   |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                     |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysreadscenario.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysreadscenario -->

# SysReadScenario

Reads a campaign scenario by campaign code and scenario code, and returns the full scenario configuration.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_READ_SCENARIO |

## Method Parameters

| Parameter    | Description                                                                          |
| ------------ | ------------------------------------------------------------------------------------ |
| campaignCode | The campaign code that owns the scenario.                                            |
| scenarioCode | The scenario code to read — for example `A` or `B`, or `_` for the control scenario. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var scenarioCode = "A";
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysReadScenario(campaignCode, scenarioCode);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_READ_SCENARIO",
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A"
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A",
        "scenarioCampaignCode": "SUMMER2026:A",
        "description": "Beach",
        "overrides": {
            "globalProperties": {
                "xpMultiplier": {
                    "name": "xpMultiplier",
                    "value": "2"
                },
                "ThemeJson": {
                    "name": "ThemeJson",
                    "value": "{\"season\":\"Summer\",\"extra\":\"Beach\"}"
                }
            },
            "cashProducts": {
                "coinBundle10": {
                    "itemId": "coinBundle10",
                    "notForSale": false,
                    "priceId": 1,
                    "showAsListPrice": false
                }
            },
            "items": {
                "beachHat": {
                    "defId": "beachHat",
                    "buyPriceDisabled": false,
                    "buyPrice": {
                        "coin": 200
                    },
                    "showAsListPrice": false
                },
                "summerHat": {
                    "defId": "summerHat",
                    "buyPriceDisabled": true,
                    "buyPrice": null,
                    "showAsListPrice": false
                }
            }
        },
        "scenarioJson": {
            "customField1": "beach"
        },
        "version": 1,
        "createdAt": 1811725200000,
        "updatedAt": 1811725200000
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                            |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| 40345 | MISSING_RECORD                        | No scenario exists for the specified `campaignCode` and `scenarioCode`.                                |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                     |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysremoveallcampaignsforuser.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysremoveallcampaignsforuser -->

# SysRemoveAllCampaignsForUser

Removes a player's participation in all campaigns, deleting all their CampaignParticipant records and clearing the campaigns map from their profile.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_REMOVE_ALL_CAMPAIGNS_FOR_USER |

## Method Parameters

| Parameter | Description                                                  |
| --------- | ------------------------------------------------------------ |
| profileId | The profile ID of the player to remove all campaigns for.    |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var profileId = "aProfileId";
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysRemoveAllCampaignsForUser(profileId);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_REMOVE_ALL_CAMPAIGNS_FOR_USER",
    "data": {
        "profileId": "aProfileId"
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {},
    "status": 200
}
```

</details>

<details>
<summary>Common Error Code</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                           |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysremovecampaignforuser.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysremovecampaignforuser -->

# SysRemoveCampaignForUser

Removes a player's participation in a specific campaign, deleting their CampaignParticipant record and removing the campaign entry from their profile.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_REMOVE_CAMPAIGN_FOR_USER |

## Method Parameters

| Parameter    | Description                                              |
| ------------ | -------------------------------------------------------- |
| profileId    | The profile ID of the player to remove the campaign for. |
| campaignCode | The campaign code to remove for the player.              |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var profileId = "aProfileId";
var campaignCode = "CHRISTMAS2026";
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysRemoveCampaignForUser(profileId, campaignCode);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_REMOVE_CAMPAIGN_FOR_USER",
    "data": {
        "profileId": "aProfileId",
        "campaignCode": "CHRISTMAS2026"
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "CHRISTMAS2026"
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Code</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                           |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/systriggercampaignforuser.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/systriggercampaignforuser -->

# SysTriggerCampaignForUser

Triggers a campaign scenario for a specific player, optionally bypassing normal eligibility constraints. The target player must have `isTester=true` on their profile. The campaign `endAt` is always respected.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_TRIGGER_CAMPAIGN_FOR_USER |

## Method Parameters

| Parameter    | Description                                                                                                                                                                                                                                                                                                              |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| profileId    | The profile ID of the player to trigger the campaign for. Player must have `isTester=true` on their profile.                                                                                                                                                                                                             |
| campaignCode | The campaign code to trigger for the player.                                                                                                                                                                                                                                                                             |
| optionsJson  | Optional control flags. `ignoreEnabled` (boolean, default false): allow triggering even if campaign is disabled. `ignoreScheduleStart` (boolean, default false): allow triggering before campaign `startAt`. `ignoreControl` (boolean, default false): exclude control scenario from weighted assignment. `scenarioCode` (string): if specified, assign this specific scenario instead of weighted assignment. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var profileId = "aProfileId";
var campaignCode = "CHRISTMAS2026";
var optionsJson = {
    "ignoreEnabled": false,
    "ignoreScheduleStart": false,
    "ignoreControl": false,
    "scenarioCode": "a"
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysTriggerCampaignForUser(profileId, campaignCode, optionsJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_TRIGGER_CAMPAIGN_FOR_USER",
    "data": {
        "profileId": "aProfileId",
        "campaignCode": "CHRISTMAS2026",
        "optionsJson": {
            "ignoreEnabled": false,
            "ignoreScheduleStart": false,
            "ignoreControl": false,
            "scenarioCode": "a"
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "CHRISTMAS2026",
        "scenarioCode": "a"
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Code</summary>

### Status Codes

| Code  | Name                                       | Description                                                                                                    |
| ----- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| 41060 | CAMPAIGN_SYS_TRIGGER_CAMPAIGN_FOR_USER_ERROR | Trigger failed — campaign disabled, has not started, has ended, player is not a tester, or player is already enrolled in a different scenario. |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN      | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.          |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysupdatecampaign.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysupdatecampaign -->

# SysUpdateCampaign

Updates an existing campaign. Only the fields present in `configJson` are changed — omitted fields keep their current values. The campaign must not have ended.

Scenario weights cannot be changed through this call; use [SysUpdateCampaignScenarioWeights](/api/capi/campaign/sysupdatecampaignscenarioweights) instead. If none of the supplied fields differ from the current values, the campaign is returned unchanged and its `version` is not incremented.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_UPDATE_CAMPAIGN |

## Method Parameters

| Parameter    | Description                                                                                                                                                                                                                                                                                                                                                              |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| campaignCode | The campaign code to update.                                                                                                                                                                                                                                                                                                                                             |
| version      | Version of the campaign being updated. Pass `-1` to update regardless of the current version.                                                                                                                                                                                                                                                                            |
| configJson   | Full or partial campaign configuration. Updatable fields are `name`, `purpose`, `category`, `enabled`, `startAt`, `endAt`, `trigger`, `target`, `campaignJson`, `abGoalType`, `abConfidence` and `notes` — see [SysCreateCampaign](/api/capi/campaign/syscreatecampaign) for their meaning and allowed values. `enabled`, `startAt` and `endAt` cannot be set to `null`. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var version = -1;
var configJson = {
    "name": "Summer Sale 2026",
    "purpose": "Evaluating impact of themes and summer sale",
    "target": {
        "type": "ALL"
    }
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysUpdateCampaign(campaignCode, version, configJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_UPDATE_CAMPAIGN",
    "data": {
        "campaignCode": "SUMMER2026",
        "version": -1,
        "configJson": {
            "name": "Summer Sale 2026",
            "purpose": "Evaluating impact of themes and summer sale",
            "target": {
                "type": "ALL"
            }
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "name": "Summer Sale 2026",
        "purpose": "Evaluating impact of themes and summer sale",
        "category": null,
        "enabled": false,
        "startAt": 1811808000000,
        "endAt": 1814227200000,
        "trigger": "LOGIN",
        "target": {
            "type": "ALL"
        },
        "scenarios": [
            {
                "scenarioCode": "_",
                "weight": 100
            }
        ],
        "campaignJson": {
            "customFieldA": "summer",
            "customFieldB": 1,
            "customFieldC": true
        },
        "abGoalType": "revenue",
        "abConfidence": null,
        "notes": null,
        "version": 2,
        "createdAt": 1811721600000,
        "updatedAt": 1811725200000
    },
    "status": 200
}
```

</details>

The returned `version` is the campaign's new version after the update. Feed it into your next call's `version` parameter if you want to detect a concurrent change rather than overwrite it.

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                                                                                                                          |
| ----- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                                                                                                                                 |
| 40001 | INVALID_REQUEST                       | The campaign has ended and can no longer be modified.                                                                                                                                                                |
| 41062 | CAMPAIGN_VERSION_MISMATCH             | The specified `version` no longer matches the campaign — it was updated by someone else. Re-read and retry.                                                                                                          |
| 40660 | INVALID_PARAMETER_VALUE               | The updated configuration is invalid — for example, `startAt` is not before `endAt`, the target segment does not exist, or a non-nullable field was set to `null`. The error message describes the specific problem. |
| 41064 | CAMPAIGN_JSON_TOO_LARGE               | The serialized `campaignJson` exceeds the maximum size allowed for the app.                                                                                                                                          |
| 41054 | CAMPAIGN_UPDATE_ERROR                 | The campaign could not be updated.                                                                                                                                                                                   |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                                                                                                                                   |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.                                                                                                               |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysupdatecampaignjson.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysupdatecampaignjson -->

# SysUpdateCampaignJson

Updates **only** the free-form `campaignJson` custom payload on a campaign. No other campaign field can be modified through this call — the schedule, trigger, target, scenario weights and A/B settings are all left untouched, and a concurrent edit to any of them in the Design Portal will not be overwritten.

The campaign must not have ended. The updated payload is picked up by already-authenticated players on their next [GetMyCampaigns](/api/capi/campaign/getmycampaigns) call — they do not need to re-authenticate.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_UPDATE_CAMPAIGN_JSON |

## Method Parameters

| Parameter    | Description                                                                                                                                                                             |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code whose `campaignJson` is being updated.                                                                                                                                |
| version      | Version of the campaign being updated. Pass `-1` to update regardless of the current version.                                                                                           |
| campaignJson | The new `campaignJson` custom payload. This **replaces** the existing payload entirely — it is not merged. Pass `null` to clear it. Oversized payloads are rejected; see the note below. |

> **Info:** `campaignJson` is returned to every player enrolled in the campaign, so keep it to the data your client actually needs. The maximum serialized size is governed by an application property — contact support if you need the limit adjusted.

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "CHRISTMAS2026";
var version = -1;
var campaignJson = {
    "theme": "winter",
    "bannerId": 7
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysUpdateCampaignJson(campaignCode, version, campaignJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_UPDATE_CAMPAIGN_JSON",
    "data": {
        "campaignCode": "CHRISTMAS2026",
        "version": -1,
        "campaignJson": {
            "theme": "winter",
            "bannerId": 7
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "CHRISTMAS2026",
        "version": 4,
        "updatedAt": 1786737600000
    },
    "status": 200
}
```

</details>

The returned `version` is the campaign's new version after the update. Feed it into your next call's `version` parameter if you want to detect a concurrent change rather than overwrite it.

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                | Description                                                                                        |
| ----- | ----------------------------------- | -------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                      | No campaign exists for the specified `campaignCode`.                                                |
| 40001 | INVALID_REQUEST                     | The campaign has ended and can no longer be modified.                                               |
| 41062 | CAMPAIGN_VERSION_MISMATCH           | The specified `version` no longer matches the campaign — it was updated by someone else. Re-read and retry. |
| 41064 | CAMPAIGN_JSON_TOO_LARGE             | The serialized `campaignJson` exceeds the maximum size allowed for the app.                         |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysupdatecampaignscenarioweights.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysupdatecampaignscenarioweights -->

# SysUpdateCampaignScenarioWeights

Sets the traffic split between a campaign's scenarios. The list you pass **replaces** the current weight distribution. The campaign must not have ended.

The list must include the control scenario (`_`), every scenario in it must already exist, and the weights must be integers that add up to exactly 100. A scenario you leave out gets no traffic.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_UPDATE_CAMPAIGN_SCENARIO_WEIGHTS |

## Method Parameters

| Parameter    | Description                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code whose scenario weights are being updated.                                   |
| version      | Version of the campaign being updated. Pass `-1` to update regardless of the current version. |
| scenarios    | Array of objects, each with a `scenarioCode` (string) and a `weight` (integer, 0–100).        |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var version = -1;
var scenarios = [
    {
        "scenarioCode": "_",
        "weight": 30
    },
    {
        "scenarioCode": "A",
        "weight": 35
    },
    {
        "scenarioCode": "B",
        "weight": 35
    }
];
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysUpdateCampaignScenarioWeights(campaignCode, version, scenarios);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_UPDATE_CAMPAIGN_SCENARIO_WEIGHTS",
    "data": {
        "campaignCode": "SUMMER2026",
        "version": -1,
        "scenarios": [
            {
                "scenarioCode": "_",
                "weight": 30
            },
            {
                "scenarioCode": "A",
                "weight": 35
            },
            {
                "scenarioCode": "B",
                "weight": 35
            }
        ]
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarios": [
            {
                "scenarioCode": "_",
                "weight": 30
            },
            {
                "scenarioCode": "A",
                "weight": 35
            },
            {
                "scenarioCode": "B",
                "weight": 35
            }
        ],
        "version": 3,
        "updatedAt": 1811732400000
    },
    "status": 200
}
```

</details>

The returned `version` is the campaign's new version after the update.

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                                |
| ----- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                                       |
| 40345 | MISSING_RECORD                        | No scenario exists for the specified `campaignCode` and `scenarioCode`.                                                    |
| 40001 | INVALID_REQUEST                       | The campaign has ended, the control scenario (`_`) is missing from `scenarios`, or the weights do not add up to 100.       |
| 40332 | UPDATE_FAILED                         | The weights could not be saved. This includes the case where `version` no longer matches the campaign — re-read and retry. |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                                         |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.                     |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysupdatescenario.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysupdatescenario -->

# SysUpdateScenario

Updates an existing variant scenario. Only the fields present in `configJson` are changed — omitted fields keep their current values. The control scenario (`_`) cannot be updated, and the campaign must not have ended.

Within `overrides`, each of `globalProperties`, `cashProducts` and `items` is handled separately: a map you include **replaces** that map entirely, and a map you omit is left unchanged. Pass `{}` to clear a map. The scenario must still contain at least one override after the update.

If none of the supplied fields differ from the current values, the scenario is returned unchanged and its `version` is not incremented.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_UPDATE_SCENARIO |

## Method Parameters

| Parameter    | Description                                                                                                                                                                                                                                                                                                                                     |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code that owns the scenario.                                                                                                                                                                                                                                                                                                       |
| scenarioCode | The scenario code to update — for example `A` or `B`. The control scenario (`_`) cannot be updated.                                                                                                                                                                                                                                             |
| version      | Version of the scenario being updated. Pass `-1` to update regardless of the current version.                                                                                                                                                                                                                                                   |
| configJson   | Full or partial scenario configuration. Updatable fields are `description`, `overrides` and `scenarioJson`. `overrides` and its `globalProperties`, `cashProducts` and `items` maps cannot be set to `null` — use `{}` to clear them. See [SysCreateScenario](/api/capi/campaign/syscreatescenario#scenario-overrides) for the override format. |

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "SUMMER2026";
var scenarioCode = "A";
var version = -1;
var configJson = {
    "description": "Beach #1",
    "scenarioJson": {
        "customField1": "beach",
        "customField2": {
            "subtheme": "beachTheme"
        }
    }
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysUpdateScenario(campaignCode, scenarioCode, version, configJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_UPDATE_SCENARIO",
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A",
        "version": -1,
        "configJson": {
            "description": "Beach #1",
            "scenarioJson": {
                "customField1": "beach",
                "customField2": {
                    "subtheme": "beachTheme"
                }
            }
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "SUMMER2026",
        "scenarioCode": "A",
        "scenarioCampaignCode": "SUMMER2026:A",
        "description": "Beach #1",
        "overrides": {
            "globalProperties": {
                "xpMultiplier": {
                    "name": "xpMultiplier",
                    "value": "2"
                },
                "ThemeJson": {
                    "name": "ThemeJson",
                    "value": "{\"season\":\"Summer\",\"extra\":\"Beach\"}"
                }
            },
            "cashProducts": {
                "coinBundle10": {
                    "itemId": "coinBundle10",
                    "notForSale": false,
                    "priceId": 1,
                    "showAsListPrice": false
                }
            },
            "items": {
                "beachHat": {
                    "defId": "beachHat",
                    "buyPriceDisabled": false,
                    "buyPrice": {
                        "coin": 200
                    },
                    "showAsListPrice": false
                },
                "summerHat": {
                    "defId": "summerHat",
                    "buyPriceDisabled": true,
                    "buyPrice": null,
                    "showAsListPrice": false
                }
            }
        },
        "scenarioJson": {
            "customField1": "beach",
            "customField2": {
                "subtheme": "beachTheme"
            }
        },
        "version": 2,
        "createdAt": 1811725200000,
        "updatedAt": 1811728800000
    },
    "status": 200
}
```

</details>

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                                                                                                                                                               |
| ----- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`.                                                                                                                                                                                                      |
| 40345 | MISSING_RECORD                        | No scenario exists for the specified `campaignCode` and `scenarioCode`.                                                                                                                                                                                   |
| 40001 | INVALID_REQUEST                       | The campaign has ended and can no longer be modified.                                                                                                                                                                                                     |
| 41063 | CAMPAIGN_SCENARIO_VERSION_MISMATCH    | The specified `version` no longer matches the scenario — it was updated by someone else. Re-read and retry.                                                                                                                                               |
| 40660 | INVALID_PARAMETER_VALUE               | The update is invalid — for example, `scenarioCode` is the control scenario, a non-nullable field was set to `null`, no overrides would remain, or an override refers to something that does not exist. The error message describes the specific problem. |
| 41054 | CAMPAIGN_UPDATE_ERROR                 | The scenario could not be updated.                                                                                                                                                                                                                        |
| 40616 | CLOUD_CODE_ONLY_METHOD                | The method was called from a client. It can only be called from Cloud Code or S2S.                                                                                                                                                                        |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features.                                                                                                                                                    |

</details>


---

<!-- source: docs/api/2_capi/campaign/sysupdatescenariojson.md -->
<!-- url: https://docs.braincloudservers.com/api/capi/campaign/sysupdatescenariojson -->

# SysUpdateScenarioJson

Updates **only** the free-form `scenarioJson` custom payload on a campaign scenario. No other scenario field can be modified through this call — in particular the scenario's **overrides** (global properties, cash product prices, item definitions) are left untouched, as is its description.

The owning campaign must not have ended. The updated payload is picked up by already-authenticated players on their next [GetMyCampaigns](/api/capi/campaign/getmycampaigns) call — they do not need to re-authenticate.

| Service | Operation |
| ------- | --------- |
| campaign | SYS_UPDATE_SCENARIO_JSON |

## Method Parameters

| Parameter    | Description                                                                                                                                                                             |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| campaignCode | The campaign code that owns the scenario.                                                                                                                                               |
| scenarioCode | The scenario code whose `scenarioJson` is being updated. Pass `"_"` for the control scenario.                                                                                           |
| version      | Version of the scenario being updated. Pass `-1` to update regardless of the current version.                                                                                           |
| scenarioJson | The new `scenarioJson` custom payload. This **replaces** the existing payload entirely — it is not merged. Pass `null` to clear it. Oversized payloads are rejected; see the note below. |

> **Info:** `scenarioJson` is returned to every player assigned to this scenario, so keep it to the data your client actually needs. The maximum serialized size is governed by an application property — contact support if you need the limit adjusted.

> **Caution:** `scenarioJson` is part of what distinguishes one variant from another. Changing it while the campaign is running changes what that variant means, but the campaign's accumulated A/B statistics continue to pool participants from before and after the change as a single group. Prefer to finalize variant payloads before the campaign starts, and treat mid-flight edits as something to note when interpreting the results.

## Usage

**C#:**

```csharp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**C++:**

```cpp
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Obj-C:**

```objectivec
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Java:**

```java
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**JavaScript:**

```javascript
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Dart:**

```dart
// Cloud Code only. To view example, switch to the Cloud Code tab
```

**Roblox:**

```lua
-- N/A
```

**GDScript:**

```gdscript
N/A
```

**Lua:**

```lua
-- Cloud Code only. To view example, switch to the Cloud Code tab
```

**Cloud Code:**

```cfscript
var campaignCode = "CHRISTMAS2026";
var scenarioCode = "a";
var version = -1;
var scenarioJson = {
    "headline": "50% off everything!",
    "bannerColor": "red"
};
var campaignProxy = bridge.getCampaignServiceProxy();

var postResult = campaignProxy.sysUpdateScenarioJson(campaignCode, scenarioCode, version, scenarioJson);
```

**Raw:**

```r
{
    "service": "campaign",
    "operation": "SYS_UPDATE_SCENARIO_JSON",
    "data": {
        "campaignCode": "CHRISTMAS2026",
        "scenarioCode": "a",
        "version": -1,
        "scenarioJson": {
            "headline": "50% off everything!",
            "bannerColor": "red"
        }
    }
}
```

<details>
<summary>JSON Response</summary>

```json
{
    "data": {
        "campaignCode": "CHRISTMAS2026",
        "scenarioCode": "a",
        "version": 2,
        "updatedAt": 1786737600000
    },
    "status": 200
}
```

</details>

The returned `version` is the scenario's new version after the update. Feed it into your next call's `version` parameter if you want to detect a concurrent change rather than overwrite it.

<details>
<summary>Common Error Codes</summary>

### Status Codes

| Code  | Name                                  | Description                                                                                                 |
| ----- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| 40345 | MISSING_RECORD                        | No campaign exists for the specified `campaignCode`, or no scenario exists for the specified `scenarioCode`. |
| 40001 | INVALID_REQUEST                       | The owning campaign has ended and can no longer be modified.                                                 |
| 41063 | CAMPAIGN_SCENARIO_VERSION_MISMATCH    | The specified `version` no longer matches the scenario — it was updated by someone else. Re-read and retry.  |
| 41064 | CAMPAIGN_JSON_TOO_LARGE               | The serialized `scenarioJson` exceeds the maximum size allowed for the app.                                  |
| 40731 | FEATURE_NOT_SUPPORTED_BY_BILLING_PLAN | Billing plan does not include the Campaign feature. Requires a plan that includes Enterprise features. |

</details>


---

<!-- source: docs/api/4_s2s/campaign/index.md -->
<!-- url: https://docs.braincloudservers.com/api/s2s/campaign -->

# Campaign

**Campaign** is a LiveOps service that enables no-code A/B testing and feature flagging. Game operators can create time-bounded campaigns that modify game behavior for targeted player segments — without deploying new code.

### API Summary

- [SysTriggerCampaignForUser](/api/capi/campaign/systriggercampaignforuser) - Triggers a campaign scenario for a specific player, bypassing normal eligibility constraints. Player must be flagged as a tester.
- [SysRemoveCampaignForUser](/api/capi/campaign/sysremovecampaignforuser) - Removes a player's participation in a specific campaign.
- [SysRemoveAllCampaignsForUser](/api/capi/campaign/sysremoveallcampaignsforuser) - Removes a player's participation in all campaigns.
- [SysCreateCampaign](/api/capi/campaign/syscreatecampaign) - Creates a new campaign. A control scenario is automatically created alongside the campaign.
- [SysReadCampaign](/api/capi/campaign/sysreadcampaign) - Reads a campaign's full configuration, optionally including the details of every scenario.
- [SysUpdateCampaign](/api/capi/campaign/sysupdatecampaign) - Updates some or all of a campaign's configuration fields.
- [SysDeleteCampaign](/api/capi/campaign/sysdeletecampaign) - Deletes a campaign along with all of its scenarios, participation records and metrics.
- [SysEnableCampaign](/api/capi/campaign/sysenablecampaign) - Enables or disables a campaign without changing any other fields.
- [SysGetCampaignPage](/api/capi/campaign/sysgetcampaignpage) - Returns a filtered, sorted page of the app's campaigns.
- [SysGetCampaignPageOffset](/api/capi/campaign/sysgetcampaignpageoffset) - Returns another page of campaigns using the context from a previous page request.
- [SysCreateScenario](/api/capi/campaign/syscreatescenario) - Creates a new variant scenario under a campaign.
- [SysReadScenario](/api/capi/campaign/sysreadscenario) - Reads a campaign scenario's full configuration.
- [SysUpdateScenario](/api/capi/campaign/sysupdatescenario) - Updates some or all of a variant scenario's configuration fields.
- [SysDeleteScenario](/api/capi/campaign/sysdeletescenario) - Deletes a variant scenario and moves its weight to the control scenario.
- [SysUpdateCampaignScenarioWeights](/api/capi/campaign/sysupdatecampaignscenarioweights) - Sets the traffic split between a campaign's scenarios.
- [SysUpdateCampaignJson](/api/capi/campaign/sysupdatecampaignjson) - Updates only the free-form `campaignJson` custom payload on a campaign.
- [SysUpdateScenarioJson](/api/capi/campaign/sysupdatescenariojson) - Updates only the free-form `scenarioJson` custom payload on a campaign scenario.

> **Tip:** All client APIs whose names begin with **"Sys"** are also available to S2S.
> For the usages of the S2S campaign APIs, refer to the brainCloud client [campaign](/api/capi/campaign) APIs.
