Industry Guide

Fitness & Personal Training Booking Form

January 2026 · 11 min read

Personal trainers need more than a calendar link. Before the first session, you need to know goals, fitness level, health conditions, and trainer preferences. A good booking form collects all of this while showing prices upfront and offering package deals.

The fitness industry runs on relationships and results. Your booking form is the first step in both - it sets expectations, screens for safety, and matches clients with the right trainer and program.

Session Types and Duration

Start with what they're booking. Personal training, duo sessions, small groups, or an initial assessment each have different pricing and duration options.

const sessionSection = form.addSubform('session', {
    title: 'Session Details'
});

sessionSection.addRow(row => {
    row.addRadioButton('sessionType', {
        label: 'Session Type',
        isRequired: true,
        options: [
            { id: 'personal', name: 'Personal Training (1-on-1)' },
            { id: 'duo', name: 'Duo Training (2 people)' },
            { id: 'small-group', name: 'Small Group (3-5 people)' },
            { id: 'assessment', name: 'Fitness Assessment' }
        ],
        orientation: 'vertical'
    });
});

const sessionType = sessionSection.radioButton('sessionType');

sessionSection.addRow(row => {
    row.addDropdown('duration', {
        label: 'Session Duration',
        isRequired: true,
        options: () => {
            const type = sessionType?.value();
            if (type === 'assessment') {
                return [{ id: '60', name: '60 minutes' }];
            }
            return [
                { id: '30', name: '30 minutes' },
                { id: '45', name: '45 minutes' },
                { id: '60', name: '60 minutes' },
                { id: '90', name: '90 minutes' }
            ];
        },
        defaultValue: '60'
    });
});

Duration options change based on session type - assessments are always 60 minutes, while training sessions offer flexibility. This keeps the form relevant and prevents invalid combinations.

Trainer Selection

Let clients choose their trainer or opt for "no preference." Show each trainer's specialty so clients can self-match based on their goals.

sessionSection.addRow(row => {
    row.addDropdown('trainer', {
        label: 'Preferred Trainer',
        options: [
            { id: 'any', name: 'No preference' },
            { id: 'mike', name: 'Mike - Strength & Conditioning' },
            { id: 'sarah', name: 'Sarah - Weight Loss & Nutrition' },
            { id: 'alex', name: 'Alex - Sports Performance' },
            { id: 'jen', name: 'Jen - Senior Fitness & Rehab' }
        ],
        defaultValue: 'any'
    });
});

const trainer = sessionSection.dropdown('trainer');

// Show trainer specialties
sessionSection.addRow(row => {
    row.addTextPanel('trainerInfo', {
        label: '',
        isVisible: () => !!trainer?.value() && trainer.value() !== 'any',
        computedValue: () => {
            const t = trainer?.value();
            if (t === 'mike') return 'Specializes in muscle building, powerlifting, and athletic performance.';
            if (t === 'sarah') return 'Expert in sustainable weight loss, meal planning, and lifestyle coaching.';
            if (t === 'alex') return 'Works with athletes on speed, agility, and sport-specific training.';
            if (t === 'jen') return 'Certified in senior fitness, injury recovery, and low-impact training.';
            return '';
        }
    });
});

The info panel appears when a specific trainer is selected, showing their specialization. Someone focused on weight loss sees that Sarah is their best match. An athlete sees Alex's sports performance background.

Pro tip

Include "No preference" as the default. New clients often don't know your trainers yet, and forcing a choice creates unnecessary friction.

Goals Assessment

Understanding goals before the first session lets trainers prepare. Weight loss clients need different programming than someone training for a marathon.

const goalsSection = form.addSubform('goals', {
    title: 'Your Fitness Goals'
});

goalsSection.addRow(row => {
    row.addCheckboxList('primaryGoals', {
        label: 'What do you want to achieve?',
        isRequired: true,
        min: 1,
        max: 3,
        options: [
            { id: 'weight-loss', name: 'Lose weight' },
            { id: 'muscle', name: 'Build muscle' },
            { id: 'strength', name: 'Get stronger' },
            { id: 'endurance', name: 'Improve endurance' },
            { id: 'flexibility', name: 'Increase flexibility' },
            { id: 'sports', name: 'Sports performance' },
            { id: 'health', name: 'General health' },
            { id: 'rehab', name: 'Injury recovery' }
        ],
        orientation: 'vertical'
    });
});

const goals = goalsSection.checkboxList('primaryGoals');

