Guides

Guides15 min de lecture

Formulaires d'inscription et de RSVP pour événements sur votre propre site

Recevez les RSVP sur votre page d'événement : formulaire, limite d'invités, décompte fiable, clôture quand c'est complet et liste d'accueil, sans billetterie.

Preet SutharFondateur, Ikiform

Placez sur votre page d'événement un formulaire de RSVP qui envoie vers un backend de formulaires, avec une réponse oui ou non, un nombre d'invités plafonné côté serveur et les détails utiles à l'organisation. Comptez les participants à partir de la dernière réponse de chaque e-mail, avec un export CSV ou un petit script, et mettez le formulaire en pause quand c'est complet. Ikiform stocke et transmet chaque RSVP mais ne gère ni billetterie, ni paiements, ni plafond de places automatique : utilisez une plateforme de billetterie si vous en avez besoin.

La plupart des événements n'ont pas besoin d'une plateforme de billetterie. Un meetup, un atelier, une soirée de lancement, un club de lecture ou une journée de conférence gratuite demandent trois choses : une page qui dit quoi et quand, un formulaire qui recueille qui vient, et un chiffre fiable la veille. Ce guide met tout cela en place sur votre propre site, en étant clair sur ce qu'un formulaire ne sait pas faire.

Le parcours d'un RSVP

Le formulaire se trouve sur votre page d'événement. Chaque RSVP est envoyé à Ikiform, qui le vérifie selon vos règles de champs, filtre le spam, le stocke et vous prévient. Ensuite, il arrive dans l'outil avec lequel vous organisez : le tableau de bord, un tableur ou un script qui compte les participants.

Comment un RSVP passe de votre page d'événement à votre décomptepaged'événementvotreformulaireRSVPIkiformvérifie lalimite, filtrele spamtableau debordchaque RSVP,export CSVe-mail auxorganisateursRépondre écrità l'invitéwebhooksignésubmission.createdtableur ouscriptdernièreréponse pare-mailRSVPdécompteComment un RSVP passe de votre page d'événement à votre décomptepaged'événementvotreformulaireRSVPIkiformvérifie lalimite, filtrele spamtableau de bordchaque RSVP,export CSVe-mail auxorganisateursRépondre écrit àl'invitéwebhook signésubmission.createdtableur ouscriptdernière réponsepar e-mailRSVPdécompte
  1. Un invité remplit le formulaire de RSVP sur votre page d'événement, qui l'envoie à votre endpoint Ikiform.
  2. Ikiform vérifie les champs, y compris la limite d'invités, et évalue le spam avant de stocker l'envoi.
  3. Chaque RSVP apparaît dans le tableau de bord, où vous pouvez le filtrer et l'exporter en CSV.
  4. Les organisateurs reçoivent un e-mail pour chaque RSVP, et Répondre écrit directement à l'invité.
  5. Ikiform envoie un webhook submission.created signé.
  6. Un tableur ou un petit script transforme les RSVP en décompte, à partir de la dernière réponse de chaque personne.
Ikiform stocke les réponses ; le décompte est une somme que vous calculez dessus. C'est l'étape qu'une billetterie ferait pour vous.

Ce qu'Ikiform ne fait pas pour les événements

Soyez au clair là-dessus avant de choisir. Un backend de formulaires recueille des réponses. Ce n'est pas un système de billetterie :

  • Pas de plafond de places. Aucun réglage ne ferme le formulaire après un certain nombre de RSVP ou d'invités. Vous surveillez le décompte et mettez vous-même le formulaire en pause.
  • Ni billets ni paiements. Pas de QR codes, pas d'appli d'accueil, pas de tarifs payants, pas de remboursements.
  • Pas d'e-mail à l'invité. Ikiform n'envoie pas d'e-mail à la personne qui remplit le formulaire. Les e-mails de notification vont uniquement à vous et à votre équipe : il n'y a donc ni réponse automatique, ni e-mail de confirmation, ni double opt-in. Envoyez-les depuis votre outil d'e-mailing, déclenché par un webhook.
  • Pas de liste d'attente. Quand vous mettez le formulaire en pause, les nouveaux envois sont refusés. Une liste d'attente serait un second formulaire que vous mettez à sa place.
  • Pas de dédoublonnage. Ikiform ne fusionne ni ne rejette les soumissions répétées par e-mail. Une répétition identique dans les 24 heures ne fait qu'augmenter le score de spam. Dédoublonnez là où vit la liste, ou au moment de l'export.

