Skip to main content

Bonuses API

Auth: Clerk session (admin) or internal secret (server-to-server grants).

Templates

GET /v1/bonus-templates?cursor=&limit=50&status=active&type=deposit_match GET /v1/bonus-templates/:id POST /v1/bonus-templates PATCH /v1/bonus-templates/:id DELETE /v1/bonus-templates/:id

// Create:
{
"name": "Welcome 100% match",
"type": "deposit_match",
"config": {
"match_percent": 100,
"cap_amount": 20000, // €200 in EUR cents
"currency": "EUR"
},
"wagering_requirement_multiplier": 30,
"wagering_basis": "bonus_plus_deposit",
"max_bet_during_wagering": 500, // €5 in EUR cents
"time_limit_hours": 720,
"max_grants_per_player": 1,
"game_contribution": {
"slots": 100, "table": 10, "live": 5, "default": 0
},
"max_win_cap": 100000 // €1000 in EUR cents
}

Grants

GET /v1/bonus-grants?player_id=&template_id=&status=active GET /v1/bonus-grants/:id

POST /v1/bonus-grants — issue:

{
"template_id": "uuid",
"player_id": "uuid",
"granted_by_kind": "manual", // manual | api | journey | campaign | auto
"granted_by_id": null, // journey_run_id / campaign_id when applicable
"deposit_amount": 10000, // for deposit_match types only
"currency_override": "USD" // optional — defaults to template's currency
}

Errors:

  • 404 BONUS_TEMPLATE_NOT_FOUND
  • 422 BONUS_TEMPLATE_NOT_ACTIVE — template is in paused status
  • 409 BONUS_GRANT_LIMIT_REACHED — anti-stacking hit
  • 422 BONUS_DEPOSIT_AMOUNT_REQUIREDdeposit_match without deposit_amount
  • 422 BONUS_CONFIG_INVALID — config doesn't match the type
  • 502 ADAPTER_REJECTED — platform refused the grant
  • 503 ADAPTER_UNAVAILABLE — platform unreachable; retry queued

Success returns the full bonus_grants row.

POST /v1/bonus-grants/:id/cancel — admin cancellation. Calls adapter.bonus.cancelBonus() then transitions to cancelled.

Bonus campaigns

Like email campaigns but for bonuses — segment + bonus_template fan-out.

GET /v1/bonus-campaigns POST /v1/bonus-campaigns PATCH /v1/bonus-campaigns/:id POST /v1/bonus-campaigns/:id/issue — kick off the fan-out.

// Stats response:
{
"data": {
"id": "uuid",
"status": "issued",
"stats": { "pending": 0, "granted": 142, "skipped": 18, "failed": 2 }
}
}

skipped = anti-stacking hit (player already has active grant of this template).

Inbound webhooks

POST /v1/adapters/:slug/webhooks/bonus-events — see Webhooks API + Adapter integration.