Blueprints/Ship an event page with live RSVP count

Ship an event page with live RSVP count

RSVP form with a 200-seat cap, email dedup, and a live counter. Fills up, form closes. That is it.

Updated March 2026

An event page needs to do three things: show the details, collect RSVPs, and let people see how many spots are left. This gives you all three. Name, email, ticket type. 200-person cap with email dedup. The public API shows the count. When it fills up, the form closes automatically. Free to start, $29/month on Pro for more projects. Sutrena Pages hosts the site -- included with your plan. `sutrena_launch` deploys the event page, then `sutrena_collect` sets up the RSVP form and webhooks.

Architecture

ToolRoleCost
Sutrena PagesStatic site hosting (included)Included
SutrenaRSVP form, dedup, cap, webhooks$0 (free) / $29/mo (Pro)

Total cost: $0-$29/mo

Pro is $29/month for 100 projects and all your other work too. Build five blueprints on Pro and it is still $29/month. That is where the value is — at scale.

A static landing page deployed on Sutrena Pages with event details, an RSVP form, and a live counter. Sutrena enforces email uniqueness and a 200-submission cap. Hit 200 and the form returns 410 Gone -- your frontend shows "Sold Out."

Fetch the count via the public API and display it directly on the page. The frontend polls every 30 seconds to keep the counter fresh.

Form Definition

Name, email, ticket type. uniqueBy prevents duplicate RSVPs from the same email. maxSubmissions caps at 200. publicResults lets the counter work without auth.

{
  "name": "Event RSVP",
  "fields": [
    {
      "name": "name",
      "label": "Full Name",
      "type": "text",
      "required": true
    },
    {
      "name": "email",
      "label": "Email",
      "type": "email",
      "required": true
    },
    {
      "name": "ticket_type",
      "label": "Ticket Type",
      "type": "select",
      "options": [
        "General",
        "VIP",
        "Student"
      ],
      "required": true
    }
  ],
  "uniqueBy": [
    "email"
  ],
  "publicResults": true,
  "maxSubmissions": 200
}

Frontend Integration

A landing page with a live counter that polls every 30 seconds, an RSVP form with ticket types, and automatic sold-out handling. The counter fetches the total from the public API. Replace frm_YOUR_FORM_ID with yours.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Tech Meetup 2026 - RSVP</title>
  <style>
    body { font-family: system-ui, sans-serif; max-width: 600px; margin: 0 auto; padding: 2rem 1rem; }
    .counter { font-size: 2rem; font-weight: bold; text-align: center; margin: 2rem 0; }
    .counter span { color: #2563eb; }
    form { display: grid; gap: 1rem; }
    input, select { padding: 0.75rem; font-size: 1rem; }
    button { padding: 0.75rem; font-size: 1rem; cursor: pointer; background: #111; color: #fff; border: none; }
    .sold-out { text-align: center; padding: 2rem; background: #fee; border-radius: 8px; }
  </style>
</head>
<body>
  <h1>Tech Meetup 2026</h1>
  <p>March 15, 2026 &middot; Downtown Conference Center</p>

  <div class="counter">
    <span id="count">...</span> / 200 spots claimed
  </div>

  <div id="form-container">
    <form id="rsvp-form">
      <input name="name" placeholder="Full Name" required />
      <input name="email" type="email" placeholder="Email" required />
      <select name="ticket_type" required>
        <option value="">Select ticket type</option>
        <option value="General">General</option>
        <option value="VIP">VIP</option>
        <option value="Student">Student</option>
      </select>
      <button type="submit">RSVP Now</button>
    </form>
  </div>
  <p id="status"></p>

  <script>
    const FORM_ID = "frm_YOUR_FORM_ID";

    // Fetch live count
    async function updateCount() {
      try {
        const res = await fetch(
          `https://sutrena.com/api/forms/${FORM_ID}/submissions?limit=1`
        );
        const data = await res.json();
        document.getElementById("count").textContent = data.total || 0;
        if (data.total >= 200) {
          document.getElementById("form-container").innerHTML =
            '<div class="sold-out"><strong>Sold Out!</strong><p>All 200 spots have been claimed.</p></div>';
        }
      } catch (e) {
        document.getElementById("count").textContent = "...";
      }
    }
    updateCount();
    setInterval(updateCount, 30000);

    // Handle RSVP
    document.getElementById("rsvp-form")?.addEventListener("submit", async (e) => {
      e.preventDefault();
      const fd = new FormData(e.target);
      const body = Object.fromEntries(fd);

      const res = await fetch(
        `https://sutrena.com/api/forms/${FORM_ID}/submit`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(body),
        }
      );

      const status = document.getElementById("status");
      if (res.ok) {
        status.textContent = "You're in! See you there.";
        updateCount();
      } else if (res.status === 409) {
        status.textContent = "You've already RSVP'd with this email.";
      } else if (res.status === 410) {
        status.textContent = "Sorry, all spots are taken!";
      }
    });
  </script>
</body>
</html>

FAQ

Can I use compound tools instead of individual API calls?

Yes. sutrena_collect creates the form and webhooks in one call. sutrena_launch deploys pages with analytics. The code examples below show primitive APIs for full control, but compound tools handle most setups faster.

What happens when all 200 spots are taken?

Sutrena returns 410 Gone. The frontend shows "Sold Out." You can increase maxSubmissions via PATCH if you want to open more spots later.

Can attendees cancel their RSVP?

You can delete a submission by email via the API. There is no self-service cancellation built in. For most events manual cancellation is fine.

Can I add a waitlist after the event sells out?

Create a second form with no cap. When the main form returns 410, redirect users to the waitlist form. Two forms, same account.

Is the RSVP count accurate in real time?

It updates every 30 seconds. Close enough for most events. If you need true real-time, you would need a webhook pushing to a WebSocket server. Probably overkill for an RSVP counter.

Do I need separate hosting?

No. Sutrena Pages hosts the HTML. Forms are also on Sutrena. One platform, one API key.

What is Sutrena?

Sutrena is the web runtime for AI agents. Forms, Pages, Analytics, Webhooks, Automations — all through 67 MCP tools and one REST API. Your agent creates web artifacts, humans interact with them, and your agent gets the data back. Use any one feature or all of them together.

Pages

Deploy HTML instantly

Forms

Collect structured data

Automations

DSL-based pipelines with 14 step types

Analytics

Privacy-first, no cookies

Webhooks

Slack, Discord, Telegram

Get started in two API calls

1. Get a trial key (no auth, no signup)

curl -X POST https://sutrena.com/api/trial

2. Create anything — a page, form, automation, or analytics site

# Create a form
curl -X POST https://sutrena.com/api/forms \
  -H "Authorization: Bearer st_trial_xxx" \
  -H "Content-Type: application/json" \
  -d '{"name": "waitlist", "fields": [{"name": "email", "label": "Email", "type": "email", "required": true}]}'

# Or deploy a page
curl -X POST https://sutrena.com/api/pages \
  -H "Authorization: Bearer st_trial_xxx" \
  -H "Content-Type: application/json" \
  -d '{"slug": "index", "title": "My Site", "html": "<h1>Live</h1>"}'

Ready to build?

Get a trial API key instantly with no signup, or create an account for the full experience.

Ship an event page with live RSVP count — Sutrena | Sutrena