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

# Earnings API

> Read what each collaborator has been paid, what is on its way and what is still owed — in cents, broken down by type and status.

# Earnings API

<Note>
  This page assumes the shared rules in [API Conventions](/api/conventions) — authentication, the two error shapes, batching and identity resolution. It only covers what is specific to earnings.
</Note>

The Earnings API lets your backend read each collaborator's money: **what has already been paid**, **what is on its way**, and **what is still owed**.

It was built for the earnings block of a home screen — the one with a total and a privacy toggle.

<Warning>
  **This API does not decide what counts as a "commission".** That word means different things at different companies: some call every payout a commission, others separate prizes from commissions strictly. So the response comes **broken down**, and your screen sums whatever your company calls a commission.
</Warning>

## How It Works

1. **You get an API Key** with the `earnings:read` scope
2. **Your backend asks** for one or many collaborators (by CPF or email)
3. **SalesOS answers** with the totals, broken down by payout type and by receivable status

***

## Authentication

```
Authorization: P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE
```

| Property           | Details                                            |
| ------------------ | -------------------------------------------------- |
| **Scope required** | `earnings:read`                                    |
| **Method**         | `POST` only                                        |
| **Rate limit**     | Configurable per key (default: 1000 requests/hour) |

***

## Endpoint Reference

```
POST https://api.play2sell.com/functions/v1/earnings-partner-api
```

One action: `earnings_status`.

### Request Schema

<ParamField body="action" type="string" required>
  Must be `"earnings_status"`
</ParamField>

<ParamField body="collaborators" type="array" required>
  Array of collaborator references (max 500)
</ParamField>

### Example

```bash theme={null}
curl -X POST https://api.play2sell.com/functions/v1/earnings-partner-api \
  -H "Authorization: P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "earnings_status",
    "collaborators": [{ "cpf": "529.982.247-25" }]
  }'
```

**Response (200):**

```json theme={null}
{
  "data": {
    "timezone": "America/Sao_Paulo",
    "reference_date": "2026-08-15",
    "collaborators": [
      {
        "cpf": "52998224725",
        "found": true,
        "user_id": "8f14e45f-0000-0000-0000-000000000001",
        "name": "Maria Santos",
        "membership_status": "active",
        "earnings": {
          "currency": "BRL",
          "paid": {
            "total_cents": 382000,
            "count": 2,
            "by_type": { "PRIZE": 380000, "COMMISSION": 2000 }
          },
          "in_transit": { "total_cents": 29000, "count": 1 },
          "receivable": {
            "total_cents": 150000,
            "count": 2,
            "by_status": { "A_RECEBER": 100000, "ATRASO": 50000 }
          },
          "last_paid_at": "2026-08-14T12:00:00.000Z"
        }
      }
    ],
    "total": 1,
    "found": 1
  },
  "meta": {
    "request_id": "1f6c1b2e-0000-4a1b-8c2d-000000000001",
    "timestamp": "2026-08-15T13:45:00.000Z"
  }
}
```

***

## Fields

| Field                    | Meaning                                                                                                                                           |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `currency`               | ISO code for every amount in the block — from the payment itself, or **your company's configured currency** for someone who has not been paid yet |
| `paid.total_cents`       | Money that has already left — settled payouts                                                                                                     |
| `paid.by_type`           | The same money split by payout type — see below                                                                                                   |
| `in_transit.total_cents` | Payouts already issued, not settled yet                                                                                                           |
| `receivable.total_cents` | Earned, not yet turned into a payout                                                                                                              |
| `receivable.by_status`   | The same amount split by stage — see below                                                                                                        |
| `last_paid_at`           | When the most recent settled payout completed                                                                                                     |

<Warning>
  **Every amount is in cents, as an integer.** Never parse them as decimals: floating-point arithmetic on money is a defect, not a rounding preference. Divide by 100 only at the moment of display.
</Warning>

***

## Payout types

`paid.by_type` splits settled money across the three types the system records:

| Type         | What it is                           |
| ------------ | ------------------------------------ |
| `COMMISSION` | Commission on a sale                 |
| `PRIZE`      | Award — campaign, ranking, incentive |
| `BONUS`      | Discretionary payment                |

<Warning>
  **Sum the types your company calls a commission — do not assume.** At one company every payout is called a commission and the whole `total_cents` is the right number. At another, only `COMMISSION` belongs on that line, and showing the total would inflate it by orders of magnitude.

  A type absent from `by_type` means the person has none of it, not zero-by-convention.
</Warning>

***

## Receivable stages

`receivable` covers everything still owed. `by_status` splits it by stage:

| Status       | Meaning                              |
| ------------ | ------------------------------------ |
| `A_RECEBER`  | Computed, waiting to be paid         |
| `ATRASO`     | **Overdue** — owed and past its date |
| `A_LIBERAR`  | Pending release                      |
| `DISPONIVEL` | Available to be paid out             |

Two stages never appear here: `PAGO` (already left, counted in `paid`) and `CANCELADO` (will never be paid).

<Warning>
  **`ATRASO` is owed money, not an error state.** It is included in `receivable.total_cents` on purpose. Filtering it out would hide, from the person who most needs to see it, money that is late.
</Warning>

<Tip>
  Cancelled amounts are excluded everywhere. Showing them would promise money that will never arrive.
</Tip>

***

## Error Handling

See [API Conventions](/api/conventions#error-shapes) for the two shapes and the status code table.

<AccordionGroup>
  <Accordion title="400 — VALIDATION_ERROR">
    Invalid body, batch over 500, CPF without 11 digits, or an item with neither `cpf` nor `email`.
  </Accordion>

  <Accordion title="403 — FORBIDDEN">
    API key is valid but lacks the `earnings:read` scope.
  </Accordion>
</AccordionGroup>

<Tip>
  **Someone who has never been paid is not an error.** The response comes back with zeros and empty breakdowns, at status 200 — and that zero is a measurement: the person exists and has no payments. Different from `found: false`.
</Tip>

***

## Rate Limits

| Limit                         | Value |
| ----------------------------- | ----- |
| Default requests per hour     | 1000  |
| Max collaborators per request | 500   |

***

## Security

* Read-only: this API never creates, approves or changes a payment
* Each key is scoped to a single company — money from another company never appears, even for the same person
* Amounts and documents are **never written to logs**; only counts are

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Player Progress API" icon="trophy" href="/api/integrations/progress">
    Level, XP, coins and ranking
  </Card>

  <Card title="Campaigns API" icon="gift" href="/api/integrations/campaigns">
    The catalog those prizes come from
  </Card>
</CardGroup>
