# Cómo crear una página de lista de espera para una app móvil antes de lanzarla en la App Store

> Una lista de espera previa al lanzamiento para una app de iOS o Android que pregunta qué teléfono se usa, lleva a los testers de iPhone a TestFlight y llena una prueba cerrada de Play.

Publicado el 2026-10-25 · https://ikiform.com/es/guides/waitlist/mobile-app

Pon un formulario de lista de espera en la landing page de tu app que pregunte qué teléfono usa la persona y si quiere probar antes. Mete a los testers de iPhone en un grupo de TestFlight con un webhook y la API de App Store Connect, y carga a los testers de Android en una prueba cerrada de Google Play desde una exportación. El día del lanzamiento, envía a cada grupo por email el enlace a su tienda.

Antes de que una app esté en una tienda, no hay botón de instalar al que enviar a la gente. Una lista de espera en tu propia landing page mantiene su interés hasta que lo haya, y cumple una segunda función que las tiendas no cubren: encuentra los testers que necesitas antes del lanzamiento.

## Qué cambia en una app móvil

- **Dos tiendas, dos listas.** El email de lanzamiento enlaza a la App Store o a Google Play, y las invitaciones de prueba pasan por TestFlight o por una prueba cerrada de Play. Necesitas saber la plataforma de cada persona para enviar la correcta.
- **Los testers tienen que coincidir con la cuenta de la tienda.** TestFlight envía una invitación por email a cualquier dirección. Una prueba cerrada de Play solo deja entrar a las cuentas de Google de su lista, así que un tester de Android que se registra con una dirección del trabajo no puede instalar la build.
- **Google Play puede exigir testers antes del lanzamiento.** Las cuentas de desarrollador personales creadas después del 13 de noviembre de 2023 deben hacer una prueba cerrada con al menos 12 testers que sigan inscritos 14 días seguidos antes de poder publicar en producción. Una lista de espera es de donde salen esos 12.
- **Las tiendas tienen sus propias herramientas previas al lanzamiento.** Vale la pena usarlas junto a una lista de espera, no en su lugar. Mira la comparación de abajo.

|   | Pedidos anticipados de la App Store o prerregistro de Play | Tu propia lista de espera |
| --- | --- | --- |
| Necesita ficha en la tienda | Sí, aprobada y lista | No. Funciona desde el primer día de la landing page |
| Qué obtienes | Un recuento, y una notificación de la tienda o una descarga automática al publicar | El email, la plataforma y las respuestas de cada persona |
| Puede invitar testers | No | Sí, por email a TestFlight o a una prueba cerrada de Play |
| Límites | El prerregistro de Play sigue desactivado en las cuentas personales nuevas hasta que se cumple el requisito de pruebas | El email de lanzamiento lo envías tú |

## Campos para una lista de espera de una app

Pregunta primero por la plataforma, porque cambia lo que significa el campo de email. El modelo de teléfono es opcional y te dice en qué dispositivos probar. La casilla de la beta separa a quienes quieren probar de quienes quieren el email de lanzamiento.

Formulario: App waitlist

- **Email** (`email`, email, obligatorio)
- **Nombre** (`first_name`, text)
- **¿Qué teléfono usas?** (`platform`, radio, obligatorio)
- **Modelo de teléfono** (`device`, text)
- **Invitadme a probar la app antes del lanzamiento** (`beta`, checkbox)

El radio `platform` es obligatorio, así que cada registro cae en una lista con la que puedes actuar. Pega la definición en la pestaña **Fields** del formulario.

## El formulario

El formulario funciona como HTML sencillo en cualquier landing page. El script hace dos cosas pequeñas: preselecciona la plataforma según el navegador del visitante y muestra la indicación sobre la cuenta de Google solo a los usuarios de Android.

`index.html`:

