# How Onari works

> Players, environments, and what happens to each event.

Source: https://docs.onari.xyz/docs/concepts/how-it-works

## Players

A player is one of your customers, identified by **your own ID** (`player_id`), up to 128 characters. Use a stable internal ID such as `user_8a21`. Onari never needs names, phone numbers, emails, BVN or anything else that identifies a person, so don't send them.

A player is created the first time you send an event for them, open the Rewards Hub for them, or call [`POST /v1/players/:id`](/docs/api/players).

## Sandbox and live

Every workspace has two separate environments:

| | Sandbox | Live |
|---|---|---|
| Keys | `sk_test_…` | `sk_live_…` |
| Players, campaigns, rewards, webhooks | Separate | Separate |
| Plan limits | None | Your plan's (see [Limits](/docs/api/limits)) |
| Counts as active players | No | Yes |

The key you use decides the environment. Test everything in sandbox first.

## What happens to an event

When `POST /v1/events` arrives, Onari does all of this in one database transaction:

1. **Checks the event type** is on your events list.
2. **Stores the event once.** Send an `idempotency_key` and a retry is recognised and ignored.
3. **Updates every running campaign** that listens for that event and that this player is in the audience for.
4. **Gives a reward** if the player has just won, unless they've reached their win limit or the campaign's budget can't cover it. The budget is a hard cap: Onari never spends past it, even with thousands of events at once.
5. **Queues a webhook** (`reward.issued`) for your server.

The response tells you the player's progress and any rewards won, so your app can celebrate straight away.

## Scheduling

Campaigns start and end on the dates your team sets, in your workspace's time zone. Leaderboards and "top N" trivia pay their winners when they close. Onari checks schedules every 5 minutes, so a campaign can start or close up to 5 minutes after its set time.
