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

# Introducción

> Qué puedes hacer con la API de VENTRY y cómo está organizada.

VENTRY es una plataforma de gestión de eventos: entradas, acreditación en puerta,
control de zonas y pago sin efectivo con pulsera. Esta API permite que un sistema
externo se integre con todo eso.

## Para qué sirve

<CardGroup cols={2}>
  <Card title="Volcar entradas" icon="ticket" href="/guides/import-tickets">
    Vendes entradas en tu plataforma y las das de alta en VENTRY para que sirvan
    para acreditarse en puerta.
  </Card>

  <Card title="Acreditar asistentes" icon="id-card" href="/guides/accreditation">
    Tu aplicación escanea el QR y la pulsera, y VENTRY hace el canje.
  </Card>

  <Card title="Consultar saldo" icon="wallet" href="/guides/cashless">
    Saldo de pulseras, consumiciones y recargas.
  </Card>

  <Card title="Sincronizar datos" icon="arrows-rotate" href="/pagination">
    Vuelca ventas y accesos a tu propio almacén de datos.
  </Card>
</CardGroup>

## Un despliegue, un evento

Cada instalación de VENTRY corresponde a **un único evento**. Tu API key ya
determina de qué evento se trata, por eso ningún endpoint pide un identificador
de evento: la URL base que te dé el organizador es la del suyo.

Dentro de ese evento, tu clave puede además estar limitada a ciertos tipos de
entrada o a ciertos días. Lo que quede fuera de ese ámbito se comporta como si no
existiera —responde `404`, no `403`—, así que no te alarmes si no ves entradas
que el organizador sí ve.

## El modelo de datos, en un minuto

<Steps>
  <Step title="Evento">
    Tiene **días** (`Day`) y **zonas** (`Zone`). Casi todo lo demás cuelga de un día.
  </Step>

  <Step title="Entradas">
    Una **entrada** (`Ticket`) tiene un **tipo** (`TicketType`), que define a qué
    zonas da acceso y qué consumiciones incluye, y una lista de días en los que vale.
  </Step>

  <Step title="Acreditación">
    En puerta, la entrada se **canjea** por una **pulsera** (`Wristband`) física.
    A partir de ahí, la pulsera es la identidad del asistente dentro del recinto.
  </Step>

  <Step title="Cashless">
    La pulsera lleva **saldo**. Se **recarga** (`topup`) y se gasta en
    **consumiciones** (`transaction`) en las barras.
  </Step>
</Steps>

## Convenciones

|                     |                                                                              |
| ------------------- | ---------------------------------------------------------------------------- |
| **Importes**        | Enteros en **céntimos**. `1250` son 12,50 €. La moneda está en `GET /event`. |
| **Fechas**          | ISO 8601 en UTC. El huso horario del evento está en `GET /event`.            |
| **Identificadores** | Cadenas de 24 caracteres hexadecimales.                                      |
| **Campos**          | `snake_case`.                                                                |

### `occurred_at` frente a `created_at`

Los terminales de VENTRY siguen cobrando cuando se cae la cobertura y sincronizan
cuando vuelve. Por eso las ventas y las recargas llevan **dos** marcas de tiempo:

* `occurred_at` — cuándo pasó de verdad.
* `created_at` — cuándo llegó al servidor.

<Warning>
  Para agrupar por tiempo o cuadrar caja hay que usar siempre **`occurred_at`**.
  Una venta de las 22:00 sincronizada a las 02:00 pertenece a la noche del viernes,
  no a la del sábado. Si agrupas por `created_at`, la facturación de un día
  aparecerá repartida en dos.
</Warning>

## Primera llamada

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

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

  console.log(await response.json());
  ```

  ```python Python theme={null}
  import os, requests

  response = requests.get(
      "https://api.ventry.es/v1/ping",
      headers={"Authorization": f"Bearer {os.environ['VENTRY_KEY']}"},
      timeout=10,
  )

  print(response.json())
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.ventry.es/v1/ping");
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("VENTRY_KEY")],
  ]);

  $response = json_decode(curl_exec($ch), true);
  curl_close($ch);

  print_r($response);
  ```
</CodeGroup>

```json theme={null}
{
  "object": "ping",
  "key": {
    "id": "6a3d04709bcd4477a1bfe4b3",
    "name": "TicketRadar producción",
    "prefix": "vk_live_8Kq2Zx",
    "scopes": ["event.read", "tickets.read", "tickets.write"]
  },
  "restrictions": { "ticket_types": [], "days": [] },
  "event": {
    "name": "Sample Event 2026",
    "currency": "EUR",
    "timezone": "Europe/Madrid"
  }
}
```

`restrictions` con listas vacías significa que tu clave ve todo el evento.
