# Events

> What to send, how to name it, and how amounts work.

Source: https://docs.onari.xyz/docs/concepts/events

An event is something a player did in your app, sent from **your server** once it's confirmed: the order is paid, the transfer has settled, the airtime was delivered.

```json
{
  "type": "transfer.completed",
  "player_id": "user_8a21",
  "amount": 500000,
  "properties": { "channel": "ussd" },
  "idempotency_key": "trf_88213"
}
```

## Your events list

Onari only accepts event types on your workspace's list (**Developers → Events**). New workspaces start with the usual events for their industry, and you can add your own. An unknown type is rejected with `422 unknown_event_type` and a `did_you_mean` hint, so typos don't silently go missing.

Names are lowercase words joined by dots or underscores, starting with a letter: `order.placed`, `bill.paid`, `kyc.completed`, `momo.p2p_sent`. Up to 64 characters.

<Callout title="Send meaningful events">
Send the actions you'd build a campaign around (orders, payments, top-ups, sign-ups). Very chatty events like `screen.viewed` add little and count toward your plan's event allowance.
</Callout>

## Amounts

Send money as an **integer in minor units** of your workspace currency: `250000` is ₦2,500.00 (kobo). Put it in `amount`, or in `properties.amount`. Campaigns use it for "spend at least ₦5,000 each time" rules and for "biggest spenders" leaderboards.

## Idempotency

Retries happen. Send an `idempotency_key` that's unique for the action (your order or transaction ID works well). If Onari has already seen that key in this environment, the event is ignored and the response is `{ "duplicate": true }`. Nobody progresses or wins twice.

## When it happened

Send `occurred_at` (ISO 8601 with a time zone) if you're sending an event later than it happened, for example when replaying a queue. Times in the future are treated as now. Streaks use it to work out which day, week or month the event belongs to.

## Referrals

When a new player signs up through someone's invite, send `referred_by` with the inviter's player ID (on their first event, or with [`POST /v1/players/:id`](/docs/api/players)). It's set once and can't point at the player themselves.

## Industry starter lists

| Industry | Events |
|---|---|
| E-commerce | `order.placed`, `order.delivered`, `review.posted`, `flash_sale.joined`, `wishlist.added`, `app.opened` |
| Fintech | `account.opened`, `kyc.completed`, `wallet.funded`, `transfer.completed`, `bill.paid`, `airtime.purchased`, `card.transaction`, `savings.deposited`, `loan.repaid`, `pos.transaction`, `app.opened` |
| Mobile money | `momo.cash_in`, `momo.cash_out`, `momo.p2p_sent`, `merchant.paid`, `app.opened` |
| Telco | `airtime.recharged`, `data.purchased`, `bundle.subscribed`, `plan.renewed`, `sim.registered` |
| Delivery and mobility | `order.placed`, `order.delivered`, `ride.completed`, `rating.given` |
