Guias

Guias15 min de leitura

Formulários de inscrição e RSVP para eventos no seu próprio site

Receba confirmações de presença na página do seu evento: formulário, limite de convidados, contagem honesta, encerramento ao lotar e lista de check-in, sem app de ingressos.

Preet SutharFundador, Ikiform

Coloque um formulário de RSVP na página do evento que envia para um backend de formulários, com resposta sim ou não, número de convidados limitado no servidor e os detalhes de que você precisa para planejar. Conte as pessoas a partir da resposta mais recente de cada e-mail, usando uma exportação CSV ou um script curto, e pause o formulário quando lotar. O Ikiform armazena e encaminha cada RSVP, mas não tem venda de ingressos, pagamentos nem limite automático de vagas; use uma plataforma de ingressos quando precisar disso.

A maioria dos eventos não precisa de uma plataforma de ingressos. Um meetup, um workshop, uma festa de lançamento, um clube de leitura ou um dia de conferência gratuito precisam de três coisas: uma página que diga o quê e quando, um formulário que registre quem vem e um número em que você possa confiar na véspera. Este guia monta isso no seu próprio site e deixa claro o que um formulário não consegue fazer.

O caminho de um RSVP

O formulário fica na página do evento. Cada RSVP é enviado ao Ikiform, que o confere com as regras dos seus campos, filtra spam, armazena e avisa você. Dali ele chega a onde você planeja: o painel, uma planilha ou um script que conta as pessoas.

Como um RSVP sai da página do evento e chega à sua contagempágina doeventoseu formuláriode RSVPIkiformconfere olimite deconvidados,filtra spampainelcada RSVP,exportação CSVe-mail aosorganizadoresReply vai aoconvidadowebhookassinadosubmission.createdplanilha ouscriptúltima respostapor e-mailRSVPcontagemComo um RSVP sai da página do evento e chega à sua contagempágina doeventoseu formuláriode RSVPIkiformconfere olimite deconvidados,filtra spampainelcada RSVP,exportação CSVe-mail aosorganizadoresReply vai aoconvidadowebhookassinadosubmission.createdplanilha ouscriptúltima resposta pore-mailRSVPcontagem
  1. Um convidado preenche o formulário de RSVP na página do evento, e ele é enviado ao seu endpoint do Ikiform.
  2. O Ikiform confere os campos, incluindo o limite de convidados, e dá uma pontuação de spam ao envio antes de armazená-lo.
  3. Cada RSVP aparece no painel, onde você pode filtrá-lo e exportá-lo como CSV.
  4. Os organizadores recebem um e-mail para cada RSVP, e o Reply vai direto para o convidado.
  5. O Ikiform envia um webhook submission.created assinado.
  6. Uma planilha ou um script curto transforma os RSVPs em uma contagem, usando a resposta mais recente de cada pessoa.
O Ikiform armazena as respostas; a contagem é uma soma que você faz sobre elas. Esse é o passo que um app de ingressos faria por você.

O que o Ikiform não faz por eventos

Tenha isto claro antes de escolher. Um backend de formulários coleta respostas. Ele não é um sistema de ingressos:

  • Sem limite de vagas. Não existe uma configuração que feche o formulário depois de um número de RSVPs ou de convidados. Você acompanha a contagem e pausa o formulário por conta própria.
  • Sem ingressos nem pagamentos. Sem QR codes, sem app de check-in, sem categorias pagas, sem reembolsos.
  • Sem e-mail para o convidado. O Ikiform não envia e-mail para quem preenche o formulário. Os e-mails de notificação vão só para você e sua equipe, então não há resposta automática, e-mail de confirmação nem double opt-in. Envie esses e-mails pela sua ferramenta de e-mail, disparados por um webhook.
  • Sem lista de espera. Quando você pausa o formulário, novos envios são recusados. Uma lista de espera seria um segundo formulário colocado no lugar dele.
  • Sem deduplicação. O Ikiform não mescla nem rejeita envios repetidos pelo e-mail. Uma repetição idêntica em até 24 horas só aumenta a pontuação de spam. Remova os duplicados onde a lista fica, ou na hora de exportar.

Cada um desses pontos tem uma solução viável mais abaixo. Se vários deles forem decisivos para você, uma plataforma de ingressos é a ferramenta certa.

Formas de receber RSVPs

