Skip to content

Photographer Booking

Build a photography studio booking system with equipment management, multi-hour sessions, and deposit handling.

Domain Mapping

Photography ConceptAvailEngine ConceptHow to Set Up
Studio/PhotographerBusinessCreate one business per studio or solo photographer
PhotographerResourceresource_type: "staff", capacity_min: 1, capacity_max: 1
Studio spaceResourceresource_type: "room", capacity_min: 1, capacity_max: 5
Equipment (camera, lighting)Resourceresource_type: "equipment", capacity_min: 1, capacity_max: 1
Session typeServiceDuration per session type (mini=30min, full=2hr, wedding=8hr)
SessionBookingduration_minutes = session length, start_time = session start
Inquiry listWaitlistClients interested in a date that's already booked

Step-by-Step Setup

1. Create the Business

bash
curl -X POST https://api.availengine.com/v1/developer/businesses \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Lens & Light Studio",
    "business_type": "photographer"
  }'

2. Add Resources

bash
# Photographers
curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Dimitris (Lead)", "resource_type": "staff", "capacity_min": 1, "capacity_max": 1, "display_order": 1}'

curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Katerina (Second Shooter)", "resource_type": "staff", "capacity_min": 1, "capacity_max": 1, "display_order": 2}'

# Studio spaces
curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Main Studio", "resource_type": "room", "capacity_min": 1, "capacity_max": 5, "display_order": 3}'

curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Natural Light Room", "resource_type": "room", "capacity_min": 1, "capacity_max": 3, "display_order": 4}'

# Equipment (optional — for tracking rented/shared gear)
curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Canon R5 Kit", "resource_type": "equipment", "capacity_min": 1, "capacity_max": 1, "display_order": 5}'

3. Define Session Types

bash
# Service records for different session lengths and prices:
# { "name": "Mini Session", "duration_minutes": 30, "price_cents": 5000 }
# { "name": "Portrait Session", "duration_minutes": 90, "price_cents": 15000 }
# { "name": "Family Session", "duration_minutes": 120, "price_cents": 25000 }
# { "name": "Wedding — Half Day", "duration_minutes": 480, "price_cents": 150000 }
# { "name": "Wedding — Full Day", "duration_minutes": 600, "price_cents": 250000 }

4. Set Operating Hours

Photographers often have flexible schedules. Set wide availability and use bookings to control actual slots:

bash
curl -X PUT https://api.availengine.com/v1/manage/hours \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "hours": [
      {"day_of_week": 0, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "12:00"},
      {"day_of_week": 1, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "18:00"},
      {"day_of_week": 2, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "18:00"},
      {"day_of_week": 3, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "18:00"},
      {"day_of_week": 4, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "18:00"},
      {"day_of_week": 5, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "18:00"},
      {"day_of_week": 6, "is_open": true, "open_time": "08:00", "close_time": "20:00", "last_booking_time": "12:00"}
    ]
  }'

Sunday Weddings

Keep Sundays open with last_booking_time: 12:00 — this allows full-day wedding bookings (10+ hours) but prevents new bookings starting in the evening.

5. Configure Settings

bash
curl -X PATCH https://api.availengine.com/v1/manage/settings \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "default_slot_interval_minutes": 30,
    "default_slot_duration_minutes": 60,
    "booking_window_days": 365,
    "min_notice_hours": 48,
    "max_capacity": 5,
    "default_deposit_amount_cents": 50
  }'
SettingWhy This Value
slot_interval_minutes: 30Sessions start on the half-hour
booking_window_days: 365Weddings book a year in advance
min_notice_hours: 482-day cancellation policy
default_deposit_amount_cents: 50€50 deposit to hold the date

6. Book a Session

bash
curl -X POST https://api.availengine.com/v1/bookings/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "YOUR_BUSINESS_ID",
    "resource_id": "DIMITRIS_ID",
    "service_id": "WEDDING_FULL_DAY_ID",
    "customer": {
      "first_name": "Alexandra",
      "last_name": "Nikolaou",
      "phone": "+306934445566",
      "email": "alexandra@example.com"
    },
    "booking_date": "2026-09-12",
    "start_time": "10:00",
    "capacity": 1,
    "customer_notes": "Wedding at Agios Georgios church, reception at Grand Hotel"
  }'

