Guías

Guías15 min de lectura

Formularios de inscripción y RSVP para eventos en tu propio sitio

Recibe RSVP en la página de tu evento: el formulario, límite de acompañantes, un recuento fiable, cierre al llenarse y lista de entrada, sin app de entradas.

Preet SutharFundador, Ikiform

Pon en la página de tu evento un formulario de RSVP que envíe a un backend de formularios, con una respuesta sí o no, un número de acompañantes limitado en el servidor y los datos que necesitas para organizar. Cuenta asistentes a partir de la última respuesta de cada email, con una exportación CSV o un script corto, y pausa el formulario cuando se llene. Ikiform guarda y reenvía cada RSVP, pero no tiene venta de entradas, pagos ni límite de aforo automático, así que usa una plataforma de entradas cuando necesites eso.

La mayoría de los eventos no necesitan una plataforma de entradas. Un meetup, un taller, una fiesta de lanzamiento, un club de lectura o una jornada gratuita de conferencias necesitan tres cosas: una página que diga qué y cuándo, un formulario que recoja quién viene y un número en el que puedas confiar el día antes. Esta guía monta eso en tu propio sitio y deja claro lo que un formulario no puede hacer.

El recorrido de un RSVP

El formulario vive en la página de tu evento. Cada RSVP se envía a Ikiform, que lo comprueba con tus reglas de campos, filtra el spam, lo guarda y te avisa. Desde ahí llega a lo que uses para organizar: el panel, una hoja de cálculo o un script que cuenta asistentes.

Cómo llega un RSVP desde la página de tu evento hasta tu recuento de asistentespágina deleventotu formulariode RSVPIkiformlímite deinvitados,filtra spampanelcada RSVP,exportar CSVemail aorganizadoresResponder va alinvitadowebhookfirmadosubmission.createdhoja oscriptúltimarespuesta poremailRSVPrecuentoCómo llega un RSVP desde la página de tu evento hasta tu recuento de asistentespágina deleventotu formulariode RSVPIkiformlímite deinvitados,filtra spampanelcada RSVP,exportar CSVemail aorganizadoresResponder va alinvitadowebhook firmadosubmission.createdhoja o scriptúltima respuestapor emailRSVPrecuento
  1. Un invitado rellena el formulario de RSVP en la página de tu evento y este se envía a tu endpoint de Ikiform.
  2. Ikiform comprueba los campos, incluido el límite de acompañantes, y puntúa el envío como posible spam antes de guardarlo.
  3. Cada RSVP aparece en el panel, donde puedes filtrarlo y exportarlo como CSV.
  4. Los organizadores reciben un email por cada RSVP, y al responder le escriben directamente al invitado.
  5. Ikiform envía un webhook submission.created firmado.
  6. Una hoja de cálculo o un script corto convierte los RSVP en un recuento de asistentes, usando la última respuesta de cada persona.
Ikiform guarda respuestas; el recuento es una suma que haces sobre ellas. Ese es el paso que una app de entradas haría por ti.

Lo que Ikiform no hace por tus eventos

Tenlo claro antes de elegir. Un backend de formularios recoge respuestas. No es un sistema de venta de entradas:

  • Sin límite de aforo. No hay ningún ajuste que cierre el formulario tras cierto número de RSVP o de invitados. Tú vigilas el recuento y pausas el formulario.
  • Sin entradas ni pagos. Sin códigos QR, sin app de control de acceso, sin niveles de pago, sin reembolsos.
  • Sin email al invitado. Ikiform no envía emails a la persona que rellena el formulario. Los emails de notificación solo van 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, activada por un webhook.
  • Sin lista de espera. Cuando pausas el formulario, los nuevos envíos se rechazan. Una lista de espera sería un segundo formulario que pones en su lugar.
  • Sin deduplicación. Ikiform no fusiona ni rechaza envíos repetidos por email. Una repetición idéntica en menos de 24 horas solo suma a la puntuación de spam. Elimina duplicados donde guardes la lista, o al exportar.

Cada uno de estos puntos tiene una solución viable más abajo. Si varios son decisivos para ti, una plataforma de entradas es mejor herramienta.

Formas de recibir RSVP

