> ## Documentation Index
> Fetch the complete documentation index at: https://lifters.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracking Sports Betting Events

> Send sports ticket events with full lifecycle coverage: open, win, lose, cashout, refund, cancel and pending.

<Snippet file="snippets/api-key-auth.mdx" />

## Event Types

Sports events follow a full ticket lifecycle. All events are sent to `POST /api/v1/sport`. The Kafka topic is fixed: `atlas.events.raw.sportsbook`.

| Event     | When to Send                                                                      | `selections`                                     |
| --------- | --------------------------------------------------------------------------------- | ------------------------------------------------ |
| `open`    | Ticket placed. Full snapshot of all selections.                                   | Required — send all selections                   |
| `win`     | One or more selections resolved as won.                                           | Required — send only the selections that changed |
| `lose`    | One or more selections resolved as lost.                                          | Required — send only the selections that changed |
| `cashout` | Ticket closed early by the player.                                                | Required — send only the selections that changed |
| `refund`  | Ticket refunded after acceptance (operator-side reversal, e.g., event voided).    | Required — send the selections impacted          |
| `cancel`  | Ticket cancelled before resolution (e.g., declined by trading, market suspended). | Required — send the selections impacted          |
| `pending` | Ticket awaiting resolution (held for risk review, awaiting settlement, etc.).     | Required — send the current snapshot             |

<Info>
  A ticket can have multiple selections (parlay/multiple bet). Sending a `win`, `lose`, or `cashout`
  event with only the changed selections allows the ticket to remain `open` until all selections resolve.
  The `ticket_status` reflects the overall ticket state, while each `selection_status` reflects individual outcomes.
</Info>

All events for the same ticket share the same `bet_id`.

## Track Ticket Open

```bash theme={null}
curl -X POST https://events.atlas.io/api/v1/sport \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "org_id": "org_abc123",
    "brand_id": "brand_xyz",
    "event": "open",
    "user_id": "user_12345",
    "currency": "BRL",
    "bet_id": "bet_abc_001",
    "bet_dt": "2026-03-11T14:30:00Z",
    "ticket_status": "open",
    "bet_type": "MULTIPLE",
    "bet_timing": "PREMATCH",
    "bet_platform": "MOBILE",
    "bet_virtual": false,
    "bet_amount": 50.00,
    "bet_amount_bonus": 0.00,
    "bet_odds": 3.50,
    "before_balance": 250.00,
    "after_balance": 200.00,
    "selections": [
      {
        "selection_id": "sel_001",
        "selection_status": "open",
        "selection_choice": "Vasco",
        "selection_sport_type": "Soccer",
        "selection_league": "Brasileirão Série A",
        "selection_competitors": ["Flamengo", "Vasco"],
        "selection_home_team": "Flamengo",
        "selection_away_team": "Vasco",
        "selection_market": "1x2",
        "selection_odds": 2.90,
        "selection_is_live": false,
        "selection_virtual": false,
        "sport_match_id": "flamengo_vs_vasco_20260311"
      }
    ]
  }'
```

## Track Ticket Win

```bash theme={null}
curl -X POST https://events.atlas.io/api/v1/sport \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "org_id": "org_abc123",
    "brand_id": "brand_xyz",
    "event": "win",
    "user_id": "user_12345",
    "currency": "BRL",
    "bet_id": "bet_abc_001",
    "bet_dt": "2026-03-11T16:00:00Z",
    "ticket_status": "win",
    "bet_amount": 50.00,
    "bet_odds": 3.50,
    "win_amount": 175.00,
    "before_balance": 200.00,
    "after_balance": 375.00,
    "selections": [
      { "selection_id": "sel_001", "selection_status": "win" },
      { "selection_id": "sel_002", "selection_status": "win" }
    ]
  }'
```

## Track Ticket Lose

```bash theme={null}
curl -X POST https://events.atlas.io/api/v1/sport \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "org_id": "org_abc123",
    "brand_id": "brand_xyz",
    "event": "lose",
    "user_id": "user_12345",
    "currency": "BRL",
    "bet_id": "bet_abc_002",
    "bet_dt": "2026-03-11T16:00:00Z",
    "ticket_status": "lose",
    "bet_amount": 50.00,
    "bet_odds": 2.10,
    "win_amount": 0.00,
    "before_balance": 200.00,
    "after_balance": 200.00,
    "selections": [
      { "selection_id": "sel_003", "selection_status": "lose" }
    ]
  }'
```

## Track Ticket Cashout

```bash theme={null}
curl -X POST https://events.atlas.io/api/v1/sport \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "org_id": "org_abc123",
    "brand_id": "brand_xyz",
    "event": "cashout",
    "user_id": "user_12345",
    "currency": "BRL",
    "bet_id": "bet_abc_003",
    "bet_dt": "2026-03-11T15:45:00Z",
    "ticket_status": "cashout",
    "bet_amount": 50.00,
    "bet_odds": 3.50,
    "win_amount": 30.00,
    "before_balance": 200.00,
    "after_balance": 230.00,
    "selections": [
      { "selection_id": "sel_004", "selection_status": "cashout" }
    ]
  }'
```

