Formulario de suscripción a newsletter6 min de lectura
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.
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.
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:
- fields.email pasa a ser email.
- fields.source pasa a ser utm_source.
- meta.referrer pasa a ser referring_site.
- fields.first_name pasa a ser custom_fields: First Name.
- double_opt_override: "on" lo añade el relay.
- reactivate_existing: false lo añade el relay.
Configura beehiiv
- En beehiiv, abre Settings, luego API en Workspace Settings, y elige Create New API Key. Cópiala enseguida; beehiiv no volverá a mostrarla.
- 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
404para cualquier otra, lo que limita el daño si se filtra. - 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.
- Crea un campo personalizado llamado
First Namesi quieres guardar los nombres. beehiiv descarta los campos personalizados que todavía no existen. - 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.
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.
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_emailesfalsepor defecto en la API. Ponlo entruesi quieres que las suscripciones de la API reciban el email de bienvenida que reciben las del embed.reactivate_existing: falsetambié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
200con la suscripción, y sustatusempieza comovalidatingmientras beehiiv comprueba la dirección, y luegopendinghasta que el lector confirma. - Ante un
429, el relay lee elRateLimit-Resetde beehiiv, una hora Unix, y lo convierte en un retrasoRetry-Afterpara 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 lista las reglas de URL, y tu propio servidor 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_sitepuede estar vacío.meta.referreresnullcuando 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
tierpara que las suscripciones entren sin suscripción de pago. Las mejoras de plan ocurren en el propio checkout de beehiiv.
Comprueba que funciona
- Elige Send test en el endpoint en Ikiform. La entrega muestra
204y beehiiv no recibe ninguna petición. - Suscríbete desde tu página con una dirección tuya. La entrega muestra
204. - En beehiiv, el suscriptor aparece como pendiente, con tu ubicación como fuente UTM y el artículo como sitio de referencia.
- Llega el email de doble opt-in. Confírmalo, y después llega el de bienvenida.
- Da de baja esa dirección en beehiiv y vuelve a suscribirte. El suscriptor sigue inactivo, porque
reactivate_existinges false.
Preguntas
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.
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.
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.
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.
¿Te atascaste en un paso o quieres una guía para tu caso? Escribe a hello@ikiform.com.