Photography Session Calculator

Streamline your photography business with instant pricing for clients. This calculator covers various session types from quick portraits to full wedding coverage, with options for prints, albums, and digital deliverables. Perfect for portrait photographers, event photographers, and studios looking to give clients transparent pricing while capturing qualified leads.

Freelance & BusinessPopular

Try the Calculator

Photography Session Quote
๐Ÿ“ธ Session Type
 
 
 
๐Ÿ“ Location & Travel
 
๐Ÿ–ผ๏ธ Prints & Products
 
 
โœจ Additional Services
 

๐Ÿ’ฐ Investment Summary
$ 300.00
+
$ 0.00
+
$ 0.00
+
$ 0.00
๐Ÿงพ Summary
$ 300.00
$100 session fee due at booking.
Final quote provided after consultation.
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
export function photographySessionCalculator(form: FormTs) {
// Base session rates
const sessionRates: Record<string, number> = {
'mini': 150, // 30 min, 10 images
'standard': 300, // 1 hour, 25 images
'extended': 500, // 2 hours, 50 images
'half-day': 800, // 4 hours, 100 images
'full-day': 1500, // 8 hours, 200 images
'wedding-basic': 2500, // 6 hours, 1 photographer
'wedding-premium': 4500 // 10 hours, 2 photographers
};
 
// Session type categories
const sessionTypeMultipliers: Record<string, number> = {
'portrait': 1.0,
'family': 1.1,
'headshot': 1.0,
'maternity': 1.1,
'newborn': 1.3,
'event': 1.2,
'corporate': 1.4,
'product': 1.3,
'real-estate': 1.0
};
 
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Photography Session Quote',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
 
form.addSpacer({ height: 20 });
 
// Session Type Section
const sessionSection = form.addSubform('sessionType', { title: '๐Ÿ“ธ Session Type' });
 
sessionSection.addRow(row => {
row.addDropdown('category', {
label: 'Photography Type',
options: [
{ id: 'portrait', name: 'Individual Portrait' },
{ id: 'family', name: 'Family Portrait' },
{ id: 'headshot', name: 'Professional Headshot' },
{ id: 'maternity', name: 'Maternity Session' },
{ id: 'newborn', name: 'Newborn Session' },
{ id: 'event', name: 'Event Coverage' },
{ id: 'corporate', name: 'Corporate/Business' },
{ id: 'product', name: 'Product Photography' },
{ id: 'real-estate', name: 'Real Estate Photography' }
],
defaultValue: 'portrait',
isRequired: true
}, '1fr');
});
 
sessionSection.addRow(row => {
row.addRadioButton('sessionLength', {
label: 'Session Package',
options: [
{ id: 'mini', name: 'Mini Session - 30 min, 10 edited images ($150)' },
{ id: 'standard', name: 'Standard Session - 1 hour, 25 images ($300)' },
{ id: 'extended', name: 'Extended Session - 2 hours, 50 images ($500)' },
{ id: 'half-day', name: 'Half-Day - 4 hours, 100 images ($800)' },
{ id: 'full-day', name: 'Full-Day - 8 hours, 200 images ($1,500)' }
],
defaultValue: 'standard',
orientation: 'vertical',
isRequired: true
});
});
 
sessionSection.addRow(row => {
row.addInteger('additionalHours', {
label: 'Additional Hours (+$150/hr)',
min: 0,
max: 8,
defaultValue: 0
}, '1fr');
row.addInteger('additionalImages', {
label: 'Additional Edited Images (+$15 each)',
min: 0,
max: 100,
defaultValue: 0
}, '1fr');
});
 
// Wedding Package (conditional)
const weddingSection = form.addSubform('weddingPackage', {
title: '๐Ÿ’’ Wedding Package',
isVisible: () => sessionSection.dropdown('category')?.value() === 'event'
});
 
weddingSection.addRow(row => {
row.addCheckbox('isWedding', {
label: 'This is a wedding or engagement',
defaultValue: false
});
});
 
weddingSection.addRow(row => {
row.addRadioButton('weddingPackage', {
label: 'Wedding Coverage',
options: [
{ id: 'none', name: 'Not applicable' },
{ id: 'wedding-basic', name: 'Essential - 6 hours, 1 photographer ($2,500)' },
{ id: 'wedding-premium', name: 'Premium - 10 hours, 2 photographers ($4,500)' }
],
defaultValue: 'none',
orientation: 'vertical',
isVisible: () => weddingSection.checkbox('isWedding')?.value() === true
});
});
 
weddingSection.addRow(row => {
row.addCheckboxList('weddingAddons', {
label: 'Wedding Add-ons',
options: [
{ id: 'engagement', name: 'Include Engagement Session (+$350)' },
{ id: 'secondShooter', name: 'Add Second Photographer (+$500)' }
],
orientation: 'vertical',
isVisible: () => weddingSection.checkbox('isWedding')?.value() === true
});
});
 
// Location Section
const locationSection = form.addSubform('location', { title: '๐Ÿ“ Location & Travel' });
 
locationSection.addRow(row => {
row.addRadioButton('locationType', {
label: 'Session Location',
options: [
{ id: 'studio', name: 'Studio (No travel fee)' },
{ id: 'local', name: 'Local (within 25 miles)' },
{ id: 'travel', name: 'Travel Required (25+ miles)' }
],
defaultValue: 'studio',
orientation: 'vertical'
});
});
 
locationSection.addRow(row => {
row.addInteger('travelMiles', {
label: 'Distance (miles)',
min: 25,
max: 200,
defaultValue: 30,
isVisible: () => locationSection.radioButton('locationType')?.value() === 'travel'
}, '1fr');
});
 
// Deliverables Section
const deliverablesSection = form.addSubform('deliverables', { title: '๐Ÿ–ผ๏ธ Prints & Products' });
 
deliverablesSection.addRow(row => {
row.addCheckboxList('printProducts', {
label: 'Print Packages',
options: [
{ id: 'printSmall', name: 'Print Package - Small (+$150)' },
{ id: 'printLarge', name: 'Print Package - Large (+$350)' },
{ id: 'canvas', name: '16x20 Canvas Print (+$200)' },
{ id: 'album', name: 'Photo Album - 20 pages (+$400)' }
],
orientation: 'vertical'
}, '1fr');
row.addCheckboxList('digitalOptions', {
label: 'Digital Options',
options: [
{ id: 'allDigital', name: 'All Images (Full Gallery) (+$300)' },
{ id: 'rushDelivery', name: 'Rush Delivery - 48 hours (+$200)' }
],
orientation: 'vertical'
}, '1fr');
});
 
// Add-ons Section
const addonsSection = form.addSubform('addons', { title: 'โœจ Additional Services' });
 
addonsSection.addRow(row => {
row.addCheckboxList('services', {
label: 'Extra Services',
options: [
{ id: 'makeupArtist', name: 'Hair & Makeup Artist (+$150)' },
{ id: 'wardrobeStylist', name: 'Wardrobe Styling (+$100)' },
{ id: 'retouching', name: 'Advanced Retouching (+$10/image)' },
{ id: 'videoclip', name: 'Behind-the-Scenes Video (+$250)' }
],
orientation: 'vertical'
});
});
 
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
 
// Quote Summary Section
const summarySection = form.addSubform('summary', { title: '๐Ÿ’ฐ Investment Summary', isCollapsible: false });
 
const getBaseSessionCost = () => {
const isWeddingEvent = weddingSection.checkbox('isWedding')?.value();
const weddingPackage = weddingSection.radioButton('weddingPackage')?.value();
 
if (isWeddingEvent && weddingPackage && weddingPackage !== 'none') {
return sessionRates[weddingPackage] || 2500;
}
 
const sessionLength = sessionSection.radioButton('sessionLength')?.value() || 'standard';
const category = sessionSection.dropdown('category')?.value() || 'portrait';
 
const baseRate = sessionRates[sessionLength] || 300;
const categoryMultiplier = sessionTypeMultipliers[category] || 1;
 
return Math.round(baseRate * categoryMultiplier);
};
 
const getTravelFee = () => {
const locationType = locationSection.radioButton('locationType')?.value();
if (locationType === 'studio') return 0;
if (locationType === 'local') return 25;
 
const miles = locationSection.integer('travelMiles')?.value() || 30;
return Math.round((miles - 25) * 0.65) + 25; // $0.65/mile after 25 miles + $25 base
};
 
const getWeddingAddonsCost = () => {
const addons = weddingSection.checkboxList('weddingAddons')?.value() || [];
let total = 0;
if (addons.includes('engagement')) total += 350;
if (addons.includes('secondShooter')) total += 500;
return total;
};
 
const getProductsCost = () => {
const prints = deliverablesSection.checkboxList('printProducts')?.value() || [];
const digital = deliverablesSection.checkboxList('digitalOptions')?.value() || [];
let total = 0;
 
if (prints.includes('printSmall')) total += 150;
if (prints.includes('printLarge')) total += 350;
if (prints.includes('canvas')) total += 200;
if (prints.includes('album')) total += 400;
if (digital.includes('allDigital')) total += 300;
if (digital.includes('rushDelivery')) total += 200;
 
return total;
};
 
const getServicesCost = () => {
const services = addonsSection.checkboxList('services')?.value() || [];
let total = 0;
 
if (services.includes('makeupArtist')) total += 150;
if (services.includes('wardrobeStylist')) total += 100;
if (services.includes('videoclip')) total += 250;
 
// Retouching cost depends on number of images
if (services.includes('retouching')) {
const sessionLength = sessionSection.radioButton('sessionLength')?.value() || 'standard';
const baseImages: Record<string, number> = {
'mini': 10, 'standard': 25, 'extended': 50, 'half-day': 100, 'full-day': 200
};
const images = baseImages[sessionLength] || 25;
const additionalImages = sessionSection.integer('additionalImages')?.value() || 0;
total += (images + additionalImages) * 10;
}
 
return total;
};
 
summarySection.addRow(row => {
row.addPriceDisplay('sessionCost', {
label: 'Session Fee',
computedValue: () => {
let cost = getBaseSessionCost();
 
// Additional hours
const additionalHours = sessionSection.integer('additionalHours')?.value() || 0;
cost += additionalHours * 150;
 
// Additional images
const additionalImages = sessionSection.integer('additionalImages')?.value() || 0;
cost += additionalImages * 15;
 
return cost;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('travelFee', {
label: 'Travel Fee',
computedValue: getTravelFee,
variant: 'default',
prefix: '+'
}, '1fr');
});
 
summarySection.addRow(row => {
row.addPriceDisplay('weddingExtras', {
label: 'Wedding Add-ons',
computedValue: getWeddingAddonsCost,
variant: 'default',
prefix: '+',
isVisible: () => weddingSection.checkbox('isWedding')?.value() === true
}, '1fr');
row.addPriceDisplay('productsTotal', {
label: 'Prints & Products',
computedValue: getProductsCost,
variant: 'default',
prefix: '+'
}, '1fr');
});
 
summarySection.addRow(row => {
row.addPriceDisplay('servicesTotal', {
label: 'Additional Services',
computedValue: getServicesCost,
variant: 'default',
prefix: '+'
});
});
 
const finalSection = form.addSubform('final', {
title: '๐Ÿงพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
 
finalSection.addRow(row => {
row.addPriceDisplay('totalInvestment', {
label: 'Total Investment',
computedValue: () => {
let total = getBaseSessionCost();
 
// Additional hours and images
const additionalHours = sessionSection.integer('additionalHours')?.value() || 0;
total += additionalHours * 150;
const additionalImages = sessionSection.integer('additionalImages')?.value() || 0;
total += additionalImages * 15;
 
// Travel
total += getTravelFee();
 
// Wedding extras
total += getWeddingAddonsCost();
 
// Products
total += getProductsCost();
 
// Services
total += getServicesCost();
 
return Math.round(total);
},
variant: 'large'
});
});
 
finalSection.addRow(row => {
row.addTextPanel('deposit', {
computedValue: () => {
const isWeddingEvent = weddingSection.checkbox('isWedding')?.value();
if (isWeddingEvent) {
return '50% deposit required to reserve your date.';
}
return '$100 session fee due at booking.';
},
customStyles: { 'font-size': '0.9rem', 'color': '#059669' }
});
});
 
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Final quote provided after consultation.',
customStyles: { 'font-size': '0.85rem', 'color': '#94a3b8', 'font-style': 'italic' }
});
});
 
form.configureSubmitButton({
label: 'Book Consultation'
});
}
 

Frequently Asked Questions

Can I create different packages for different session types?

Yes, you can configure unique pricing for portraits, events, weddings, commercial work, and any other session type with custom deliverables for each.

Does it handle print and album pricing?

Absolutely. You can add print packages, albums, canvas prints, and other physical products as add-ons with customizable pricing.

Can I set different rates for travel?

Yes, the calculator includes travel fee options based on distance, with customizable mileage rates and minimum distances.

How do I handle wedding photography packages?

Wedding packages can include multiple photographers, hours of coverage, engagement sessions, albums, and more - all with configurable pricing.