> ## 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.

# API de Progreso del Jugador

> Lea el nivel, XP, monedas y posición en el ranking de sus colaboradores — hecha para la franja de identidad de una pantalla de inicio de súper app.

# API de Progreso del Jugador

<Note>
  Esta página presupone las reglas comunes en [Convenciones de la API](/es/api/conventions) — autenticación, los dos formatos de error, lotes y resolución de identidad. Aquí queda solo lo específico del progreso.
</Note>

La API de Progreso del Jugador permite que su backend lea dónde está cada colaborador en la gamificación de su empresa: **en qué nivel está**, **cuánto XP tiene**, **cuántas monedas puede gastar** y **cuál es su posición en el ranking**.

Fue hecha para la franja superior de una pantalla de inicio — la que saluda a la persona y muestra cómo va.

<Note>
  La **escalera de niveles la configura su empresa**: cuántos niveles, los nombres, qué exige cada uno y cómo se ve cada uno. Esta API devuelve lo que esté configurado — no conoce ninguna escalera específica.
</Note>

## Cómo funciona

1. **Usted recibe una API Key** con el alcance `progress:read`
2. **Su backend consulta** uno o varios colaboradores (por CPF o correo)
3. **SalesOS responde** con la escalera **una sola vez arriba**, y luego el estado de cada persona

***

## Autenticación

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

| Propiedad             | Detalles                                                       |
| --------------------- | -------------------------------------------------------------- |
| **Alcance requerido** | `progress:read`                                                |
| **Método**            | Solo `POST`                                                    |
| **Límite de uso**     | Configurable por clave (predeterminado: 1000 solicitudes/hora) |

***

## Referencia del endpoint

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

Una acción: `progress_status`.

### Esquema de la solicitud

<ParamField body="action" type="string" required>
  Debe ser `"progress_status"`
</ParamField>

<ParamField body="collaborators" type="array" required>
  Lista de referencias de colaboradores (máximo 500)
</ParamField>

<ParamField body="period" type="string">
  Período del XP y del ranking: `daily`, `weekly`, `monthly` o `all_time`. Ausente = `all_time`.
</ParamField>

<ParamField body="ranking_scope" type="string">
  Universo del ranking: `tenant` (toda la empresa) u `org_unit` (la unidad de la propia persona). Ausente = `tenant`.
</ParamField>

### Ejemplo

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

**Respuesta (200):**

```json theme={null}
{
  "data": {
    "timezone": "America/Sao_Paulo",
    "reference_date": "2026-08-14",
    "period": "all_time",
    "ranking_scope": "tenant",
    "levels": [
      { "order": 1, "key": "level_01", "name": "Inicial",
        "requirements": [], "appearance": null },
      { "order": 2, "key": "level_02", "name": "Avanzado",
        "requirements": [{ "type": "min_xp", "value": 500 }],
        "appearance": { "color": "#7B2D8E" } }
    ],
    "collaborators": [
      {
        "cpf": "52998224725",
        "found": true,
        "user_id": "8f14e45f-0000-0000-0000-000000000001",
        "name": "Maria Santos",
        "membership_status": "active",
        "level": {
          "order": 2, "key": "level_02", "name": "Avanzado",
          "appearance": { "color": "#7B2D8E" }
        },
        "next_level": {
          "order": 3, "key": "level_03", "name": "Legendario",
          "requirements": [{ "type": "min_xp", "value": 2000 }],
          "appearance": null
        },
        "xp": {
          "period": "all_time", "current": 1200,
          "all_time": 1200, "monthly": 300, "daily": 0
        },
        "coins": { "balance": 640, "source": "playcoin" },
        "ranking": { "scope": "tenant", "period": "all_time", "position": 1, "total": 240 }
      }
    ],
    "total": 1,
    "found": 1
  },
  "meta": {
    "request_id": "1f6c1b2e-0000-4a1b-8c2d-000000000001",
    "timestamp": "2026-08-14T13:45:00.000Z"
  }
}
```

***

## Campos

### La escalera (nivel superior)

| Campo                   | Significado                                                      |
| ----------------------- | ---------------------------------------------------------------- |
| `levels[]`              | La escalera de niveles de su empresa, del primero al último      |
| `levels[].order`        | Posición en la escalera — es a ella que `level.order` se refiere |
| `levels[].name`         | El nombre del nivel **tal como su empresa lo configuró**         |
| `levels[].requirements` | Lo que ese nivel exige (p. ej. `min_xp`, `min_missions_count`)   |
| `levels[].appearance`   | Configuración visual del nivel — vea la advertencia abajo        |