EnfoquePunto fuerteInconvenientes
Plataforma de entradas, como Eventbrite o LumaEntradas, pagos, límites de aforo, listas de espera, emails de confirmación y control de acceso, todo incluidoLa página del evento y la lista de asistentes viven en su plataforma con su marca. Las entradas de pago tienen comisiones; revisa sus páginas de precios
Google FormsGratis y rápido. Un interruptor para dejar de aceptar respuestasParece de Google, no de tu evento. Una página aparte y sin límite de acompañantes en el servidor
Invitación de calendario o chat de grupoSuficiente para veinte amigosSin números fiables, sin necesidades alimentarias y sin lista el día del evento
Tu propio formulario y un backend de formularios, como IkiformTu página, tu diseño, cualquier campo. Límite de acompañantes comprobado en el servidor, spam filtrado, aviso por email a los organizadores, CSV y webhooksCuentas asistentes, cierras la inscripción y envías confirmaciones tú mismo, o con un webhook a una herramienta de email

Para un evento de pago, usa una plataforma de entradas. Para un evento gratuito en el que la página y la lista deben seguir siendo tuyas, el resto de esta guía es la configuración. La página sobre Eventbrite compara ambas opciones con más detalle.

Campos que hacen posible la organización

Pregunta solo lo que vayas a usar. Cada pregunta de aquí cambia algo que pides, reservas u organizas. Pruébalo: la vista previa ejecuta el validador de Ikiform en tu navegador, así puedes ver el 422 que recibiría un cuarto acompañante.

Vista previa

Ejecuta el validador de Ikiform en tu navegador. No se envía nada.

¿Puedes venir?

Sin contarte a ti. Hasta 3.

Pega esta definición en la pestaña Fields del formulario e Ikiform la aplicará en cada envío, desde cualquier página. La plantilla de RSVP para eventos tiene una versión más corta con código generado.
CampoPor quéTen en cuenta
attendingUn No también es información: te evita perseguir a la genteUn radio con yes y no, para que el recuento sea un filtro
guestsEl número para el que pides comida y sillasUn number con min: 0, max: 3, integer: true. Ikiform rechaza 5 y 1.5 en el servidor
dietaryRecuento para el cateringUn select se suma sin problemas. El texto libre no
access_needsAcceso sin escalones, asientos, una sala tranquilaOpcional. Léelas todas antes del día
emailAvisar de cambios y relacionar respuestas modificadasTambién es la dirección de respuesta de cada email de notificación
Pide solo lo que el evento necesita. Las respuestas sobre alimentación y accesibilidad pueden ser datos de salud; explica en el formulario por qué las pides, guarda la exportación en un lugar privado y elimina los envíos cuando termine el evento.

El formulario de RSVP

Elige tu stack. Cada versión agradece de forma distinta un Sí y un No, oculta las preguntas sobre acompañantes ante un No y envía guests como 0 cuando alguien no viene, para que tus sumas cuadren.

Pega el formulario en la página del evento. Envía de la forma clásica y redirige a tu página de confirmación, así que funciona sin JavaScript. El script corto oculta las preguntas sobre acompañantes cuando alguien responde No y pone el número de acompañantes en 0.

event.html
<form id="rsvp" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label for="name">Name</label>
  <input id="name" name="name" autocomplete="name" required maxlength="120">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required>
  <fieldset>
    <legend>Can you make it?</legend>
    <label><input type="radio" name="attending" value="yes" required> Yes</label>
    <label><input type="radio" name="attending" value="no"> No</label>
  </fieldset>
  <div id="if-going">
    <label for="guests">Guests you're bringing</label>
    <input id="guests" name="guests" type="number" min="0" max="3" step="1" value="0">
    <label for="dietary">Dietary needs</label>
    <select id="dietary" name="dietary">
      <option value="none">None</option>
      <option value="vegetarian">Vegetarian</option>
      <option value="vegan">Vegan</option>
      <option value="gluten_free">Gluten free</option>
      <option value="other">Other, tell us below</option>
    </select>
    <label for="access_needs">Access needs or anything else</label>
    <textarea id="access_needs" name="access_needs" rows="3" maxlength="1000"></textarea>
  </div>
  <input type="hidden" name="_redirect" value="https://example.com/meetup/registered">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button type="submit">Send RSVP</button>
</form>
<script>
  const rsvp = document.getElementById("rsvp");
  const extra = document.getElementById("if-going");
  rsvp.addEventListener("change", () => {
    const no = rsvp.elements.attending.value === "no";
    extra.hidden = no;
    if (no) rsvp.elements.guests.value = "0";
  });
