What You'll Build

A complete event registration system with attendee tracking, ticket types, and real-time updates. Manage everything from a Google Sheet without complex event platforms.

Step 1: Create Your Event Sheet

Set up a Google Sheet with these columns:

  • Name - Attendee full name
  • Email - Contact email
  • Event - Event name
  • Ticket Type - Early Bird, Regular, VIP, etc.
  • Date Registered - Registration timestamp
  • Confirmed - Yes/No confirmation status

Step 2: Design Your Registration Form

Use the HTML template to create an attractive registration page. Customize ticket types, pricing, and event details to match your event.

Step 3: Handle Registrations

The JavaScript code captures form submissions and saves them to your Sheet. Each registration is timestamped and initially marked as unconfirmed.

Step 4: Manage Attendees

View and manage registrations directly in your Google Sheet. Update the Confirmed column to Yes after payment or manual approval.

Step 5: Display Attendee Count

Use the attendee widget snippet to show real-time registration numbers on your event page. Great for social proof!

Use Cases

  • Meetups - Track RSVPs for local community events
  • Conferences - Manage multi-track event registrations
  • Workshops - Limit capacity with real-time attendee counts
  • Webinars - Collect registrations and send reminders

Advanced Features

  • Set up webhooks to send confirmation emails automatically
  • Integrate with payment processors (Stripe, PayPal)
  • Add QR code generation for check-in
  • Create a check-in app using the API
  • Send automated reminders before the event
  • Track attendance and no-shows
  • Export attendee lists for badges and certificates

Pro Tips

  • Use Google Sheets formulas to auto-calculate ticket revenue
  • Add conditional formatting to highlight VIP tickets
  • Create a separate sheet for waitlist management
  • Use data validation to standardize ticket types
