For Photographers

Stop Answering
"How Much for a Session?"
Let a Calculator Do It

Free pricing calculator for your photography website. Clients build custom packages instantly. You get qualified leads. Setup in 5 minutes.

No credit card required
Free forever for calculators
Works on Squarespace, WordPress, any site
๐Ÿ“ธ Build Your Photo Session Package
๐Ÿ“ท Session Details
 
โœจ Customize Your Package
 
 
๐Ÿ–ผ๏ธ Print Package
 
๐Ÿ’ฐ Your Custom Quote
$ 300.00
๐Ÿ“ธ Includes: 25 edited photos in online gallery
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
export function photographyPricingForm(form: FormTs) {
form.setTitle(() => '๐Ÿ“ธ Build Your Photo Session Package');
 
form.configureCompletionScreen({
type: 'text',
title: () => '๐ŸŽ‰ Quote Ready!',
message: () => 'Your custom photography quote has been generated. Download your PDF to save the details.'
});
 
// Pricing data
const sessionRates: Record<string, number> = {
'mini': 150,
'standard': 300,
'extended': 450,
'full-day': 800
};
 
const locationFees: Record<string, number> = {
'studio': 0,
'outdoor-local': 50,
'client-home': 75,
'travel': 150
};
 
const addonPrices: Record<string, number> = {
'extraOutfits': 50,
'hairMakeup': 150,
'rushDelivery': 100,
'printRelease': 75,
'extraDigitals': 100,
'slideshow': 125
};
 
const printPackages: Record<string, number> = {
'none': 0,
'basic': 150,
'standard': 300,
'premium': 500
};
 
// Session Details
const session = form.addSubform('session', {
title: () => '๐Ÿ“ท Session Details',
mobileBreakpoint: 0
});
 
session.addRow(row => {
row.addDropdown('type', {
label: 'Session Type',
defaultValue: 'standard',
isRequired: true,
options: [
{ id: 'mini', name: 'โšก Mini Session (20 min, 10 photos)' },
{ id: 'standard', name: '๐Ÿ“ธ Standard Session (1 hr, 25 photos)' },
{ id: 'extended', name: '๐ŸŒŸ Extended Session (2 hrs, 50 photos)' },
{ id: 'full-day', name: '๐Ÿ‘‘ Full Day (4+ hrs, 100+ photos)' }
]
}, '1fr');
 
row.addDropdown('occasion', {
label: 'Occasion',
defaultValue: 'portrait',
isRequired: true,
options: [
{ id: 'portrait', name: '๐Ÿ‘ค Individual Portrait' },
{ id: 'couple', name: '๐Ÿ’‘ Couple Session' },
{ id: 'family', name: '๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Family Portrait' },
{ id: 'headshot', name: '๐Ÿ’ผ Professional Headshot' },
{ id: 'maternity', name: '๐Ÿคฐ Maternity' },
{ id: 'newborn', name: '๐Ÿ‘ถ Newborn' }
]
}, '1fr');
});
 
session.addRow(row => {
row.addDropdown('location', {
label: 'Location',
defaultValue: 'studio',
isRequired: true,
options: [
{ id: 'studio', name: '๐Ÿ  Studio (no fee)' },
{ id: 'outdoor-local', name: '๐ŸŒณ Outdoor - Local (+$50)' },
{ id: 'client-home', name: '๐Ÿก Your Home (+$75)' },
{ id: 'travel', name: 'โœˆ๏ธ Travel Location (+$150)' }
]
}, '1fr');
 
row.addInteger('people', {
label: 'Number of People',
defaultValue: 1,
min: 1,
max: 15,
isRequired: true
}, '1fr');
});
 
// Extras
const extras = form.addSubform('extras', {
title: () => 'โœจ Customize Your Package',
mobileBreakpoint: 500
});
 
extras.addRow(row => {
row.addCheckboxList('sessionExtras', {
label: 'Session Add-ons',
orientation: 'vertical',
options: [
{ id: 'extraOutfits', name: '๐Ÿ‘— Extra Outfit Changes (+$50)' },
{ id: 'hairMakeup', name: '๐Ÿ’„ Hair & Makeup (+$150)' },
{ id: 'rushDelivery', name: 'โšก Rush Delivery 48hrs (+$100)' }
]
}, '1fr');
 
row.addCheckboxList('digitalExtras', {
label: 'Digital Extras',
orientation: 'vertical',
options: [
{ id: 'printRelease', name: '๐Ÿ“œ Print Release (+$75)' },
{ id: 'extraDigitals', name: '๐Ÿ“ 20 Extra Digitals (+$100)' },
{ id: 'slideshow', name: '๐ŸŽฌ Animated Slideshow (+$125)' }
]
}, '1fr');
});
 
// Print Package
const prints = form.addSubform('prints', {
title: () => '๐Ÿ–ผ๏ธ Print Package',
mobileBreakpoint: 0
});
 
prints.addRow(row => {
row.addRadioButton('printPackage', {
label: 'Select Print Package',
defaultValue: 'none',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'none', name: 'โŒ No Prints (digital only)' },
{ id: 'basic', name: '๐Ÿ“ท Basic - 5 prints up to 8x10 (+$150)' },
{ id: 'standard', name: '๐Ÿ–ผ๏ธ Standard - 10 prints + 1 canvas (+$300)' },
{ id: 'premium', name: '๐Ÿ‘‘ Premium - 20 prints + album (+$500)' }
]
});
});
 
