# Envía a beehiiv las suscripciones de tu propio formulario de newsletter

> Conecta tu propio formulario de suscripción con beehiiv: un relay crea cada suscripción con el doble opt-in activado, la ubicación como fuente UTM y la página como referrer.

Publicado el 2026-10-25 · https://ikiform.com/es/guides/newsletter-signup/beehiiv

Envía tu propio formulario a Ikiform y apunta el webhook a un relay que llame al endpoint de crear suscripción de beehiiv. Envía `double_opt_override: "on"` para que beehiiv envíe la confirmación, pasa la ubicación del formulario como `utm_source` y la página como `referring_site`, y deja `reactivate_existing` en false para que una suscripción nunca deshaga en silencio una baja. Una llamada a la API por suscripción, con la clave guardada en el relay.

## Qué cambia con beehiiv

La API de beehiiv se organiza en torno a publicaciones. Una suscripción es una dirección de email suscrita a una publicación, y se crea con un `POST` a `/v2/publications/{publicationId}/subscriptions`. Todo lo relativo a la suscripción viaja en esa única petición: si hay que confirmar, si se envía el email de bienvenida, de dónde vino el lector y los campos personalizados. No hay un paso aparte de etiqueta o formulario como en [Kit](https://ikiform.com/es/guides/newsletter-signup/kit.md).

beehiiv también informa de la captación en términos de UTM. Sus registros de suscripción llevan `utm_source`, `utm_medium`, `utm_campaign` y `referring_site`. Relaciona con ellos los campos de tu formulario, y cada suscriptor en beehiiv mostrará qué ubicación y qué artículo lo trajeron:

Diagrama: Cómo convierte el relay un envío de Ikiform en una suscripción de beehiiv

1. fields.email pasa a ser email.
2. fields.source pasa a ser utm_source.
3. meta.referrer pasa a ser referring_site.
4. fields.first_name pasa a ser custom_fields: First Name.
5. double_opt_override: "on" lo añade el relay.
6. reactivate_existing: false lo añade el relay.

Los cuatro primeros vienen del evento de Ikiform. Los dos últimos son decisiones fijas que el relay toma para cada suscripción.

## Configura beehiiv

1. En beehiiv, abre **Settings**, luego **API** en **Workspace Settings**, y elige **Create New API Key**. Cópiala enseguida; beehiiv no volverá a mostrarla.
2. En un plan de pago, limita la clave a la única publicación que alimenta el formulario. Una clave limitada a una publicación recibe `404` para cualquier otra, lo que limita el daño si se filtra.
3. Busca el id de la publicación, el id con prefijo que la API de beehiiv usa en la ruta. El endpoint de la API que lista las publicaciones lo devuelve.
4. Crea un campo personalizado llamado `First Name` si quieres guardar los nombres. beehiiv descarta los campos personalizados que todavía no existen.
5. Configura los emails de doble opt-in y de bienvenida en los ajustes de la publicación. El relay los activa en cada petición; su contenido vive en beehiiv.

> La página de precios de beehiiv incluye acceso a la API en todos los planes, con límites de frecuencia de la API más bajos en los planes más baratos. Su Send API, para enviar emails mediante la API, está limitada a planes superiores, pero este relay solo crea suscripciones y no la necesita.

## El relay

Esto es una Netlify Function, que encaja con un sitio que ya está en Netlify: se ejecuta en tu propio dominio, junto al sitio estático, sin un servicio aparte. Instala `@netlify/functions` para los tipos y define las tres variables en los ajustes de entorno del sitio.

`netlify/functions/beehiiv.mts`:

```ts
import type { Config } from "@netlify/functions";
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";

export default async (request: Request) => {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({
      payload,
      headers: request.headers,
      secret: Netlify.env.get("IKIFORM_WEBHOOK_SECRET")!,
    });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const { email, first_name, consent, source } = event.data.fields;
  if (consent !== true || typeof email !== "string") return new Response("Skipped", { status: 200 });

  const publication = Netlify.env.get("BEEHIIV_PUBLICATION_ID");
  const answer = await fetch(`https://api.beehiiv.com/v2/publications/${publication}/subscriptions`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${Netlify.env.get("BEEHIIV_API_KEY")}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      email,
      double_opt_override: "on",
      send_welcome_email: true,
      reactivate_existing: false,
      utm_source: typeof source === "string" ? source : "website",
      utm_medium: "signup_form",
      referring_site: event.data.meta.referrer ?? undefined,
      custom_fields: typeof first_name === "string" && first_name ? [{ name: "First Name", value: first_name }] : [],
    }),
  });

  if (answer.status === 429) {
    const reset = Number(answer.headers.get("ratelimit-reset"));
    const wait = reset ? Math.max(1, reset - Math.floor(Date.now() / 1000)) : 60;
    return new Response("beehiiv rate limit", { status: 503, headers: { "retry-after": String(wait) } });
  }
  if (!answer.ok) return new Response(`beehiiv answered ${answer.status}: ${await answer.text()}`, { status: 502 });
  return new Response(null, { status: 204 });
};

