## Responses and Errors

All successful responses are sent with 2xx HTTP codes.

All errors are sent with 4xx or 5xx HTTP codes.

### Error Response Body:

| Field | Required | Description |
|  --- | --- | --- |
| code | True | System code for identification type of the error. |
| message | False | Message with error details. |
| timestamp | False | Timestamp of the error occurrence. |
| path | False | Request path that caused the error. |


### Example of Error Response Body:

```
{
    "code": "REQUEST_NOT_VALID",
    "message": "bet - must not be null, betNumber - must not be null, currencyCode - must not be null, endDateTime - must not be null, name - must not be empty, startDateTime - must not be null",
    "timestamp": "2026-01-25T14:30:00Z",
    "path": "/api/v1/campaign"
}
```

### Error Codes

| HTTP Code | Code | Description |
|  --- | --- | --- |
| 400 | REQUEST_NOT_VALID | The request is invalid or violates a business rule. Refer to [Campaign Validation Rules](/content/integration/public-api/promotions-api/validation-rules). |
| 400 | ACTION_FORBIDDEN | The requested action is not permitted for the current state of the campaign or player. |
| 400 | CAMPAIGN_ALREADY_STARTED | The campaign has already started and can no longer be modified or deleted. |
| 400 | CAMPAIGN_ALREADY_ENDED | The campaign has ended and can no longer be modified. |
| 400 | CAMPAIGN_DISABLED | The campaign has been disabled and can no longer be modified. |
| 400 | DUPLICATED_EXTERNAL_CAMPAIGN_ID | Another campaign within the brand already uses the specified `externalCampaignId`. |
| 400 | BRAND_REQUIRED | The credentials used require the brand to be specified in the request path. |
| 400 | ROUND_NOT_FINISHED | Symbol mapping was requested for a round that is still in progress. |
| 400 | GAME_NOT_SUPPORTED | The game does not support symbol mapping. |
| 401 | NOT_AUTHORIZED | Authentication failed, or the required mTLS headers were absent. |
| 403 | INSUFFICIENT_SCOPE | The credentials used do not include the scope required by this endpoint. |
| 403 | BRAND_NOT_ALLOWED | The credentials used do not have access to the brand specified in the request path. |
| 403 | BRAND_MISMATCH | The brand specified in the request path does not match the brand associated with the credentials used. |
| 403 | ACCESS_TO_ROUND_DENIED | The round belongs to a different brand. |
| 404 | CAMPAIGN_NOT_FOUND | No campaign with the specified ID exists for the brand. |
| 404 | PARTICIPANT_NOT_FOUND | The specified player is not a participant of the campaign. |
| 404 | ROUND_NOT_FOUND | No round with the specified ID exists. |
| 404 | GAME_ACTION_EVENTS_SUBSCRIPTION_NOT_FOUND | No Game Events subscription exists for the brand. |
| 429 | TOO_MANY_REQUESTS | A rate limit has been exceeded. The applicable limits are listed under [Promotions](/content/integration/public-api/promotions-api#api-rate-limiting). |
| 500 | UNKNOWN_ERROR | An unexpected error occurred while processing the request. |
| 504 | TIMEOUT | A RubyPlay service did not respond within the expected time. |