# Cómo crear una lista de emails previa al lanzamiento en Product Hunt

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

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

Empieza a recoger emails en tu propia página de cuatro a seis semanas antes del lanzamiento, con un campo oculto de origen para saber de qué canal vino cada registro. Pide a la gente que acepte recibir un email el día del lanzamiento, exporta la lista la semana anterior y divídela en dos envíos: uno justo después de que empiece el día de Product Hunt a las 12:01 a. m. hora del Pacífico, y otro para América en su mañana.

Un lanzamiento en Product Hunt tiene una fecha fija y una ventana de 24 horas. Quienes tienen más probabilidades de probar tu producto y dejar un comentario útil son quienes pidieron saber de ti, así que la lista importa más que la publicación del lanzamiento. Esta página cubre lo que cambia cuando la lista se crea para ese único día.

## Qué tiene de distinto una lista para Product Hunt

- **La fecha límite es fija.** Una lista de espera normal puede esperar hasta que el producto esté listo. Aquí, la lista tiene que estar exportada, limpia y cargada en tu herramienta de email antes de una fecha que elegiste hace semanas.
- **El día va en hora del Pacífico.** Los lanzamientos se publican a las 12:01 a. m. PT y compiten por el ranking de ese día. Tu lista está en todas las zonas horarias, así que un solo envío a una hora encuentra a la mitad durmiendo.
- **Lo que pides es feedback, no votos.** Las reglas de Product Hunt prohíben pedir upvotes, y hacerlo puede descalificar un lanzamiento. Pide a la lista que pruebe el producto y comente qué cambiaría. Está dentro de las reglas, y de todos modos los comentarios lucen más que un número.
- **El día del lanzamiento trae un pico.** Los visitantes de Product Hunt llegan a tu sitio y se registran con minutos de diferencia. Los límites del formulario que no importaron durante semanas pueden importar durante unas horas.

Diagrama: Una lista de lanzamiento en Product Hunt desde el primer registro hasta el día siguiente

1. De cuatro a seis semanas antes, la página se publica con el formulario, y cada canal en el que la compartes tiene su propio valor de ref.
2. Una semana antes, exporta la lista, quita los duplicados y divide a quienes aceptaron en dos tandas por país.
3. El día anterior, sube el límite de todo el formulario para que el tráfico del lanzamiento no se rechace.
4. A las 12:01 a. m. hora del Pacífico se publica el lanzamiento.
5. Minutos después, envía la tanda 1 a todos los que están fuera de América, donde es por la mañana o por la tarde.
6. Hacia las 6 a. m. hora del Pacífico, envía la tanda 2 a América.
7. Al día siguiente, da las gracias a la lista y compara qué valores de ref trajeron a las personas que se registraron y se quedaron.

Ikiform registra el país de cada registro, así que la división no necesita una pregunta extra en el formulario. Los países desconocidos van en la segunda tanda.

## El formulario