```html
<form id="app-waitlist" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <fieldset>
    <legend>Which phone do you use?</legend>
    <label><input type="radio" name="platform" value="iphone" required> iPhone</label>
    <label><input type="radio" name="platform" value="android"> Android</label>
  </fieldset>

  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" inputmode="email" required>
  <p id="email-hint" hidden>Use the Google account you sign in to Google Play with.</p>

  <label for="first_name">First name</label>
  <input id="first_name" name="first_name" autocomplete="given-name" maxlength="60">

  <label for="device">Phone model</label>
  <input id="device" name="device" maxlength="80" placeholder="iPhone 15, Pixel 8">

  <label><input type="checkbox" name="beta" value="true"> Invite me to test the app before launch</label>
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button>Join the waitlist</button>
</form>

<script>
  const form = document.getElementById("app-waitlist");
  const agent = navigator.userAgent;
  const guess = /iPhone|iPad/.test(agent) ? "iphone" : /Android/.test(agent) ? "android" : null;
  if (guess) form.querySelector(`[name="platform"][value="${guess}"]`).checked = true;
  const hint = () => {
    document.getElementById("email-hint").hidden = form.platform.value !== "android";
  };
  form.addEventListener("change", hint);
  hint();
</script>
```

- La suposición solo preselecciona un radio. La gente puede cambiarlo, y sin el script no hay nada seleccionado, así que `required` les obliga a elegir.
- `inputmode="email"` y `autocomplete="email"` importan aquí más que en ningún otro sitio: la mayoría de los visitantes de la landing page de una app están en un teléfono.
- Configura **Redirect after submit** con una página de agradecimiento que explique qué pasa después en cada plataforma. Para una versión del formulario con un framework, consulta la [guía principal](https://ikiform.com/es/guides/waitlist.md#form) y añade estos campos.

## Lleva a los testers a cada tienda

Diagrama: Cómo llegan los testers de iPhone y Android a la beta de cada tienda

1. Un usuario de iPhone que marca la casilla de la beta dispara un webhook firmado.
2. Tu relay lo verifica y llama a la API de App Store Connect para añadir la dirección a un grupo de TestFlight.
3. Apple envía por email la invitación de TestFlight cuando el grupo tiene una build disponible.
4. Los testers de Android se recogen igual, y luego se exportan como CSV y se filtran por plataforma.
5. Pegas las cuentas de Google en la lista de emails de la prueba cerrada en Play Console.
6. Les envías el enlace de inscripción de la prueba desde tu herramienta de email.

Apple tiene una API para testers; las pruebas cerradas de Google Play se gestionan en Play Console o con Google Groups, así que la parte de Android es una exportación semanal.

### iPhone: añade testers a TestFlight

En App Store Connect, crea un grupo de pruebas externas y una clave de API en **Users and Access** › **Integrations**, con el rol App Manager o Admin. Luego añade un relay que escuche el webhook `submission.created` de Ikiform. Este es un route handler de Next.js y usa `jose` para firmar el token de Apple; funciona en cualquier servidor que tenga `fetch`.

`app/api/testflight/route.ts`:

```ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { importPKCS8, SignJWT } from "jose";

async function appStoreToken() {
  const key = await importPKCS8(process.env.ASC_PRIVATE_KEY!, "ES256");
  return new SignJWT({})
    .setProtectedHeader({ alg: "ES256", kid: process.env.ASC_KEY_ID!, typ: "JWT" })
    .setIssuer(process.env.ASC_ISSUER_ID!)
    .setAudience("appstoreconnect-v1")
    .setIssuedAt()
    .setExpirationTime("15m")
    .sign(key);
}

export async function POST(request: Request) {
  const payload = await request.text();
  try {
    const event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
    if (event.type !== "submission.created") return new Response(null, { status: 204 });
    const { email, first_name, platform, beta } = event.data.fields;
    if (platform !== "iphone" || beta !== true) return new Response(null, { status: 204 });

    const response = await fetch("https://api.appstoreconnect.apple.com/v1/betaTesters", {
      method: "POST",
      headers: { authorization: `Bearer ${await appStoreToken()}`, "content-type": "application/json" },
      body: JSON.stringify({
        data: {
          type: "betaTesters",
          attributes: { email: String(email), firstName: first_name ? String(first_name) : undefined },
          relationships: { betaGroups: { data: [{ type: "betaGroups", id: process.env.ASC_BETA_GROUP_ID! }] } },
        },
      }),
    });
    if (response.ok || response.status === 409) return new Response(null, { status: 204 });
    return new Response(`App Store Connect answered ${response.status}`, { status: 502 });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
}
```

- `ASC_PRIVATE_KEY` es el contenido del archivo `.p8` que te da Apple, saltos de línea incluidos. `ASC_KEY_ID` y `ASC_ISSUER_ID` están en la misma página.
- Los tokens de Apple pueden durar como máximo 20 minutos, así que el relay firma uno nuevo por cada entrega.
- Un `409` significa que Apple rechazó el cambio por un conflicto, a menudo porque la dirección ya es tester. El relay lo da por hecho, así que si un tester nunca recibe la invitación, revisa el grupo en App Store Connect. Cualquier otro fallo responde `502`, así que Ikiform reintenta la entrega.
- TestFlight permite hasta 10.000 testers externos por app. La primera build que das a un grupo externo pasa por Beta App Review, y cada build caduca a los 90 días.

Añade la URL del relay en **Webhooks** en Ikiform y copia el secreto `whsec_` en `IKIFORM_WEBHOOK_SECRET`. Un espacio de trabajo puede tener 3 endpoints, así que esto puede funcionar junto a un relay que alimenta tu herramienta de email.

### Android: llena una prueba cerrada

La API de publicación de Google Play gestiona los testers de las pruebas cerradas mediante Google Groups, no con direcciones sueltas, así que esta parte es una exportación semanal. Exporta la lista con **Export CSV**, fíltrala en una hoja de cálculo por `platform` = `android` y `beta` = `true`, y añade los emails a la lista de emails de la prueba cerrada en **Test and release** › **Testing** › **Closed testing** › **Manage track** › **Testers** en Play Console. Luego envía a esas personas el enlace de inscripción de la prueba desde tu herramienta de email.

Si estás cumpliendo el requisito de 12 testers, invita a más de 12. Quienes se dan de baja o nunca se inscriben no cuentan, y los 14 días necesitan 12 testers inscritos todo el tiempo.

> Ikiform no envía emails a la persona que rellena el formulario. Los emails de notificación van solo a ti y a tu equipo, así que no hay respuesta automática, email de confirmación ni doble opt-in. Envíalos desde tu herramienta de email, activados por un [webhook](https://ikiform.com/es/docs/webhooks.md). TestFlight envía su propia invitación, así que los testers de iPhone sabrán de Apple. Los testers de Android solo sabrán de ti.

## El día del lanzamiento

Exporta toda la lista y divídela por `platform`. Envía a cada mitad un email con un solo enlace a la tienda. Quien eligió iPhone no necesita el enlace de Play, y un único email con dos insignias pierde toques en una pantalla pequeña. Si recogiste `device`, compara tus informes de fallos con los modelos que indicó la gente antes de enviar.

## Comprueba que funciona

1. En **Allowed domains** del formulario, añade el dominio de tu sitio, y `localhost` mientras desarrollas. Déjalo vacío para aceptar envíos desde cualquier sitio.
2. Abre la página en un teléfono. La plataforma correcta está preseleccionada, y en Android aparece la indicación sobre la cuenta de Google.
3. Envía como tester de iPhone. El envío muestra `platform` como `iphone` y `beta` como `true`.
4. Abre el endpoint del relay en **Webhooks**. La entrega muestra `succeeded` y la dirección aparece en tu grupo de TestFlight.
5. Envía como tester de Android, exporta el CSV y confirma que la fila aparece al filtrar con `platform` en `android`.
6. Envía con el honeypot relleno, `_gotcha=bot`. Sigue recibiendo una respuesta de éxito, pero el envío se guarda como spam y no manda email ni webhook.

## Problemas habituales

| Problema | Qué hacer |
| --- | --- |
| Las entregas del relay fallan con `502` y Apple respondió `401` | El token es incorrecto: revisa el id de la clave, el id del emisor y que la clave privada conservó sus saltos de línea en la variable de entorno. |
| Se añadió un tester pero no recibió el email de TestFlight | El grupo aún no tiene build, o la primera build sigue en Beta App Review. Las invitaciones salen cuando hay una build disponible para el grupo. |
| Un tester de Android no puede abrir el enlace de inscripción | La dirección de la lista no es la cuenta de Google con la que inició sesión en el teléfono. Pídele que se vuelva a registrar con esa cuenta. |
| `422 validation_failed` | El envío no coincide con la definición de campos del formulario. `error.fields` indica cada campo y el motivo. Haz coincidir el `name` del input con el id del campo. |
| El envío está en el panel pero no llegó ningún email ni webhook | Se guardó como spam. El spam no envía nada. Ábrelo con el filtro **Spam** para ver los motivos y márcalo como no spam para que se envíen su email y sus webhooks. |

## Preguntas

### ¿Necesito una lista de espera si la App Store tiene pedidos anticipados?

Hacen cosas distintas. Los pedidos anticipados y el prerregistro de Play necesitan una ficha aprobada en la tienda y te dan un recuento, no contactos. Una lista de espera funciona desde el primer día, te da el email y la plataforma de cada persona y te permite invitar testers.

### ¿Cómo encuentro 12 testers para el requisito de pruebas cerradas de Google Play?

Pídelos en tu lista de espera. Una casilla de beta y una pregunta sobre la plataforma te muestran quién tiene un teléfono Android y quiere probar. Pon sus cuentas de Google en la lista de emails de la prueba cerrada y envíales el enlace de inscripción.

### ¿Puede Ikiform añadir testers a TestFlight automáticamente?

No directamente. Ikiform envía un webhook firmado por cada registro, y un relay corto que despliegas tú añade la dirección a un grupo de TestFlight mediante la API de App Store Connect, como se muestra arriba.

### ¿Puede Ikiform enviar un email a la persona que envió el formulario?

No. Ikiform te envía emails a ti y a tu equipo, no a quien envía el formulario, así que no hay respuesta automática ni email de confirmación. Envía un webhook a tu herramienta de email y manda la confirmación desde allí.

### ¿Ikiform es gratis?

No, no hay plan gratuito. Probar es gratis: puedes enviar 50 envíos de prueba al mes desde localhost antes de pagar. Para pasar a producción, Pro empieza en 6 $/mes por 500 envíos, o puedes pagar una sola vez 10.000 envíos por 49 $ o 50.000 envíos por 149 $, con créditos que nunca caducan.

## Más guías

- [Lista de espera para un nuevo SaaS](https://ikiform.com/es/guides/waitlist.md): Crea una lista de espera previa al lanzamiento en tu propia landing page: el formulario, el antispam, los duplicados, los emails de confirmación y una exportación limpia el día del lanzamiento.
- [Registro a una beta con filtro](https://ikiform.com/es/guides/waitlist/beta-signup.md): Un formulario de solicitud para una beta con preguntas de filtro que aplica el servidor, y un script que puntúa a los candidatos y elige cada grupo de la lista.
- [Lista para lanzar en Product Hunt](https://ikiform.com/es/guides/waitlist/product-hunt.md): Reúne una lista semanas antes de Product Hunt, etiqueta cada registro por canal y envía el email del lanzamiento en dos tandas según el reinicio en hora del Pacífico.
- [Lista de espera en HTML puro](https://ikiform.com/es/guides/waitlist/html.md): Una página de lista de espera completa en HTML puro y sin build que funciona con JavaScript desactivado, muestra un agradecimiento en línea cuando carga y recurre a un plan B cuando hace falta.
- [Lista de espera en Next.js](https://ikiform.com/es/guides/waitlist/nextjs.md): Una lista de espera con el App Router de Next.js: una server action que reenvía registros con una clave secreta, useActionState, un agradecimiento optimista y un límite por visitante.
- [Lista de espera en Framer](https://ikiform.com/es/guides/waitlist/framer.md): Dos formas de recoger registros de lista de espera en Framer: el formulario de Framer con un webhook a Ikiform, o un code component que conserva los límites por visitante y el antispam.
