Formulario de suscripción a newsletter

Formulario de suscripción a newsletter7 min de lectura

Envía a Kit las suscripciones de tu propio formulario de newsletter

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.

Preet SutharFundador, Ikiform

Envía tu propio formulario a Ikiform y apunta un webhook de Ikiform a un relay que haga hasta tres llamadas a la API v4 de Kit: crear el suscriptor, añadirlo a un formulario de Kit y etiquetar dónde se suscribió. Créalo como inactive y añádelo a un formulario con el incentive email activado, y Kit debería enviar su propia confirmación, algo que pruebas una vez con una dirección tuya porque Kit solo lo documenta para su endpoint en bloque. El relay guarda la API key de Kit; tu página nunca la ve.

Qué cambia con Kit

Kit divide una suscripción en objetos separados. Un suscriptor es una persona. Un formulario es de dónde vino, y lleva el email de confirmación, que Kit también llama incentive email: su paso de doble opt-in. Una etiqueta es un rótulo por el que segmentas. La API v4 tiene un endpoint para cada uno, y tanto el endpoint del formulario como el de la etiqueta necesitan que el suscriptor exista antes. Así que una suscripción de Ikiform se convierte en una breve secuencia de llamadas, en orden:

Las llamadas a la API de Kit que hace el relay por cada suscripciónwebhook deIkiformverificado porel relayPOST/v4/subscribersstate: inactivePOST/v4/forms/{id}/subscribersenvía elincentive emailPOST/v4/tags/{id}/subscribersetiqueta laubicación123Las llamadas a la API de Kit que hace el relay por cada suscripciónwebhook de Ikiformverificado por el relayPOST /v4/subscribersstate: inactivePOST/v4/forms/{id}/subscribersenvía el incentive emailPOST/v4/tags/{id}/subscribersetiqueta la ubicación123
  1. El relay recibe el webhook firmado de Ikiform y lo verifica.
  2. Crea el suscriptor en Kit como inactivo. Si la dirección ya existe, Kit actualiza el nombre y no toca el estado.
  3. Añade el suscriptor a tu formulario de Kit. Si el incentive email de ese formulario está activado, Kit envía la confirmación.
  4. Si el source de la suscripción tiene una etiqueta, etiqueta al suscriptor. Este paso es opcional.
Cada llamada depende de la anterior, así que el relay se detiene en el primer fallo y deja que Ikiform reintente.
LlamadaKit respondeSignificado
Crear suscriptor201Suscriptor nuevo, creado en el estado que enviaste
Crear suscriptor200Ya existe. Nombre actualizado, estado sin cambios
Añadir al formulario201 o 200Añadido, o ya estaba en el formulario. La documentación de formularios en bloque de Kit dice que quien ya está en un formulario no vuelve a recibir el incentive email
Cualquier llamada401API key incorrecta o ausente
Añadir al formulario o etiquetar404El id del formulario o de la etiqueta no existe en esta cuenta
Cualquier llamada429Por encima del límite de frecuencia de la API key

Configura Kit

  1. En Kit, crea un formulario para estas suscripciones, como "Website signup". No lo vas a incrustar; es el registro de dónde vinieron los suscriptores y el lugar del incentive email.
  2. Abre los ajustes del formulario y activa el incentive email si quieres doble opt-in. Escribe el email y configura adónde lleva el enlace de confirmación.
  3. Busca el id numérico del formulario, en la app de Kit o con el endpoint de la API que lista los formularios. Crea una etiqueta por ubicación si las quieres, y apunta sus ids.
  4. Crea una API key v4 en los ajustes de desarrollador de Kit y guárdala para el entorno del relay.
La documentación de la API de Kit dice que el acceso a la API depende de que el plan de la cuenta sea elegible, y su página de precios incluye apps e integraciones a partir del plan Creator. Comprueba que tu plan puede crear una clave v4 antes de construir sobre ella.

El relay

Un route handler de Next.js recibe el webhook y un pequeño módulo habla con Kit. Los mismos dos archivos funcionan en cualquier hosting Node o edge que te dé una URL HTTPS pública.

lib/kit.ts
const KIT = "https://api.kit.com/v4";

const TAGS: Record<string, number> = {
  footer: 1111111,
  post: 2222222,
};