// Calculate functions
const getBasePrice = () => {
const sessionType = session.dropdown('type')?.value() || 'standard';
const people = session.integer('people')?.value() || 1;
 
let baseRate = sessionRates[sessionType] || 300;
 
// Additional person fee (after first 2 people)
if (people > 2) {
baseRate += (people - 2) * 25;
}
 
return baseRate;
};
 
const getLocationFee = () => {
const location = session.dropdown('location')?.value() || 'studio';
return locationFees[location] || 0;
};
 
const getAddonsTotal = () => {
let total = 0;
const sessionExtras = extras.checkboxList('sessionExtras')?.value() || [];
const digitalExtras = extras.checkboxList('digitalExtras')?.value() || [];
 
const allSelected = [...sessionExtras, ...digitalExtras];
 
for (const addonId of allSelected) {
total += addonPrices[addonId] || 0;
}
 
return total;
};
 
const getPrintPackagePrice = () => {
const printPkg = prints.radioButton('printPackage')?.value() || 'none';
return printPackages[printPkg] || 0;
};
 
const getTotalPrice = () => {
return getBasePrice() + getLocationFee() + getAddonsTotal() + getPrintPackagePrice();
};
 
const getSelectedAddons = () => {
const sessionExtras = extras.checkboxList('sessionExtras')?.value() || [];
const digitalExtras = extras.checkboxList('digitalExtras')?.value() || [];
return [...sessionExtras, ...digitalExtras];
};
 
// Quote Summary
const summary = form.addSubform('summary', {
title: () => '๐Ÿ’ฐ Your Custom Quote',
isCollapsible: false,
});
 
summary.addRow(row => {
row.addPriceDisplay('totalPrice', {
label: 'Total Investment',
computedValue: () => getTotalPrice(),
alignment: 'center',
variant: 'large'
});
});
 
summary.addRow(row => {
row.addTextPanel('includes', {
computedValue: () => {
const sessionType = session.dropdown('type')?.value() || 'standard';
const photoCounts: Record<string, string> = {
'mini': '10 edited photos',
'standard': '25 edited photos',
'extended': '50 edited photos',
'full-day': '100+ edited photos'
};
return `๐Ÿ“ธ Includes: ${photoCounts[sessionType] || '25 edited photos'} in online gallery`;
},
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
textAlign: 'center'
}
});
});
 
form.configureSubmitButton({
label: () => 'Request This Package'
});
 