Chacun de ces points a une solution praticable ci-dessous. Si plusieurs sont rédhibitoires, une plateforme de billetterie est le meilleur outil.

Les façons de recueillir des RSVP

ApprochePoints fortsCompromis
Plateforme de billetterie, comme Eventbrite ou LumaBillets, paiements, limites de places, listes d'attente, e-mails de confirmation et accueil, tout est inclusLa page de l'événement et la liste des participants vivent sur leur plateforme, avec leur marque. Les billets payants ont des frais ; consultez leurs pages de tarifs
Google FormsGratuit et rapide. Un interrupteur pour ne plus accepter de réponsesRessemble à Google, pas à votre événement. Une page à part, et pas de limite d'invités côté serveur
Invitation d'agenda ou groupe de discussionSuffisant pour vingt amisAucun chiffre fiable, pas de régimes alimentaires et pas de liste le jour J
Votre propre formulaire et un backend de formulaires, comme IkiformVotre page, votre design, tous les champs voulus. Limite d'invités vérifiée côté serveur, spam filtré, organisateurs prévenus par e-mail, CSV et webhooksVous comptez les participants, fermez les inscriptions et envoyez les confirmations vous-même, ou via un webhook vers un outil d'e-mailing

Pour un événement payant, utilisez une plateforme de billetterie. Pour un événement gratuit dont la page et la liste doivent rester à vous, la suite de ce guide est la mise en place. La page Eventbrite compare les deux plus en détail.

Des champs qui rendent l'organisation possible

Ne demandez que ce sur quoi vous allez agir. Chaque question ici change quelque chose que vous commandez, réservez ou organisez. Essayez : l'aperçu exécute le validateur d'Ikiform dans votre navigateur, vous voyez donc le 422 que recevrait un quatrième invité.

Aperçu

Exécute le validateur d'Ikiform dans votre navigateur. Rien n'est envoyé.

Serez-vous là ?

Sans vous compter. Jusqu'à 3.

Collez cette définition dans l'onglet Fields du formulaire et Ikiform l'applique à chaque envoi, depuis n'importe quelle page. Le modèle de RSVP d'événement en propose une version plus courte avec du code généré.
ChampPourquoiÀ garder en tête
attendingUn Non est aussi une information : il vous évite de relancer les gensUn radio avec yes et no, pour que le décompte soit un filtre
guestsLe nombre pour lequel vous commandez repas et chaisesUn number avec min: 0, max: 3, integer: true. Ikiform refuse 5 et 1.5 côté serveur
dietaryLe décompte pour le traiteurUn select s'additionne proprement. Le texte libre, non
access_needsAccès de plain-pied, places assises, salle calmeFacultatif. Lisez chaque réponse avant le jour J
emailPrévenir les gens des changements et rapprocher les réponses modifiéesSert aussi d'adresse de réponse pour chaque e-mail de notification
Ne demandez que ce dont l'événement a besoin. Les réponses sur l'alimentation et l'accessibilité peuvent être des données de santé : indiquez sur le formulaire pourquoi vous les demandez, gardez l'export dans un endroit privé et supprimez les soumissions une fois l'événement passé.

Le formulaire de RSVP

Choisissez votre stack. Chaque version remercie différemment un Oui et un Non, masque les questions sur les invités pour un Non et envoie guests à 0 quand quelqu'un ne vient pas, pour que vos totaux restent justes.

