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

# Autenticación

> Cómo obtener, usar y rotar una API key de VENTRY.

Todas las llamadas viajan con una API key en la cabecera `Authorization`:

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.ventry.es/v1/event \
    -H "Authorization: Bearer vk_live_8Kq2ZxR7pN3mW9tYbC4vD6fH1jL5sA0e"
  ```

  ```js Node.js theme={null}
  await fetch("https://api.ventry.es/v1/event", {
    headers: { Authorization: `Bearer ${process.env.VENTRY_KEY}` },
  });
  ```

  ```python Python theme={null}
  requests.get(
      "https://api.ventry.es/v1/event",
      headers={"Authorization": f"Bearer {os.environ['VENTRY_KEY']}"},
      timeout=10,
  )
  ```

  ```php PHP theme={null}
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer " . getenv("VENTRY_KEY"),
  ]);
  ```
</CodeGroup>

## Obtener una clave

La emite el organizador del evento desde el panel de VENTRY, en **API /
Integraciones**. Al crearla elige:

* **Permisos** (*scopes*): qué puedes leer y escribir.
* **Ámbito**: si la clave se limita a ciertos tipos de entrada o días.
* **Límite de peticiones** por minuto.
* **IPs autorizadas**, si quiere restringir desde dónde se puede usar.

<Warning>
  La clave **se muestra una sola vez**, en el momento de crearla. VENTRY sólo
  guarda un hash, así que ni el organizador ni el equipo de VENTRY pueden
  recuperarla después. Si se pierde, hay que revocarla y emitir otra.
</Warning>

### Claves con permisos de escritura

Cualquier clave que pida un permiso de escritura nace **desactivada** y responde:

```json theme={null}
{
  "error": {
    "type": "permission_error",
    "code": "key_pending_activation",
    "message": "Esta API key solicita permisos de escritura y todavía no ha sido activada por un administrador del evento.",
    "request_id": "req_9f2c1a4e7b304d51"
  }
}
```

Es intencionado: escribir en un evento en marcha —crear entradas, acreditar
asistentes, mover saldo— exige que una persona lo autorice de forma explícita.
Pídele al organizador que la active desde el panel.

## Permisos

| Scope            | Qué permite                                      | Activación |
| ---------------- | ------------------------------------------------ | ---------- |
| `event.read`     | Días, zonas, tipos de entrada y datos del evento | Automática |
| `tickets.read`   | Consultar entradas y su estado                   | Automática |
| `tickets.write`  | Crear y anular entradas                          | **Manual** |
| `checkins.read`  | Registro de escaneos en puerta                   | Automática |
| `checkins.write` | Acreditar entradas y validar zonas               | **Manual** |
| `cashless.read`  | Saldos, consumiciones y recargas                 | Automática |
| `cashless.write` | Recargar saldo de pulseras                       | **Manual** |
| `reports.read`   | Resumen agregado de ventas                       | Automática |
| `*`              | Todo, presente y futuro                          | **Manual** |

Llamar a un endpoint sin su permiso devuelve `403 insufficient_scope`.

## Formato de la clave

```
vk_live_8Kq2ZxR7pN3mW9tYbC4vD6fH1jL5sA0e
└┬┘ └┬─┘ └──────────────┬──────────────┘
 │   │                  └─ secreto (32 bytes aleatorios)
 │   └──────────────────── entorno: live o test
 └──────────────────────── prefijo de VENTRY
```

El prefijo `vk_live_` no es decorativo: permite que los escáneres de secretos de
GitHub y similares detecten una clave publicada por error.

## Buenas prácticas

<AccordionGroup>
  <Accordion title="Guárdala como un secreto de servidor">
    Una API key de VENTRY puede leer datos personales de asistentes y, según sus
    permisos, escribir en el evento. **Nunca** la incrustes en una aplicación
    móvil, en JavaScript de navegador ni en un repositorio. Si tu aplicación de
    puerta necesita acreditar, que hable con tu backend y sea éste quien llame a
    VENTRY.
  </Accordion>

  <Accordion title="Pide sólo los permisos que uses">
    Si únicamente vuelcas entradas, pide `event.read` y `tickets.write`. Cuantos
    menos permisos, menos daño hace una clave comprometida.
  </Accordion>

  <Accordion title="Usa el ámbito">
    Si sólo gestionas un tipo de entrada, pídele al organizador que limite la
    clave a ese tipo. Deja de ser posible tocar por error entradas que no son
    tuyas.
  </Accordion>

  <Accordion title="Rota sin cortes">
    No hay rotación automática. Para rotar sin interrumpir el servicio: pide una
    clave nueva, despliégala, comprueba que funciona con `GET /ping`, y sólo
    entonces pide que revoquen la anterior. Una clave revocada deja de funcionar
    de inmediato.
  </Accordion>

  <Accordion title="Registra el request_id">
    Cada respuesta lleva la cabecera `X-Request-Id`. Guárdala en tus logs: es lo
    que permite al soporte de VENTRY encontrar tu petición exacta.
  </Accordion>
</AccordionGroup>

## Errores de autenticación

| Código                   | Situación                                                               |
| ------------------------ | ----------------------------------------------------------------------- |
| `missing_api_key`        | Falta la cabecera `Authorization` o no tiene el formato `Bearer vk_...` |
| `invalid_api_key`        | La clave no existe                                                      |
| `revoked_api_key`        | La clave fue revocada                                                   |
| `expired_api_key`        | La clave tenía fecha de caducidad y ya pasó                             |
| `key_pending_activation` | Tiene permisos de escritura sin activar                                 |
| `ip_not_allowed`         | Tu IP no está en la lista autorizada de la clave                        |
| `insufficient_scope`     | La clave no tiene el permiso que exige ese endpoint                     |