// Configure PDF
form.configurePdf('quoteDocument', (pdf) => {
pdf.configure({
filename: 'photography-quote.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: 'Download Your Quote',
header: {
title: 'Photography Session Quote',
subtitle: 'Custom Package Details'
},
footer: {
text: 'Thank you for choosing us for your photography needs!',
showPageNumbers: true
}
});
 
pdf.addSection('Session Details', (section) => {
section.addRow((row) => {
const typeMap: Record<string, string> = {
'mini': 'Mini Session (20 min)',
'standard': 'Standard Session (1 hr)',
'extended': 'Extended Session (2 hrs)',
'full-day': 'Full Day (4+ hrs)'
};
const type = session.dropdown('type')?.value() || 'standard';
row.addField('Session Type', typeMap[type] || type);
});
section.addRow((row) => {
const occasionMap: Record<string, string> = {
'portrait': 'Individual Portrait',
'couple': 'Couple Session',
'family': 'Family Portrait',
'headshot': 'Professional Headshot',
'maternity': 'Maternity',
'newborn': 'Newborn'
};
const occasion = session.dropdown('occasion')?.value() || 'portrait';
row.addField('Occasion', occasionMap[occasion] || occasion);
});
section.addRow((row) => {
const locationMap: Record<string, string> = {
'studio': 'Studio',
'outdoor-local': 'Outdoor - Local',
'client-home': 'Client Home',
'travel': 'Travel Location'
};
const location = session.dropdown('location')?.value() || 'studio';
row.addField('Location', locationMap[location] || location);
 
const people = session.integer('people')?.value() || 1;
row.addField('Number of People', people.toString());
});
});
 
const selectedAddons = getSelectedAddons();
if (selectedAddons.length > 0) {
pdf.addSection('Add-On Services', (section) => {
const addonLabels: Record<string, string> = {
'extraOutfits': 'Extra Outfit Changes',
'hairMakeup': 'Hair & Makeup',
'rushDelivery': 'Rush Delivery (48hrs)',
'printRelease': 'Print Release',
'extraDigitals': '20 Extra Digitals',
'slideshow': 'Animated Slideshow'
};
 
const tableRows = selectedAddons.map(addonId => [
addonLabels[addonId] || addonId,
`$${addonPrices[addonId] || 0}`
]);
 
section.addTable(['Service', 'Price'], tableRows);
});
}
 
const printPkg = prints.radioButton('printPackage')?.value() || 'none';
if (printPkg !== 'none') {
pdf.addSection('Print Package', (section) => {
const printLabels: Record<string, string> = {
'basic': 'Basic - 5 prints up to 8x10',
'standard': 'Standard - 10 prints + 1 canvas',
'premium': 'Premium - 20 prints + album'
};
section.addRow((row) => {
row.addField('Package', printLabels[printPkg] || printPkg);
row.addField('Price', `$${getPrintPackagePrice()}`);
});
});
}
 
pdf.addSection('Quote Summary', (section) => {
section.addRow((row) => {
row.addField('Base Session', `$${getBasePrice()}`);
});
 
const locationFee = getLocationFee();
if (locationFee > 0) {
section.addRow((row) => {
row.addField('Location Fee', `$${locationFee}`);
});
}
 
if (selectedAddons.length > 0) {
section.addRow((row) => {
row.addField('Add-ons', `$${getAddonsTotal()}`);
});
}
 
if (printPkg !== 'none') {
section.addRow((row) => {
row.addField('Print Package', `$${getPrintPackagePrice()}`);
});
}
 
section.addDivider();
section.addSpacer(10);
section.addRow((row) => {
row.addField('TOTAL', `$${getTotalPrice()}`);
});
});
 
pdf.addSection('What\'s Included', (section) => {
const sessionType = session.dropdown('type')?.value() || 'standard';
const includes: Record<string, string[]> = {
'mini': ['20-minute session', '10 professionally edited photos', 'Online gallery for 30 days'],
'standard': ['1-hour session', '25 professionally edited photos', 'Online gallery for 60 days', '1 outfit change'],
'extended': ['2-hour session', '50 professionally edited photos', 'Online gallery for 90 days', '2 outfit changes'],
'full-day': ['4+ hour session', '100+ professionally edited photos', 'Online gallery for 1 year', 'Unlimited outfit changes']
};
 
const items = includes[sessionType] ?? includes['standard'] ?? [];
items.forEach(item => {
section.addText(`โ€ข ${item}`);
});
});
 
pdf.addSection('Terms & Conditions', (section) => {
section.addText('โ€ข This quote is valid for 14 days from the date of generation.');
section.addText('โ€ข 50% retainer required to book your session date.');
section.addText('โ€ข Rescheduling requires 48-hour notice.');
section.addText('โ€ข Photos delivered within 2-3 weeks (rush delivery available).');
section.addSpacer(10);
section.addText('Questions? Contact us at hello@photographer.com');
});
});
}
 

