Use casesRecipes

Fitness & Wellness Class Booking

Let members browse class schedules, view trainer profiles, choose a membership tier or pay per session, and book — over WhatsApp and web chat.

DifficultyIntermediate
TrackBuilder Track or Developer Track
ChannelsWhatsAppWeb Chat
IntegrationsGoogle Calendar (class schedule)Stripe (payments)Trainer/class data (knowledge base)

What you'll build

An agent that handles the full class booking flow: browse the weekly schedule, read trainer profiles and class descriptions, check live availability via Google Calendar, choose a membership tier or pay per session via Stripe, and receive a booking confirmation. Members and drop-ins are both handled in the same conversation.

Customer journey

A member messages on WhatsApp or Web Chat to book a yoga or spin class. The agent reads the class schedule KB, checks capacity in Google Calendar, and processes pay-per-session checkout via 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: "fitness" });
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="fitness")
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: "Fitness booking agent",
  system_prompt: "You help members browse the class schedule, read trainer profiles, choose a membership tier or pay per session, and book classes.",
});
console.log(workflow.id);
workflow = client.workflows.create(
    name="Fitness booking agent",
    system_prompt="You help members browse the class schedule, read trainer profiles, choose a membership tier or pay per session, and book classes.",
)
print(workflow.id)

2. Create the agent

const agent = await bimpe.agents.create(
  {
    name: "Fitness booking agent",
    description: "Helps clients browse and book fitness and wellness classes.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-fitness-booking-agent-v1" },
);

console.log(agent.id);
agent = client.agents.create(
    name="Fitness booking agent",
    description="Helps clients browse and book fitness and wellness classes.",
    workflow_id=workflow.id,
    idempotency_key="create-fitness-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.

Three knowledge bases cover the class catalogue, trainer profiles, and membership tiers. The agent uses all three to answer questions and guide the payment step.

// Class schedule and descriptions
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Classes",
  content:
    "YOGA FLOW — Mon/Wed/Fri 07:00 and 18:30 — 60 min — all levels — max 16 — with Priya\n" +
    "HIIT CIRCUIT — Tue/Thu 06:30 and 17:30 — 45 min — intermediate — max 20 — with Marcus\n" +
    "PILATES REFORMER — Mon/Wed 10:00 and Sat 09:00 — 55 min — beginner friendly — max 10 — with Sofia\n" +
    "SPIN — Tue/Thu/Sat 07:00 and 19:00 — 45 min — all levels — max 24 — with Dani\n" +
    "MEDITATION & BREATHWORK — Sun 09:00 — 45 min — all levels — max 20 — with Priya\n" +
    "BOXING FITNESS — Tue/Thu 18:00 — 60 min — beginner friendly — max 12 — with Marcus\n\n" +
    "Cancellation policy: cancel at least 6 hours before the class to avoid a missed-class charge. " +
    "Pay-per-session cancellations: credit applied to next booking. Member cancellations: counted against monthly allowance.",
});

// Trainer profiles
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Trainers",
  content:
    "Priya — certified yoga instructor (500hr RYT) and mindfulness coach — 8 years experience — " +
    "specialises in vinyasa flow and restorative yoga\n" +
    "Marcus — strength and conditioning coach — NASM certified — specialises in HIIT and boxing fitness — " +
    "former semi-professional footballer\n" +
    "Sofia — STOTT Pilates certified instructor — 6 years experience — specialises in reformer Pilates " +
    "for rehabilitation and posture correction\n" +
    "Dani — indoor cycling instructor — certified spin coach — specialises in power and endurance rides — " +
    "creates bespoke playlists for each class",
});

// Membership tiers and pay-per-session pricing
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Membership and pricing",
  content:
    "PAY PER SESSION — £15/class — book and pay for individual classes with no commitment\n" +
    "STARTER MEMBERSHIP — £45/month — 4 classes per month — any class type — rolling monthly, cancel anytime\n" +
    "UNLIMITED MEMBERSHIP — £85/month — unlimited classes — priority booking 48h before general release — " +
    "includes 1 free guest pass per month\n" +
    "WELLNESS MEMBERSHIP — £110/month — unlimited classes + 1 x 60-min PT session per month + " +
    "10% discount on all retail products\n\n" +
    "Memberships auto-renew monthly. Cancel anytime with 30 days notice. " +
    "First month pro-rated if joining mid-month.\n" +
    "Student and NHS discount: 15% off all membership tiers — proof required at sign-up.",
});
# Class schedule and descriptions
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Classes",
    "content": (
        "YOGA FLOW — Mon/Wed/Fri 07:00 and 18:30 — 60 min — all levels — max 16 — with Priya\n"
        "HIIT CIRCUIT — Tue/Thu 06:30 and 17:30 — 45 min — intermediate — max 20 — with Marcus\n"
        "PILATES REFORMER — Mon/Wed 10:00 and Sat 09:00 — 55 min — beginner friendly — max 10 — with Sofia\n"
        "SPIN — Tue/Thu/Sat 07:00 and 19:00 — 45 min — all levels — max 24 — with Dani\n"
        "MEDITATION & BREATHWORK — Sun 09:00 — 45 min — all levels — max 20 — with Priya\n"
        "BOXING FITNESS — Tue/Thu 18:00 — 60 min — beginner friendly — max 12 — with Marcus\n\n"
        "Cancellation policy: cancel at least 6 hours before the class to avoid a missed-class charge. "
        "Pay-per-session cancellations: credit applied to next booking. Member cancellations: counted against monthly allowance."
    ),
})