goalsSection.addRow(row => {
    row.addTextarea('goalDetails', {
        label: 'Tell us more about your goals',
        isVisible: () => (goals?.value()?.length || 0) > 0,
        placeholder: 'Any specific targets? Timeline? Past experience?',
        rows: 3
    });
});

Limiting to 3 goals forces prioritization. "Everything" isn't actionable, but "weight loss, strength, and flexibility" gives the trainer a clear direction. The optional details field lets motivated clients share more context.

Fitness Level

Current fitness level and exercise frequency help trainers calibrate intensity. A beginner needs different programming than someone who trains five days a week.

goalsSection.addRow(row => {
    row.addRadioButton('fitnessLevel', {
        label: 'Current Fitness Level',
        isRequired: true,
        options: [
            { id: 'beginner', name: 'Beginner - New to exercise' },
            { id: 'intermediate', name: 'Intermediate - Exercise occasionally' },
            { id: 'advanced', name: 'Advanced - Train regularly' },
            { id: 'athlete', name: 'Athlete - Competitive level' }
        ],
        orientation: 'vertical'
    });
});

goalsSection.addRow(row => {
    row.addDropdown('exerciseFrequency', {
        label: 'How often do you currently exercise?',
        options: [
            { id: 'never', name: 'Rarely or never' },
            { id: '1-2', name: '1-2 times per week' },
            { id: '3-4', name: '3-4 times per week' },
            { id: '5+', name: '5+ times per week' }
        ]
    });
});

The descriptions ("New to exercise", "Train regularly") help clients self-assess accurately. Without guidance, everyone claims to be "intermediate."

See more booking forms in our gallery.

Health Screening

Health information is critical for safety. Trainers need to know about conditions that affect programming - heart issues, joint problems, back pain.

const healthSection = form.addSubform('health', {
    title: 'Health Information'
});

healthSection.addRow(row => {
    row.addCheckboxList('healthConditions', {
        label: 'Do you have any of the following?',
        options: [
            { id: 'heart', name: 'Heart condition' },
            { id: 'blood-pressure', name: 'High blood pressure' },
            { id: 'diabetes', name: 'Diabetes' },
            { id: 'asthma', name: 'Asthma' },
            { id: 'joint', name: 'Joint problems' },
            { id: 'back', name: 'Back issues' },
            { id: 'none', name: 'None of the above' }
        ],
        orientation: 'vertical'
    });
});

const conditions = healthSection.checkboxList('healthConditions');

healthSection.addRow(row => {
    row.addTextarea('healthDetails', {
        label: 'Please provide details',
        isVisible: () => {
            const selected = conditions?.value() || [];
            return selected.length > 0 && !selected.includes('none');
        },
        isRequired: () => {
            const selected = conditions?.value() || [];
            return selected.length > 0 && !selected.includes('none');
        },
        placeholder: 'Help us understand any limitations or precautions needed',
        rows: 3
    });
});

healthSection.addRow(row => {
    row.addCheckbox('medicalClearance', {
        label: 'I confirm I have medical clearance to exercise',
        isRequired: true
    });
});