AbordagemBom emContras
Plataforma de ingressos, como Eventbrite ou LumaIngressos, pagamentos, limite de vagas, listas de espera, e-mails de confirmação e check-in, tudo incluídoA página do evento e a lista de participantes ficam na plataforma deles, com a marca deles. Ingressos pagos têm taxas; confira as páginas de preços
Google FormsGratuito e rápido. Um botão para parar de aceitar respostasParece o Google, não o seu evento. Uma página separada e nenhum limite de convidados no servidor
Convite de calendário ou grupo de mensagensServe para vinte amigosNenhum número confiável, nada de restrições alimentares e nenhuma lista no dia
Seu próprio formulário e um backend de formulários, como o IkiformSua página, seu design, quaisquer campos. Limite de convidados conferido no servidor, spam filtrado, organizadores avisados por e-mail, CSV e webhooksVocê conta as pessoas, encerra as inscrições e envia as confirmações por conta própria, ou com um webhook para uma ferramenta de e-mail

Para um evento pago, use uma plataforma de ingressos. Para um evento gratuito em que a página e a lista devem continuar suas, o resto deste guia é a configuração. A página sobre o Eventbrite compara os dois com mais detalhes.

Campos que tornam o planejamento possível

Pergunte só o que vai fazer você agir. Cada pergunta aqui muda algo que você encomenda, reserva ou organiza. Experimente: a prévia roda o validador do Ikiform no seu navegador, então você vê o 422 que um quarto convidado receberia.

Prévia

Roda o validador do Ikiform no seu navegador. Nada é enviado.

Você vai conseguir ir?

Sem contar você. Até 3.

Cole esta definição na aba Fields do formulário e o Ikiform a aplica em todo envio, vindo de qualquer página. O modelo de RSVP para eventos tem uma versão mais curta com código gerado.
CampoPor quêLembre-se
attendingUm Não também é informação: evita que você fique cobrando as pessoasUm radio com yes e no, para a contagem ser um filtro
guestsO número para o qual você encomenda comida e cadeirasUm number com min: 0, max: 3, integer: true. O Ikiform recusa 5 e 1.5 no servidor
dietaryContagem para o buffetUm select soma de forma limpa. Texto livre não
access_needsAcesso sem degraus, assentos, uma sala silenciosaOpcional. Leia todas antes do dia
emailAvisar as pessoas sobre mudanças e casar respostas alteradasTambém é o reply-to de cada e-mail de notificação
Peça só o que o evento precisa. Respostas sobre alimentação e acessibilidade podem ser informações de saúde; diga no formulário por que você pergunta, guarde a exportação em um lugar privado e exclua os envios quando o evento terminar.

O formulário de RSVP

Escolha sua stack. Cada versão agradece um Sim e um Não de forma diferente, esconde as perguntas sobre convidados para um Não e envia guests como 0 quando alguém não vem, para as suas somas continuarem certas.

Cole o formulário na página do evento. Ele envia do jeito tradicional e redireciona para a sua página de confirmação, então funciona sem JavaScript. O script curto esconde as perguntas sobre convidados quando alguém responde Não e volta o número de convidados para 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>
As versões no servidor enviam com uma chave secreta, então o Ikiform pula Allowed domains e a verificação humana. Todo envio passa a vir do IP do seu servidor, e o limite Standard de 5 por minuto por visitante conta todos os seus visitantes juntos. Escolha o limite de taxa Relaxed ou Custom para um formulário que você envia por um servidor, e mantenha IKIFORM_SECRET_KEY em variáveis de ambiente só do servidor. As versões no servidor também repassam o header Origin do navegador quando existe, porque o fetch do próprio servidor não envia nenhum e o Ikiform usa esse header para contar os envios de teste gratuitos de localhost.

Os guias de frameworks na documentação vão mais a fundo: Next.js, Astro, SvelteKit, Nuxt, React, Vue e HTML puro. Em um criador de sites, a versão HTML vai colada em um bloco de embed.

Conte as pessoas pela resposta mais recente

As pessoas mudam de ideia. Alguém diz Sim com dois convidados na segunda e Não na quinta; são dois envios, e o segundo é o que vale. Então a regra é: uma resposta por e-mail, a mais nova, e depois some um pela pessoa mais os convidados dela.

Por que a contagem usa o RSVP mais recente de cada pessoaAda: sim2convidadosBen: sim0convidadosAda: nãomudou deideia1 pessoasó o Benvale a últimaSegundaQuartaQuintacontagemPor que a contagem usa o RSVP mais recente de cada pessoaAda:sim2convidadosBen:sim0convidadosAda:nãomudoudeideia1pessoasóoBenvale a últimaSegundaQuartaQuintacontagem
  1. Segunda: Ada confirma presença com 2 convidados. Somar todos os envios contaria 3 pessoas.
  2. Quarta: Ben confirma presença sem convidados.
  3. Quinta: Ada envia o formulário de novo e diz não. O Ikiform armazena isso como um segundo envio dela.
  4. Pegando só o envio mais novo de cada e-mail, Ada é um não, então a contagem é 1: Ben.
