Skip to main content

How to collect event registrations, manage capacity, and send automated confirmations in Formaloo

Learn how to build a complete event registration system in Formaloo, with ticket capacity limits, automated PDF tickets, and confirmation emails sent on every submission.

What you'll build

By the end of this guide you'll have a fully automated event registration system. It starts with a form that collects attendee details, enforces ticket availability limits so you never oversell, and links each registrant to a user profile. The moment someone submits, Formaloo generates a branded PDF ticket and emails it to them automatically. You'll also have a ready-to-send bulk email campaign to invite past attendees to your next event.

When to use this

  • You're running a paid or free event and need to cap attendance by ticket type

  • You want attendees to receive a confirmation email with their ticket the instant they register

  • Your team needs to track registrant status (confirmed, waitlisted, cancelled) without manually updating a spreadsheet

  • You've run events before and want to re-invite past attendees without building a separate mailing list tool

Step-by-step

Part 1 — Build the registration form

This part covers creating the form, setting ticket availability limits so each tier can't be oversold, and connecting a user profile so every registrant gets their own record.

1. Open Magic Create: From your Formaloo homepage, click Magic Create in the top navigation.

2. Paste the form prompt: Use the prompt below and hit Create. Formaloo builds the full form for you and opens it in the form editor.

Create an event registration form with these fields: full name (short text, required), email address (email, required), phone number (phone, optional), ticket type (single choice: Normal / VIP / Early bird / Student), dietary or accessibility needs (long text, optional), how did you hear about us (single choice: Social media / Email / Friend or colleague / Website / Other). Also add three admin-only fields: registration status (dropdown: Confirmed / Waitlisted / Cancelled), internal notes (long text), and reviewed by (assignee field).

3. Set field IDs: For each field, open its settings and assign the IDs below. These IDs power the answer piping in your email and PDF templates — they must match exactly.

Field

ID

Type

Notes

What's your full name?

name

Short text

Required

What's your email address?

email

Email

Required

What's your phone number?

phone

Phone

Optional

Which ticket type would you like?

ticket_type

Single choice

Normal, VIP, Early bird, Student

Do you have any dietary or accessibility needs?

notes

Long text

Optional

How did you hear about this event?

source

Single choice

Social media, Email, Friend/colleague, Website, Other

Registration status (admin only)

status

Dropdown

Confirmed, Waitlisted, Cancelled

Internal notes (admin only)

admin_notes

Long text

Hidden from registrant

Reviewed by (admin only)

reviewed_by

Assignee

Staff member who processed the registration

📖 For the full guide on field IDs and answer piping, see how to dynamically pull form data into emails, PDFs, and AI prompts.

4. Enable availability limits on the ticket type field: Scroll to the Which ticket type would you like? field and click it to open its settings. Under Reservation, toggle on Availability limit for each choice option and set the number of tickets available per tier. Once a tier sells out, Formaloo disables it automatically — no manual intervention needed.

5. Add a user profile field: Scroll to the bottom of the form and click Add field. Search for User profile and add it. In the field settings, click Select user directory, then either create a new user directory or search for an existing one (for example, "event registration"). Select it and confirm. Each person who submits the form will now have their own profile record linked to your portal.

Part 2 — Create the PDF ticket template

Each attendee gets a branded PDF ticket attached to their confirmation email. You build the template once here — Formaloo generates a personalised copy for every form submission.

1. Open PDF templates: Click your profile icon in the top-right corner, go to Apps & integrations, then click PDF templates.

2. Create a new template: Click + Add new template.

3. Switch to HTML mode: In the template editor, click the HTML / code toggle to switch from the visual editor to raw HTML.

