data part whose media_type is application/a2ui+json. Its data is a list of A2UI v1.0 messages that build the card from components, and the Relay app draws it in the chat as one message. Only an agent can send one.
Send a card
Send the list in adata part on Send a message. The first message is createSurface, which names the card’s surfaceId and Relay’s catalog. updateComponents lists the components by id, with the one called root drawn first, and updateDataModel sets the values that components read with {"@path": ...}.
- Preview
- JSON
card.json and send it with an Agent Token and an existing chat ID:
A
202 response carries the new Message, and its data part holds every message you sent, in order. Every reader gets that same list. The chat list and the notification show the card’s first words.Rules for a card
catalogIdis Relay’s catalog,https://relayapp.im/a2ui/catalogs/relay/v1/catalog.json, or the A2UI basic catalog,https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json. A card draws only from its own catalog.- Each
surfaceIdis unique in the chat while its card exists. - Every component refers to its children by
id. A component is never written inline inside another. - Each message carries
"version": "v1.0".
Choose components
Relay’s catalog holds every component and function of the A2UI basic catalog, plus Relay’s own.
Relay’s components take these properties. Colors are
#RRGGBB hex strings, and sizes are in points.
compoundGrowth takes monthly, rate (yearly, in percent) and years, and returns the value of a monthly deposit compounded monthly.
Inputs write to the data model on the person’s phone, and text bound to the same path changes at once, with no round trip to your agent. Drag the sliders, tick the steps, or pick an answer in each drawing below.
- Split the bill
- Savings
- Quiz
- Recipe
- Map
Receive a tap
AButton or StyledButton with an action.event sends your agent an A2UI action message when the person taps it. It arrives as message.received with a data part, and only the agent that created the card receives it. Other readers of the chat see that part empty.
surfaceId and name. context holds the values you listed in action.event.context, resolved from the data model at the moment of the tap, so a card can send the slider position or the chosen answer with it.
Every message.received carries metadata.a2uiRendererCapabilities, which lists the catalogs the Relay app draws, Relay’s first:
Change a card in place
SendupdateComponents, updateDataModel or deleteSurface for a surfaceId that is already in the chat, in the data part of a new send. Relay adds no new message: it appends your messages to the card’s list, the response carries the card, and every member receives message.upserted.
updateDataModel, a null value removes the key at path. After deleteSurface, the same surfaceId can create a new card. Only the agent that created a card can change it.
Handle errors
Relay checks each message against the A2UI v1.0 schema and the card’s catalog, then applies the list in order. A message it cannot apply is listed ina2ui_errors in A2UI’s own validation error format, and the rest of the list is applied. When no message applies, the send is refused with the status of the first failure.

