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

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

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:

Diagrama: Las llamadas a la API de Kit que hace el relay por cada suscripción

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.

| Llamada | Kit responde | Significado |
| --- | --- | --- |
| Crear suscriptor | `201` | Suscriptor nuevo, creado en el estado que enviaste |
| Crear suscriptor | `200` | Ya existe. Nombre actualizado, estado sin cambios |
| Añadir al formulario | `201` o `200` | Añ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 llamada | `401` | API key incorrecta o ausente |
| Añadir al formulario o etiquetar | `404` | El id del formulario o de la etiqueta no existe en esta cuenta |
| Cualquier llamada | `429` | Por 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`:

```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`:

```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`:

```bash
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](https://ikiform.com/es/docs/webhooks.md).

## 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](https://ikiform.com/blog/form-submissions-to-your-own-server.md) 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](https://ikiform.com/es/docs/webhooks.md).

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

### ¿Puedo usar mi propio formulario HTML con Kit en lugar de un embed de Kit?

Sí. Envía tu formulario a Ikiform y deja que un relay añada cada suscripción mediante la API v4 de Kit: crear el suscriptor, añadirlo a un formulario de Kit y, si quieres, etiquetarlo. Kit los trata como si vinieran de ese formulario.

### ¿Enviará Kit el email de confirmación a las suscripciones de mi propio formulario?

Debería, si el relay crea el suscriptor como inactivo y lo añade a un formulario de Kit con el incentive email activado. La documentación de formularios en bloque de Kit dice que añadir suscriptores a un formulario con doble opt-in envía el incentive email. El endpoint individual que usa este relay no lo dice, así que pruébalo con una dirección tuya.

### ¿Necesito el flujo OAuth de Kit?

No. OAuth es para apps que instalan otros usuarios de Kit. Para tu propia lista basta con una API key v4 en la cabecera X-Kit-Api-Key, y se queda en el entorno del relay.

### ¿Cuántas suscripciones por minuto puede gestionar el relay?

Kit permite 120 peticiones cada 60 segundos móviles por API key, y cada suscripción usa dos o tres peticiones, así que unas 40 a 60 por minuto. Por encima de eso, el relay responde 503 e Ikiform reintenta más tarde.

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

Sí. Apunta el webhook de Ikiform a Zapier o Make y usa su acción de Kit para añadir un suscriptor a un formulario. Revisa en las opciones de la acción la etiqueta y el formulario.

## 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.
- [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.
- [beehiiv](https://ikiform.com/es/guides/newsletter-signup/beehiiv.md): 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.
- [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.
- [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.
