# Build an AI receptionist for your client

Configure a small business’s AI receptionist with Claude Code, Codex or another coding agent: owner-approved knowledge, services and one inbox, with website chat, voice and SMS checked separately.

## Start with the receptionist

Give your client an AI receptionist that knows their actual services, prices, hours and handoff rules. Latchbell provides the business knowledge, appointment and request tools, and shared inbox. You can configure it over MCP or REST while building the client’s website.

Website chat, voice and SMS have separate setup requirements. Publishing knowledge or finishing setup does not activate all three. Check `receptionist_readiness` before promising a channel is ready, then verify its real customer experience with the owner.

[Read this guide as Markdown](https://staging3.latchbell.com/developers.md) · [Owner setup skill and OAuth helper](https://staging3.latchbell.com/business.md) · [Live front desk OpenAPI](https://staging3.latchbell.com/openapi.json?tag=front-desk) · [MCP endpoint](https://staging3.latchbell.com/mcp) · [Pricing](https://staging3.latchbell.com/pricing)

## 1. Connect the owner’s business

Give your coding agent [https://staging3.latchbell.com/business.md](https://staging3.latchbell.com/business.md). It contains the complete setup sequence and explains the single-file Node helper used below. Download the helper into your working directory; no npm package or shared API key is needed.

For MCP, connect [https://staging3.latchbell.com/mcp](https://staging3.latchbell.com/mcp) using your client’s OAuth flow and read tools/list. For REST, inspect the live front desk OpenAPI before calling an operation, then use the helper. Confirm that receptionist_readiness is available; if it is absent, use the documented reads and ask Latchbell to check channel configuration. The business owner signs in and consents in Latchbell’s browser window. A new owner creates their business there; never ask them to paste a code, password or token into the coding agent.

```bash
curl -fsS --output latchbell.mjs 'https://staging3.latchbell.com/developers/latchbell.mjs'
curl -fsS --output latchbell-openapi.json 'https://staging3.latchbell.com/openapi.json?tag=front-desk'
export LATCHBELL_CLIENT_NAME='Codex'
# Or export LATCHBELL_CLIENT_NAME='Claude Code'; keep it set for later calls.
node latchbell.mjs signin new
# Existing business: node latchbell.mjs signin
node latchbell.mjs GET my_business
node latchbell.mjs GET front_desk
# Confirm receptionist_readiness exists in the live spec before calling it.
node latchbell.mjs GET receptionist_readiness
```

The helper keeps OAuth credentials locally with restricted file permissions. Keep them out of source control, generated sites, screenshots and logs. Use the exact business returned by `my_business`; do not configure a different client’s account.

## 2. Configure a salon starter

The following fictional salon is a setup fixture for a dedicated test business. It is not a real business’s price list. For a client, replace every fact with owner-provided information and review changes with them before saving. These commands change setup; they do not place a test call or send a customer message.

```bash
node latchbell.mjs POST add_receptionist_source '{"title":"Fictional salon fixture","note":"Juniper Demo Salon is fictional. A haircut is $65 for 45 minutes, payable at the visit. Open Tuesday through Saturday, 9am to 5pm in the business time zone. Appointment requests need owner confirmation. Ask the owner about color treatments, cancellations and anything not listed; do not invent a policy."}'
node latchbell.mjs POST update_booking_setup '{"settings":{"enabled":true,"services":[{"id":"haircut","name":"Haircut","duration":45,"priceCents":6500,"payment":"later"}],"hours":{"2":[[540,1020]],"3":[[540,1020]],"4":[[540,1020]],"5":[[540,1020]],"6":[[540,1020]]},"leadMinutes":120,"bufferMinutes":15}}'
node latchbell.mjs POST update_front_desk '{"settings":{"kind":"beauty","bookingMode":"request","greeting":"Thanks for contacting Juniper Demo Salon. How can we help?","handoff":"Ask the owner about unlisted services, policy exceptions or any request for a person."}}'
node latchbell.mjs GET receptionist
```

To teach a real receptionist, use `add_receptionist_source` for the owner’s website or notes, or the helper’s `FILE` command for their menu photos and PDFs. Reading and rebuilding happen in the background. Wait until `still_reading` is false and no source is queued, then compare the business brief (`draft`) against the originals. It goes live by itself as it is rebuilt, so correct misread prices and unresolved questions right away.

The example uses `bookingMode: request`, so the receptionist asks the owner to confirm. For direct appointments, review the fixed prices, durations, business time zone, hours and availability first, then change to `bookingMode: confirm` only at the owner’s request. Customers must approve the service, price and a live time before `book_appointment`; only a confirmed result is a booking. For staff and multi-service selection menus, follow `service_setup` and the live OpenAPI instead of assuming this single-service fixture covers them.

## 3. Review and check each channel

Show the actual brief to the owner: it is already live, so fix what they correct at once with `edit_receptionist_source` (the brief is rebuilt from it). Only after their approval, finish front desk setup with `update_front_desk`. Read readiness again afterwards. Setting `complete: true` is not a phone activation or a channel test.

```bash
# Run only after the owner approves the reviewed brief and setup.
node latchbell.mjs POST update_front_desk '{"complete":true}'
node latchbell.mjs GET receptionist_readiness
node latchbell.mjs GET receptionist_service
```

| Channel | Setup and verification |
| --- | --- |
| Website chat | Questions on the business page, its website and from customers’ own assistants reach the inbox. Latchbell’s AI desk answers them while the owner’s AI answers switch is on (Calls & messages) and the business has AI credits; otherwise they wait for the owner. A deployment with no desk shows `not_configured`, an operator step. Verify an owner-approved test question. |
| Voice | Phone answering requires an active paid plan and a separately connected, routed line. Read actual rates and state from receptionist_service. The owner completes Stripe checkout and approves number setup or forwarding. An active subscription alone does not prove calls work; verify an incoming call after readiness checks. On a call the AI answers from the business brief, books or takes the request the way the business works, and saves a message for anything else. |
| SMS | Texts to the business’s own number come through a Mac signed in to Messages with that number, paired in Calls & messages under Texts ([https://staging3.latchbell.com/app/calls](https://staging3.latchbell.com/app/calls)), which installs Latchbell on that Mac; [https://staging3.latchbell.com/app/link](https://staging3.latchbell.com/app/link) lists the paired Macs. While AI answers are on and there are AI credits, the AI answers them at once, back as a text from that number; otherwise they wait in the inbox for the owner or a connected assistant (message_customer). A plan’s text allowance does not turn on texting from the Latchbell number. Verify receipt and reply with an owner-approved test text. |

Read `channels.website_chat`, `channels.voice` and `channels.sms` separately. Each provides next actions identifying whether the owner, assistant or Latchbell operator must act. `verification.basis: saved_configuration` and `live_verified: false` mean the report has not performed a live test. Never buy a number, activate a paid plan, place a call or send a text merely to exercise this guide. Agree on the channel, cost, destination and test with the owner first; a successful channel test establishes the actual experience.

## 4. Verify the handoff to the inbox

Start with read-only calls: check `business_info` for the exact business id or slug returned by the owner’s account, and `receptionist_readiness` for the owner’s setup. The following is an example `contact_business` request body, not a command to send it. Use only an authorized test business and an agreed test; sending it creates a real conversation and can notify or invoke the business’s connected services.

```json
{
  "business": "REPLACE_WITH_AUTHORIZED_TEST_BUSINESS_ID",
  "customer_name": "Demo Customer",
  "message": "TEST: Please ask the owner about a haircut on Saturday afternoon.",
  "request_type": "appointment"
}
```

A successful request returns a private conversation and `reply_token`. Keep the token private; use `inquiry_status` to check replies and `follow_up_business` for the same conversation. Check the owner’s `inquiries` and inbox to confirm the handoff. A request is not a confirmed appointment, order, inventory hold or payment. Replying with `message_customer` can contact a real customer; do it only when authorized.

For the owner’s acceptance check, verify a known-price question, an unknown-policy question that reaches the owner, and a request appearing in the inbox. Test chat, voice and SMS independently for the channels the client has chosen. This guide performs no external test messages by default.

## Use the supported integration surface

- Use the [live OpenAPI](https://staging3.latchbell.com/openapi.json) for current request and response schemas. Owner operations are under [the front desk tag](https://staging3.latchbell.com/openapi.json?tag=front-desk). REST reads use GET and changes use POST at https://staging3.latchbell.com/api/v1/<tool>; owner calls require the owner’s OAuth access token.
- Discover the same operations with MCP tools/list at [https://staging3.latchbell.com/mcp](https://staging3.latchbell.com/mcp). The [owner skill](https://staging3.latchbell.com/business.md) covers source correction, owner approvals, billing links, phone setup and ongoing inbox work.
- Existing page tools edit and publish the hosted template page. The newer HTML/JavaScript and multi-page site designer does not expose its draft and publishing workflow through the public owner API yet. The Site SDK assumes a Latchbell-hosted same-origin page; it is not a drop-in SDK for any external website.
- Catalogs and order requests are useful inputs to a receptionist. They are not a full ecommerce platform: do not promise live inventory, payment collection, delivery tracking or fulfillment just because an order request was accepted.
- Show the owner [current pricing](https://staging3.latchbell.com/pricing), and use receptionist_service for their actual plan, rates, usage and billing state. Free setup and an inbox do not establish paid-channel readiness.