Parte del formulario de solo email de la [guía principal](https://ikiform.com/es/guides/waitlist.md#form) y añade dos cosas: una casilla que pide el email del día del lanzamiento y un `ref` oculto que se rellena desde el enlace por el que llegó la persona.

`index.html`:

```html
<form id="launch-list" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required>
  <label>
    <input name="launch_reminder" type="checkbox" value="true">
    Email me the morning we launch on Product Hunt
  </label>
  <input type="hidden" name="ref" value="direct">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button>Get early access</button>
</form>

<script>
  const params = new URLSearchParams(location.search);
  const ref = params.get("ref") || params.get("utm_source");
  if (ref) {
    document.querySelector('#launch-list [name="ref"]').value = ref.toLowerCase().replace(/[^a-z0-9_-]/g, "").slice(0, 40);
  }
</script>
```

- La casilla empieza sin marcar. Un email el día del lanzamiento es algo distinto del acceso anticipado, así que la gente lo acepta de forma explícita. Ikiform guarda `true` o `false` con la fecha y hora del registro.
- El script copia `?ref=` o `?utm_source=` en el input oculto y elimina todo lo que no sea una letra, un dígito, `-` o `_`. Sin ninguno de los dos, `ref` se queda en `direct`.
- Product Hunt suele añadir `ref=producthunt` a los enlaces de tu página de lanzamiento, así que los registros del día del lanzamiento se etiquetan solos.

Añade la definición de campos en la pestaña **Fields** del formulario. Ikiform rechaza entonces los envíos sin email, guarda la casilla como un `true` o `false` real y limita `ref` a 40 caracteres para que nadie lo llene de basura.

`Campos`:

```json
{
  "version": 1,
  "title": "Launch list",
  "fields": [
    { "id": "email", "type": "email", "label": "Email", "required": true },
    { "id": "launch_reminder", "type": "checkbox", "label": "Email me the morning we launch on Product Hunt" },
    { "id": "ref", "type": "text", "label": "Source", "validation": { "max_length": 40 } }
  ]
}
```

### Un ref por canal

Decide los valores antes de compartir el enlace en ningún sitio, y úsalos siempre:

| Dónde lo compartes | Enlace | ref guardado |
| --- | --- | --- |
| Tus posts en X o Bluesky | `example.com/?ref=x` | `x` |
| LinkedIn | `example.com/?ref=linkedin` | `linkedin` |
| Un post en una comunidad, como Indie Hackers | `example.com/?ref=ih` | `ih` |
| Tu newsletter o tu blog | `example.com/?utm_source=newsletter` | `newsletter` |
| Tu página de lanzamiento en Product Hunt | Lo añade Product Hunt | `producthunt` |

## Prepara el formulario para el tráfico del lanzamiento

Los límites por defecto sirven para una página previa al lanzamiento tranquila. El día del lanzamiento no es tranquilo. Cada visitante puede enviar 5 por minuto, que es de sobra, pero todo el formulario tiene un tope de 300 por minuto. Un lanzamiento en portada puede traer más registros que eso en un minuto con mucho movimiento.

- El día anterior, abre los ajustes del formulario y elige un [límite de frecuencia](https://ikiform.com/es/docs/rate-limits.md) Custom con un límite más alto para el formulario. Vuelve a dejarlo como estaba después de la semana del lanzamiento.
- Si haces una demo en un meetup o un coworking, todos comparten una IP. Elige Relaxed ese día.
- Un envío rechazado recibe `429 rate_limited` y una cabecera `Retry-After`. El formulario HTML sencillo muestra la página de error de Ikiform con un enlace de vuelta.
- Activa la verificación humana en **Spam check** si el día del lanzamiento trae bots. El formulario sencillo no necesita cambios para ello; consulta [protección antispam](https://ikiform.com/es/docs/spam.md#human-check).

## Divide el email del lanzamiento en dos tandas

Una semana antes del lanzamiento, lee la lista con la [API REST](https://ikiform.com/es/docs/api.md#list-submissions) y divídela. Este script conserva el registro más reciente por email, descarta a quien no marcó la casilla y escribe dos archivos CSV según el país que registró Ikiform. Necesita una clave secreta con `submissions:read`.

`waves.mjs`:

```js
import { writeFileSync } from "node:fs";
import { createClient } from "@ikiform/sdk";

const AMERICAS = new Set(["US", "CA", "MX", "BR", "AR", "CO", "CL", "PE", "EC", "UY", "PY", "BO", "VE", "GT", "CR", "PA", "DO", "PR"]);
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY });
const seen = new Set();
const waves = { midnight: [], morning: [] };

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received", limit: 100 })) {
  const email = String(submission.fields.email ?? "").trim().toLowerCase();
  if (!email || seen.has(email)) continue;
  seen.add(email);
  if (submission.fields.launch_reminder !== true) continue;
  const country = submission.meta.country ?? "";
  const wave = !country || AMERICAS.has(country) ? waves.morning : waves.midnight;
  wave.push([email, String(submission.fields.ref ?? "").replaceAll(",", ""), country].join(","));
}

for (const [name, rows] of Object.entries(waves)) {
  writeFileSync(`wave-${name}.csv`, ["email,ref,country", ...rows].join("\n"));
  console.log(`${name}: ${rows.length} people`);
}
```

- Los registros llegan del más nuevo al más antiguo, así que a una persona que se registró dos veces se la juzga por su última respuesta. Si desmarcó la casilla la segunda vez, queda fuera.
- Importa ambos archivos en tu herramienta de email como segmentos separados y prográmalos: la tanda 1 para unos minutos después de las 12:01 a. m. hora del Pacífico, la tanda 2 para hacia las 6 a. m. hora del Pacífico.
- Ejecútalo una vez más la víspera del lanzamiento para recoger los registros de la última semana.

### El email del día del lanzamiento

Envíalo desde tu herramienta de email, para que las bajas y los rebotes se gestionen. Empieza por el producto, enlaza la página del lanzamiento en segundo lugar y pide un comentario, no un voto:

`Email del día del lanzamiento`:

```text
Subject: We're on Product Hunt today

Hi,

You joined the Acme list a few weeks ago. Today we launched on Product Hunt,
and the product is open to everyone on this list first.

Try it: https://acme.example/start
Our launch page: https://www.producthunt.com/products/acme

If you have a minute, tell us on the launch page what you'd change.
Honest comments help more than anything else today.

Ada, founder of Acme
```

> 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). Si quieres un email de bienvenida en cuanto alguien se une, reenvía los registros por webhook a tu herramienta de email; la [guía principal](https://ikiform.com/es/guides/waitlist.md#confirm) muestra el relay.

## El día después

Vuelve a exportar la lista con **Export CSV**, filtrada a los últimos 7 días, y cuenta los registros por `ref`. Los canales que trajeron a personas que luego iniciaron sesión son donde irá tu próxima publicación de lanzamiento. Envía desde tu herramienta de email un breve agradecimiento a quienes se unieron el día del lanzamiento; te encontraron en Product Hunt y todavía no saben nada de ti.

## Comprueba que funciona

Haz esto una semana antes del lanzamiento, no la noche anterior.

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 con `?ref=x` y envía. El envío muestra `ref` como `x` y `launch_reminder` como `false`.
3. Envía otra vez con la casilla marcada y sin query string. `ref` vale `direct` y `launch_reminder` vale `true`.
4. Abre **Submissions** en el panel. El nuevo envío está ahí con todos los campos que mandaste.
5. Ejecuta el script de tandas y comprueba que cada dirección de prueba está en el archivo que esperas según su país.
6. ¿No llegó nada? Cambia el filtro de estado del panel a **Spam**. El spam recibe la misma respuesta de éxito que un envío real.

## Problemas habituales

| Problema | Qué hacer |
| --- | --- |
| `429 rate_limited` | Un visitante envió más de lo que permite el límite de frecuencia del formulario. Standard permite 5 por minuto por visitante. Espera lo que indique `Retry-After`, o elige Relaxed o Custom para formularios que envían desde una IP compartida. |
| `422` con Unknown field para `utm_source` u otro parámetro | Solo está definido `ref`. El script lee `utm_source` y lo pone en `ref` en lugar de enviarlo, así que comprueba que no añadiste otro input oculto. |
| Todos los registros tienen `ref` en `direct` | El script se ejecuta antes de que exista el formulario, o el `id` del formulario es otro. Coloca el script después del formulario y deja `id="launch-list"`. |
| Un país aparece vacío en la exportación | Ikiform no pudo saber dónde estaba el visitante. El script pone los países vacíos en la tanda de la mañana, que encuentra despierta a América y al resto más tarde en su día. |
| 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

### ¿Con cuánta antelación debo empezar una lista de espera antes de lanzar en Product Hunt?

De cuatro a seis semanas te da tiempo para compartir la página en algunos sitios y aprender cuáles funcionan. Empieza antes si todavía no tienes audiencia; al principio la lista crece despacio.

### ¿Puedo pedir a mi lista de espera que vote en Product Hunt?

No. Las reglas de Product Hunt prohíben pedir upvotes, y hacerlo puede descalificar un lanzamiento. Pide a la gente que pruebe el producto y deje un comentario sobre qué cambiaría. Así te mantienes dentro de las reglas y obtienes feedback útil.

### ¿A qué hora debo enviar el email del lanzamiento?

Los lanzamientos se publican a las 12:01 a. m. hora del Pacífico. Envía una tanda unos minutos después a quienes están fuera de América, y una segunda hacia las 6 a. m. hora del Pacífico a América, para que la mayoría lo lea por la mañana.

### ¿Sabe Ikiform de qué país vino un registro?

Normalmente sí. Cada envío registra el país de la conexión del visitante cuando puede, y aparece en la API y en los webhooks como meta.country. Puede estar vacío, así que tómalo como una pista.

### ¿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 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 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.
- [Lista de espera para app móvil](https://ikiform.com/es/guides/waitlist/mobile-app.md): 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.
- [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.
