BookFlow — Business Guide
This guide is for the owner, manager, or staff member of a business that runs on BookFlow. It covers everything you do from the dashboard at <https://app.bookflow.app>: setting up your account, taking bookings, managing customers, configuring the embeddable widget, and reading analytics. If you are a developer integrating with BookFlow, read the Developer API Guide. If you are an end-user who booked an appointment, read the User Guide.
Table of contents
- 1.1 Creating an account
- 1.2 Connecting Stripe
- 1.3 Adding services
- 1.4 Adding staff
- 1.5 Setting hours and availability
- 3.1 The calendar view
- 3.2 Creating a booking on behalf of a customer
- 3.3 Rescheduling and cancelling
- 3.4 Refunds
- 3.5 No-shows
- CRM (customers)
- Analytics
- Widget and website integration
- Notifications
- Pricing tiers
- Best practices
- Troubleshooting
1. Setup
1.1 Creating an account
Go to <https://app.bookflow.app/register> and fill in:
- Email — the address you'll use to sign in. We send a one-time sign-in
link rather than a password.
- Name — your full name; appears on receipts and email footers.
- Business name — shown to customers on the booking page and in the
confirmation email.
- Business slug — the URL identifier. It must be lowercase letters,
numbers, and dashes only, 3–40 characters, and unique across BookFlow. This becomes your public URL: book.bookflow.app/book/<slug>.
The slug is permanent. If you need to change it later, contact support; it cannot be self-served because it can break existing links and SEO.
After registration you land in the dashboard. The first-run checklist walks you through the rest of the setup: Stripe, services, staff, hours.
1.2 Connecting Stripe
BookFlow uses Stripe Connect (Express) so payments land in your own Stripe account; BookFlow never holds your money. Onboarding takes about five minutes.
- In the dashboard, open Settings → Payments.
- Click Connect with Stripe. You are redirected to Stripe; sign in
or create an account.
- Fill in your business details (legal name, address, tax id, bank
account for payouts).
- Stripe verifies your identity and returns you to BookFlow.
- BookFlow shows your connection status:
pending_verification— Stripe is still checking your details.restricted— provide whatever Stripe asked for and click
Refresh status to retry.
ready— you can now accept card payments.
If the business does not require payment at booking time, you can skip this step. You can also run the business in manual payments mode (cash on arrival); toggle this in **Settings → Payments → Accept card payments**.
1.3 Adding services
Open Services in the sidebar. Click New service and fill in:
- Name (1–200 chars) — e.g. "Women's Cut & Color".
- Description (optional, up to 2000 chars) — appears on the booking
page.
- Duration in minutes (positive integer, max 24 × 60). The system uses
this for availability and conflict detection. If a haircut takes 45 minutes and you want 10 minutes of buffer to clean up afterward, set the duration to 55.
- Price in the smallest currency unit (cents for USD, pence for GBP,
etc.) and a 3-letter currency code.
- Image URL (optional) — square JPG/PNG, ≥ 600 × 600 px.
- Display order — controls the order on the booking page. Lower
numbers come first.
- Active — when off, the service is hidden from the booking page but
preserved in historical bookings.
Pricing tip — BookFlow does not take a cut on top of Stripe's
per-transaction fee. Your displayed price is the price the customer
pays; Stripe's fee comes out of your payout.
The same form is used for editing. Soft-delete by toggling Active off rather than deleting, so historical bookings still display the right service.
1.4 Adding staff
Open Staff in the sidebar. Click Add staff member and enter:
- Name — appears on the booking page and confirmation email.
- Bio (optional) — short paragraph shown to customers choosing
between staff.
- Avatar URL (optional) — square image, ≥ 400 × 400 px.
- Email (optional) — if present, BookFlow invites the staff member
to set up a dashboard account with limited permissions (they can see only their own calendar and customer notes).
- Active — when off, the staff member is hidden from the booking
page but historical bookings are preserved.
- Display order — controls ordering on the booking page.
A staff member with no service assignments cannot be selected for booking. Open the staff member, then Services tab, and tick the services they can perform.
To give a staff member dashboard access:
- Add their email to their profile.
- They receive an invitation email; clicking it lets them sign in.
- Their role defaults to
staff(read-only on most screens, write on
their own calendar). You can promote them to admin in Team.
1.5 Setting hours and availability
Open Settings → Hours. For each day of the week, set one or more shifts (e.g. Mon–Fri 09:00–18:00, Sat 10:00–14:00). Outside these shifts, no slots are offered.
Per-staff hours can differ from the business hours. In the staff profile, Hours tab lets you override. For example, you might have a Saturday intern who only works Sat 10:00–14:00, while the rest of the staff is off.
Time off (vacation, sick day) is handled in Settings → Time off or directly on the staff member. Time off blocks the staff member from being assigned bookings in that window, but the business stays open if other staff are available.
2. Dashboard overview
The dashboard (/dashboard) is the first thing you see after sign-in. It's a single screen with:
- Today's bookings — chronological list of every booking for today.
- This week — number of bookings, revenue, and utilization (booked
minutes / available minutes).
- Unread messages — a counter; click to open the conversation.
- Recent activity — cancellations, reschedules, new customers.
The sidebar (left on desktop, top on mobile) navigates:
- Dashboard — overview screen.
- Calendar — see all bookings in a day/week/month grid.
- Bookings — list view with filters and bulk actions.
- Customers — CRM.
- Services — service catalog.
- Staff — staff directory.
- Analytics — charts and exports.
- Integrations — widget code, webhooks, API keys.
- Settings — account, payments, hours, branding, plan.
3. Bookings
3.1 The calendar view
The calendar view (under Calendar in the sidebar) defaults to a day-per-staff grid. Use the top toolbar to switch to week or month view, filter by service, or filter by staff.
Click any empty cell to create a booking for that staff member at that time; click an existing booking to see details. Drag a booking to a new time to reschedule. Drop on a different staff column to reassign.
3.2 Creating a booking on behalf of a customer
Sometimes the customer calls instead of booking online. From the dashboard, click Bookings → New booking in the top right. Fill in:
- Service
- Staff (or "any available")
- Date and time
- Customer — either select an existing customer or create a new one
The system checks availability for you, creates the booking, charges the customer's card if your settings require it, and sends the confirmation email exactly as if the customer had booked online. The customer gets the same manage link.
3.3 Rescheduling and cancelling
Open a booking, then click Reschedule or Cancel.
- Reschedule opens the slot picker with the new availability.
- Cancel asks for a reason (tracked for analytics) and offers a
refund based on your cancellation policy. The customer is emailed immediately; the staff member is notified if they have an account.
3.4 Refunds
Open a booking, then Refund. You can refund:
- Full — the entire amount, including Stripe's fee.
- Partial — specify a smaller amount.
- No refund — for no-shows, mark the booking as
no_showinstead
of cancelling; the customer is charged but the business keeps the money.
Refunds post back to the customer's original payment method. Stripe typically settles within 5–10 business days.
Note — BookFlow does not refund Stripe's processing fee when you
refund a charge. Stripe keeps the percentage fee regardless.
3.5 No-shows
Open the booking and click Mark as no-show. The slot is released, the customer's card is not charged (if you hadn't pre-charged), and the customer is not notified by default. The booking is recorded as no_show for analytics.
4. CRM (customers)
The CRM (Customers in the sidebar) lists every customer who has booked with your business, plus any you've added manually. Columns:
- Name
- Email (click to compose)
- Phone
- Bookings — count, click to drill in
- Lifetime value — sum of paid bookings
- Last visit
- Tags — free-form labels you can filter by
Click a customer to see:
- Profile (name, email, phone, notes)
- Upcoming and past bookings
- Payments (including refunds)
- Internal notes — visible only to staff, never to the customer
- Tags and segments
To add a customer manually: Customers → Add customer. Useful for walk-ins whose contact info you want to capture without them booking online yet.
To export: Customers → Export → CSV. The export respects the active filter, so you can export a segment (e.g. "all customers with tag 'vip' and at least 3 bookings").
5. Analytics
The Analytics section has four tabs:
- Overview — bookings and revenue over the last 30/90/365 days, with
the same period a year ago for comparison.
- Services — bookings and revenue per service, with a stacked bar
showing distribution across services over time.
- Staff — per-staff bookings, revenue, and utilization.
- Customers — new vs. returning, average lifetime value, churn.
Each chart supports hover for exact values and click-through to filter the underlying list. Use the Export button on any chart to download the underlying data as CSV.
Two metrics worth understanding:
- Utilization — booked minutes / available minutes. A higher number
means tighter scheduling. For most service businesses 60–80% is healthy; > 90% risks over-booking; < 40% suggests you have excess capacity.
- No-show rate — no_shows / total bookings. A rate above 10% is
worth tackling: enable SMS reminders, require card on file, or charge a deposit.
6. Widget and website integration
The embeddable widget is a tiny JavaScript bundle (~6 KB gzipped) that turns any <div> into a full booking flow. There are two ways to use it.
6.1 Popup mode (recommended for most sites)
Add the snippet to your site's HTML, just before </body>:
html<script src="https://cdn.bookflow.app/widget.js" defer></script> <div id="bookflow-launcher" data-bookflow-slug="bramble-and-co" data-bookflow-mode="popup" ></div>
The widget injects a floating Book now button in the bottom-right corner. Clicking it opens the booking flow in a modal.
6.2 Inline mode
For a fully embedded experience, set data-bookflow-mode="inline":
html<script src="https://cdn.bookflow.app/widget.js" defer></script> <div data-bookflow-slug="bramble-and-co" data-bookflow-mode="inline" style="min-height: 600px" ></div>
The flow renders inside the <div>. Useful for a dedicated "Book" page on your site.
6.3 Programmatic init
If you don't want to drop a <div> in your HTML, you can call BookFlowWidget.init({...}) from your own JS:
html<script src="https://cdn.bookflow.app/widget.js" defer></script> <script> window.addEventListener("DOMContentLoaded", () => { window.BookFlowWidget.init({ slug: "bramble-and-co", mode: "popup", }); }); </script>
6.4 Branding the widget
The widget inherits your business's brand color. Set it in Settings → Branding → Brand color (a hex like #0EA5A4). The widget also reads your logo URL (optional) and uses it as the modal header icon.
To override the widget's copy (e.g. the CTA button text), pass data-bookflow-cta="Make an appointment".
6.5 Self-hosted widget
If you cannot use the public CDN, you can self-host the bundle. Build it from source:
bashcd apps/widget pnpm build
The output (dist/widget.iife.js) is a single file you can host on your own CDN. Then point the script tag at it:
html<script src="https://your-cdn.example.com/widget.iife.js" defer></script> <div data-bookflow-slug="bramble-and-co" data-bookflow-base-url="https://api.bookflow.app" ></div>
data-bookflow-base-url is required when self-hosting so the widget knows which API to call.
7. Notifications
BookFlow sends transactional notifications on three channels:
- Email — via SendGrid. Sent for booking confirmation, reminder (24
hours before), cancellation, and refund. Email is always on and cannot be disabled.
- SMS — via Twilio. Sent for confirmation and reminder. Per-message
fees apply and are billed to your BookFlow account.
- Webhook — JSON payloads to a URL you configure. Use this to pipe
bookings into your own systems (Zapier, Make, custom backend).
You control which notifications go out in Settings → Notifications:
- Email confirmation: on / off
- Email reminder (24h before): on / off
- SMS confirmation: on / off
- SMS reminder (24h before): on / off
- Custom reminders (e.g. 1 hour before): configurable in the same panel
up to 3 reminders per booking
- Webhook URL and signing secret
The widget and the public booking page also display a confirmation toast to the customer immediately after the booking; this is a client-side action and does not depend on the email/SMS queue.
8. Pricing tiers
BookFlow is sold in three plans. Prices are in USD; other currencies are billed at the current exchange rate.
| Free | Pro | Business | |
|---|---|---|---|
| Monthly price | $0 | $29 / month | $99 / month |
| Bookings / month | 50 | 500 | unlimited |
| Staff | 1 | 5 | unlimited |
| Services | unlimited | unlimited | unlimited |
| Customer CRM | yes | yes | yes |
| Card payments | 2.9% + 30¢ per transaction | 2.5% + 30¢ per transaction | 2.2% + 30¢ per transaction |
| SMS reminders | — | + $0.04 per message | + $0.04 per message |
| Custom branding | — | yes | yes |
| Embeddable widget | yes | yes | yes |
| Webhooks | — | yes | yes |
| API access | read-only | full | full |
| Multi-location | — | — | yes |
| White-label widget domain | — | — | yes |
| Priority support | — | email + chat |
Stripe processing fees are charged by Stripe; the values above are the additional markup BookFlow applies on top of Stripe's fees. The actual Stripe fee is always deducted by Stripe from your payout; BookFlow's markup is billed monthly.
To change plans: Settings → Plan → Change plan. Downgrades take effect at the end of the current billing period; upgrades are immediate and pro-rated.
9. Best practices
- Set a cancellation cutoff — at least 24 hours. It reduces no-shows
without alienating customers.
- Send reminders — the 24-hour email reminder alone reduces no-shows
by ~30%. SMS brings another ~10%.
- Require a card for high-value services — even if you don't charge
on booking, having a card on file means you can charge a no-show fee without chasing the customer.
- Use display order to put your best-selling services first. Most
customers pick the first option.
- Tag your customers — "vip", "first-time", "coupon-2026" — and
filter the calendar and exports by tag. The CRM can be a lot more than a contact list.
- Set a buffer between appointments — 5–15 minutes of buffer built
into the service duration prevents the day from sliding late.
- Review analytics weekly — the Week-over-Week chart on the
dashboard is enough to catch sudden drops or spikes before they become patterns.
10. Troubleshooting
My booking page shows "Business not found". The slug is wrong, the tenant was soft-deleted, or DNS hasn't propagated. Check the URL against Settings → Account → Slug.
The widget is loaded but does nothing. Open the browser dev console. Look for messages tagged bookflow. The most common cause is a CSP that blocks the widget's API call. Allow api.bookflow.app in your connect-src directive.
A customer says they paid but I don't see the booking. Check Bookings → Search → by Stripe payment id. The id is on the customer's card statement or in the Stripe receipt. If the booking is there but in pending status, payment confirmation is still in flight; wait 30 seconds and refresh.
My Stripe status is "restricted". Stripe needs more information. Open **Settings → Payments → Update on Stripe, complete whatever Stripe asked for, then click Refresh status** in the BookFlow dashboard.
Reminder emails are going to spam. Ask the customer to whitelist [email protected]. If it keeps happening at scale, set up SPF/DKIM on your custom sending domain in Settings → Notifications → Custom domain.
I want to import customers from another system. Settings → Import → CSV upload. Required columns: `name, email, phone (optional), notes (optional), createdAt (ISO 8601)`. The importer deduplicates by email — existing customers are updated, not duplicated.
For anything else, see the Developer API Guide for the raw HTTP API, or email <[email protected]>.