Express Flows

Express pages: the page version of each of your intents, for agents that navigate a site instead of calling tools. The same intent is your Agent Action on the page and your /mcp tool, so one configuration serves every surface.

Express Flows

An express flow is the page version of one of your intents. GET /agent/express/{intent} renders it and POST /agent/express/{intent} submits it. It is built for agents that navigate a site instead of calling tools (computer-use agents, and anything that simply follows a link): semantic HTML, large targets, autocomplete attributes and step annotations, and a form that works with JavaScript off.

You configure each intent once, under Interaction → Express Flows. The same intent is also the Agent Action your pages register (see Agent Actions) and the tool your hosted /mcp lists, so every surface answers from one configuration. Express pages are served on your own domain wherever /agent/* is: by the WordPress plugin, the Cloudflare Worker, or our edge.

Handler kinds

Every intent carries a handler that decides what happens when an agent (or the express page) submits it.

HandlerPOST /agent/express/{intent} doesTypical intents
proxy (default)Forwards the form submission to your form_action_url unchanged and returns its responseExisting forms, custom backends
leadRecords a lead through the Inception Agents API (contract C2: /leads/intake → /leads/confirm), delivers it once it is complete, returns the receiptrequest_quote, request_callback, request_consultation
bookingRecords the request, offers real slots when a calendar is connected (/bookings/request → /bookings/confirm), and writes the chosen time to that calendarbook_call, book_appointment, schedule_tour
lookupAnswers from your facts (GET /api/v1/content/lookup) — read-onlyget_pricing, check_fit
pointRedirects to the point (GET /agent/{intent}) — read-onlyInception Points exposed as actions

For lead intents one POST completes the request when the submission carries the person’s details: name, an email address or phone number, and consent_contact. Without them the API records the request and answers awaiting_confirmation with a reference the agent completes later with confirm_request. A booking intent against a connected calendar always takes a second step, because the person (or their agent) chooses one of the offered times with confirm_booking. Every answer renders as an HTML receipt page, or as JSON when the caller sends Accept: application/json:

curl -s -X POST https://your-domain.com/agent/express/request_callback \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d '{"topic":"Pricing for 3 locations","name":"Ada Lovelace","email":"ada@example.com","consent_contact":true}'
# → {"ref":"IA-7K2Q","status":"verified","receipt":{"reference":"IA-7K2Q","expected_response":"within one business day","next_steps":[...]},"content":[...],"structuredContent":{...}}

The zero-JS form gains a Your details block (name, email, phone, consent) for lead / booking intents whose form schema does not already collect identity, so a form-only agent can complete the request in one submit. A request completed through the express form is recorded as express_form, and it never opts the person into marketing: only their own tick on the card does that (see how requests are approved).

Card page mode

When a lead or booking intent names a card_template (intake_confirm, slot_picker or callback_now), GET /agent/express/{intent} renders the same branded card the page script shows on your pages: the lead-family widget bundle, mounted in a sandboxed iframe with a tiny inline host. No external script is loaded. The card’s Confirm posts to the same express URL as JSON and flips to the receipt; Not now reveals the plain form.

The zero-JS form stays in the page underneath as the fallback: it is what a non-JavaScript fetcher gets, what a dismissed card falls back to, and what renders if the card cannot mount. Query-string parameters prefill the card (?goal=…&email=…), so an agent can deep-link a filled card for the person to confirm.

Three renderings of one template, in order of fidelity: the in-page card (the page script), the server-rendered express page (this mode, for computer-use agents that navigate but cannot call the page’s actions), and structured data (JSON-LD potentialAction pointing at the express URL) for server-side fetchers. The lead tools carry no card inside a chat thread: an agent calling them from a chat, or from its own servers through /mcp, gets the reference or the receipt as text.

The capabilities manifest

Every enabled intent is listed in /.well-known/agent-capabilities.json on your domain, with its tool name, annotations, handler, form schema and express URL, so an agent can find the express page for anything it could also call as a tool. Abridged:

{
  "intents": [
    {
      "intent": "request_callback",
      "tool_name": "request_callback",
      "handler": "lead",
      "card_template": "callback_now",
      "express_url": "https://your-domain.com/agent/express/request_callback",
      "annotations": { "consequentialHint": true },
      "steps": [ ... ]
    }
  ]
}

Descriptors endpoint

The page script needs the capabilities manifest and the agent index to build the page’s tool set. When your own domain serves both at /.well-known/agent-capabilities.json and /agent/index.json (the plugin, the Worker and our edge all do), the page reads them there; everywhere else (Wix, Squarespace, Webflow, GoDaddy, a script-tag install anywhere) it gets them from the API in one call:

GET https://inception-agents-api.inception-agents.workers.dev/api/v1/webmcp/descriptors?domain=your-domain.com
{
  "domain": "your-domain.com",
  "manifest": { "intents": [ { "intent": "book_call", "tool_name": "book_call", "handler": "booking", "card_template": "intake_confirm", "inject_on_pages": ["/book", "/pricing"], "steps": [ ... ] } ] },
  "agentIndex": { "endpoints": [ { "path": "/agent/briefing", "method": "GET" }, { "path": "/agent/pricing", "method": "GET" } ] },
  "tools": [ { "name": "book_call", "description": "...", "inputSchema": { ... }, "annotations": { "consequentialHint": true }, "meta": { "handler": "booking", "intent": "book_call", "card_template": "intake_confirm" } } ]
}

tools is the budgeted list (at most eight: actions first, then get_briefing, ask_site, then points) every descriptor carrying meta.handler; manifest and agentIndex are the raw documents the page uses to match intents to pages. Public, CORS *, cached five minutes. It 404s for a domain that is not registered. See Agent Actions for what registers on the page and how to verify.

Verify

# The express page an agent navigates to (swap in one of your intents)
curl -s https://your-domain.com/agent/express/request_callback | head -40

# Every intent, with its express URL
curl -s https://your-domain.com/.well-known/agent-capabilities.json

What counts

A completed lead or booking request is billed once, when it reaches you, whichever way it was approved; nothing an agent reads first is billed. See what is billed.

API Endpoints

EndpointMethodDescription
GET /.well-known/agent-capabilities.jsonGETReturns the capabilities manifest (every intent with its tool name, annotations, handler, form schema and express URL)
GET /agent/express/:intentGETThe express page: the zero-JS form, or the card page when the intent names a card_template
POST /agent/express/:intentPOSTSubmit: proxy to your form handler, or the unified lead / booking / lookup write (HTML receipt, or JSON with Accept: application/json)
GET /api/v1/webmcp/descriptors?domain=GETManifest + agent index + the budgeted tool descriptors the page registers, for a domain (public)

For full API documentation, see the REST API Reference.