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
| Tool | Role | Cost |
|---|---|---|
| Sutrena Pages | Static site hosting (included) | Included |
| Sutrena | RSVP 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 · 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>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.
Sutrena returns 410 Gone. The frontend shows "Sold Out." You can increase maxSubmissions via PATCH if you want to open more spots later.
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.
Create a second form with no cap. When the main form returns 410, redirect users to the waitlist form. Two forms, same account.
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.
No. Sutrena Pages hosts the HTML. Forms are also on Sutrena. One platform, one API key.
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
1. Get a trial key (no auth, no signup)
curl -X POST https://sutrena.com/api/trial2. 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>"}'Get a trial API key instantly with no signup, or create an account for the full experience.