HTML
JavaScript
Attendees Widget
Python
PHP
cURL
<!DOCTYPE html>
<html>
<head>
    <title>Event Registration</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        .event-header { text-align: center; margin-bottom: 30px; }
        .event-header h1 { color: #667eea; }
        .form-group { margin-bottom: 20px; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
        input, select { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; }
        .ticket-options { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
        .ticket-option { padding: 15px; border: 2px solid #ddd; border-radius: 8px; cursor: pointer; text-align: center; }
        .ticket-option.selected { border-color: #667eea; background: #f0f4ff; }
        .ticket-option .price { font-size: 1.5rem; color: #667eea; font-weight: bold; }
        button { width: 100%; background: #667eea; color: white; padding: 15px; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; font-weight: bold; }
        button:hover { background: #5568d3; }
        .success { background: #d4edda; color: #155724; padding: 15px; border-radius: 4px; margin-top: 20px; }
    </style>
</head>
<body>
    <div class="event-header">
        <h1>📅 Tech Conference 2024</h1>
        <p>Join us for an amazing day of talks and networking!</p>
    </div>
    
    <form id="registrationForm">
        <div class="form-group">
            <label>Full Name</label>
            <input type="text" name="name" required>
        </div>
        
        <div class="form-group">
            <label>Email Address</label>
            <input type="email" name="email" required>
        </div>
        
        <div class="form-group">
            <label>Select Ticket Type</label>
            <div class="ticket-options">
                <div class="ticket-option" data-ticket="Early Bird">
                    <div>Early Bird</div>
                    <div class="price">$49</div>
                </div>
                <div class="ticket-option" data-ticket="Regular">
                    <div>Regular</div>
                    <div class="price">$79</div>
                </div>
            </div>
            <input type="hidden" name="ticket" required>
        </div>
        
        <button type="submit">Register Now</button>
    </form>
    
    <div id="status"></div>
    
    <script src="registration.js"></script>
</body>
</html>
const API_URL = 'https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data';
const API_KEY = 'YOUR_API_KEY';
const EVENT_NAME = 'Tech Conference 2024';

// Ticket selection
document.querySelectorAll('.ticket-option').forEach(option => {
    option.addEventListener('click', function() {
        document.querySelectorAll('.ticket-option').forEach(o => o.classList.remove('selected'));
        this.classList.add('selected');
        document.querySelector('input[name="ticket"]').value = this.dataset.ticket;
    });
});

// Form submission
document.getElementById('registrationForm').addEventListener('submit', async (e) => {
    e.preventDefault();
    
    const formData = new FormData(e.target);
    const data = {
        Name: formData.get('name'),
        Email: formData.get('email'),
        Event: EVENT_NAME,
        'Ticket Type': formData.get('ticket'),
        'Date Registered': new Date().toISOString(),
        Confirmed: 'No'
    };
    
    try {
        const response = await fetch(API_URL, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${API_KEY}`
            },
            body: JSON.stringify(data)
        });
        
        if (response.ok) {
            document.getElementById('status').innerHTML = 
                '<div class="success">✓ Registration successful! Check your email for confirmation.</div>';
            e.target.reset();
            document.querySelectorAll('.ticket-option').forEach(o => o.classList.remove('selected'));
        } else {
            throw new Error('Registration failed');
        }
    } catch (error) {
        document.getElementById('status').innerHTML = 
            '<div style="color:red; padding:15px; background:#f8d7da; border-radius:4px;">✗ Registration failed. Please try again.</div>';
    }
});
// Attendee list widget (read-only view)
const API_URL = 'https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data';
const API_KEY = 'YOUR_API_KEY';

async function loadAttendees() {
    try {
        const response = await fetch(API_URL, {
            headers: { 'Authorization': `Bearer ${API_KEY}` }
        });
        
        const data = await response.json();
        const attendees = data.data || [];
        
        const confirmedCount = attendees.filter(a => a.Confirmed === 'Yes').length;
        
        document.getElementById('attendeeCount').textContent = confirmedCount;
        
        const listHtml = attendees
            .filter(a => a.Confirmed === 'Yes')
            .map(a => `
                <div class="attendee">
                    <strong>${a.Name}</strong>
                    <span class="ticket-badge">${a['Ticket Type']}</span>
                </div>
            `).join('');
        
        document.getElementById('attendeeList').innerHTML = listHtml;
        
    } catch (error) {
        console.error('Failed to load attendees:', error);
    }
}

loadAttendees();
// Refresh every 30 seconds
setInterval(loadAttendees, 30000);
from flask import Flask, request, jsonify
import requests
from datetime import datetime

app = Flask(__name__)

SHEET_ID = 'YOUR_SHEET_ID'
API_KEY = 'YOUR_API_KEY'
API_URL = f'https://sheetapi.pro/api/v1/sheets/{SHEET_ID}/data'

@app.route('/register', methods=['POST'])
def register():
    data = request.json
    
    payload = {
        'Name': data.get('name'),
        'Email': data.get('email'),
        'Event': data.get('event', 'My Event'),
        'Ticket Type': data.get('ticket_type'),
        'Date Registered': datetime.now().isoformat(),
        'Confirmed': 'No'
    }
    
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {API_KEY}'
    }
    
    response = requests.post(API_URL, json=payload, headers=headers)
    
    if response.status_code == 200:
        # TODO: Send confirmation email
        return jsonify({
            'success': True, 
            'message': 'Registration successful'
        })
    else:
        return jsonify({
            'success': False, 
            'error': 'Registration failed'
        }), 500

@app.route('/attendees', methods=['GET'])
def get_attendees():
    headers = {'Authorization': f'Bearer {API_KEY}'}
    response = requests.get(API_URL, headers=headers)
    
    if response.status_code == 200:
        attendees = response.json().get('data', [])
        confirmed = [a for a in attendees if a.get('Confirmed') == 'Yes']
        
        return jsonify({
            'success': True,
            'total': len(attendees),
            'confirmed': len(confirmed),
            'attendees': confirmed
        })
    else:
        return jsonify({'success': False}), 500

if __name__ == '__main__':
    app.run(debug=True)
<?php
// event-registration.php
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $data = json_decode(file_get_contents('php://input'), true);
    
    $payload = [
        'Name' => $data['name'],
        'Email' => $data['email'],
        'Event' => $data['event'] ?? 'My Event',
        'Ticket Type' => $data['ticket_type'],
        'Date Registered' => date('c'),
        'Confirmed' => 'No'
    ];
    
    $ch = curl_init('https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer YOUR_API_KEY'
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200) {
        // TODO: Send confirmation email
        echo json_encode(['success' => true, 'message' => 'Registered successfully']);
    } else {
        http_response_code(500);
        echo json_encode(['success' => false, 'error' => 'Registration failed']);
    }
}
?>
# Register a new attendee
curl -X POST https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "Name": "Jane Smith",
    "Email": "jane@example.com",
    "Event": "Tech Conference 2024",
    "Ticket Type": "Early Bird",
    "Date Registered": "2024-01-15T10:30:00Z",
    "Confirmed": "No"
  }'

# Get all attendees
curl -X GET https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data \
  -H "Authorization: Bearer YOUR_API_KEY"

# Update confirmation status (requires row ID)
curl -X PATCH https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data/5 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"Confirmed": "Yes"}'