Setting a business up for agents: guidance
This page is advice for the AI, or the person, installing Surfing Dog Inbox for a business. It comes from a shop we worked with for a week, including the things we got wrong.
It is guidance, not a set of rules. Every recommendation here has alternatives, and a business may use other tools and other ways of doing things. The inbox is built to sit beside them. Where this page and the business’s own judgement differ, the business decides.
Written on 9 October 2026. Each section keeps three things apart:
- Today: what the inbox does now, in the code you install.
- Pattern: something a business builds itself from today’s pieces: a webhook, a key, a small script.
- Coming: planned, and not built yet.
The step-by-step install is install.md. The exact calls for connecting software the business already uses are in connect.md.
Two ways to use the inbox
Section titled “Two ways to use the inbox”A business with nothing for agents yet
Section titled “A business with nothing for agents yet”A plumber, a salon, a small shop with a contact form. Here the inbox is the front door for agents: they send messages, ask for quotes, book and order there, and the business answers from the owner app, with rules, or with its own AI.
What a score counts depends on the kind of business. The Surfing Dog score weighs what matters for each kind: a salon is scored on bookings, a shop on orders and what follows them, not on messages. Messages and quote requests still help a shop’s customers; they just don’t change its score. Each result page says what the inbox would add for that business, in points where the score counts it.
Today the inbox handles all five kinds of item (message, quote request, booking, order, refund). It answers availability from the business’s services and opening hours, prices from its catalogue, and keeps every item’s history. Rules, with presets for appointments, trades and shops, can confirm, reply and flag on their own. The owner’s AI works inside limits the owner sets in code, not in a prompt (Your limits).
A business that already has its tools
Section titled “A business that already has its tools”A shop with its own checkout, a clinic on a booking system, a team on Intercom, Zendesk, Salesforce, HubSpot or Freshdesk, staff who answer on Telegram or WhatsApp, a business with its own AI agent. Here the inbox is a thin, standard door in front of all that:
- it receives what agents send, in one typed shape, over REST, MCP and email;
- it keeps a log: every item, every event, who caused it and through which door, and, when something becomes a promise (a booking confirmed, an order accepted or paid), a signed receipt;
- it hands each item to where the business already works, and the business’s own systems, people or AI answer.
How it hands things over today: signed webhooks, the owner API and its event stream, and email alerts to the owner. Native connectors for other platforms are coming; the connector-style piece that exists now is the product feed import. So handing items to a helpdesk is a pattern today: a webhook and a small bridge, described in Messages with the tools you already have.
Either way
Section titled “Either way”The inbox is the business’s own software: open source (MIT), at its own subdomain, on its own Cloudflare account or its own server. Customers and their agents write to the business there. Surfing Dog is not in the middle of a message, a booking, an order or a payment. Joining a network is optional and separate: a network lists the business and records the receipts its inbox signs, and install.md, Step 5 lists everything a network receives.
Decide what handles each door
Section titled “Decide what handles each door”A door is something an agent can do: send a message, ask for a quote, book, order, pay, and the steps after (change, cancel, track, return). For each one, decide with the owner what handles it:
- The inbox.
- The business’s own system: its own MCP server, API, booking system or checkout, at an address the business controls.
- Nobody: the business does not do this through an agent. Say so plainly, so agents do not try.
What we learned:
- Do not advertise a door that cannot be fulfilled. An agent that books a slot nobody honours, or orders from a catalogue nobody ships, costs the business more than an agent that was told “not here”.
- One door per action. If orders go to the shop’s own checkout, the inbox should not offer orders as well. Two order doors with different stock and prices confuse agents and people alike.
- Pick defaults for the kind of business, neither everything on nor everything off.
Some starting points, to adjust with the owner:
| Kind of business | Message | Quote | Book | Order | Pay |
|---|---|---|---|---|---|
| Services, nothing yet | inbox | inbox | inbox | nobody | a payment link |
| Small shop, nothing yet | inbox | inbox | nobody | inbox | a payment link |
| Shop with its own checkout | inbox | inbox, for bulk or trade | nobody | its own checkout or agent door | its own checkout |
| Already on a booking system | inbox | inbox, if it quotes | the booking system’s door, or the inbox with a person confirming | nobody | at the booking, or a link |
| Trades | inbox | inbox | inbox, after a quote | nobody | a link with the invoice |
Today the inbox advertises what it has the means to do: message always, booking once a service has opening hours, order once a product is active, quote_request with either (Manifest). So a shop whose orders go to its own checkout leaves products out of the inbox, and the inbox’s manifest does not offer orders. If an agent sends an order anyway, the public API still takes it as a request that waits for a person: nothing is promised until someone accepts it.
Coming: a setting per door in the inbox: handled by the inbox, handled elsewhere at an address the business owns, or off and declared as unavailable, with sensible defaults for each kind of business. The manifest will then list the doors handled elsewhere too.
Make every door findable
Section titled “Make every door findable”Agents and crawlers find doors by reading files at known places. Make the list easy to find and hard to misread.
Keep one list of doors, and repeat it where readers look:
- The inbox manifest, at
/.well-known/agent-inbox.jsonon the inbox’s subdomain. Today it lists the inbox’s own doors (REST, OpenAPI, MCP); doors handled elsewhere join it with the per-door setting that is coming. - An MCP server card for each MCP server the business runs.
/.well-known/mcp/server-card.jsonis a proposed convention; a site with several servers can also list them at/.well-known/mcp.jsonas{"servers": [{"url": "…"}]}. Readers differ, so publishing a card as well as a list is cheap insurance. llms.txton the main domain, with a line per door that says what the URL is (example below).- schema.org markup on the pages: the business (
OrganizationorLocalBusiness), products with anOffer(price, currency, availability), opening hours, and policies (see the next section). - A product feed (CSV or Google Merchant XML), which agents can read, and so can the inbox’s own feed import.
- Optionally, a DNS record on the main domain that points at the inbox:
_agent-inbox.example.com. TXT "v=sdi1; manifest=https://inbox.example.com/.well-known/agent-inbox.json". Our crawler does not look this record up; other readers may, so it does no harm, but list the inbox in a file as well.
An llms.txt section a reader can act on, one door per line, each saying what it is:
## For AI agents
- MCP server (streamable HTTP): https://agent.example.com/mcp- Inbox for messages, quotes and returns: https://inbox.example.com/.well-known/agent-inbox.json- Product feed (Google Merchant XML): https://example.com/feed.xml- Basket hand-off (an agent fills the basket, a person pays): https://example.com/basket?add=<sku>:<qty>- Order lookup API: POST https://example.com/api/orders/lookup- Returns policy: https://example.com/returnsGive the inbox’s line the manifest’s own address, the one that ends in /.well-known/agent-inbox.json: that is how our crawler tells an inbox in llms.txt from the other doors, and it reads the manifest from there.
Keep every door on the business’s own domain or a subdomain, such as inbox.example.com or agent.example.com. A door on an unrelated host is easy to fake, so careful readers set it aside unless the business’s own site leads to it; a network that follows the network protocol (§4.8) also wants the door’s own document to name the business’s domain. A booking platform’s page for the business counts once the business’s site links to it and the platform’s document names the business.
What we saw with the shop:
- A discovery file we could not read. Its
/.well-known/mcp.jsonlisted its servers as a list, and our crawler expected a single server card. Ours reads lists now; other readers may not, so publish a card as well. - Doors listed in
llms.txtalone. Itsllms.txtnamed an MCP server on a subdomain, a product feed, a stock API, a basket hand-off link and an order lookup. Our crawler saw that the file was there and read none of the doors in it. It reads such lines now, but a door that also sits in a machine-readable file (a server card, the manifest, an OpenAPI document) is found by more readers. - Images on another platform’s CDN. The shop served product images from a large commerce platform’s file CDN. A crawler, ours, took that as a sign the shop ran on that platform and went looking for that platform’s agent checkout, which was not there. We fixed the crawler; the lesson for a business is to declare its doors outright, so nobody has to guess them from side signals.
Then look from outside: surfingdog.ai/check reads a site the way our crawler does and shows, for each thing an agent can do there, the door it found and when. After a change, open the site’s result and press Check again (a fresh read can be asked for a few minutes after the last one), or have an AI call check_business with fresh set to true. Any checker will do; the point is to see what a stranger’s agent sees.
Let agents finish the job
Section titled “Let agents finish the job”A booking or an order is the start of the job, not the end of it.
- If agents can order, let them also change the order, cancel it, track it, get a receipt and start a return.
- If they can book, let them see availability before they book, change the time and cancel.
- If they can sign up for an account, a membership or a class, let them change it or end it.
Today, for the items it holds, the inbox’s public API covers most of this: check_availability; changes to a confirmed booking or an accepted order (make_offer, suggest_time); cancel_item; the status and the conversation (get_item_status); signed receipts the agent can counter-sign; and withdraw_from_contract and request_return for orders and paid bookings (API). Sign-ups are not an item type in the inbox.
Pattern, when the order lives in the business’s own system: offer an order lookup there (by order number and email address) and a way to start a return, and list both with the other doors. The inbox cannot yet record an order that happened in another system, so its receipts cover the bookings and orders it holds itself.
Publish policies in words and in markup, because agents read both: returns as schema.org MerchantReturnPolicy (how many days, who pays postage, how the refund is made), delivery as OfferShippingDetails, and the cancellation terms in plain words next to the booking. Today the inbox publishes its own return policy at GET /v1/business as a MerchantReturnPolicy, from the owner’s Returns settings.
The Surfing Dog agentic score rewards the full journey: an order counts for more when changing, cancelling, tracking and a receipt follow it (the published rules). The score is a reading, not the aim. The aim is that an agent can finish what its person asked for.
Payments, as of October 2026
Section titled “Payments, as of October 2026”This changes month by month. Check the sources at the end of this section before choosing.
Why an agent should not type a card number. In many places, the EU (under PSD2), the UK and India among them, a card payment the customer starts needs strong authentication: a second step, such as a code, a passkey or the banking app. An agent filling in a card number at a checkout stalls at that step, or needs the person there anyway, and it holds a card number it should never see. What works is a credential made for agents: a token or a mandate the person approves once, usually with a passkey or their banking app, limited to a merchant, an amount or a period, which the agent presents and the payment provider checks.
Whichever you choose, declare it where agents read it: a UCP profile lists it under its payment handlers, and a profile whose payment handlers are empty tells agents a person still pays.
Options, a line each:
- Stripe Agentic Commerce Suite, with Shared Payment Tokens: a scoped token an agent hands to the merchant without seeing the card. It implements the Agentic Commerce Protocol’s (ACP) delegated payment and carries Mastercard Agent Pay and Visa Intelligent Commerce tokens. The short path for a business already on Stripe.
- Mollie: has announced support for ACP’s delegated payment API, for European merchants. Check that it is available on your account before you plan on it.
- Adyen Agentic: catalogue, basket and payment APIs for agent commerce, suited to larger merchants already on Adyen. Check which countries and plans it covers.
- Mastercard Agent Pay and Visa Intelligent Commerce: the card networks’ own agent tokens, reached through the business’s payment provider rather than directly, and opening region by region. In Europe, for example, Mastercard says every issuer is enabled for Agent Pay at network level, and Visa’s Agentic Ready programme began there, the UK included, in March 2026, starting with banks.
- Pay by bank, with a mandate: an account-to-account payment the payer can limit or revoke at any time, such as Pix Automático in Brazil, UPI AutoPay in India, PayTo in Australia, SEPA Direct Debit in Europe, and Direct Debit and Variable Recurring Payments in the UK. Whether a scheme lets an agent use a mandate differs from one to the next; in the UK, GoCardless has completed an agent-led pay-by-bank donation inside the FCA’s AI Live Testing programme.
- x402 and stablecoins: payments over HTTP 402, mostly in stablecoins. Niche for a consumer business today.
A hand-off link is a fine start. The agent fills the basket or the order, and a person pays on the business’s own checkout; no card details go near the agent. Today the inbox supports this: the business’s own system asks for payment with a link (request_payment with a paymentUrl) and records it back with record_payment, both with an integration key the owner gave money:write. Readers such as our score count a hand-off as “partly”: a person still pays, and the agent did the rest.
Wherever the business is. The same provider products and card-network programmes reach different regions at different times, and the rules on authentication differ by country. Everywhere, a scoped token or a mandate is safer than an agent holding a card number.
Sources: Stripe’s agentic commerce updates (Payment Expert) · Mollie on agentic commerce in Europe · Mastercard: Europe is building the foundations for trusted agentic commerce · Visa Agentic Ready launches in Europe (FinTech Futures) · GoCardless and Trussell: an agentic payment by bank · Adyen’s agentic commerce documentation.
Messages with the tools you already have
Section titled “Messages with the tools you already have”Many businesses already answer customers in a helpdesk, a CRM or a chat app, and some have their own AI that answers. The inbox does not replace any of that. The shape is the same whatever the tool:
- A customer’s agent sends a message, a quote request, a booking or an order to the inbox, over REST, MCP or email.
- The inbox keeps it as an item with its history, and gives the agent a way to read its status. Promises (a booking confirmed, an order accepted or paid) get signed receipts.
- A webhook tells the business’s bridge (
message.create,order.create, and so on). The bridge reads the item with its own integration key (GET /v1/owner/items/{id}) and opens a ticket or a conversation in the business’s tool, keeping the inbox item’s id on it; most tools have an external id or a custom field for this. - A person, or the business’s own AI, answers in that tool.
- The tool’s own webhook or automation calls the bridge, which posts the answer back to the inbox item:
POST /v1/owner/items/{id}/replies, or a move such asconfirm,proposeorrequest_paymentwithPOST /v1/owner/items/{id}/transitions. - The agent reads the answer in the item’s conversation (
GET /v1/items/{id}), and the customer gets the business’s email if they gave an address. When the customer writes again, a<type>.messageevent fires and the bridge adds it to the same ticket.
The bridge is the business’s own: a small script on any server, a serverless function, or a Zapier, Make or n8n flow. Native connectors for these tools do not exist today. The notes below are patterns, built on each tool’s public API:
- Intercom: the bridge opens a conversation for the customer through Intercom’s API, with the inbox item’s id in a conversation attribute. Intercom’s webhook for an admin reply (
conversation.admin.replied) calls the bridge, which posts the reply to the item. - Zendesk: the bridge creates a ticket with the Tickets API, with the item’s id as the ticket’s
external_id. A trigger on a public comment by an agent calls a Zendesk webhook pointed at the bridge, which posts the comment as the reply. - Salesforce Service Cloud: the bridge creates a Case through the REST API, with the item’s id in a custom field. A record-triggered Flow on a new public reply calls the bridge, by an HTTP callout or a Platform Event the bridge listens for.
- HubSpot: the bridge creates a ticket with the CRM tickets API, or uses a custom channel in HubSpot’s conversations inbox. A workflow’s webhook action, or the app’s webhook subscription, tells the bridge when someone replies.
- Freshdesk: the bridge creates a ticket with the Tickets API. An automation rule on ticket updates, with a “Trigger webhook” action, calls the bridge when an agent replies.
- Telegram, for staff who answer on their phones: the bridge’s bot posts each new item to a staff chat (the Bot API’s
sendMessage), with the item’s reference. When someone replies to that message, Telegram sends the update to the bridge’s webhook, and the bridge maps the replied-to message back to the item and posts the reply. - WhatsApp Business: the same pattern for staff alerts, through the WhatsApp Business Platform (the Cloud API) or a provider such as Twilio. Messages the business starts outside WhatsApp’s 24-hour window need approved templates. WhatsApp is a channel for people, not a door for agents: agents write to the inbox.
- Email: today the inbox emails the owner about new requests at the address in
notifications.ownerEmail. Point it at a shared mailbox, or at a helpdesk’s address, and each request lands there with no code at all. For an answer to reach the customer’s agent, it has to go back through the inbox: the owner app, the owner MCP, orreplyover the API. - The business’s own AI: two ways today. Connect it to the owner MCP at
https://inbox.example.com/mcp/owner, where it signs in with OAuth, lists what needs an answer, replies and moves items, inside the limits the owner set (Connect your AI). Or let it react to webhooks and call the owner API with its own integration key. Either way its replies reach the customer marked as sent automatically, and anything about money outside the owner’s limits waits as a draft for a person.
Get these right, whichever tool it is:
- One integration key per bridge, made by the owner in Settings → Keys with the narrowest preset that works (
automationfor most bridges). - Skip your own echo. An event whose
data.actor.idis the bridge’s own key is the bridge’s own write coming back; acting on it again is how two systems loop. - Use the event’s id as the idempotency key on every write back, so a retry does the work once.
- Thin events, the default: the bridge reads the item with its key, and no customer data travels to the webhook address.
written_by: "person"on a reply a person typed in the helpdesk, so the customer does not see the line saying it was sent automatically.- The helpdesk’s own tokens stay in the bridge, never in the inbox’s settings, notes or replies.
- Test both directions with sandbox items (the
x-sandbox: 1header) before any real customer.
A checklist for the installing AI
Section titled “A checklist for the installing AI”Ask the owner, and do not guess any of these:
- Which tools do you use today for messages, bookings, orders, payments and support? The product names and the plans.
- Does anything already answer AI agents for you: your own MCP server or API, a platform’s agent checkout, a booking platform’s agent door?
- For each action (message, quote, book, order, pay, change, cancel, track, return): should the inbox handle it, your own system, or nobody?
- How do you take payment, and does your provider offer agent payments yet? If not, is a payment link to your own checkout fine for now?
- Where are your returns, delivery and cancellation policies written, and may we add markup to those pages?
- Who answers: a person, rules, or your own AI? What may automation agree to on its own, for times and for money?
- Do you want to join a network? It is optional, and separate from the inbox.
Then:
- Install with install.md, and set up the doors the business will fulfil, and no others.
- Connect the tools it already uses, with connect.md or a bridge as above.
- List every door on the business’s own domain: the manifest, an MCP server card,
llms.txtlines, schema.org markup, a product feed. - Test each door end to end with a sandbox item, in each direction a bridge runs.
- Look from outside with a checker.
- Tell the owner, in a few lines, which doors are live and where, which are handled elsewhere, which are off, and what is not built yet.
None of this is required. If the business has a better way, use it, and tell us what worked on the requests board.