Use casesRecipes

Photography Session Booking

Let clients browse packages, pick a location, schedule a session, and pay a deposit — across WhatsApp and web chat.

DifficultyBeginner
TrackBuilder Track
ChannelsWhatsAppWeb Chat
IntegrationsGoogle Calendar (scheduling)Stripe (deposit)Packages (knowledge base)

What you'll build

An agent that guides clients through booking a photography session: package browsing, location selection, schedule checking via Google Calendar, and deposit collection via Stripe. The agent handles all pre-booking questions from a knowledge base so you spend your time behind the camera, not the inbox.

Customer journey

A client uses WhatsApp or Web Chat to enquire about packages and book a session. The agent quotes from the packages KB, checks calendar availability, and collects a deposit through Stripe.

Loading diagram…

See Deploying and testing channels for connect and test steps per channel.

Prerequisites

  • BimpeAI account with an API key (sk_…)
  • Read Anatomy of a workflow agent first — this recipe skips steps covered there
  • Google Calendar and Stripe connected in the Console dashboard (see Step 4)
  • WhatsApp Business number and/or web chat widget connected in the Console dashboard (see Step 4)

Steps

1. Find or create the workflow

import { BimpeAI } from "@bimpeai/sdk";

const bimpe = new BimpeAI({ apiKey: process.env.BIMPEAI_API_KEY! });

const page = await bimpe.workflows.list({ scope: "public", search: "photography" });
const workflow = page.data[0];
console.log(workflow.id, workflow.name);
import os
from bimpeai import BimpeAI

client = BimpeAI(api_key=os.environ["BIMPEAI_API_KEY"])

page = client.workflows.list(scope="public", search="photography")
workflow = page.data[0]
print(workflow.id, workflow.name)

Or build a new workflow from scratch with workflows.create instead of finding one. name and system_prompt are required; it returns the new Workflow whose id you bind the agent to. See Anatomy of a workflow agent for the full set of optional fields like rules and flows.

const workflow = await bimpe.workflows.create({
  name: "Photography booking agent",
  system_prompt: "You help clients browse packages, pick a shoot location, schedule a session, and pay a deposit.",
});
console.log(workflow.id);
workflow = client.workflows.create(
    name="Photography booking agent",
    system_prompt="You help clients browse packages, pick a shoot location, schedule a session, and pay a deposit.",
)
print(workflow.id)

2. Create the agent

const agent = await bimpe.agents.create(
  {
    name: "Photography booking agent",
    description: "Books photography sessions, checks availability, and collects the deposit via Stripe.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-photography-booking-agent-v1" },
);

console.log(agent.id);
agent = client.agents.create(
    name="Photography booking agent",
    description="Books photography sessions, checks availability, and collects the deposit via Stripe.",
    workflow_id=workflow.id,
    idempotency_key="create-photography-booking-agent-v1",
)

print(agent.id)

3. Add knowledge bases (optional)

Knowledge bases are optional; an agent whose workflow and integrations already cover everything it needs to say can skip this step. This recipe uses one to ground the agent in the details it must quote accurately.

Two knowledge bases cover the session packages and the available shoot locations. The agent draws on both to answer client questions before booking.

// Session packages
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Packages",
  content:
    "MINI SESSION — £150 — 30 min — 1 location — 10 edited digital images delivered in 7 days\n" +
    "STANDARD SESSION — £280 — 60 min — 1–2 locations — 25 edited digital images delivered in 7 days\n" +
    "PREMIUM SESSION — £450 — 90 min — up to 3 locations — 50 edited digital images + 1 printed 30x40cm canvas — delivered in 5 days\n" +
    "FAMILY PORTRAIT — £320 — 60 min — 1 location — up to 6 people — 30 edited digital images — delivered in 7 days\n\n" +
    "All packages include: online gallery for download, print-release licence, pre-shoot style consultation.\n" +
    "Deposit: 30% of package price required to secure the date. Balance due on the day of the shoot.\n" +
    "Rescheduling: free up to 72 hours before the session. Within 72 hours a rescheduling fee of £30 applies.\n" +
    "Cancellation: deposit is non-refundable if cancelled within 14 days of the session.",
});

