Agent intent
What agents asked your website: search queries, zero-result demand, AI referrers. Captured at emission, PII-screened, and rendered in Console answers and the weekly digest.
Last updated
What gets captured#
Since events v0.4, request.intent_signals is populated at emission instead of being an empty object. The shape stays open (Record<string, unknown>), and these are the well-known keys every emitter uses:
| Key | Meaning |
|---|---|
query | Free-text search sent to this site: a ?q=-style param or a protocol search tool argument. Recorded only after the screen below. |
query_param | Where the query came from: q, query, search, s (WordPress), keyword, term, or a protocol tool name like mcp.search_catalog. |
referrer_platform | AI platform classified from the Referer header (chatgpt, perplexity, claude, gemini, copilot, …). On a human event this marks a visitor an AI conversation sent. |
utm_source / utm_medium | Sanitized campaign params. utm_source=chatgpt.com is a live convention on AI click-throughs. |
tool | Protocol tool or operation that ran: mcp.search_catalog, mcp.get_product, mcp.get_policies, ucp.discovery, ucp.catalog, ucp.checkout, acp.feed. |
result_count | Result count for a search-shaped request. 0 is the zero-result-demand signal: an agent asked for something the catalog could not answer. |
capability_version | Version of the explicit capability vocabulary: 1 for the fields below. Older emitters omit these fields. |
requested_capability | One supported capability identifier, such as pricing.read, quote.request or booking.create. This describes the request; it does not authorize an action. |
missing_capability | The requested capability when the adapter explicitly reports it unavailable. A page miss or an absent field alone does not prove a capability is unavailable. |
action_status | For action capabilities: requested, offered, succeeded, failed or unsupported, as explicitly reported by the adapter. A succeeded action does not establish a paid order or revenue. |
The shared implementation lives in @rebilder/events (scrubQueryText, classifyReferrerPlatform, extractUrlIntentSignals, buildProtocolIntentSignals), so the gateway, the protocol adapters, and platform apps emit identical shapes.
Screening query text#
Recorded URLs are unchanged by this feature: request.url keeps its emission-time allowlist (page, variant, sku, lang, locale, currency), so search text never rides the URL and Miss-Report grouping stays clean. Queries live only in intent_signals.query.
The protocol channel#
On the protocol path, the adapter is the only code that knows which tool ran and how many results came back, while the event belongs to whichever emitter mounted it. Adapters therefore stamp x-rebilder-intent-tool, x-rebilder-intent-query (URI-encoded, post-screen) and x-rebilder-intent-results on their responses. Mounted through @rebilder/gateway, those headers are folded into the gateway’s event and stripped before the response leaves. On a standalone protocol mount they stay on the wire. The capability channel adds x-rebilder-intent-capability, x-rebilder-intent-missing-capability and x-rebilder-intent-action-status. These carry only supported identifiers and statuses, never private terms, prices or credentials; the gateway strips them with the other intent headers.
Where it renders#
- Console answers: the answer-rate headline (answered = served on the markdown or protocol path), the query table with zero-result counts, AI-referred visitors by platform with the orders that followed (labeled inference, same 7-day product-URL evidence standard as funnel attribution), and the per-platform breakdown.
- The unanswered searches finding: zero-result searches surface as an attention finding with the query list and a concrete fix.
- The weekly digest (opt-in, Console settings): the same numbers, mailed. Setting the address turns it on; clearing it turns it off immediately; unsubscribes are honoured permanently.
The event schema is on the Events page.