Collez le formulaire dans la page de l'événement. Il envoie de façon classique et redirige vers votre page de confirmation, il fonctionne donc sans JavaScript. Le petit script masque les questions sur les invités quand quelqu'un répond Non et remet le nombre d'invités à 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>
Les versions côté serveur envoient avec une clé secrète, donc Ikiform ignore Allowed domains et sa vérification humaine. Chaque envoi vient alors de l'IP de votre serveur, et la limite Standard de 5 par minute et par visiteur compte tous vos visiteurs ensemble. Choisissez la limite de débit Relaxed ou Custom pour un formulaire que vous envoyez via un serveur, et gardez IKIFORM_SECRET_KEY dans des variables d'environnement réservées au serveur. Les versions serveur transmettent aussi l'en-tête Origin du navigateur quand il existe, car le fetch d'un serveur n'en envoie aucun et Ikiform s'en sert pour compter les soumissions de test gratuites depuis localhost.

Les guides par framework de la documentation vont plus loin : Next.js, Astro, SvelteKit, Nuxt, React, Vue et HTML simple. Sur un créateur de sites, la version HTML se colle dans un bloc d'intégration.

Compter à partir de la dernière réponse

Les gens changent d'avis. Quelqu'un répond Oui avec deux invités le lundi et Non le jeudi : cela fait deux soumissions, et c'est la seconde qui compte. La règle est donc : une réponse par e-mail, la plus récente, puis on compte un pour la personne plus ses invités.

Pourquoi le décompte utilise le dernier RSVP de chaque personneAda : oui2 invitésBen : oui0 invitéAda : nona changéd'avis1personneBen seulla dernière gagneLundiMercrediJeudidécomptePourquoi le décompte utilise le dernier RSVP de chaque personneAda :oui2invitésBen :oui0invitéAda :nonachangéd'avis1personneBenseulla dernière gagneLundiMercrediJeudidécompte
  1. Lundi : Ada répond oui avec 2 invités. Additionner toutes les soumissions compterait 3 personnes.
  2. Mercredi : Ben répond oui sans invité.
  3. Jeudi : Ada renvoie le formulaire et répond non. Ikiform le stocke comme une deuxième soumission de sa part.
  4. En ne gardant que la soumission la plus récente de chaque e-mail, Ada a répondu non : le décompte est donc de 1, Ben.
Additionner toutes les lignes compterait le groupe de trois d'Ada. Compter la ligne la plus récente par e-mail donne le bon chiffre.

Dans un tableur

  1. Dans Submissions, choisissez le formulaire de RSVP, réglez le statut sur Received et la période sur All time, puis cliquez sur Export CSV.
  2. Importez-le dans Google Sheets et triez par created_at, du plus récent au plus ancien.
  3. Sélectionnez les données et utilisez Données > Nettoyage des données > Supprimer les doublons sur la colonne email. Sheets garde la première ligne qu'il rencontre, qui est désormais la plus récente.
  4. Comptez, avec attending en colonne G et guests en colonne H. Adaptez les lettres à votre export :
Google Sheets
=COUNTIF(G2:G, "yes") + SUMIF(G2:G, "yes", H2:H)

L'export contient d'abord id, created_at, form et status, puis une colonne par champ. Un fichier contient jusqu'à 100 000 lignes.

Avec un script

Pour un chiffre que vous pouvez recalculer à tout moment, lisez les RSVP via l'API REST. Les listes arrivent de la plus récente à la plus ancienne, donc la première soumission vue pour chaque e-mail est la dernière. Lancez ceci avec Node et une clé d'API secrète :

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));

Le tableau des repas compte des RSVP, pas des personnes, car un seul formulaire ne peut pas dire quel invité mange quoi. Si les repas de chaque invité comptent, comme pour un mariage, demandez-les par personne ; la page sur les RSVP de mariage montre comment faire.

Fermer les inscriptions quand c'est complet

Ikiform n'arrête pas le formulaire à un chiffre donné : mettez donc en place deux choses, une alerte avant d'être complet et un moyen de fermer. Fermez à deux endroits, le formulaire et la page :

  1. Dans les réglages du formulaire, choisissez Pause form. Dès lors, les envois sont refusés avec 403 form_paused, ainsi un onglet resté ouvert ou un bot ne peut plus en ajouter.
  2. Remplacez le formulaire de votre page d'événement par une phrase comme Registration is closed. Email us to join the waitlist. Les visiteurs ne doivent jamais tomber sur l'erreur.
  3. Si vous rouvrez, choisissez Resume form et remettez le formulaire en place.