// Shoot locations
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Locations",
  content:
    "URBAN STREETS (East London) — industrial backdrop, brick walls, neon signs — suitable year-round\n" +
    "BOTANICAL GARDENS (Kew, SW London) — lush greenery, glasshouses, open lawns — best spring/summer\n" +
    "CLIFFSIDE (Brighton, 60 min from London) — dramatic coastal views — best April–September\n" +
    "IN-STUDIO (Shoreditch, E1) — controlled lighting, seamless backdrops, props available — year-round\n\n" +
    "Travel: sessions within 10 miles of Central London included. Beyond 10 miles a £0.45/mile travel fee applies.\n" +
    "Brighton sessions include a £35 travel supplement.",
});
# Session packages
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Packages",
    "content": (
        "MINI SESSION — £150 — 30 min — 1 location — 10 edited digital images delivered in 7 days\n"
        "STANDARD SESSION — £280 — 60 min — 1–2 locations — 25 edited digital images delivered in 7 days\n"
        "PREMIUM SESSION — £450 — 90 min — up to 3 locations — 50 edited digital images + 1 printed 30x40cm canvas — delivered in 5 days\n"
        "FAMILY PORTRAIT — £320 — 60 min — 1 location — up to 6 people — 30 edited digital images — delivered in 7 days\n\n"
        "All packages include: online gallery for download, print-release licence, pre-shoot style consultation.\n"
        "Deposit: 30% of package price required to secure the date. Balance due on the day of the shoot.\n"
        "Rescheduling: free up to 72 hours before the session. Within 72 hours a rescheduling fee of £30 applies.\n"
        "Cancellation: deposit is non-refundable if cancelled within 14 days of the session."
    ),
})

# Shoot locations
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Locations",
    "content": (
        "URBAN STREETS (East London) — industrial backdrop, brick walls, neon signs — suitable year-round\n"
        "BOTANICAL GARDENS (Kew, SW London) — lush greenery, glasshouses, open lawns — best spring/summer\n"
        "CLIFFSIDE (Brighton, 60 min from London) — dramatic coastal views — best April–September\n"
        "IN-STUDIO (Shoreditch, E1) — controlled lighting, seamless backdrops, props available — year-round\n\n"
        "Travel: sessions within 10 miles of Central London included. Beyond 10 miles a £0.45/mile travel fee applies.\n"
        "Brighton sessions include a £35 travel supplement."
    ),
})

4. Connect channels and integrations (dashboard)

Channels, Google Calendar, and Stripe are connected in the dashboard

The API cannot create channel connections, but integrations can now be configured through it; see Configuring integrations. Connect your messaging channels on the Deploy screen and Google Calendar and Stripe on the Integrations screen of the Console dashboard. The SDK lists what is active but cannot modify channel connections.

  1. In the Console dashboard, pick your agent from the switcher at the top, then open Deploy.
  2. Under Messaging & Chat, click Connect on the WhatsApp card and follow the prompts to link your WhatsApp Business number.
  3. Under Messaging & Chat, click Connect on the Web Chat Widget card to add the widget to your photography website or portfolio.
  4. Open Integrations, find Google Calendar, and click Connect to check shoot date availability.
  5. Open Integrations, find Stripe, and click Connect to collect the 30% deposit that secures the booking.

Connect WhatsApp

Customers message your WhatsApp Business number for support and transactions.

  1. Open the Deploy screen in the Console dashboard and select your agent.
  2. Under Messaging & Chat, click Connect on the WhatsApp card.
  3. Follow the prompts to link your WhatsApp Business number.
  4. Once connected, customers can message your business number and the agent replies within WhatsApp's 24-hour session window.

Full reference: Deploying and testing channels.

Connect Web Chat

Visitors use the chat widget embedded on your website or app.

  1. Open Deploy and select your agent.
  2. Under Messaging & Chat, click Connect on the Web Chat Widget card.
  3. Copy the embed snippet and paste it into your site's HTML before the closing body tag.
  4. Publish your site — the chat bubble appears in the corner and routes messages to this agent.

Full reference: Deploying and testing channels.

Also on Instagram and Messenger: the same Deploy → Connect flow applies. Testers use the Deploy panel links or getTestCode deep links for each network. Instagram · Messenger

5. Test your agent

Before going live, exercise the agent on a test channel. Fetch the test code (created on first request), then test on WhatsApp — share the deep link or start message with a human tester, or inject a message from your server.

Test WhatsApp

Human tester: fetch the test code with agents.getTestCode (or use the Deploy panel). Share the deep link or start <code> message with a tester.

SDK injection: call conversations.send with is_test_channel: true and the matching channel_type.

Full reference: Deploying and testing channels.

Test Web Chat

Playground: open Playground → Chat in the dashboard for a quick sanity check.

SDK injection: call conversations.send with channel_type: "webchat" and a stable channel_user_id, or set is_test_channel: true before go-live.

Full reference: Deploying and testing channels.

const { channels } = await bimpe.agents.getTestCode(agent.id);
// A tester opens channels.whatsapp.url, or sends channels.whatsapp.start_message
// to channels.whatsapp.phone_number, to open a 24-hour test window.
console.log(channels.whatsapp.start_message, channels.whatsapp.url);

// Or inject a test message yourself:
await bimpe.conversations.send(agent.id, {
  message: "How much is a standard family portrait session in Kew?",
  channel_type: "whatsapp",
  channel_user_id: "<tester-whatsapp-number>",
  is_test_channel: true,
});
test_code = client.agents.get_test_code(agent.id)
# A tester opens .url, or sends .start_message to .phone_number, to open a 24-hour window.
print(test_code.channels.whatsapp.start_message, test_code.channels.whatsapp.url)