export const config: Config = {
  path: "/hooks/beehiiv",
};
```

- `double_opt_override: "on"` envía el email de confirmación sea cual sea el valor por defecto de la publicación. Usa `"not_set"` para seguir el ajuste de la publicación, y nunca `"off"` en un formulario público.
- `send_welcome_email` es `false` por defecto en la API. Ponlo en `true` si quieres que las suscripciones de la API reciban el email de bienvenida que reciben las del embed.
- `reactivate_existing: false` también es el valor por defecto. Escríbelo explícitamente para que nadie lo cambie más adelante sin pensar; reactiva a quienes se dieron de baja.
- beehiiv responde `200` con la suscripción, y su `status` empieza como `validating` mientras beehiiv comprueba la dirección, y luego `pending` hasta que el lector confirma.
- Ante un `429`, el relay lee el `RateLimit-Reset` de beehiiv, una hora Unix, y lo convierte en un retraso `Retry-After` para Ikiform.

La URL de la función es `https://your-site.com/hooks/beehiiv`. Añádela en **Webhooks** en Ikiform y copia el secreto `whsec_` en `IKIFORM_WEBHOOK_SECRET`. La [documentación de webhooks](https://ikiform.com/es/docs/webhooks.md) lista las reglas de URL, y [tu propio servidor](https://ikiform.com/blog/form-submissions-to-your-own-server.md) muestra cómo saltarte una entrega que ya has procesado.

## Elegir los valores UTM

Los campos UTM de beehiiv son texto libre, así que decide los valores una vez y mantenlos consistentes, o los registros se dividirán en casi duplicados como `footer` y `Footer`. El input oculto `source` del formulario es el `utm_source` natural. Mantén fijo `utm_medium`, para poder distinguir cada suscripción de tus propios formularios de las páginas alojadas de beehiiv y de las importaciones:

| Ubicación | Input `source` | `utm_source` | `utm_medium` |
| --- | --- | --- | --- |
| Footer del sitio | `footer` | `footer` | `signup_form` |
| Final de un post | `post` | `post` | `signup_form` |
| Página de la newsletter | `newsletter-page` | `newsletter-page` | `signup_form` |

Si haces una campaña que enlaza a una página con el formulario, lee la campaña de la URL de la página en el relay. `meta.referrer` contiene la URL completa de la página, con la query string incluida cuando el navegador la envía, así que el relay puede copiar de ella un parámetro `utm_campaign` a la petición.

## Límites de frecuencia por plan

beehiiv mide su límite por API key en ventanas fijas de 60 segundos, y el límite depende del plan. Cada suscripción es una petición:

| Plan de beehiiv | Peticiones por minuto |
| --- | --- |
| Free | 30 |
| Lite | 180 |
| Pro | 500 |
| Enterprise | 800, más bajo petición |

Treinta por minuto basta para la mayoría de formularios de footer, pero un post de lanzamiento en una publicación gratuita puede superarlo. El `503` del relay hace que Ikiform espere y reintente en lugar de perder la suscripción. Los nombres y límites de los planes cambian, así que consulta la página de límites de frecuencia de beehiiv si el tuyo no aparece.

## Errores comunes

