A2UI — Agent-to-User Interface
A2UI is a structured format for agents to request input from humans. Instead of plain text prompts, agents describe what they need as a JSON spec — fields, actions, validation rules, sensitivity flags — and the rendering surface decides how to present it. A2UI is transport-agnostic. The same spec renders as a React form in the dashboard, Slack buttons, an email summary, or raw JSON in a webhook payload.Why A2UI?
When an agent needs human input, the naive approach is to print a text message and hope the human knows what to do. That breaks down in production:- Approvals need structured responses. “Do you approve?” needs a yes/no button, not a free-text reply.
- Forms need validation. An agent asking for credentials needs a password field, not a plaintext input.
- Different channels have different capabilities. Slack can render buttons. Email can’t. The dashboard can render anything.
- Sensitive data needs protection. Credentials should never appear in Slack notifications or logs.
The Spec
An A2UI payload is a JSON object describing a set of components. Each component has a type and properties that tell the renderer what to display.Field Types
Sensitivity
Fields can be markedsensitive: true. Sensitive fields are:
- Never included in Slack messages, emails, or webhook payloads
- Only rendered in the dashboard or terminal (full A2UI clients)
- When a form contains sensitive fields, non-dashboard channels show a summary of the non-sensitive fields and a link: “This request contains sensitive fields — [complete it in the dashboard].”
Examples
Policy Approval (Simple)
When a policy guard blocks a tool invocation:Structured Input (Credentials)
When an agent needs login credentials:Multi-Field Form
When an agent needs structured data:How A2UI Payloads Flow
- Agent hits a blocking point — policy approval, tool confirmation, or explicit
request_user_inputcall - A2UI builder constructs the spec —
a2ui_approval_builder.tsora2ui_form_builder.tsin the mesh - Spec is embedded in the A2A task — as a
DataPartwith MIME typeapplication/json+a2ui - Message enters
input-required— the A2UI spec is persisted intask_data - Notification pipeline fires — renderers translate the spec for each configured channel
- Human responds — from dashboard, Slack, or webhook callback
- Resolution flows back — field values mapped back to the A2UI field IDs, forwarded to the mesh
- Agent continues — receives the response and resumes execution
Rendering Surfaces
Relationship to A2A
A2UI payloads travel inside A2A messages asDataPart objects:
application/json+a2ui MIME type tells the receiving client that this part contains a renderable A2UI spec rather than arbitrary data.
When the A2A task state is input-required and the task contains an A2UI DataPart, clients know they need to render a form and send the response back.
Relationship to ADK Tool Confirmation
ADK’srequire_confirmation and request_confirmation() produce tool confirmation events. Svantic maps these to A2UI specs:
This means ADK tool confirmations flow through the same notification pipeline as Svantic’s policy approvals — same dashboard UI, same Slack integration, same webhook callbacks.
Further Reading
- Notifications & Approvals — the full notification pipeline
- Push Notifications — A2A-level async task updates
- Streaming & Events — how A2UI events flow in SSE streams
- Guardrails & Safety — policies that produce A2UI approval requests
- A2UI specification — the full A2UI component reference