4. Paste the ticket code: Delete any existing content and paste the full HTML below. The @name, @email, @ticket_type, @status, @phone, @source, and @notes variables pull live data from each form submission.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Event Ticket</title> <style>   @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&family=Space+Mono:wght@400;700&display=swap');   * { margin: 0; padding: 0; box-sizing: border-box; }   @page { size: A4 portrait; margin: 0; }   body {     width: 210mm; height: 297mm; background: #eeeef5;     display: flex; align-items: center; justify-content: center;     font-family: 'Inter', sans-serif;     -webkit-print-color-adjust: exact; print-color-adjust: exact;   }   .ticket {     width: 148mm; background: #ffffff; border-radius: 20px; overflow: hidden;     box-shadow: 0 20px 60px rgba(0,0,0,0.14), 0 2px 8px rgba(0,0,0,0.06);     display: flex; flex-direction: column;   }   .ticket-hero {     background: linear-gradient(155deg, #1a1a2e 0%, #16213e 55%, #0f3460 100%);     padding: 36px 32px 32px; position: relative; overflow: hidden;   }   .ticket-hero::before {     content: ''; position: absolute; right: -40px; top: -40px;     width: 160px; height: 160px;     background: radial-gradient(circle, rgba(108,71,255,0.35) 0%, transparent 70%);   }   .ticket-hero::after {     content: ''; position: absolute; left: 20px; bottom: -30px;     width: 120px; height: 120px;     background: radial-gradient(circle, rgba(255,71,199,0.18) 0%, transparent 70%);   }   .hero-eyebrow {     font-size: 9px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase;     color: rgba(255,255,255,0.38); margin-bottom: 10px; position: relative; z-index: 1;   }   .hero-title {     font-size: 34px; font-weight: 900; color: #ffffff; line-height: 1.05;     letter-spacing: -0.5px; margin-bottom: 24px; position: relative; z-index: 1;   }   .hero-bottom { display: flex; justify-content: space-between; align-items: flex-end; position: relative; z-index: 1; }   .ticket-type-badge {     background: linear-gradient(135deg, #6c47ff, #c147ff); color: #fff;     font-size: 11px; font-weight: 800; letter-spacing: 2px; text-transform: uppercase;     padding: 7px 18px; border-radius: 30px;   }   .status-badge {     background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.18);     color: rgba(255,255,255,0.65); font-size: 9px; font-weight: 700;     letter-spacing: 1.5px; text-transform: uppercase; padding: 5px 12px; border-radius: 20px;   }   .ticket-body {     padding: 28px 32px 24px; display: flex; flex-direction: column; gap: 20px;     border-left: 4px solid; border-image: linear-gradient(180deg, #6c47ff, #c147ff, #ff6b6b) 1;   }   .section-label { font-size: 8px; font-weight: 700; letter-spacing: 2.5px; text-transform: uppercase; color: #c0c0d8; margin-bottom: 5px; }   .attendee-name { font-size: 24px; font-weight: 800; color: #1a1a2e; letter-spacing: -0.3px; line-height: 1.1; margin-bottom: 4px; }   .attendee-email { font-family: 'Space Mono', monospace; font-size: 11px; color: #8888aa; }   .info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 16px; }   .info-cell .cell-label { font-size: 8px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: #c8c8e0; margin-bottom: 4px; }   .info-cell .cell-value { font-size: 13px; font-weight: 600; color: #2a2a4a; line-height: 1.3; }   .pill-type { display: inline-block; background: #f0ecff; border: 1px solid #d0c0ff; color: #6c47ff; font-size: 10px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; padding: 3px 10px; border-radius: 5px; }   .notes-value { font-size: 12px; font-weight: 400; color: #a0a0c0; font-style: italic; }   .tear-line { display: flex; align-items: center; position: relative; margin: 0; }   .tear-notch { width: 18px; height: 18px; background: #eeeef5; border-radius: 50%; flex-shrink: 0; }   .tear-notch.left { margin-left: -9px; }   .tear-notch.right { margin-right: -9px; }   .tear-dash { flex: 1; border: none; border-top: 2px dashed #dcdcec; }   .ticket-stub { padding: 20px 32px 28px; display: flex; flex-direction: column; align-items: center; gap: 16px; background: #fafafa; }   .stub-label { font-size: 8px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: #c0c0d8; }   .barcode { display: flex; align-items: flex-end; gap: 2.5px; height: 44px; }   .bar { width: 2.5px; border-radius: 1px; background: #d8d8ee; }   .bar.a { background: #6c47ff; }   .bar.m { background: #3a3a6a; }   .stub-info { font-family: 'Space Mono', monospace; font-size: 9px; color: #b0b0c8; text-align: center; line-height: 1.8; } </style> </head> <body> <div class="ticket">   <div class="ticket-hero">     <div class="hero-eyebrow">Event ticket</div>     <div class="hero-title">Your Event<br>Name Here</div>     <div class="hero-bottom">       <div class="ticket-type-badge">@ticket_type</div>       <div class="status-badge">@status</div>     </div>   </div>   <div class="ticket-body">     <div>       <div class="section-label">Attendee</div>       <div class="attendee-name">@name</div>       <div class="attendee-email">@email</div>     </div>     <div class="info-grid">       <div class="info-cell">         <div class="cell-label">Phone</div>         <div class="cell-value">@phone</div>       </div>       <div class="info-cell">         <div class="cell-label">Ticket type</div>         <div class="cell-value"><span class="pill-type">@ticket_type</span></div>       </div>       <div class="info-cell">         <div class="cell-label">Referred by</div>         <div class="cell-value">@source</div>       </div>       <div class="info-cell">         <div class="cell-label">Special needs</div>         <div class="cell-value notes-value">@notes</div>       </div>     </div>   </div>   <div class="tear-line">     <div class="tear-notch left"></div>     <hr class="tear-dash">     <div class="tear-notch right"></div>   </div>   <div class="ticket-stub">     <div class="stub-label">Admit one · scan at entrance</div>     <div class="barcode">       <div class="bar a" style="height:80%"></div><div class="bar m" style="height:100%"></div>       <div class="bar" style="height:55%"></div><div class="bar a" style="height:90%"></div>       <div class="bar" style="height:65%"></div><div class="bar m" style="height:100%"></div>       <div class="bar a" style="height:75%"></div><div class="bar" style="height:50%"></div>       <div class="bar a" style="height:100%"></div><div class="bar" style="height:70%"></div>       <div class="bar m" style="height:85%"></div><div class="bar" style="height:45%"></div>       <div class="bar a" style="height:100%"></div><div class="bar" style="height:60%"></div>       <div class="bar m" style="height:80%"></div><div class="bar a" style="height:55%"></div>       <div class="bar" style="height:100%"></div><div class="bar" style="height:72%"></div>       <div class="bar a" style="height:90%"></div><div class="bar m" style="height:65%"></div>     </div>     <div class="stub-info">@name · @ticket_type</div>   </div> </div> </body> </html>

