A2UI v0.9.1 Data Flow
A2UI defines messages, not a required transport. A server can carry them through A2A, AG-UI, SSE, WebSockets, MCP, or another channel that preserves complete JSON objects and the required ordering.
Lifecycle
The server first creates a Surface and identifies the negotiated Catalog:
{"version":"v0.9.1","createSurface":{"surfaceId":"status","catalogId":"https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"}}
It then sends flat component definitions. One component uses the conventional ID root:
{"version":"v0.9.1","updateComponents":{"surfaceId":"status","components":[{"id":"root","component":"Column","children":["heading","value"]},{"id":"heading","component":"Text","text":"Service status","variant":"h2"},{"id":"value","component":"Text","text":{"path":"/status"}}]}}
Data arrives separately and updates bound components:
{"version":"v0.9.1","updateDataModel":{"surfaceId":"status","path":"/status","value":"Operational"}}
When the Surface is no longer needed, the server deletes it:
{"version":"v0.9.1","deleteSurface":{"surfaceId":"status"}}
Streaming behavior
Each message must be complete and valid before it changes renderer state. The interface may appear incrementally as component and data messages arrive, but the exact visual loading behavior belongs to the host. A2UI does not guarantee a skeleton, animation frame rate, or automatic recovery from malformed data.
The renderer should reject updates for unknown Surfaces, duplicate active Surface creation, unsupported Catalogs, invalid component graphs, unsafe URLs, and unauthorized actions. Define how the surrounding transport handles ordering, duplicates, reconnection, backpressure, and truncated streams.
User actions
When a user activates a component, the renderer can send an action event to the agent through the chosen transport. It resolves permitted context bindings and includes origin metadata required by the versioned client-to-server schema. The host must authorize the operation; a Button definition is never permission by itself.
Two-way data binding is local by default. Client data reaches the server only through configured synchronization or an action context. Avoid sending private values that the action does not need.
See the message reference and official v0.9.1 protocol.