Docs
Point your form at https://api.subba.pro/f/{formId}. subba filters spam, classifies the enquiry, replies in your voice, and books meetings, all from one request. There is also a JSON booking API and an MCP server for AI agents.
Connect a form
Drop your form id into the action. Classic HTML forms work as-is (no JavaScript needed):
<form action="https://api.subba.pro/f/{formId}" method="POST">
<input name="name" />
<input name="email" type="email" required />
<textarea name="message" required></textarea>
<!-- Honeypot: keep it hidden and empty. Bots fill it; real people never see it. -->
<input name="hp_website" tabindex="-1" autocomplete="off"
style="position:absolute;left:-9999px" aria-hidden="true" />
<button>Send</button>
</form> Or POST JSON from your own frontend:
POST /f/{formId} HTTP/1.1
Host: api.subba.pro
Content-Type: application/json
{
"name": "Sam",
"email": "[email protected]",
"message": "Do you have space in a beginner class next week?"
} Either way you get:
HTTP/1.1 200 OK
{ "ok": true, "status": "processed" } Only email and message are required; name, subject, and phone are used when present. Your form must POST from its registered origin.
Reply modes
notify | subba drafts a reply and alerts you. You send it. Safest to start with. |
draft | subba drafts and stores a one-tap reply, plus the owner alert. |
auto | subba sends the reply itself and, on Pro and up with a connected calendar, books the meeting with a Google Meet link. |
Start on notify, move up as you learn to trust it. You are always in control.
Chat widget
Drop a chat assistant on your site with one line. It sits as a bubble in the corner, or opens from any element with a data-subba-chat attribute.
<script src="https://api.subba.pro/f/{formId}/chat.js" defer></script> The assistant answers visitor questions and can take a booking or start a membership, all in the chat window. To keep it accurate, open your form in the dashboard and click Analyse my website and fill knowledge: subba reads your site and drafts an editable knowledge base (services, prices, hours, policies) that the assistant is grounded in. Edit it and save.
It never books or charges on its own. When a visitor wants to book or subscribe, the assistant shows a confirmation card with the exact service, time, and price; the visitor adds their name and email and taps to confirm. Paid bookings and memberships open Stripe checkout on your own connected account.
How we keep the AI safe
- Grounded, not guessing: it answers only from your knowledge and live availability, and offers to pass anything it is unsure of to your team.
- Double-checked: a second AI pass verifies each reply is on-topic and supported before it is shown, with a safe fallback if not.
- Actions are validated, not spoken into being: prices and times come from your data, never the chat text. Every booking is re-checked against live availability at confirm time, and money moves only through Stripe checkout after a human taps confirm.
- Injection-resistant: visitor text is treated as data, not instructions, and replies render as plain text only, so nothing typed in chat can change the assistant's behaviour or run code.
- Abuse limits: origin-locked to your site, rate limited, with an optional Cloudflare Turnstile bot check.
Calendar booking
Connect Google Calendar once (/oauth/google/start?form={formId}). In auto mode on Pro and up, a booking-intent enquiry is scheduled automatically with a Google Meet link, and both you and the customer are notified.
Booking API
Every business with booking enabled gets a public slug. These JSON endpoints power the hosted widget, the embeddable widget, and any client you build.
GET /api/b/{slug}/services lists bookable services:
{
"business": "Zen Yoga Studio",
"services": [
{ "id": "svc_1", "name": "Beginner class", "type": "class",
"duration": 60, "price": 1400, "currency": "gbp", "requiresPayment": true }
]
} GET /api/b/{slug}/slots?service={id}&date=YYYY-MM-DD returns open appointment slots (start in epoch ms), or upcoming sessions with seats left for a class.
POST /api/b/{slug}/book creates the booking:
POST /api/b/{slug}/book
Content-Type: application/json
{ "service": "svc_1", "start": 1756713600000,
"name": "Sam", "email": "[email protected]" } { "ok": true, "bookingId": "bk_123",
"checkoutUrl": "https://checkout.stripe.com/...", "confirmed": false } For a class, send sessionId instead of start. When the service requires payment, follow checkoutUrl to Stripe; otherwise the booking is confirmed straight away. Embed the widget on any site with <script src="https://api.subba.pro/b/{slug}/embed.js"></script>.
Payments
Take payment for bookings straight into your own Stripe account. In the dashboard you can connect an existing Stripe account (OAuth) or set up new payouts (Stripe hosted onboarding). When a service requires payment or a deposit, /book returns a Stripe checkoutUrl and the funds settle to your connected account; subba only takes its platform fee.
AI agents & MCP
subba is agent-ready. An MCP server (Streamable HTTP, JSON-RPC 2.0) is available at https://api.subba.pro/mcp with the tools list_services, check_availability, and create_booking. Add it to any MCP-capable client:
POST https://api.subba.pro/mcp
Content-Type: application/json
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" } Agents can also discover subba through /AGENTS.md, /llms.txt, the /ai2w manifest, and /.well-known/agent.json. Support for the Agentic Commerce Protocol (ACP) and Agent Payments Protocol (AP2) is planned.
Plans & limits
| Plan | Price | Enquiries | Includes |
|---|---|---|---|
| Starter | £9.99 / mo | 10 enquiries | Auto-reply, spam filtering, owner alerts |
| Pro | £29.99 / mo | 30 enquiries | Everything in Starter, plus auto-booking and your voice |
| Studio | £99.99 / mo | 100 enquiries | Everything in Pro, plus multiple forms and team alerts |
Enquiries are metered per calendar month; spam does not count. If you reach your limit subba still captures the lead and alerts you, then pauses auto-replies until you upgrade. Change plan any time from the dashboard.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_email / invalid_message | Required fields missing or malformed. |
403 | origin_not_allowed | Request Origin did not match the form’s registered origin. |
404 | form_not_found / service_not_found | Unknown form, business, or service id. |
409 | slot unavailable | The slot or class session is no longer free. |
413 | payload_too_large | Body exceeded the size cap. |
429 | rate_limited | Per-form, per-IP rate limit hit. |
Security
- Endpoints are locked to your form’s origin; spam is filtered before any AI runs.
- Customer emails are stored in the audit log only as salted hashes.
- Per-form, per-IP rate limits, plus a Cloudflare edge rate rule.
- Stripe webhooks are signature-verified; calendar tokens are never exposed.
- Append-only submission log; no stack traces on errors.