5. Name and save the template: Click the template name field at the top, type Ticket PDF, and click Save.

📖 For the full PDF template guide, see how to create PDF templates to turn responses into documents.

Part 3 — Set up the confirmation email template

This template is what registrants receive the moment they submit the form. It includes a warm confirmation message and the PDF ticket as an attachment.

1. Open email templates: Click your profile icon, go to Apps & integrations, then click Email templates.

2. Create a new template: Click + Add new template. Remove any default content from the editor.

3. Open the AI editor: Click the AI block or the AI generation button inside the template editor.

4. Paste the prompt below and run it. The AI generates a fully styled HTML email with the confirmation message and a ticket card section, all with the correct @field_id variables already wired in.

Email template AI prompt — paste this exactly:

Create a single-column HTML email template with two clear sections. Use inline CSS only (no style blocks). Max width 600px, centered, white background, clean modern design. Font: system-ui or Arial.
Section 1 — Confirmation message. White background, 40px top/bottom padding, 32px side padding. Include in order: (1) a small label in uppercase, purple (#6c47ff), letter-spacing 2px, font-size 11px — text: "You're registered"; (2) a bold 26px heading in dark navy (#1a1a2e): "See you soon, @name! 🎉"; (3) a paragraph at 15px, line-height 1.7, color #555570: "Your spot is confirmed. We're looking forward to seeing you. Everything you need is in your ticket below — just bring this email or a screenshot to the entrance."; (4) a light grey info row (#f7f7fc background, 8px border-radius, 16px 20px padding, 13px, #6666aa): "📅 Check the event details below · 🎟 Your ticket type: @ticket_type · ✅ Status: @status"; (5) a centered CTA button — background #6c47ff, white text, bold, 14px, 14px 32px padding, 30px border-radius, no underline — text: "View event details →".
Section 2 — Ticket card. A visual ticket card separated by 8px. White background, border 1px solid #e8e8f0, border-radius 16px, max-width 560px, margin auto. Top band: background linear-gradient(135deg, #1a1a2e, #0f3460), padding 28px 32px — include eyebrow "EVENT TICKET" (rgba(255,255,255,0.4), 9px, letter-spacing 3px), event name heading in white 24px bold, and ticket type badge in gradient #6c47ff to #c147ff with @ticket_type. Body: white, padding 24px 32px, border-left 4px solid #6c47ff. Use tables for email compatibility. Row 1: left column shows "ATTENDEE" label + @name (18px bold) + @email (monospace 11px); right column shows "STATUS" label + @status in a green pill. Dashed divider. Row 2: four columns — PHONE/@phone, TICKET TYPE/@ticket_type (purple pill), REFERRED BY/@source, SPECIAL NEEDS/@notes (italic). Footer stub: #fafafa background, border-top 2px dashed #dcdcec, centered — "Present this ticket at the entrance" italic + "Powered by Formaloo" small uppercase.
Footer below the card: #f7f7fc, 24px padding, centered, 11px, #b0b0c8 — "You're receiving this because you registered for this event. Questions? Reply to this email."

5. Name the template: Click the template name field and type Event confirmation.

6. Set the email subject: Find the subject line field and enter your event confirmation subject (for example: "You're in — here's your ticket").

7. Add your sender email: Fill in your admin email address in the sender field.

8. Attach the PDF ticket: Under PDF attachment, toggle it on. Select the Ticket PDF template you created in Part 2. Formaloo will now generate a personalised PDF ticket and attach it to every confirmation email automatically.

9. Save the template: Click Save.

10. Wire up the notification: Go back to your registration form, open the Notify tab, and click Email notifications. Enable Receive email notification, add your admin email as a recipient, then change the email template dropdown to Event confirmation. Save.

Note: This step sends the confirmation to the registrant. The recipient address Formaloo uses is pulled from the @email field on the form — make sure that field ID is set correctly (see Part 1, step 3).

📖 See how to send and receive email notifications for the full setup guide.

Part 4 — Send a bulk campaign to past attendees

You have a new event coming up. This part covers sending a personalised email to people who attended your last event, inviting them to register before tickets go public.

1. Open the email campaign tool: Click your profile icon, go to Apps & integrations, and search for Send email. Click it, then click New email campaign.

2. Fill in the campaign details:

  • Campaign title: a label for your own reference (for example: "Summer event — past attendee early access")

  • Subject line: You were there last time. Here's your early access.

  • Sender name: your organisation name or event name

  • Sender email: your admin email address

  • Paste the email body:
    Hi @name,

    We looked at who came to [Last Event Name] and put together a short list of people who should hear about this first.

    You're on it.

    [Next Event Name] is happening on [Date] in [Location]. Same format, new speakers, bigger crowd. We're opening registration early for people who were at the last one before it goes public.

    Your ticket from last time: @ticket_type. That same tier is available now, plus we've added a VIP option if you want priority seating and access to the pre-event dinner.

    Here's what's different this time:
    [Speaker or headline change]
    [Format change]
    [Capacity or venue change]
    Early access closes on [Date]. After that, tickets go to the general waitlist. Register here: [Registration link] If you have questions, just reply to this email. See you there, [Your name] [Your title], [Organisation]

3. Assign an AI agent to handle replies: Under Reply to, instead of entering a static email, click Assign agent and select the AI agent linked to your registration form. Formaloo routes incoming replies to the agent, which collects information and responds automatically.

📖 If you haven't set up a CC Formaloo agent yet, see how to use CC Formaloo to collect data from email threads.

4. Add your recipients: Click Recipients, then choose one of the following:

  • From a user directory: Select any existing user directory from your past events.

  • Import users: Paste a list of emails in CSV format, or upload an Excel file that has an email column. Click Import file to load them.

6. Send the campaign: Save the draft to review it, or click Send to send immediately.

What you now have

Your event registration system is fully automated from end to end. Every new registrant hits an availability-enforced form, gets logged to a user profile, receives a confirmation email with a branded PDF ticket attached, and lands in your admin view with a status field your team can update. When the next event comes around, you can re-engage your entire past-attendee list with a personalised campaign in minutes — no spreadsheet exports, no manual emails.

What's next

  • Handle incoming registration queries automatically with CC Formaloo Registrants who reply to their confirmation email can be routed to an AI agent that collects information and responds on your behalf — so no inquiry sits unanswered. → How to use CC Formaloo to collect data from email threads

  • Build an attendee portal so registrants can view their own tickets Give attendees a login-protected portal where they can see their registration status and ticket details — and give your team a Kanban board to manage all registrations in one view. → How to create a portal and manage users' access

  • Add conditional email logic for waitlisted attendees Send a different confirmation email to registrants placed on the waitlist versus those confirmed — using advanced logic conditions on the status field. → How to send and receive conditional email notifications

Learn other use cases

Ready-to-use templates

Event registration and ticketing system, Skip the build. This template already includes the registration form with capacity-enforced ticket tiers, PDF ticket generation, confirmation emails, an attendee portal, and the full admin view. Open it in Formaloo, update your event details, and you're ready to go.

Ready to build this?

💬 Get help from our concierge team Our team will help you set this up for your specific use case.

📅 Book a demo for Team/Enterprise setup See how teams use Formaloo at scale with advanced permissions and integrations.

Did this answer your question?