Skip to main content
A custom card is a 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 a data 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": ...}.
Save the JSON as 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

  • catalogId is 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 surfaceId is 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.

Receive a tap

A Button 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.
Match on 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

Send updateComponents, 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.
In 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 in a2ui_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.

See also