# Trainer profiles
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Trainers",
    "content": (
        "Priya — certified yoga instructor (500hr RYT) and mindfulness coach — 8 years experience — "
        "specialises in vinyasa flow and restorative yoga\n"
        "Marcus — strength and conditioning coach — NASM certified — specialises in HIIT and boxing fitness — "
        "former semi-professional footballer\n"
        "Sofia — STOTT Pilates certified instructor — 6 years experience — specialises in reformer Pilates "
        "for rehabilitation and posture correction\n"
        "Dani — indoor cycling instructor — certified spin coach — specialises in power and endurance rides — "
        "creates bespoke playlists for each class"
    ),
})

# Membership tiers and pay-per-session pricing
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Membership and pricing",
    "content": (
        "PAY PER SESSION — £15/class — book and pay for individual classes with no commitment\n"
        "STARTER MEMBERSHIP — £45/month — 4 classes per month — any class type — rolling monthly, cancel anytime\n"
        "UNLIMITED MEMBERSHIP — £85/month — unlimited classes — priority booking 48h before general release — "
        "includes 1 free guest pass per month\n"
        "WELLNESS MEMBERSHIP — £110/month — unlimited classes + 1 x 60-min PT session per month + "
        "10% discount on all retail products\n\n"
        "Memberships auto-renew monthly. Cancel anytime with 30 days notice. "
        "First month pro-rated if joining mid-month.\n"
        "Student and NHS discount: 15% off all membership tiers — proof required at sign-up."
    ),
})

4. Connect channels and integrations (dashboard)

Google Calendar, Stripe, and channels are configured 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 fitness studio website.
  4. Open Integrations, find Google Calendar, and click Connect so the agent can check live class availability.
  5. Open Integrations, find Stripe, and click Connect so the agent can collect pay-per-session payments and membership sign-ups.

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: "Can I book the 7am yoga flow on Friday?",
  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="Can I book the 7am yoga flow on Friday?",
    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: "fitness" });
const workflow = page.data[0];

// 2. Create agent
const agent = await bimpe.agents.create(
  {
    name: "Fitness booking agent",
    description: "Helps clients browse and book fitness and wellness classes.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-fitness-booking-agent-v1" },
);

// 3. Add knowledge bases
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Classes",
  content:
    "Yoga Flow — Mon/Wed/Fri 07:00 and 18:30 — 60 min — with Priya\n" +
    "HIIT Circuit — Tue/Thu 06:30 and 17:30 — 45 min — with Marcus\n" +
    "Spin — Tue/Thu/Sat 07:00 and 19:00 — 45 min — with Dani",
});

await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Membership and pricing",
  content:
    "Pay per session: £15/class\n" +
    "Starter: £45/month (4 classes)\n" +
    "Unlimited: £85/month\n" +
    "Wellness: £110/month (unlimited + monthly PT session)",
});

// 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="fitness")
workflow = page.data[0]

# 2. Create agent
agent = client.agents.create(
    name="Fitness booking agent",
    description="Helps clients browse and book fitness and wellness classes.",
    workflow_id=workflow.id,
    idempotency_key="create-fitness-booking-agent-v1",
)

# 3. Add knowledge bases
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Classes",
    "content": (
        "Yoga Flow — Mon/Wed/Fri 07:00 and 18:30 — 60 min — with Priya\n"
        "HIIT Circuit — Tue/Thu 06:30 and 17:30 — 45 min — with Marcus\n"
        "Spin — Tue/Thu/Sat 07:00 and 19:00 — 45 min — with Dani"
    ),
})

client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Membership and pricing",
    "content": (
        "Pay per session: £15/class\n"
        "Starter: £45/month (4 classes)\n"
        "Unlimited: £85/month\n"
        "Wellness: £110/month (unlimited + monthly PT session)"
    ),
})

# 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

Stripe is required for pay-per-session checkout. Update class schedule KB when the timetable changes.

Variations

  • Add a new-joiner discount knowledge base entry for the agent to apply automatically when a client mentions it is their first visit.
  • Send a class reminder to WhatsApp 2 hours before the session using conversations.send (create-or-send by channel) from a scheduled script.
  • Create a separate agent for corporate wellness packages with a bespoke pricing knowledge base and a dedicated web chat channel on a B2B landing page.

On this page