Skip to main content

Widget and ambient-agent action refusals

The widget’s action endpoints — callback scheduling, the transcript email, and queue-position reads — answer with a structured code when they refuse a request. Most of these codes are a configuration or a pace signal you own, not an outage. This runbook decodes each one and names the one fix that clears it. A browser-resident (ambient) agent that drives the widget on a visitor’s behalf signs its requests, and those signed requests pass through extra gates a plain human visitor never touches. If your visitors are humans only, the codes you will see are the embed-origin, widget-state, queue, and transcript ones below; the three AGENT_ACTION_* codes only ever answer an agent-attributed request.

One ledger, three lanes

Every visitor session keeps one action ledger, and three lanes read from it before an agent-attributed callback is allowed through (Widget flow model has the full mechanics):
  1. Action rate lane — a sliding window scoped to the session: 5 callbacks/hour and 30 messages/hour by default. A request that would breach the window is refused with Retry-After seconds and charges nothing.
  2. Per-session caps — cumulative ceilings of 50 actions or 100 preview-cost units per session, so a long-lived session cannot grind under the hourly lane. A refusal here names the only way out: a new session.
  3. Compliance (quiet hours) — an agent-scheduled callback is a future outbound voice leg, so it runs through your tenant’s quiet-hours window for the voice channel. The gate is default-OPEN: it only refuses when you have opted the voice channel into quiet hours and the recipient’s local time is outside your window, and it tells you next_allowed_at when it does.
In front of all three sits the trust gate: the widget’s agent capability and trust policy decide whether a given agent may act on this widget at all. Every agent-attributed action — allowed or refused — is logged, so you can reconstruct what a browser agent did. A scheduled callback that clears these gates is placed exactly like your queue callbacks — your routing, your dialing windows. Nothing on this page adds or bypasses an outbound path.

Code by code: cause and fix

Retry classes

The same three classes the Error Code Reference routes by apply here:

Fixes that never help

  • Retrying AGENT_ACTION_RATE_LIMITED without waiting out Retry-After — the sliding window counts the retries too.
  • Retrying AGENT_ACTION_CAP_REACHED in the same session — the cap is cumulative by design.
  • Re-sending an origin-failed embed from the same page — the origin is a property of the page that serves the widget, not of the request your script builds.
  • Reading AGENT_ACTION_DENIED as a billing or account suspension — it is always the widget’s own agent capability and trust configuration.