L'alerte peut être un gestionnaire de webhook qui recompte à chaque Oui et poste sur le webhook d'une messagerie, comme celui de Slack, une fois 90 % de la capacité dépassés. Voici un route handler Next.js ; la même logique tourne sur n'importe quel serveur :

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;
  }
}
  • Il recompte via l'API à chaque fois, donc une réponse modifiée est prise en compte. Chaque clé peut faire 100 requêtes d'API par minute, ce qui couvre plusieurs milliers de RSVP par décompte.
  • L'alerte demande à une personne de mettre en pause. La pause est une action du tableau de bord, donc rien ne ferme par surprise.
  • Ajoutez l'endpoint sous Webhooks et copiez son secret dans IKIFORM_WEBHOOK_SECRET. Un espace de travail peut avoir 3 endpoints ; la documentation des webhooks couvre les nouvelles tentatives.
Des inscriptions ouvertes à fermées, sans rien d'automatiqueouvertformulairesur la pagealerte à90 %le webhookrecomptePauseform403form_pausedpage« complet »listed'attentepar e-mailles RSVPvous décidezDes inscriptions ouvertes à fermées, sans rien d'automatiqueouvertformulaire sur la pagealerte à 90 %le webhook recomptePause form403 form_pausedpage « complet »liste d'attente par e-mailles RSVPvous décidez
  1. Tant que les inscriptions sont ouvertes, chaque RSVP est envoyé à Ikiform.
  2. Votre gestionnaire de webhook recompte les dernières réponses à chaque Oui et vous alerte à 90 % de la capacité.
  3. Vous décidez quand c'est complet et choisissez Pause form, qui refuse les nouveaux envois avec 403 form_paused.
  4. Vous remplacez le formulaire de la page par un message de clôture et un moyen de rejoindre une liste d'attente.
C'est une personne qui décide de fermer. C'est plus lent que le plafond strict d'une billetterie, mais un changement de dernière minute ne bloque jamais quelqu'un que vous auriez laissé entrer.

Des confirmations sans e-mail de confirmation

Ikiform n'envoie pas d'e-mail à l'invité : donnez-lui donc ce dont il a besoin sur la page de remerciement, avec la date, l'heure, l'adresse et un fichier de calendrier. Un fichier .ics statique à côté de la page fonctionne dans toutes les applis d'agenda. Faites-y un lien depuis la page de confirmation sous le libellé 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

Les heures qui se terminent par Z sont en UTC, les applis d'agenda les affichent donc dans le fuseau horaire de chaque invité. Si vous voulez un vrai e-mail de confirmation, envoyez chaque RSVP par webhook à votre outil d'e-mailing, directement ou via Zapier, Make ou n8n, et envoyez-le depuis cet outil. La même liste reçoit ensuite le rappel la veille.

Réponses modifiées et annulations

Dites aux gens comment changer leur réponse : Plans changed? Send the form again with the same email. Votre décompte utilise déjà la réponse la plus récente, il n'y a donc rien d'autre à faire. Les notifications affichent chaque changement en temps réel, ce qui est utile la semaine de l'événement.

Deux personnes sur le même Wi-Fi partagent une adresse IP, et la limite de débit compte par IP. La limite par défaut (Standard, 5 par minute et par visiteur) convient à une page d'événement. Ne définissez pas de limite Custom d'un envoi par jour pour empêcher les répétitions : cela bloque un deuxième membre du foyer sur le même réseau, et la règle de la dernière réponse gère déjà les répétitions.

Le jour J

Exportez les RSVP, supprimez les doublons comme ci-dessus, filtrez sur attending = yes, triez par nom et imprimez. Ajoutez des colonnes pour cocher les arrivées et les invités présents. Une liste imprimée fonctionne quand le réseau du lieu ne passe pas. Gardez la colonne des besoins d'accessibilité sur l'exemplaire de l'équipe d'accueil, et la colonne alimentaire sur celui du traiteur.