function call(path: string, body: Record<string, unknown>) {
  return fetch(`${KIT}${path}`, {
    method: "POST",
    headers: {
      "X-Kit-Api-Key": process.env.KIT_API_KEY!,
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(body),
  });
}

export async function addToKit(signup: { email: string; firstName?: string; source: string; referrer?: string }) {
  const created = await call("/subscribers", {
    email_address: signup.email,
    first_name: signup.firstName ?? null,
    state: "inactive",
  });
  if (!created.ok) return created;

  const joined = await call(`/forms/${process.env.KIT_FORM_ID}/subscribers`, {
    email_address: signup.email,
    referrer: signup.referrer ?? null,
  });
  if (!joined.ok) return joined;

  const tag = TAGS[signup.source];
  if (!tag) return joined;
  return call(`/tags/${tag}/subscribers`, { email_address: signup.email });
}
app/api/kit/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { addToKit } from "@/lib/kit";

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.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 answer = await addToKit({
    email,
    firstName: typeof first_name === "string" ? first_name : undefined,
    source: typeof source === "string" ? source : "unknown",
    referrer: typeof event.data.meta.referrer === "string" ? event.data.meta.referrer : undefined,
  });

  if (answer.status === 429) return new Response("Kit rate limit", { status: 503, headers: { "retry-after": "60" } });
  if (!answer.ok) return new Response(`Kit answered ${answer.status}: ${await answer.text()}`, { status: 502 });
  return new Response(null, { status: 204 });
}
.env.local
IKIFORM_WEBHOOK_SECRET=whsec_...
KIT_API_KEY=your-v4-api-key
KIT_FORM_ID=1234567
  • X-Kit-Api-Key es como la API v4 de Kit recibe una API key personal. OAuth es para apps que instalan otras personas; un relay para tu propia lista no lo necesita.
  • Enviar state: "inactive" es lo que mantiene a un suscriptor nuevo sin confirmar hasta que hace clic. Si lo omites, Kit lo crea como active, y el estado no se puede cambiar después con el mismo endpoint.
  • El referrer de la página va a Kit como referrer del formulario, así que Kit muestra de qué artículo vino el lector.
  • El cuerpo del error de Kit va dentro del 502, así que el registro de entregas de Ikiform muestra el propio mensaje de Kit.
  • Relaciona cada valor de source con un id de etiqueta en TAGS. Un source sin etiqueta se salta la tercera llamada.

Añade la URL de la ruta en Webhooks en el panel de Ikiform, elige el formulario de la newsletter y copia el secreto whsec_ en IKIFORM_WEBHOOK_SECRET. Todas las reglas de la URL y de cada respuesta están en la documentación de webhooks.

Límites de frecuencia y reintentos

Kit permite 120 peticiones cada 60 segundos móviles por API key. Cada suscripción cuesta dos o tres, así que caben unas 40 a 60 suscripciones por minuto antes de que Kit responda 429. Es más que suficiente para un formulario de footer, y va justo el día que un post se hace viral.

El relay responde 503 con Retry-After cuando Kit dice 429, e Ikiform espera antes de volver a intentarlo. Un reintento ejecuta toda la secuencia desde el principio. Es seguro: crear devuelve 200 para un suscriptor existente, y añadir a alguien que ya está en el formulario devuelve 200. La documentación de formularios en bloque de Kit dice que quien ya está en un formulario no vuelve a recibir el incentive email; el endpoint individual no lo dice, así que prueba un reintento con una dirección tuya. Tu propio servidor muestra cómo registrar cada webhook-id si prefieres saltarte los reintentos que ya has completado.

Errores comunes

  • Los campos personalizados deben existir antes. Si añades fields a la llamada de creación, usa la clave de cada campo, como last_name, y crea el campo en Kit antes de enviarlo.
  • Los suscriptores activos siguen activos. Como crear nunca cambia el estado de un suscriptor existente, a un lector confirmado que se vuelve a suscribir no se le pide que confirme otra vez.
  • Lectores que se dieron de baja. Un lector que se dio de baja y se vuelve a suscribir ya existe, así que crear devuelve 200 y no cambia su estado. Revisa en Kit cómo quieres tratarlos.
  • Un formulario, muchas ubicaciones. Usa un formulario de Kit para la web y etiquetas para las ubicaciones. Varios formularios de Kit significan varios incentive emails que mantener sincronizados.
  • Ningún email de Ikiform. Ikiform no envía email a la persona que rellena el formulario. Los emails de notificación van solo a ti y a tu equipo, así que no hay autorespuesta, email de confirmación ni doble opt-in. Envíalos desde tu herramienta de email, activados por un webhook.

Comprueba que funciona

  1. Elige Send test en el endpoint en Ikiform. La entrega muestra 204 y no cambia nada en Kit.
  2. Suscríbete en tu página con una dirección tuya. La entrega muestra 204.
  3. En Kit, el suscriptor aparece en tu formulario como no confirmado, con la etiqueta de la ubicación.
  4. Llega el incentive email. Haz clic en el enlace y el suscriptor pasa a estar confirmado.
  5. Vuelve a suscribirte con la misma dirección. La entrega muestra 204 y no llega un segundo incentive email.
  6. Pon un KIT_FORM_ID incorrecto un momento. La entrega muestra 502 con el mensaje 404 de Kit.

Preguntas

¿Te atascaste en un paso o quieres una guía para tu caso? Escribe a hello@ikiform.com.