Embed limits and errors
Look up embed limits, error statuses, failure stages and recovery actions.
This page covers embed tokens, Kit, iframe and Hosted. The source column distinguishes fixed validation, Dashboard policy and component behavior. Policy values come from the configuration saved for your agent.
Limits
| Item | Value and unit | Source |
|---|---|---|
external_user_id | 1–128 characters; ASCII letters, digits or _ . : @ - | Issuance validation |
ttl_seconds | 60–3600 seconds, capped by policy ttl_max_seconds; omission uses policy default | Issuance validation and policy |
system_message | Text across all text blocks ≤8192 UTF-8 bytes | Issuance validation |
metadata | ≤16 keys; keys 1–64 characters, string values ≤512 characters | Issuance validation |
budget_cents | 0 through policy session maximum, in US cents; omission uses policy default | Issuance validation and policy |
Issuance allowed_origins | Subset of policy entries, matched exactly | Issuance validation |
| Policy origins | ≤50 HTTPS origins; wildcards match one subdomain level without a port | Embed policy |
allow_localhost | false by default; allows HTTP localhost / 127.0.0.1, with optional port, when enabled | Embed policy |
max_active_sessions_per_user | 1–100 active sessions per user; idle history is excluded | Embed policy |
per_user_rate_per_min | 1–600 requests/minute/user | Embed policy |
blocked_end_users | ≤1000 user IDs | Embed policy |
monthly_cap_cents | Nonnegative integer US cents; null means uncapped; UTC calendar month | Policy and monthly accounting |
| Page context | ≤32 items; complete JSON ≤4096 UTF-8 bytes | API validation; Kit trims oldest entries |
| Session title / initial events | Title ≤500 characters; ≤50 initial plain-text user messages | Embedded session validation |
| Attachment picker | ≤5 files/message; each ≤10 MiB (10,485,760 bytes); PNG, JPEG, GIF, WebP, PDF, TXT, MD | Kit input validation; the first message of a new session still accepts only plain text |
startScreen.prompts | First 4 displayed | Kit component |
| Hosted exchange credential | 60 seconds, usable once | Hosted exchange validation |
The monthly action stop_new_sessions rejects new sessions; alert_only does not block them. Dashboard monetary inputs use US dollars; API budget fields use cents. An exhausted session budget stops new work while retaining tool confirmation and interruption.
Server errors
These statuses apply to ordinary HTTP failures. Once a stream opens, errors arrive inside the stream and cannot change its HTTP status. Retryability refers to the original request, before changing configuration or credentials.
EMBED_TOKEN_EXPIRED
401 · Access · No direct retry. The token expired. Refreshable Kit access obtains another token and replays an expiry-failed request at most once. Hosted requires a new host-issued link.
EMBED_TOKEN_REVOKED
401 · Access/stream · Not retryable. Kit stops refreshing. End old access and have the host recheck eligibility. Do not automatically issue tokens to bypass revocation.
EMBED_ORIGIN_NOT_ALLOWED
403 · Origin check · Not retryable. Check scheme, host and port against the policy and any narrower issuance allowlist. After correction, issue again and verify.
EMBED_USER_BLOCKED
403 · Issuance/session creation · Not retryable. An administrator must review the user under Operations → End users. If access should resume, unblock and issue a new token.
EMBED_RATE_LIMITED
429 · Requests/session creation/anonymous issuance · Retry later. Request frequency, active sessions or daily anonymous sessions reached their limit. Wait for the rate window, running sessions or next UTC day respectively.
EMBED_BUDGET_EXHAUSTED
402 · Session work/anonymous issuance · Not retryable. Session budget or daily anonymous spending is exhausted. Review the budget; continue with a new token and session only when authorized, or wait for daily recovery. Do not loop issuance to bypass limits.
EMBED_MONTHLY_CAP_REACHED
402 · Session creation · Not retryable. The monthly cap requires stopping new sessions. An administrator decides whether to change the cap or action, or wait for the next UTC month.
EMBED_FIELD_NOT_ALLOWED
400 · Issuance/session creation · Not retryable. Remove unauthorized agent_override. Embedded session creation accepts only title, time_zone and initial_events. Initial events are plain-text user.message events with optional page context.
Other refusals
| Code | HTTP / stage | Recovery | Retryable |
|---|---|---|---|
INVALID_PARAMS | 400 / validation | Correct the reported type, range or size | No |
UNAUTHENTICATED | 401 / authentication | Check missing/invalid credentials or a disabled publishable key | No |
NOT_FOUND | 404 / resource or Hosted exchange | Verify organization, public ID and policy; obtain a fresh Hosted link if expired or consumed | No |
UPSTREAM_UNAVAILABLE | 502 / upstream call | Retry later; check management writes for partial completion first | Yes |
For session permissions, archiving and event-content errors, see Agent limits and errors.
Kit errors and retries
praxis.error detail can be a KitError with code, status, retryable and message, or only { message }. Status 0 means no HTTP response.
| Code | Status / stage | Recovery and retryability |
|---|---|---|
network_error, stream_disconnected | 0 / network or stream | Retry after restoring connectivity |
http_error | Response status / HTTP | Inspect response; without explicit retryable, 429 and 5xx permit retry |
invalid_token | 0 / token retrieval | getToken returned an empty value; correct it, retryable |
invalid_response | Response status / JSON or history | Check format and pagination progress; no automatic retry |
invalid_stream | Response status / stream | Check SSE content and JSON; no automatic retry |
event_cursor_not_found | 200 / history recovery | Reload history to locate the session; no automatic retry |
callback_error | 0 / callback | Fix the host exception; not retryable |
aborted, disposed | 0 / lifecycle | Cancelled request or destroyed component; do not retry the old instance |
Non-Hosted token retrieval retries retryable failures up to 3 times at 1, 2 and 4 seconds. Revocation or budget refusal stops that retry loop. Transport-owned stream recovery reconnects at most 5 times; the interface may own recovery instead. Do not add an unlimited retry loop.
Diagnose failures
Retain time, environment, public agent_… ID, HTTP status, error code and X-Request-Id without credentials. Check token status under Operations → Issuance records, then replay the session. Repeat embed tests after recovery. See the Agent API for field definitions.