</script>
Las versiones del lado del servidor envían con una clave secreta, así que Ikiform se salta Allowed domains y su verificación humana. Todos los envíos llegan entonces desde la IP de tu servidor, y el límite Standard de 5 por minuto por visitante cuenta a todos tus visitantes juntos. Elige el límite de frecuencia Relaxed o Custom para un formulario que envías a través de un servidor, y guarda IKIFORM_SECRET_KEY en variables de entorno solo del servidor. Las versiones de servidor también reenvían la cabecera Origin del navegador cuando existe, porque el fetch propio de un servidor no envía ninguna e Ikiform la usa para contar los envíos de prueba gratuitos desde localhost.

Las guías por framework de la documentación profundizan más: Next.js, Astro, SvelteKit, Nuxt, React, Vue y HTML simple. En un creador de sitios, la versión HTML se pega en un bloque de embed.

Cuenta asistentes a partir de la última respuesta

La gente cambia de opinión. Alguien dice Sí con dos acompañantes el lunes y No el jueves; son dos envíos, y el segundo es el que vale. Así que la regla es: una respuesta por email, la más reciente, y luego cuentas uno por la persona más sus acompañantes.

Por qué el recuento usa el RSVP más reciente de cada personaAda: sí2acompañantesBen: sí0acompañantesAda: nocambió deidea1personasolo Bengana la últimaLunesMiércolesJuevesrecuentoPor qué el recuento usa el RSVP más reciente de cada personaAda:sí2acompañantesBen:sí0acompañantesAda:nocambiódeidea1personasoloBengana la últimaLunesMiércolesJuevesrecuento
  1. Lunes: Ada responde que sí con 2 acompañantes. Sumar todos los envíos contaría 3 personas.
  2. Miércoles: Ben responde que sí sin acompañantes.
  3. Jueves: Ada vuelve a enviar el formulario y dice que no. Ikiform lo guarda como un segundo envío suyo.
  4. Tomando solo el envío más reciente de cada email, Ada es un no, así que el recuento es 1: Ben.
Sumar todas las filas contaría el grupo de tres de Ada. Contar la fila más reciente por email da el número correcto.

En una hoja de cálculo

  1. En Submissions (envíos), elige el formulario de RSVP, pon el estado en Received y el rango de fechas en All time, y luego Export CSV.
  2. Impórtalo en Google Sheets y ordénalo por created_at, del más reciente al más antiguo.
  3. Selecciona los datos y usa Data > Data cleanup > Remove duplicates sobre la columna email. Sheets conserva la primera fila que encuentra, que ahora es la más reciente.
  4. Cuenta, con attending en la columna G y guests en la columna H. Ajusta las letras a tu exportación:
Google Sheets
=COUNTIF(G2:G, "yes") + SUMIF(G2:G, "yes", H2:H)

La exportación tiene primero id, created_at, form y status, y luego una columna por campo. Un archivo contiene hasta 100.000 filas.

Con un script

Para obtener un número que puedas recalcular en cualquier momento, lee los RSVP con la API REST. Las listas vienen de la más reciente a la más antigua, así que el primer envío que aparece para cada email es el último. Ejecuta esto con Node y una clave de API secreta:

headcount.ts
import { createClient } from "@ikiform/sdk";

const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });
const latest = new Map<string, Record<string, unknown>>();

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 && !latest.has(email)) latest.set(email, submission.fields);
}

let people = 0;
const meals = new Map<string, number>();
for (const fields of latest.values()) {
  if (fields.attending !== "yes") continue;
  people += 1 + Number(fields.guests ?? 0);
  const meal = String(fields.dietary ?? "none");
  meals.set(meal, (meals.get(meal) ?? 0) + 1);
}

console.log(`${latest.size} people replied. ${people} are coming, guests included.`);
console.table(Object.fromEntries(meals));

La tabla de comidas cuenta RSVP, no personas, porque un formulario no puede decir qué come cada acompañante. Si las comidas de los invitados importan, como en una boda, pregunta por persona; la página de RSVP para bodas muestra cómo.

Cerrar la inscripción cuando se llena