Somar todas as linhas contaria o grupo de três da Ada. Contar a linha mais nova por e-mail acerta.

Em uma planilha

  1. Em Submissions, escolha o formulário de RSVP, defina o status como Received e o período como All time, depois clique em Export CSV.
  2. Importe no Google Sheets e ordene por created_at, do mais novo para o mais antigo.
  3. Selecione os dados e use Dados > Limpeza de dados > Remover cópias na coluna email. O Sheets mantém a primeira linha que encontra, que agora é a mais nova.
  4. Conte, com attending na coluna G e guests na coluna H. Ajuste as letras à sua exportação:
Google Sheets
=COUNTIF(G2:G, "yes") + SUMIF(G2:G, "yes", H2:H)

A exportação traz primeiro id, created_at, form e status, e depois uma coluna por campo. Um arquivo tem até 100.000 linhas.

Com um script

Para ter um número que você pode recalcular a qualquer momento, leia os RSVPs pela API REST. As listas vêm da mais nova para a mais antiga, então o primeiro envio visto para cada e-mail é o mais recente. Rode isto com Node e uma chave 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));

A tabela de refeições conta RSVPs, não pessoas, porque um único formulário não diz qual convidado come o quê. Se as refeições dos convidados importam, como em um casamento, pergunte por pessoa; a página de RSVP de casamento mostra como.

Encerrando as inscrições quando lotar

O Ikiform não para o formulário em um número, então prepare duas coisas: um alerta antes de lotar e um jeito de encerrar. Encerre em dois lugares, no formulário e na página:

  1. Nas configurações do formulário, escolha Pause form. A partir daí, os envios são recusados com 403 form_paused, então uma aba antiga ou um bot não conseguem adicionar mais ninguém.
  2. Troque o formulário na página do evento por uma frase como Registration is closed. Email us to join the waitlist. Os visitantes nunca devem dar de cara com o erro.
  3. Se reabrir, escolha Resume form e coloque o formulário de volta.

O alerta pode ser um handler de webhook que refaz a contagem a cada Sim e envia uma mensagem para um webhook de chat, como o do Slack, quando você passa de 90% da capacidade. Este é um route handler do Next.js; a mesma lógica roda em qualquer 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;
  }
}
  • Ele refaz a contagem pela API a cada vez, então uma resposta alterada é levada em conta. Cada chave pode fazer 100 requisições à API por minuto, o que cobre vários milhares de RSVPs por contagem.
  • O alerta diz a uma pessoa que é hora de pausar. Pausar é uma ação no painel, então nada fecha de surpresa.
  • Adicione o endpoint em Webhooks e copie o segredo dele para IKIFORM_WEBHOOK_SECRET. Um workspace pode ter 3 endpoints; a documentação de webhooks explica as novas tentativas.
Das inscrições abertas ao encerramento, sem nada automáticoabertoformuláriona páginaalerta de90%handlerrefaz acontagemPauseform403form_pausedpáginadizencerradolista deespera pore-mailRSVPsvocê decideDas inscrições abertas ao encerramento, sem nada automáticoabertoformulário na páginaalerta de 90%handler refaz a contagemPause form403 form_pausedpágina diz encerradolista de espera por e-mailRSVPsvocê decide
  1. Enquanto as inscrições estão abertas, cada RSVP é enviado ao Ikiform.
  2. Seu handler de webhook refaz a contagem das respostas mais recentes a cada Sim e avisa você ao atingir 90% da capacidade.
  3. Você decide quando lotou e escolhe Pause form, que recusa novos envios com 403 form_paused.
  4. Você troca o formulário na página por uma mensagem de encerramento e um jeito de entrar numa lista de espera.
Uma pessoa decide encerrar. Isso é mais lento que o limite rígido de um app de ingressos, e significa que uma mudança de planos de última hora nunca deixa de fora alguém que você teria aceitado.

Confirmações sem e-mail de confirmação

O Ikiform não envia e-mail ao convidado, então dê a ele o que precisa na página de agradecimento: data, horário, endereço e um arquivo de calendário. Um arquivo .ics estático ao lado da página funciona em todo app de calendário. Coloque um link para ele na página de confirmação 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

Horários terminados em Z estão em UTC, então os apps de calendário mostram cada um no fuso horário do próprio convidado. Se você quer um e-mail de confirmação de verdade, envie cada RSVP por webhook para sua ferramenta de e-mail, direto ou via Zapier, Make ou n8n, e mande o e-mail de lá. A mesma lista depois recebe o lembrete na véspera.