The details field appears only when conditions are selected (and "none" isn't checked). The medical clearance checkbox protects both trainer and client.

Pricing Display

Show prices based on session type and duration. Different combinations have different rates - personal training costs more than small groups, longer sessions cost more than shorter ones.

const sessionType = sessionSection.radioButton('sessionType');
const duration = sessionSection.dropdown('duration');

// Pricing matrix
const prices: Record<string, Record<string, number>> = {
    'personal': { '30': 45, '45': 60, '60': 75, '90': 100 },
    'duo': { '30': 60, '45': 80, '60': 100, '90': 130 },
    'small-group': { '30': 80, '45': 100, '60': 120, '90': 150 },
    'assessment': { '60': 50 }
};

const pricingSection = form.addSubform('pricing', {
    title: 'Session Price',
    sticky: 'bottom'
});

pricingSection.addRow(row => {
    row.addPriceDisplay('sessionPrice', {
        label: 'Price',
        computedValue: () => {
            const type = sessionType?.value();
            const dur = duration?.value();
            if (!type || !dur) return 0;
            return prices[type]?.[dur] || 0;
        },
        currency: '$',
        suffix: '/session'
    });
});

// Package discount
pricingSection.addRow(row => {
    row.addTextPanel('packageOffer', {
        label: '',
        computedValue: () => {
            const type = sessionType?.value();
            const dur = duration?.value();
            if (!type || !dur) return '';
            const single = prices[type]?.[dur] || 0;
            const pack10 = Math.round(single * 10 * 0.85);
            return 'Buy 10 sessions for $' + pack10 + ' (save 15%)';
        },
        isVisible: () => !!sessionType?.value() && !!duration?.value()
    });
});

The price updates instantly as clients change session type or duration. Showing the package discount ("Buy 10 for 15% off") encourages commitment without being pushy.

Session Packages

Most fitness businesses offer package discounts. Let clients choose between single sessions and multi-session packs with built-in savings.

sessionSection.addRow(row => {
    row.addRadioButton('package', {
        label: 'Purchase Option',
        isRequired: true,
        options: [
            { id: 'single', name: 'Single session' },
            { id: 'pack-5', name: '5-session pack (10% off)' },
            { id: 'pack-10', name: '10-session pack (15% off)' },
            { id: 'monthly', name: 'Monthly unlimited' }
        ],
        orientation: 'vertical'
    });
});

const packageType = sessionSection.radioButton('package');

const getPackagePrice = (base: number, pkg: string): number => {
    if (pkg === 'single') return base;
    if (pkg === 'pack-5') return Math.round(base * 5 * 0.9);
    if (pkg === 'pack-10') return Math.round(base * 10 * 0.85);
    if (pkg === 'monthly') return 299;
    return base;
};

pricingSection.addRow(row => {
    row.addPriceDisplay('totalPrice', {
        label: 'Total',
        computedValue: () => {
            const type = sessionType?.value();
            const dur = duration?.value();
            const pkg = packageType?.value();
            if (!type || !dur || !pkg) return 0;
            const base = prices[type]?.[dur] || 0;
            return getPackagePrice(base, pkg);
        },
        currency: '$',
        variant: 'large'
    });
});

The total price adjusts based on the package selected. Seeing "$637 for 10 sessions" vs "$75 per session" makes the value obvious. Monthly unlimited offers predictability for committed clients.

Contact Information

Collect what you need to follow up - name, email, phone. The notes field catches scheduling preferences or questions that don't fit elsewhere.

const contactSection = form.addSubform('contact', {
    title: 'Your Information'
});

contactSection.addRow(row => {
    row.addTextbox('firstName', {
        label: 'First Name',
        isRequired: true
    });

    row.addTextbox('lastName', {
        label: 'Last Name',
        isRequired: true
    });
});

contactSection.addRow(row => {
    row.addEmail('email', {
        label: 'Email',
        isRequired: true
    });

    row.addTextbox('phone', {
        label: 'Phone',
        isRequired: true,
        placeholder: '(555) 123-4567'
    });
});

contactSection.addRow(row => {
    row.addTextarea('notes', {
        label: 'Anything else we should know?',
        placeholder: 'Scheduling preferences, questions, etc.',
        rows: 3
    });
});

Keep this section simple. You already have detailed information from the earlier sections - contact info just enables the follow-up conversation.

What Makes Fitness Forms Work

A few patterns make fitness booking forms effective:

Goals first: Understanding why someone wants training shapes everything else. Lead with goals, then collect logistics.

Trainer matching: Show specialties so clients can self-select. The right match leads to better results and longer retention.

Health screening: Non-negotiable for liability and safety. Make it easy to disclose conditions and require acknowledgment.

Transparent pricing: Show prices before asking for contact info. People want to know if they can afford it before committing their details.

Package incentives: Display savings prominently. Committed clients want packages; show them the value clearly.

After the Booking

The form is the start, not the end. Use the collected information to:

  • Send confirmation with what to expect at the first session
  • Share the client's goals and health info with the assigned trainer
  • Recommend content based on their goals (nutrition guides, workout tips)
  • Follow up if they don't complete the booking

Common Questions

Should I require health information upfront?

Yes. It's standard practice and protects everyone. Most clients expect it. You can make specific condition details optional, but always include a general health acknowledgment checkbox.

How do I handle online vs in-person sessions?

Add a session format field (in-person, virtual, hybrid). Virtual sessions might have different pricing and don't need location selection. Show relevant fields based on the format choice.

Should I collect payment in the form?

For single sessions or packages, yes - if you have payment integration. For consultations or assessments, collecting contact info and following up often works better. Match your sales process.

How detailed should the goals section be?

Detailed enough to personalize the first session, not so detailed it feels like an exam. 1-3 primary goals plus optional context is the sweet spot. Save deeper assessment for the actual session.

Ready to Build Your Fitness Booking Form?

Start with our examples and customize for your training business.