Ikiform no detiene el formulario al llegar a un número, así que prepara dos cosas: un aviso antes de llenarte y una forma de cerrar. Cierra en dos sitios, el formulario y la página:

  1. En los ajustes del formulario, elige Pause form. A partir de ahí, los envíos se rechazan con 403 form_paused, así que ni una pestaña antigua ni un bot pueden añadir más.
  2. Sustituye el formulario de la página del evento por una frase como Registration is closed. Email us to join the waitlist. Los visitantes nunca deberían toparse con el error.
  3. Si reabres, elige Resume form y vuelve a poner el formulario.

El aviso puede ser un manejador de webhook que recuenta con cada Sí y publica en un webhook de chat, como el de Slack, cuando superas el 90 % del aforo. Esto es un route handler de Next.js; la misma lógica funciona en cualquier servidor:

app/api/rsvp-alert/route.ts
import { createClient } from "@ikiform/sdk";
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";

const CAPACITY = 80;
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });

async function peopleComing(formId: string) {
  const seen = new Set<string>();
  let people = 0;
  for await (const submission of ikiform.submissions.iterate({ formId, status: "received", limit: 100 })) {
    const email = String(submission.fields.email ?? "").trim().toLowerCase();
    if (!email || seen.has(email)) continue;
    seen.add(email);
    if (submission.fields.attending === "yes") people += 1 + Number(submission.fields.guests ?? 0);
  }
  return people;
}

export async function POST(request: Request) {
  const payload = await request.text();
  try {
    const event = await verifyWebhook({
      payload,
      headers: request.headers,
      secret: process.env.IKIFORM_WEBHOOK_SECRET!,
    });
    if (event.type !== "submission.created" || event.data.fields.attending !== "yes") {
      return new Response(null, { status: 204 });
    }
    const people = await peopleComing(event.data.form.id);
    if (people >= CAPACITY * 0.9) {
      await fetch(process.env.ALERT_WEBHOOK_URL!, {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          text: `${people} of ${CAPACITY} places taken. Pause the RSVP form in Ikiform when you're full.`,
        }),
      });
    }
    return new Response(null, { status: 204 });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
}
  • Recuenta mediante la API cada vez, así que un cambio de respuesta se refleja. Cada clave puede hacer 100 peticiones a la API por minuto, lo que alcanza para varios miles de RSVP por recuento.
  • El aviso le dice a una persona que pause. Pausar es una acción del panel, así que nada se cierra por sorpresa.
  • Añade el endpoint en Webhooks y copia su secreto en IKIFORM_WEBHOOK_SECRET. Un espacio de trabajo puede tener 3 endpoints; la documentación de webhooks explica los reintentos.
De la inscripción abierta a la cerrada, sin nada automáticoabiertoformularioen la páginaaviso al90 %el webhookrecuentaPauseform403form_pausedla páginadicecerradolista deespera poremailconfirmacionestú decidesDe la inscripción abierta a la cerrada, sin nada automáticoabiertoformulario en la páginaaviso al 90 %el webhook recuentaPause form403 form_pausedla página dice cerradolista de espera por emailconfirmacionestú decides
  1. Mientras la inscripción está abierta, cada RSVP se envía a Ikiform.
  2. Tu manejador de webhook recuenta las últimas respuestas con cada Sí y te avisa al 90 % del aforo.
  3. Tú decides cuándo estás lleno y eliges Pause form, que rechaza los nuevos envíos con 403 form_paused.
  4. Sustituyes el formulario de la página por un mensaje de cierre y una forma de apuntarse a una lista de espera.
Una persona toma la decisión de cerrar. Es más lento que el tope fijo de una app de entradas, y significa que un cambio de planes de última hora nunca deja fuera a alguien a quien habrías dejado entrar.

Confirmaciones sin email de confirmación

Ikiform no envía emails al invitado, así que dale lo que necesita en la página de agradecimiento: la fecha, la hora, la dirección y un archivo de calendario. Un archivo .ics estático junto a la página funciona en cualquier app de calendario. Enlázalo desde la página de confirmación como Add to calendar:

meetup.ics
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Meetup//RSVP//EN
BEGIN:VEVENT
UID:meetup-2027-03-14@example.com
DTSTAMP:20261025T090000Z
DTSTART:20270314T183000Z
DTEND:20270314T210000Z
SUMMARY:Example meetup
LOCATION:The Old Library, 12 High Street, London
DESCRIPTION:Doors at 6:30 pm. Reply to the organiser if your plans change.
END:VEVENT
END:VCALENDAR