Why Photographers Love It

Stop losing leads to "I'll think about it." Let clients see prices and book while they're excited.

Save Hours on DMs

No more "what are your rates?" in every message. Clients see prices upfront 24/7.

More Bookings

Clients who build their own package are ready to book. Less back-and-forth, more conversions.

Look Professional

Interactive pricing builds trust. Stand out from photographers with PDF price lists.

No Coding Required

Describe your packages. Our AI builds your calculator in minutes.

Add a Pricing Calculator in 3 Steps

1

Build Your Calculator

Use our AI assistant or pick a template. Set your session rates, packages, and add-ons.

2

Customize Your Look

Match your brand aesthetic. Mobile-friendly by default. Looks beautiful everywhere.

3

Embed Anywhere

Copy 2 lines of code. Works on Squarespace, WordPress, Wix, Showit, or any custom site.

Add to your website
<script src="https://formts.com/widget.js"></script>
<formts-widget link-id="your-calculator"></formts-widget>

Everything You Need to Automate Pricing

Real-Time Calculations

Prices update instantly as clients build their package. No page reloads, no waiting.

Email Notifications

Get notified the moment someone requests a quote. Never miss a potential booking.

PDF Quotes

Auto-generate beautiful quote PDFs with your branding. Clients can save and share.

Conditional Logic

Show wedding add-ons only for wedding inquiries. Smart forms that adapt to each client.

Works Everywhere

Embed on any website with 2 lines of code. Squarespace, WordPress, Showit, custom sites.

Mobile Optimized

Looks stunning on phones and tablets. Most clients will browse on mobile.

Frequently Asked Questions

Do I need to know how to code?

No. Our AI assistant builds the calculator from your description. Just tell it about your session types and pricing. You can also start from a template and customize it - no coding required.

Will it work on my Squarespace/WordPress/Showit site?

Yes. FormTs works on any website that allows custom HTML. You just paste 2 lines of code where you want the calculator to appear. Works on Squarespace, WordPress, Showit, Wix, and any custom site.

Is the calculator really free?

Yes. Calculators that don't collect submissions are completely free - no limits, no credit card. If you want to collect client details, the Free plan includes 100 submissions/month. Need more? Pro gives you 1,000/month.

Can I customize my packages and pricing?

Absolutely. You control everything - session types, hourly rates, package bundles, add-ons like albums and prints. The calculator uses YOUR pricing exactly as you define it.

How do I get notified when someone requests a quote?

All submissions appear in your dashboard instantly. Pro plan includes email notifications and webhooks to connect with Zapier, Dubsado, HoneyBook, or your CRM.

What if I want to change my pricing later?

Edit anytime from your dashboard. Changes go live instantly - no need to touch your website code again. Update prices seasonally, add new packages, or change the design whenever you want.

Ready to Stop Losing Leads to Price Shoppers?

Join photographers who automated their pricing and started booking more clients. Start with a free template or let AI build your custom calculator.

No credit card required. Free plan available. Setup in under 10 minutes.