Response with deposit:

json
{
  "booking_id": "uuid",
  "status": "pending",
  "confirmation_code": "AV-WD7K3L",
  "deposit": {
    "amount_cents": 5000,
    "client_secret": "pi_xxx_secret_yyy",
    "deposit_type": "charge"
  }
}

The €50 deposit holds the date. Show Stripe Elements to collect payment. On success, the booking auto-confirms.

Photography-Specific Patterns

Deposit as Date-Hold

Photography sessions (especially weddings) need a deposit to hold the date. Without it, another client could book the same date. The flow:

  1. Client inquires about a date → you send them your booking link
  2. Client fills booking form → AvailEngine creates a pending booking
  3. Client sees Stripe payment form → pays deposit
  4. Webhook fires deposit.paid → booking transitions to confirmed
  5. Date is now locked. Nobody else can book that photographer that day.

If the deposit isn't paid, the booking stays pending. You can decide: auto-cancel after 48 hours, or leave it and let the client pay when ready.

Multi-Day Events

For events spanning multiple days (festival coverage, destination wedding):

bash
# Day 1 — Friday setup + rehearsal dinner
curl -X POST ... -d '{"booking_date": "2026-09-11", "start_time": "14:00", "duration_minutes": 360, ...}'

# Day 2 — Saturday wedding
curl -X POST ... -d '{"booking_date": "2026-09-12", "start_time": "10:00", "duration_minutes": 600, ...}'

# Day 3 — Sunday brunch + sendoff
curl -X POST ... -d '{"booking_date": "2026-09-13", "start_time": "10:00", "duration_minutes": 180, ...}'

Add a confirmation_code prefix or grouping in customer_notes to link multi-day bookings.

Second Shooter Booking

When a client books the lead photographer and also needs a second shooter:

  1. Lead photographer is booked as primary resource
  2. Second shooter is booked separately for the same time slot
  3. Use staff_notes to cross-reference: "Second shooter for AV-WD7K3L"

Or create a combined resource: "Dimitris + Second Shooter" with capacity 2.

Mini Session Days

Photographers often run "mini session" days — multiple 30-min slots back to back:

  1. Create a blackout date for all other dates that month
  2. Open only one specific Saturday
  3. Set slot_interval_minutes: 30, slot_duration_minutes: 30
  4. Clients book individual 30-min slots
  5. All 12-16 slots fill up fast — use webhooks to post "only 3 slots left!" on social media

Weather-Dependent Sessions

Outdoor sessions need a rain date. Two approaches:

Option A: Book the rain date as a separate pending booking. If the weather is good, cancel the rain date. If bad, confirm the rain date.

Option B: Use staff_notes to record the backup date: "Rain date: Sept 13". If needed, reschedule by PATCHing the booking date.

Client Galleries & Follow-Up

Use webhooks to automate post-session workflow:

  1. booking.completed fires → trigger: "Thanks for your session!" email with gallery link
  2. booking.checked_in fires → trigger: "Your photographer is ready" SMS (for studio sessions)
  3. booking.confirmed fires → trigger: "Session confirmed for [date]" with prep guide

Widget Integration

js
const client = new AvailEngine('avail_live_YOUR_KEY');
// Photography booking widget flow:
// 1. Client selects session type (mini, portrait, wedding)
// 2. Session type sets duration + price
// 3. Show calendar with available dates
// 4. Only dates with enough open time for the session duration appear
// 5. Client picks date + start time
// 6. Collect client info + event details
// 7. Show deposit payment form
// 8. On payment success → confirmation page with booking code

async function getAvailableDates(businessId, month, sessionType) {
  // Check each weekend day in the month
  // Filter to days where the full session duration is available
  const slots = await client.availability(businessId, {
    date: '2026-09-12',
    durationMinutes: sessionType.durationMinutes,
    capacity: 1
  });
  return slots;
}

Dashboard Tips

  • Blackout Dates: Block out vacation weeks and personal time so clients can't book them
  • Google Calendar: Connect to sync sessions to your phone calendar with client name and location
  • Staff notes: Record shot lists, locations, and special requests — visible to you and your second shooter
  • Webhooks: Set up booking created → auto-reply email with prep guide and what to wear

Next: Back to all guides → | Back to Clinic →

Released under the MIT License.