<Warning>
  **La cantidad de niveles es de su empresa, no una constante.** Construya la pantalla a partir del arreglo. Una escalera puede tener nueve peldaños donde otra tiene diez, y ambas son correctas.
</Warning>

### Por colaborador

| Campo                                          | Significado                                                                                      |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `level`                                        | El nivel en el que está la persona ahora, con nombre y apariencia                                |
| `next_level`                                   | El siguiente peldaño y lo que exige. **Ausente** cuando la persona está en la cima               |
| `xp.period`                                    | El período que usted pidió, devuelto como eco                                                    |
| `xp.current`                                   | XP en ese período — el número a mostrar junto al nombre                                          |
| `xp.all_time` · `monthly` · `weekly` · `daily` | La misma puntuación en todos los períodos. **Un período sin medición viene ausente, no en cero** |
| `coins.balance`                                | Monedas disponibles para gastar                                                                  |
| `ranking.scope`                                | El universo en el que se calculó la posición                                                     |
| `ranking.position` · `total`                   | Posición y cuántas personas hay en ese universo                                                  |

***

## Apariencia del nivel

La identidad visual del nivel — el color, y lo que su empresa configure — viene en `appearance`.

<Warning>
  **`appearance` puede venir `null`, y null no significa "sin color".** Significa que nadie ha configurado uno todavía. En ese caso use su propio fallback, pero no fije una paleta indexada por nombre de nivel: el día en que la empresa renombre un nivel o cambie los colores, la pantalla con paleta fija seguirá mostrando la anterior, sin ningún error.
</Warning>

<Tip>
  Lea el color desde la respuesta incluso cuando hoy parezca constante. Es precisamente por eso que viaja en el payload en vez de vivir en su app.
</Tip>

***

## Períodos

El XP se guarda en cuatro períodos, y la pantalla suele mostrar uno de ellos. Como "200 XP" en un diseño no dice cuál, esta API devuelve **los cuatro** más el que usted pidió.

| `period`   | Cubre                                 |
| ---------- | ------------------------------------- |
| `daily`    | Hoy, en la zona horaria de la empresa |
| `weekly`   | La semana en curso                    |
| `monthly`  | El mes en curso                       |
| `all_time` | Todo desde el ingreso de la persona   |

<Warning>
  Un período desconocido se **rechaza con 400**, no se responde con ceros. Una respuesta en cero haría que su pantalla afirmara que la persona no tiene XP — una ausencia que no es cierta.
</Warning>

<Warning>
  **Un período que nunca se midió viene ausente, no como `0`.** En el ejemplo anterior falta `weekly`: esa persona no tiene fila de puntuación semanal. En cambio `daily: 0` es distinto — se midió, y dio cero.

  Trate los dos casos por separado. Escribir "0 XP esta semana" para un período ausente le dice a la persona que no puntuó, cuando la verdad es que nadie calculó ese período para ella.
</Warning>

***

## Ranking

Una posición solo significa algo junto a su universo, así que `scope`, `period` y `total` viajan siempre con ella.

| `ranking_scope` | Universo                            |
| --------------- | ----------------------------------- |
| `tenant`        | Toda la empresa                     |
| `org_unit`      | Solo la unidad de la propia persona |

<Tip>
  `total` es contra cuántas personas se midió la posición. "#12 de 240" se lee muy distinto de "#12 de 13" — muéstrelo.
</Tip>

***

## Manejo de errores

Vea [Convenciones de la API](/es/api/conventions#formatos-de-error) para los dos formatos y la tabla de códigos.

<AccordionGroup>
  <Accordion title="400 — VALIDATION_ERROR">
    Cuerpo inválido, lote por encima de 500, CPF sin 11 dígitos, un elemento sin `cpf` ni `email`, o `period` / `ranking_scope` desconocido.
  </Accordion>

  <Accordion title="403 — FORBIDDEN">
    API Key válida, pero sin el alcance `progress:read`.
  </Accordion>
</AccordionGroup>

<Tip>
  **Una empresa sin escalera configurada no es un error.** La respuesta llega con `levels: []` y estado 200.
</Tip>

***

## Límites de uso

| Límite                                | Valor |
| ------------------------------------- | ----- |
| Solicitudes por hora (predeterminado) | 1000  |
| Máximo de colaboradores por solicitud | 500   |

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="API de Misiones" icon="bullseye-arrow" href="/es/api/integrations/missions">
    El progreso que genera el XP mostrado aquí
  </Card>

  <Card title="API de Campañas" icon="gift" href="/es/api/integrations/campaigns">
    Donde se gastan las monedas
  </Card>
</CardGroup>