- **Los nombres de los campos personalizados son exactos.** beehiiv relaciona los campos personalizados por nombre y descarta los desconocidos con un aviso en la respuesta, no con un error. Una errata significa que los nombres desaparecen sin avisar.
- **`referring_site` puede estar vacío.** `meta.referrer` es `null` cuando el navegador no envió referrer, y el relay omite el campo.
- **Suscriptores existentes.** La documentación de beehiiv dice que la llamada crea o actualiza la suscripción, pero no qué cambia para un suscriptor activo. Prueba con tu propia dirección confirmada antes de poner el formulario en todas las páginas.
- **Las claves valen para todo el workspace por defecto.** Una clave sin restricción de publicación puede acceder a todas las publicaciones del workspace. Limítala.
- **Los niveles de pago se quedan en beehiiv.** Omite `tier` para que las suscripciones entren sin suscripción de pago. Las mejoras de plan ocurren en el propio checkout de beehiiv.

## Comprueba que funciona

1. Elige **Send test** en el endpoint en Ikiform. La entrega muestra `204` y beehiiv no recibe ninguna petición.
2. Suscríbete desde tu página con una dirección tuya. La entrega muestra `204`.
3. En beehiiv, el suscriptor aparece como pendiente, con tu ubicación como fuente UTM y el artículo como sitio de referencia.
4. Llega el email de doble opt-in. Confírmalo, y después llega el de bienvenida.
5. Da de baja esa dirección en beehiiv y vuelve a suscribirte. El suscriptor sigue inactivo, porque `reactivate_existing` es false.

## Preguntas

### ¿Puedo usar mi propio formulario con beehiiv en lugar de su embed?

Sí. Envía tu formulario a Ikiform y deja que un relay llame al endpoint de crear suscripción de beehiiv para cada suscripción. Tu formulario mantiene tu diseño, y beehiiv sigue confirmando, dando la bienvenida y enviando emails al lector.

### ¿Funciona la API de beehiiv en todos los planes de beehiiv?

La página de precios de beehiiv incluye acceso a la API en todos los planes, y su página de límites de frecuencia da a su plan más bajo 30 peticiones por minuto. La Send API está limitada a planes superiores, pero crear suscripciones no la usa.

### ¿Cómo hago que beehiiv envíe un email de doble opt-in a las suscripciones de la API?

Envía double_opt_override con el valor "on" en la petición de crear suscripción, o "not_set" para usar el ajuste propio de la publicación. "off" activa al suscriptor de inmediato sin email.

### ¿Puedo conectar beehiiv sin código?

Sí. beehiiv funciona con Zapier y Make, que respetan sus límites de frecuencia por ti. Apunta el webhook de Ikiform a la automatización y usa su acción de beehiiv para añadir un suscriptor.

## Más guías

- [Formulario de suscripción a newsletter](https://ikiform.com/es/guides/newsletter-signup.md): Crea un formulario de suscripción a tu newsletter con tu propio markup, registra el consentimiento, bloquea los registros de bots y pasa cada suscriptor a Kit, MailerLite, beehiiv o cualquier herramienta.
- [Doble opt-in](https://ikiform.com/es/guides/newsletter-signup/double-opt-in.md): Ikiform no envía emails de confirmación, así que el doble opt-in se hace en tu herramienta de email: un relay añade cada suscripción como no confirmada y la herramienta envía el enlace.
- [Sitio estático](https://ikiform.com/es/guides/newsletter-signup/static-site.md): Añade un formulario de suscripción a tu newsletter en un sitio estático con Hugo, Jekyll, Eleventy o Astro, deja la API key fuera de la página y confirma en la herramienta.
- [Kit (ConvertKit)](https://ikiform.com/es/guides/newsletter-signup/kit.md): Conecta tu propio formulario de newsletter con Kit mediante un relay que crea el suscriptor, lo añade a un formulario de Kit para el incentive email y etiqueta la ubicación.
- [MailerLite](https://ikiform.com/es/guides/newsletter-signup/mailerlite.md): Conecta tu propio formulario de suscripción con MailerLite: un relay añade a los lectores nuevos como no confirmados para el doble opt-in y nunca pide a un suscriptor que confirme dos veces.
- [Formulario de newsletter en Next.js](https://ikiform.com/es/guides/newsletter-signup/nextjs.md): Un formulario de newsletter en el footer de Next.js: una server action con comprobación de consentimiento y Turnstile que envía a Ikiform, más un route handler que añade a los lectores a Kit.
