Design for availability
PlayerPal is an asynchronous loyalty layer that sits beside your platform, not in front of it. If every PlayerPal service were unavailable, your players could still log in, launch games, place bets, have rounds settled and be paid. This page explains the rule and the outbox pattern that keeps it true in your integration.
The rule
AvailableLogin, game launch, wagering, settlement and payouts never call PlayerPal and never wait for it. Everything PlayerPal needs reaches it later, in batches, from your own outbox.
- No PlayerPal call before or during game launch. The operator creates the launch session with the game provider directly.
- No PlayerPal call per wager or round. The operator's wallet stays authoritative and the game provider owns the round.
- The alias travels with the launch. A game provider receives its PlayerPal player alias (
pp_plr_prv_…) in the operator's launch metadata. PlayerPal issues it when the player links, so nothing is looked up at launch. - Activity is sent later, in batches. Write it to a local outbox and deliver it asynchronously.
- The widget is optional and fails open. If it cannot load, play is unaffected.
What depends on PlayerPal
| Moment | Calls PlayerPal? | Needed for play? | If PlayerPal is unavailable |
|---|---|---|---|
| Login and game launch | No | No | No impact |
| Each wager, settlement or payout | No | No | No impact; activity stays in your outbox |
| Batch delivery | One call per batch | No | Keep the batch and retry with backoff |
| Player links an account | Yes | No | Show "unavailable"; games stay usable |
| Widget or status display | Optional read | No | Show a neutral or unavailable state |
| Viewing or redeeming Points | Yes | No | Not available until PlayerPal recovers |
Recommended outbox pattern
AvailableRecord eligible activity in your own database and let a background worker deliver it. The worker is the only part of your system that talks to PlayerPal.
Guidelines:
- Write the outbox row in the same database transaction as settlement. Then a crash can never settle a round without recording its activity, or the reverse.
- Assign the
batch_idonce, when you form the batch, and store it. Reuse it on every retry so PlayerPal can deduplicate. - Retry until delivered. Use exponential backoff with jitter and no fixed give-up point. Alert if a batch has been pending for longer than you expect.
- Survive restarts. On startup, resume any batch that was pending or retrying.
- Do not let one stuck batch block newer ones. Keep delivering fresh batches while an older one retries.
- Send many events per call. One batch of hundreds or thousands of events is better than one call per round.
- Cache tokens per worker, not per player, and refresh before expiry.
- Check a batch only after an ambiguous response, using its status endpoint.
What an outbox record holds
AvailableKeep each event exactly as you will send it, plus two delivery fields: the batch_id it was assigned to (empty until a batch is formed) and its delivery state. The shape below is an example; use whatever storage you already run.
{
"event_id": "round-8812-settled",
"type": "round_settled",
"player_id": "pp_plr_prv_XXXX",
"occurred_at": "2026-10-15T12:03:11Z",
"game_ref": "your-game-ref",
"round_ref": "round-8812",
"currency": "EUR",
"bet": "2.00",
"win": "0.00",
"batch_id": "rounds-2026-10-15-0001",
"state": "pending"
}
state | Meaning |
|---|---|
queued | Written with settlement, not yet in a batch |
pending | Assigned to a batch that is being delivered or retried |
accepted | PlayerPal returned a receipt for its batch |
The event fields match an activity batch. Store the batch itself too, with its batch_id, its event IDs and an attempt count, so a restarted worker can resume it unchanged.
During an outage
Available- Play continues. Nothing in login, launch, wagering, settlement or payout calls PlayerPal.
- Points arrive late, not differently. Eligibility is based on when the activity happened (
occurred_at), not when it reached PlayerPal. Activity that happened before a player unlinked still counts when it arrives later. - Analytics catch up. KPIs reflect delayed batches once they are delivered and processed.
- Your data is safe while it stays in your outbox. Delivery protection comes from your durable outbox and the reuse of the same
batch_id.
PlayerPal does not yet publish availability or freshness commitments. Contact PlayerPal for current targets.
Ways to deliver data
| Endpoint | Use |
|---|---|
POST /v1/activity-batches | Batches of settled-round activity that feed Points |
POST /v1/activity-uploads, then .../complete | Large activity files through a signed upload URL |
POST /v1/ingest | Daily pseudonymous facts that feed KPIs, up to 10,000 records per batch |
All three accept at-least-once delivery. See Idempotency and errors.
Availability checklist
- Login, launch, wagering, settlement and payouts complete with PlayerPal blocked at your network edge.
- The outbox record is written in the same transaction as settlement.
- Each batch gets its
batch_idonce, and every retry resends the identical batch. - Retries use exponential backoff with jitter, and you alert on batches pending longer than you expect.
- A restarted worker resumes pending batches, and a stuck batch does not hold back newer ones.
- Link and widget screens show a neutral or unavailable state instead of an error when PlayerPal does not answer.
Block PlayerPal, play a few rounds and restart your worker. Play is unaffected, the rows stay queued or pending, and once you unblock PlayerPal every batch is accepted exactly once.