# Or inject a test message yourself:
client.conversations.send(
    agent.id,
    message="How much is a standard family portrait session in Kew?",
    channel_type="whatsapp",
    channel_user_id="<tester-whatsapp-number>",
    is_test_channel=True,
)

See Test your agent for the other test channels and the pause-AI rule.

6. Verify and go live

const integrations = await bimpe.agents.integrations.list(agent.id);
const channels = await bimpe.agents.channels.list(agent.id);
console.log("Integrations:", integrations.map((i) => i.name));
console.log("Channels:", channels.map((c) => c.type));
integrations = client.agents.integrations.list(agent.id)
channels = client.agents.channels.list(agent.id)
print("Integrations:", [i.name for i in integrations])
print("Channels:", [c.type for c in channels])

Full example

import { BimpeAI } from "@bimpeai/sdk";

const bimpe = new BimpeAI({ apiKey: process.env.BIMPEAI_API_KEY! });

// 1. Find workflow
const page = await bimpe.workflows.list({ scope: "public", search: "photography" });
const workflow = page.data[0];

// 2. Create agent
const agent = await bimpe.agents.create(
  {
    name: "Photography booking agent",
    description: "Books photography sessions, checks availability, and collects the deposit via Stripe.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-photography-booking-agent-v1" },
);

// 3. Add knowledge bases
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Packages",
  content:
    "Mini Session — £150 — 30 min — 10 images\n" +
    "Standard Session — £280 — 60 min — 25 images\n" +
    "Premium Session — £450 — 90 min — 50 images + canvas print\n" +
    "Deposit: 30% required to secure the date.",
});

await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Locations",
  content:
    "Urban Streets (East London) — year-round\n" +
    "Botanical Gardens (Kew) — best spring/summer\n" +
    "In-Studio (Shoreditch) — year-round, controlled lighting",
});

// 4. Verify integrations and channels (configured via dashboard)
const integrations = await bimpe.agents.integrations.list(agent.id);
const channels = await bimpe.agents.channels.list(agent.id);
console.log("Agent ID:", agent.id);
console.log("Integrations:", integrations.map((i) => i.name));
console.log("Channels:", channels.map((c) => c.type));

// 5. Stream messages in a booking conversation
const controller = new AbortController();

for await (const event of bimpe.conversations.messages.stream(
  agent.id,
  "<conversation_id>",
  { signal: controller.signal },
)) {
  console.log(event.role, event.message);
}
import os
from bimpeai import BimpeAI

client = BimpeAI(api_key=os.environ["BIMPEAI_API_KEY"])

# 1. Find workflow
page = client.workflows.list(scope="public", search="photography")
workflow = page.data[0]

# 2. Create agent
agent = client.agents.create(
    name="Photography booking agent",
    description="Books photography sessions, checks availability, and collects the deposit via Stripe.",
    workflow_id=workflow.id,
    idempotency_key="create-photography-booking-agent-v1",
)

# 3. Add knowledge bases
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Packages",
    "content": (
        "Mini Session — £150 — 30 min — 10 images\n"
        "Standard Session — £280 — 60 min — 25 images\n"
        "Premium Session — £450 — 90 min — 50 images + canvas print\n"
        "Deposit: 30% required to secure the date."
    ),
})

client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Locations",
    "content": (
        "Urban Streets (East London) — year-round\n"
        "Botanical Gardens (Kew) — best spring/summer\n"
        "In-Studio (Shoreditch) — year-round, controlled lighting"
    ),
})

# 4. Verify integrations and channels (configured via dashboard)
integrations = client.agents.integrations.list(agent.id)
channels = client.agents.channels.list(agent.id)
print("Agent ID:", agent.id)
print("Integrations:", [i.name for i in integrations])
print("Channels:", [c.type for c in channels])

# 5. Stream messages in a booking conversation
for event in client.conversations.messages.stream(agent.id, "<conversation_id>"):
    print(event.role, event.message)

Deploy and go live

Go-live checklist

  • Store your API key in BIMPEAI_API_KEY (server-side only).
  • Confirm Google Calendar appears in integrations.list or is connected in the dashboard.
  • Confirm Stripe appears in integrations.list or is connected in the dashboard.
  • Verify WhatsApp is connected on the Deploy screen (agents.channels.list shows it enabled).
  • Verify Web Chat is connected on the Deploy screen (agents.channels.list shows it enabled).
  • Set Escalation Email under Settings → Agent if humans must take over.
  • Switch the agent to live with updateLiveStatus / update_live_status.
  • Monitor the Conversations screen (or stream via SDK) after launch.

After go-live

Confirm Google Calendar and Stripe before opening bookings. Update packages KB when pricing changes.

Variations

  • Add a seasonal promotions knowledge base entry (e.g. a Christmas mini session offer) and update it around the relevant period.
  • Add a FAQ knowledge base covering what to wear, how to prepare children for a shoot, and image delivery timelines.
  • Send a session preparation guide to the client's WhatsApp the day before using conversations.send (create-or-send by channel) from a scheduled script.

On this page