Respostas alteradas e cancelamentos

Diga às pessoas como mudar a resposta: Plans changed? Send the form again with the same email. Sua contagem já usa a resposta mais nova, então não é preciso mais nada. As notificações mostram cada mudança no momento em que acontece, o que é útil na semana do evento.

Duas pessoas no mesmo Wi-Fi compartilham um endereço IP, e o limite de taxa conta por IP. O padrão Standard, de 5 por minuto por visitante, serve para uma página de evento. Não defina um limite Custom de um envio por dia para barrar repetições: isso bloqueia uma segunda pessoa da mesma casa na mesma rede, e a regra da resposta mais recente já cuida das repetições.

No dia

Exporte os RSVPs, remova os duplicados como acima, filtre por attending = yes, ordene por nome e imprima. Adicione colunas para marcar presença e para os convidados que chegaram. Uma lista impressa funciona quando o sinal do local não funciona. Deixe a coluna de acessibilidade na cópia da equipe da porta e a coluna de alimentação na do buffet.

Spam não chega à sua lista: o honeypot, a pontuação de spam e os limites de taxa filtram antes da contagem, e spam não envia e-mail nem webhook. Confira o filtro Spam uma vez antes de imprimir, caso um RSVP real com uma mensagem incomum tenha ido parar lá. Endereços descartáveis somam 2 à pontuação de spam.

Escolha o seu caso

Um casamento, um evento comunitário gratuito e uma escala de voluntários contam de formas diferentes. Estas páginas mostram o que muda.

Confira se funciona

Teste o ciclo completo uma semana antes de anunciar o evento. O Ikiform não tem plano gratuito. Testar é grátis: um workspace sem plano aceita 50 envios de teste por mês a partir de localhost. Para entrar no ar, escolha o Pro a partir de US$ 6/mês para 500 envios, ou pague uma vez: 10.000 envios por US$ 49 ou 50.000 envios por US$ 149, com créditos que nunca expiram. Veja os preços.

  1. Em Allowed domains do formulário, adicione o domínio do seu site, mais localhost enquanto desenvolve. Deixe vazio para aceitar envios de qualquer lugar.
  2. Envie um Sim com dois convidados e um Não a partir de e-mails diferentes. Os dois chegam, e o Não mostra guests como 0.
  3. Envie três convidados, depois quatro. O quarto é recusado com Must be at most 3.
  4. Confira a caixa de entrada de cada destinatário das notificações. Cada um recebe um e-mail com os campos, e Reply vai para quem enviou quando o formulário tem um campo email.
  5. Rode o script de contagem ou a fórmula da planilha. O resultado deve bater com o que você enviou.
  6. Pause o formulário e envie mais uma vez. Você recebe 403 form_paused. Retome o formulário.
  7. Envie com o honeypot preenchido, _gotcha=bot. Ele ainda recebe uma resposta de sucesso, mas o envio é armazenado como spam e não dispara e-mail nem webhook.
  8. Não chegou nada? Mude o filtro de status do painel para Spam. Spam recebe a mesma resposta de sucesso de um envio real.

Solução de problemas

ProblemaO que fazer
A contagem está alta demaisVocê está somando todos os envios. Mantenha só o mais novo por e-mail e confira se um Não envia guests como 0.
403 form_paused na página publicadaO formulário está pausado no painel. Retome-o ou troque o formulário na página por uma mensagem de encerramento.
422 validation_failed mencionando guestsMais convidados que o max do campo, ou um número decimal. Mostre a mensagem do Ikiform ao lado do campo, como os exemplos fazem.
403 origin_not_allowed, ou todo envio cai no spamO domínio da página não está em Allowed domains do formulário. Adicione-o, mais localhost para testes locais. Subdomínios de um domínio listado são permitidos.
429 rate_limitedUm visitante enviou mais do que o limite de taxa do formulário permite. O Standard permite 5 por minuto por visitante. Espere o Retry-After, ou escolha Relaxed ou Custom para formulários que enviam a partir de um único IP compartilhado.
O envio está no painel, mas nenhum e-mail ou webhook chegouEle foi armazenado como spam. Spam não envia nada. Abra-o no filtro Spam para ver os motivos e marque-o como não spam para enviar o e-mail e os webhooks dele.
O navegador cai na página de agradecimento do Ikiform em vez da suaO _redirect é ignorado, a menos que o domínio dele esteja em Allowed domains e ele seja uma URL https:. Adicione o domínio, ou defina Redirect after submit nas configurações do formulário.

Perguntas

Travou em algum passo ou quer um guia para o seu caso? Envie um e-mail para hello@ikiform.com.