# Lista de espera con correo de confirmación (/es/recipes/waitlist)

No hay configuración de Bitelio más simple que una lista de espera: tu app rastrea un evento, un flujo de trabajo reacciona a él, y sale un correo.

## Configuración

import {Step, Steps} from 'fumadocs-ui/components/steps';

<Steps>
  <Step>
    ### Crea la plantilla de confirmación

    Ve a **Plantillas → Nueva plantilla** y construye una plantilla **Marketing**. Donde quieras que aparezcan datos del contacto, coloca un marcador `{{variable}}`:

    ```text
    Subject: You're on the list, {{firstName}}

    Hi {{firstName}}, thanks for joining the {{product}} waitlist.
    We'll let you know as soon as your spot opens up.
    ```
  </Step>

  <Step>
    ### Rastrea la inscripción desde tu backend

    Cuando se envíe el formulario, llama a `POST /v1/track` con la clave pública (`pk_*`) del proyecto. Este endpoint no acepta claves secretas. Llamarlo desde tu backend permite validar antes el formulario, pero la clave pública no autentica al cliente ni demuestra su consentimiento. Nunca expongas una clave secreta en el navegador.

    ```bash
    curl https://api.bitelio.com/v1/track \
      -H "Authorization: Bearer pk_your_public_key" \
      -H "Content-Type: application/json" \
      -d '{
        "event": "waitlist.joined",
        "email": "ada@example.com",
        "subscribed": true,
        "data": { "firstName": "Ada", "product": "Beta" }
      }'
    ```

    Envía `subscribed: true` solo cuando la persona acepte explícitamente estos mensajes de marketing. También vuelve a suscribir a un contacto existente, así que no lo repitas al actualizar datos en segundo plano. Para confirmar antes del consentimiento, utiliza [doble opt-in](/es/recipes/double-opt-in).

    Una sola solicitud hace dos cosas: hace upsert del contacto (suscrito salvo que indiques lo contrario) y registra un evento `waitlist.joined` contra él. Cada clave dentro de `data` se escribe en el contacto, así que la plantilla puede leerla de vuelta como `{{firstName}}`, `{{product}}`, etcétera.

    <Callout title="Elige un nombre de evento estable" type="info">
      Una vez que un flujo de trabajo se ha ejecutado aunque sea una vez, su evento disparador queda **fijado permanentemente**. Elige un nombre con espacio de nombres como `waitlist.joined` en lugar de uno genérico que más adelante podrías querer usar para otra cosa.
    </Callout>
  </Step>

  <Step>
    ### Crea el flujo de trabajo

    En **Flujos de trabajo → Nuevo flujo de trabajo**:

    * **Disparador**: `EVENT` en `waitlist.joined`
    * Añade un paso `SEND_EMAIL` que apunte a la plantilla del paso 1

    Activa el flujo de trabajo. Los flujos de trabajo nuevos empiezan desactivados, y uno desactivado nunca se dispara — sin importar cuántos eventos lleguen.
  </Step>
</Steps>

## Etiquetar inscripciones para más adelante

Para que los miembros de la lista de espera sean fáciles de segmentar más adelante, inserta un paso `UPDATE_CONTACT` antes del correo:

```json
{ "stage": "waitlist", "waitlistSource": "{{event.referrer}}" }
```

Ahora un [segmento](/es/concepts/segments) sobre `stage == "waitlist"` te da una audiencia limpia para campañas de seguimiento — un enfoque más ordenado que segmentar según si `waitlist.joined` se disparó alguna vez.

## Qué sigue

<Cards>
  <Card title="Flujos de trabajo" href="/es/concepts/workflows">
    Cómo se comportan los disparadores y qué hace cada tipo de paso.
  </Card>

  <Card title="API de registro de eventos" href="/es/api-reference/public-api/trackEvent">
    La referencia completa de `POST /v1/track`.
  </Card>
</Cards>