Le spam n'atteint pas votre liste : le honeypot, le score de spam et les limites de débit le filtrent avant qu'il ne compte, et le spam n'envoie ni e-mail ni webhook. Vérifiez une fois le filtre Spam avant d'imprimer, au cas où un vrai RSVP avec un message inhabituel s'y serait retrouvé. Les adresses jetables ajoutent 2 au score de spam.

Choisissez votre cas

Un mariage, un événement associatif gratuit et un planning de bénévoles se comptent chacun différemment. Ces pages couvrent ce qui change.

Vérifiez que tout fonctionne

Testez toute la boucle une semaine avant d'annoncer l'événement. Ikiform n'a pas d'offre gratuite. Les tests sont gratuits : un espace de travail sans offre accepte 50 soumissions de test par mois depuis localhost. Pour passer en production, choisissez Pro à partir de 6 $/mois pour 500 soumissions, ou payez une seule fois : 10 000 soumissions pour 49 $ ou 50 000 soumissions pour 149 $, avec des crédits qui n'expirent jamais. Voir les tarifs.

  1. Dans Allowed domains du formulaire, ajoutez le domaine de votre site, plus localhost pendant le développement. Laissez vide pour accepter les envois de partout.
  2. Envoyez un Oui avec deux invités et un Non depuis deux e-mails différents. Les deux arrivent, et le Non affiche guests à 0.
  3. Envoyez trois invités, puis quatre. Le quatrième est refusé avec Must be at most 3.
  4. Vérifiez la boîte de réception de chaque destinataire des notifications. Chacun reçoit un e-mail avec les champs, et Reply répond à l'expéditeur quand le formulaire a un champ email.
  5. Lancez le script de décompte ou la formule du tableur. Le résultat doit correspondre à ce que vous avez envoyé.
  6. Mettez le formulaire en pause et envoyez-le encore une fois. Vous recevez 403 form_paused. Relancez-le.
  7. Envoyez avec le honeypot rempli, _gotcha=bot. L'envoi reçoit quand même une réponse de succès, mais la soumission est stockée comme spam et n'envoie ni e-mail ni webhook.
  8. Rien n'est arrivé ? Passez le filtre de statut du tableau de bord sur Spam. Le spam reçoit la même réponse de succès qu'une vraie soumission.

Dépannage

ProblèmeQue faire
Le décompte est trop élevéVous additionnez toutes les soumissions. Ne gardez que la plus récente par e-mail, et vérifiez qu'un Non envoie guests à 0.
403 form_paused sur la page en ligneLe formulaire est en pause dans le tableau de bord. Relancez-le, ou remplacez le formulaire de la page par un message de clôture.
422 validation_failed mentionnant guestsPlus d'invités que le max du champ, ou un nombre décimal. Affichez le message d'Ikiform à côté du champ, comme le font les exemples.
403 origin_not_allowed, ou tous les envois finissent en spamLe domaine de la page n'est pas dans les Allowed domains du formulaire. Ajoutez-le, plus localhost pour les tests en local. Les sous-domaines d'un domaine listé sont autorisés.
429 rate_limitedUn visiteur a envoyé plus que ce que permet la limite de débit du formulaire. Standard autorise 5 envois par minute et par visiteur. Attendez la durée de Retry-After, ou choisissez Relaxed ou Custom pour les formulaires qui envoient depuis une seule IP partagée.
La soumission est dans le tableau de bord mais aucun e-mail ni webhook n'est arrivéElle a été stockée comme spam. Le spam n'envoie rien. Ouvrez-la sous le filtre Spam pour voir les raisons, et marquez-la comme non-spam pour envoyer son e-mail et ses webhooks.
Le navigateur arrive sur la page de remerciement d'Ikiform au lieu de la vôtre_redirect est ignoré sauf si son domaine figure dans Allowed domains et qu'il s'agit d'une URL https:. Ajoutez le domaine, ou définissez plutôt Redirect after submit dans les réglages du formulaire.

Questions

Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.