## Request Fields

### Envelope Fields (all events)

<ParamField body="org_id" type="string" required>
  Organization identifier.
</ParamField>

<ParamField body="brand_id" type="string" required>
  Brand identifier.
</ParamField>

<ParamField body="event" type="string" required>
  Event type. Allowed values: `open`, `win`, `lose`, `cashout`, `refund`,
  `cancel`, `pending`.
</ParamField>

<ParamField body="ip" type="string">
  Player IP address at event time.
</ParamField>

<ParamField body="geolocation_lat" type="number">
  Player latitude at event time.
</ParamField>

<ParamField body="geolocation_long" type="number">
  Player longitude at event time.
</ParamField>

<ParamField body="is_test" type="boolean">
  Marks the event as operator test traffic. When `true`, the event is accepted
  (202) but rerouted to an audit-only store — it never appears in analytics,
  dashboards or risk scoring. Defaults to `false` when omitted.
</ParamField>

### Ticket Fields

<ParamField body="user_id" type="string" required>
  Your internal user identifier. Must be consistent for the player.
</ParamField>

<ParamField body="currency" type="string" required>
  ISO 4217 currency code (for example: `BRL`).
</ParamField>

<ParamField body="bet_id" type="string" required>
  Ticket identifier used to correlate open, win, lose and cashout events.
</ParamField>

<ParamField body="bet_dt" type="string" required>
  ISO 8601 timestamp for the event in the ticket lifecycle.
</ParamField>

<ParamField body="ticket_status" type="string" required>
  Current ticket status. Allowed values: `open`, `win`, `lose`, `cashout`, `cancel`, `reject`, `refund`.
</ParamField>

<ParamField body="bet_type" type="string">
  Allowed values: `SINGLE`, `MULTIPLE`, `SYSTEM`.
</ParamField>

<ParamField body="bet_amount" type="number">
  Bet amount (real + bonus according to your accounting model).
</ParamField>

<ParamField body="bet_amount_bonus" type="number">
  Bonus portion of the stake.
</ParamField>

<ParamField body="bet_odds" type="number">
  Combined odds for the ticket.
</ParamField>

<ParamField body="bet_platform" type="string">
  Allowed values: `WEB`, `MOBILE`, `APP`.
</ParamField>

<ParamField body="bet_timing" type="string">
  Allowed values: `LIVE`, `PREMATCH`.
</ParamField>

<ParamField body="bet_virtual" type="boolean">
  Indicates whether this is a virtual sports ticket.
</ParamField>

<ParamField body="win_amount" type="number">
  Amount won. `0` or omit for `open`. `0` for a losing ticket.
</ParamField>

<ParamField body="before_balance" type="number">
  Balance before ticket update.
</ParamField>

<ParamField body="after_balance" type="number">
  Balance after ticket update.
</ParamField>

### Selection Fields

<ParamField body="selections" type="array" required>
  Always required (min 1). For `open`, send the full snapshot of all selections. For `win`, `lose`, and `cashout`, send only the selections that changed status.
</ParamField>

<ParamField body="selections[].selection_id" type="string" required>
  Stable selection identifier inside the ticket.
</ParamField>

<ParamField body="selections[].selection_status" type="string" required>
  Current status of the selection. Allowed values: `open`, `win`, `lose`, `cashout`, `cancel`, `refund`, `partial_win`, `partial_lose`.
</ParamField>

<ParamField body="selections[].selection_choice" type="string">
  Chosen option inside the market (for market `1x2`, the choice can be `Vasco`).
</ParamField>

<ParamField body="selections[].selection_sport_type" type="string">
  Sport category (for example `Soccer`, `Basketball`).
</ParamField>

<ParamField body="selections[].selection_league" type="string">
  League or competition name.
</ParamField>

<ParamField body="selections[].selection_competitors" type="array">
  Competitor names as provided by your trading feed.
</ParamField>

<ParamField body="selections[].selection_home_team" type="string">
  Home team name.
</ParamField>

<ParamField body="selections[].selection_away_team" type="string">
  Away team name.
</ParamField>

<ParamField body="selections[].selection_market" type="string">
  Market name (for example `1x2`, `Handicap`, `Total Goals`).
</ParamField>

<ParamField body="selections[].selection_odds" type="number">
  Odds for this selection.
</ParamField>

<ParamField body="selections[].selection_is_live" type="boolean">
  Indicates whether selection was in-play.
</ParamField>

<ParamField body="selections[].selection_virtual" type="boolean">
  Indicates whether selection belongs to a virtual event.
</ParamField>

<ParamField body="selections[].sport_match_id" type="string">
  Match identifier in your sportsbook feed.
</ParamField>

<ParamField body="selections[].selection_event_name" type="string">
  Optional event name for the selection in your feed model.
</ParamField>

## GGR Calculation (Sports)

```
Sports Turnover = sum(open.bet_amount)
Sports GGR = sum(open.bet_amount) - sum(win.win_amount)
```