Las horas que terminan en Z están en UTC, así que las apps de calendario las muestran en la zona horaria de cada invitado. Si quieres un email de confirmación de verdad, envía cada RSVP por webhook a tu herramienta de email, directamente o a través de Zapier, Make o n8n, y mándalo desde ahí. La misma lista recibe después el recordatorio del día antes.

Respuestas modificadas y cancelaciones

Explica a la gente cómo cambiar su respuesta: Plans changed? Send the form again with the same email. Tu recuento ya usa la respuesta más reciente, así que no hace falta nada más. Las notificaciones muestran cada cambio en el momento, lo que resulta útil la semana del evento.

Dos personas en la misma Wi-Fi comparten dirección IP, y el límite de frecuencia cuenta por IP. El preset por defecto, Standard, con 5 por minuto por visitante, basta para la página de un evento. No pongas un límite Custom de un envío al día para frenar repeticiones: bloquea a un segundo miembro del hogar en la misma red, y la regla de la última respuesta ya resuelve las repeticiones.

El día del evento

Exporta los RSVP, elimina duplicados como arriba, filtra por attending = yes, ordena por nombre e imprímelo. Añade columnas para marcar la llegada y para los acompañantes que llegaron. Una lista impresa funciona cuando en el local no hay cobertura. Deja la columna de accesibilidad en la copia del equipo de la puerta, y la de alimentación en la del catering.

El spam no llega a tu lista: el honeypot, la puntuación de spam y los límites de frecuencia lo filtran antes de que cuente, y el spam no envía emails ni webhooks. Revisa una vez el filtro Spam antes de imprimir, por si un RSVP real con un mensaje poco habitual acabó ahí. Las direcciones desechables suman 2 a la puntuación de spam.

Elige tu caso

Una boda, un evento comunitario gratuito y un turno de voluntarios se cuentan de forma distinta. Estas páginas explican qué cambia.

Comprueba que funciona

Prueba el circuito completo una semana antes de anunciar el evento. Ikiform no tiene plan gratuito. Probar es gratis: un espacio de trabajo sin plan acepta 50 envíos de prueba al mes desde localhost. Para pasar a producción, elige Pro desde 6 $/mes por 500 envíos, o paga una sola vez: 10.000 envíos por 49 $ o 50.000 envíos por 149 $, con créditos que nunca caducan. Consulta los precios.

  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 lugar.
  2. Envía un Sí con dos acompañantes y un No desde emails distintos. Llegan ambos, y el No muestra guests como 0.
  3. Envía tres acompañantes y luego cuatro. El cuarto se rechaza con Must be at most 3.
  4. Revisa la bandeja de entrada de cada destinatario de las notificaciones. Cada uno recibe un email con los campos, y Reply va a quien envió el formulario cuando este tiene un campo email.
  5. Ejecuta el script de recuento o la fórmula de la hoja. Debería coincidir con lo que enviaste.
  6. Pausa el formulario y envía una vez más. Recibes 403 form_paused. Reanúdalo.
  7. Envía con el honeypot relleno, _gotcha=bot. Igualmente recibe una respuesta de éxito, pero el envío se guarda como spam y no envía email ni webhook.
  8. ¿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.

Solución de problemas

ProblemaQué hacer
El recuento sale demasiado altoEstás sumando todos los envíos. Quédate solo con el más reciente por email, y comprueba que un No envía guests como 0.
403 form_paused en la página publicadaEl formulario está en pausa en el panel. Reanúdalo, o sustituye el formulario de la página por un mensaje de cierre.
422 validation_failed que menciona guestsMás acompañantes que el max del campo, o un decimal. Muestra el mensaje de Ikiform junto al campo, como hacen los ejemplos.
403 origin_not_allowed, o todos los envíos acaban en spamEl dominio de la página no está en Allowed domains del formulario. Añádelo, y localhost para las pruebas locales. Los subdominios de un dominio de la lista están permitidos.
429 rate_limitedUn 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.
El envío está en el panel pero no llegó ningún email ni webhookSe guardó como spam. El spam no envía nada. Ábrelo en el filtro Spam para ver los motivos y márcalo como no spam para enviar su email y sus webhooks.
El navegador acaba en la página de agradecimiento de Ikiform en lugar de la tuya_redirect se ignora salvo que su dominio esté en Allowed domains y sea una URL https:. Añade el dominio, o configura Redirect after submit en los ajustes del formulario.

Preguntas

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