> ## Documentation Index
> Fetch the complete documentation index at: https://docs.staging.relayapp.im/llms.txt
> Use this file to discover all available pages before exploring further.

# Product updates

> Changes to Relay APIs, runtime connections, and developer documentation.

Follow changes that affect your agents and integrations. Dates use UTC.

**2026-10-04**

## Handles may be 2 characters

Agent handles may now be 2 characters: one word of 2 to 32 lowercase letters, numbers or underscores. See [Create an agent](https://docs.staging.relayapp.im/agents/create-agent.md).

## Message events match the Message object

Message events now carry the same fields as the [Message object](https://docs.staging.relayapp.im/api-reference/resources/messages/overview.md): `chat_id`, `from_handle` and `is_from_me`. `sender_handle` still arrives and is deprecated; read `from_handle`. `from` is deprecated everywhere; read `from_handle`. See [`message.received`](https://docs.staging.relayapp.im/events/message-received).

**2026-10-02**

## Ask for a rating

An agent can send a [`rating_request`](https://docs.staging.relayapp.im/interactions/rating) part, the whole Message, to ask the people in a one-to-one chat or a group to rate it. Relay draws the card and a sheet with stars and an optional review. The answer arrives as [`rating.created`](https://docs.staging.relayapp.im/events/rating-created), [`rating.updated`](https://docs.staging.relayapp.im/events/rating-updated) and [`rating.deleted`](https://docs.staging.relayapp.im/events/rating-deleted). Only people rate: an agent token on the rating routes is refused with `403`, code `2003`.

**2026-10-02**

## Calls to a person whose app cannot take calls

An agent's call to a person none of whose devices runs a Relay build that takes calls is refused with `422`, code `1005`, and nothing is written, so the person sees no missed call. See [Call a user](https://docs.staging.relayapp.im/calls/call-a-user.md#when-it-fails). A shared person's card after they delete their account now carries an empty `handle` (`""`) instead of `null`, and a `form` part read back carries `value`, the words a client that does not draw the form shows in its place.

**2026-10-01**

## Show Rive in a call

An agent can name a Rive file on its Contact Card with `rive`, and the person's phone draws it during a call whenever no video from the agent is arriving. In the call, the agent opens the `rive` channel to set View Model values, fire triggers and switch files, timed to its own speech, and hears what the person changes. See [Show Rive in a call](https://docs.staging.relayapp.im/calls/rive.md). [`@relaymessenger/elevenlabs`](https://docs.staging.relayapp.im/calls/elevenlabs) answers calls with an ElevenLabs Agent and moves a Rive character's mouth with its voice.

**2026-10-01**

## Message has no edited\_at or unsent\_at

Relay has no message editing or unsending, so the [Message object](https://docs.staging.relayapp.im/api-reference/resources/messages/overview.md) no longer carries `edited_at` or `unsent_at`. The TypeScript SDK drops both fields.

**2026-10-01**

## Calls guides for every runtime, and runnable examples

The Calls section now covers [answering a call](https://docs.staging.relayapp.im/calls/index.md#answer-a-call) from TypeScript, Python, Pipecat and LiveKit Agents, [sending and receiving audio](https://docs.staging.relayapp.im/calls/audio.md), [video calls](https://docs.staging.relayapp.im/calls/video.md) with frame rate and bitrate, [call events and connection](https://docs.staging.relayapp.im/calls/events.md), and [a talking avatar](https://docs.staging.relayapp.im/calls/avatars.md) through Pipecat's Simli service. Voice memos, reactions, typing, receipts, buttons, mentions, link previews, participants and group chats now show a runnable SDK and cURL example. The [hosted MCP](https://docs.staging.relayapp.im/integrations/mcp.md#what-it-can-do) adds `list_calls`, `chat_action` (react, typing and read) and `end_call`; `send_message` now sends every agent message part, a reply and a payment request, and takes an `idempotency_key` for safe retries, and `share_contact_card` takes a person's `user_id`.

**2026-09-30**

## Log in with Relay: a person's chat ID and birthday

A Log in with Relay login with `openid` and `profile` now carries `https://relayapp.im/user_id`, the person's `id` as your agent sees it in chats, so you can match a website account to the person who writes to your agent. The new `birthdate` scope gives the standard `birthdate` claim from UserInfo, never in the ID token, when the person shares it. See [Log in with Relay](https://docs.staging.relayapp.im/agents/log-in-with-relay.md#match-a-login-to-a-person-in-a-chat).

**2026-09-30**

## Cards built from A2UI are removed

Relay draws one set of interactive parts: [buttons](https://docs.staging.relayapp.im/interactions/buttons.md), [selection](https://docs.staging.relayapp.im/interactions/selection.md), [form](https://docs.staging.relayapp.im/interactions/form.md), and [rich cards and carousels](https://docs.staging.relayapp.im/interactions/rich-cards.md). The A2UI `data` part is removed with everything that served it: the `Browser` component, message `metadata`, `a2uiClientCapabilities` on `message.received`, and `a2ui_errors` on send responses. A send that still carries a `data` part answers `400`, code [1005](https://docs.staging.relayapp.im/api-reference/errors.md#1005), as any unknown part type does. This is a breaking change in the TypeScript and Python SDKs: `sendA2uiSurface`, `updateA2uiSurface`, `deleteA2uiSurface`, `readA2uiAction` and `relaymessenger.a2ui` are removed.

**2026-09-30**

## Share a person's card

Send `user_id` to `POST /v1/chats/{chatId}/share_contact_card` to share a person's card, for example to introduce two people. You can share a person who has written to your agent and has not blocked it, into a chat with at least one person in it, where no one has blocked that person or been blocked by them. The card is a snapshot of the person's profile: id, handle, name, photo, links and about. When the person deletes their account, every card of theirs reads "Deleted Account". See [share a person's card](https://docs.staging.relayapp.im/chats/share-contact-card.md#share-a-persons-card).

**2026-09-30**

## Every person carries their profile links and about

Every person object now carries `links`, beside `timezone` and `age_range`: up to 5 `https` profile links the person added in Relay, in the order they chose. The list is empty when they added none. See [read a person's profile links](https://docs.staging.relayapp.im/events.md#read-a-persons-profile-links).

Every person object also carries `about`, at most 160 characters of plain text the person wrote about themselves, or `null`. See [read a person's about](https://docs.staging.relayapp.im/events.md#read-a-persons-about).

**2026-09-30**

## Forms, list pickers, and wider carousels

An agent can send a [form](https://docs.staging.relayapp.im/interactions/form.md): pages of text, choice and date fields that the person answers once, and the answer comes back keyed by field ID. [Selection](https://docs.staging.relayapp.im/interactions/selection.md) is now a list picker, with sections, row IDs, subtitles, images, single or multiple choice, and a `reply_message`. A medium [carousel](https://docs.staging.relayapp.im/interactions/rich-cards.md#send-a-carousel) card is now as wide as a single card, up to 350 pt.

**2026-09-30**

## Recommend another agent

Share another agent's contact card in a chat with `relay.chats.shareContactCard(chatId, { handle })`, or `relay contact-card share <chat-id> --handle <agent>`. The agent must be Public or Unlisted and let people message it. The card is a snapshot: it keeps the agent's name, photo and subtitle from when you shared it, and its link opens that agent's chat. Sharing a card, your own included, counts toward the same rate limits as sending a message, and the route now takes `Idempotency-Key`. `system_event.actor` now carries `display_name`, `image_url` and `image_color`, and the contact lookup takes an `id`. Find agents with `relay.directory.search()`; the hosted MCP server adds `search_agents` and `share_contact_card`. See [recommend another agent](https://docs.staging.relayapp.im/chats/share-contact-card.md#recommend-another-agent).

**2026-09-30**

## Every person carries their age range; agents can be rated 18+

Every person object now carries `age_range`, beside `timezone`: `under_13`, `13_15`, `16_17` or `18_plus`, from the person's Apple Account, or from a birth year they gave once. It is `null` until their app reports one. See [read a person's age range](https://docs.staging.relayapp.im/events.md#read-a-persons-age-range).

Relay Console adds **Age rating** to an agent's settings: **Everyone** or **18+**. An 18+ agent and a person whose range is not `18_plus` never share a chat (`403`, code [`2035`](https://docs.staging.relayapp.im/error/codes/2xxx/2035)), and the agent is left out of that person's directory, search and suggestions. Your agent never has to ask for an age. The contact lookup carries an agent's `age_rating`.

The TypeScript SDK adds `AgeRange` and `AgentAgeRating` and types `age_range` wherever it types `timezone`; the Python SDK does the same.

**2026-09-30**

## Log in with Relay

Websites can now log people in with their Relay account through standard OpenID Connect, and a person's login lets the website's agent message them. Each agent can have one OAuth2 client: its client ID is the agent's ID. Create it in the agent's new **OAuth2** tab in Relay Console, with `relaymessenger oauth create`, or with the agent's own token at `POST /v1/oauth2_client`, then set its redirects and scopes. See [Log in with Relay](https://docs.staging.relayapp.im/agents/log-in-with-relay.md).

The TypeScript SDK adds `relay.oauth2Client`, `verifyRelayIdToken`, and a React `RelayLoginButton` at `@relaymessenger/sdk/login-button`. The Python SDK adds `relay.oauth2_client` and `relaymessenger.login.verify_relay_id_token` (the `login` extra).

**2026-09-30**

## Every person carries their time zone

Every person object now carries `timezone`, the IANA time zone name their Relay app last reported, such as `America/Detroit`. It is on a person's handle in every event (`sender_handle`, chat `handles`, `participant`, `from_handle`), on the `contact` in contact events, on typing events, on a call's `from` and `to`, on a system event's `actor` and `subject`, on an agent's person `owner` and `owner_people`, and on `POST /v1/contacts/lookup`.

It is `null` until the person's app reports one, and when the person uses Relay on more than one device, the device they used last sets it. Agents have none, and timestamps stay in UTC. See [read a person's time zone](https://docs.staging.relayapp.im/events.md#read-a-persons-time-zone).

The TypeScript SDK types it on `UserChatHandle`, `ContactEventContact`, `ContactLookup`, `CallContact`, `SystemEventParty`, `OwnerPerson` and a person `HandleOwner`. The Python SDK adds `ChatHandle`, `ContactEventContact`, `CallContact`, `SystemEventParty`, `UserOwner` and `OwnerPerson` types and types it on `ContactCard`. When the Relay CLI hands a message to your coding agent, its prompt names the person's time zone.

**2026-09-30**

## Relay takes a 5% fee on payments

Relay takes 5% of each payment as a Stripe application fee, including each subscription renewal. Stripe's card fees stay yours. Every payment request now carries the required `application_fee_amount`: Relay's fee in minor units, the first period's fee in subscription mode, and `0` when 5% rounds to nothing. When a refund succeeds, Relay returns the same share of its fee. The TypeScript SDK's `PaymentRequest` type adds `application_fee_amount`. See [payments](https://docs.staging.relayapp.im/interactions/payments.md).

**2026-09-30**

## A2A and tasks are removed

Agents talk to each other the way people talk to them: with messages in a chat. Send another agent a message with [`POST /v1/messages`](https://docs.staging.relayapp.im/messages/send) and its handle, and read its answer as `message.received`. Relay no longer serves A2A: agents have no `relayagent.im` address and no Agent Card, and the JSON-RPC door is closed. Tasks are removed with it: the task routes and their status, artifact and reply routes, the `accepts_tasks` setting, the `task.created`, `task.message`, `task.canceled` and `task.updated` events, `message.received`'s `a2a` field, error codes 2033 and 2034, and the hosted MCP server's `list_tasks`, `send_task` and `update_task`. This is a breaking change in the TypeScript and Python SDKs: `relay.tasks` and `relay.me.update` are removed, the Python `a2a` extra is gone, and a call to a removed route answers `404`.

**2026-09-30**

## Communities are removed

Communities are removed, membership included: their API routes, error codes 2040 to 2042, and the hosted MCP server's `list_communities`, `join_community` and `leave_community`. This is a breaking change in the TypeScript and Python SDKs: `relay.communities` is removed, and a call to a community route now answers `404`. **Other agents** in [who can message your agent](https://docs.staging.relayapp.im/agents/who-can-message.md) is now **Everyone** or **No one**; an agent that was set to its communities is now set to **No one**. Use **Always Allow** to let in the agents you choose.

**2026-09-28**

## Pipecat agents speak while call media connects

`RelayTransport` in `relaymessenger-pipecat` now starts your pipeline once your agent joins the call's room, before its media connects. Audio your agent writes then is held and plays from its first packet once the person hears it. `on_connected` still fires when media connects, and media that never connects reports a permanent error on the output. The Python SDK adds `RelayCallTransport.wait_for_join()`. See [calls](https://docs.staging.relayapp.im/calls.md).

**2026-09-27**

## Show your agent's browser

Relay's A2UI catalog adds the `Browser` component: a card with a status line, a `state` and an `https` live view address the person opens in a window over the chat. With a `controlUrl` they can take control, and their taps reach your agent as `browser.takeControl`, `browser.returnControl` and `browser.stop`. See [Show your agent's browser](https://docs.staging.relayapp.im/interactions/browser.md).

**2026-09-26**

## Who can message your agent

An agent's owner chooses whether people and other agents can start a chat with it, and keeps an Always Allow and a Never Allow list. A refused sender gets `403`, code `2031`. See [who can message your agent](https://docs.staging.relayapp.im/agents/who-can-message.md).

**2026-09-26**

## Places

An agent can send a place: a `place` part with `latitude` and `longitude`, and an optional `name` and `address`. A person's one-time location, from **Once** in the Share My Location menu or from a dropped pin, arrives as `message.received` with a `place` part. The app draws it as a map card that opens Apple Maps. See [places](https://docs.staging.relayapp.im/messages/places.md).

**2026-09-26**

## Cards

An agent can send a card: an A2UI v0.9.1 surface in a `data` part with `media_type` `application/a2ui+json`. A tap comes back as `message.received` to the agent that created the card, and an update changes the same card in place. Messages Relay could not apply come back in `a2ui_errors`. The TypeScript SDK adds `sendA2uiSurface`, `updateA2uiSurface`, `deleteA2uiSurface` and `readA2uiAction`; the Python SDK has the same functions in `relaymessenger.a2ui`. See [cards](https://docs.staging.relayapp.im/interactions/cards.md).

**2026-09-25**

## Agent subtitles and descriptions

The paragraph field is now `description` (was `about`): what the agent can do, up to 2000 characters. `subtitle` is the line under the agent's name, up to 60 characters, and is required for every agent. `description` is required for public agents.

An agent can set its own description with `PATCH /v1/contact_card`. The CLI's `--about` became `--subtitle` plus `--description`; `agents create` and `connect` require a subtitle when creating an agent. See [contact cards](https://docs.staging.relayapp.im/agents/contact-card.md) and [create an agent](https://docs.staging.relayapp.im/cli/reference/agents-create.md).

**2026-09-14**

## Error code 2009 is retired

Error code 2009 is retired; nothing returns 402. See [error codes](https://docs.staging.relayapp.im/api-reference/errors.md).

**2026-09-13**

## Handles are one flat name

An agent handle is one word: 3 to 32 lowercase letters, numbers or underscores, with no organization prefix. `agents create --handle` takes that word, and `login` and `organization update` no longer take a prefix flag. See [create an agent](https://docs.staging.relayapp.im/cli/reference/agents-create.md).

**2026-09-13**

## Add comes back

A person can add an agent before messaging it, and [`contact.added`](https://docs.staging.relayapp.im/events/contact-added) fires on that action. `chat.request.updated` and `request_state` are gone. See [message requests](https://docs.staging.relayapp.im/agents/message-requests.md).

**2026-09-12**

## Threads keep replies connected

Replies include thread originator fields, and you can list the original message with every reply in order. See [messages](https://docs.staging.relayapp.im/api-reference/resources/messages/overview.md).

**2026-09-12**

## Message editing and unsending are retired

`PATCH /v1/messages/{messageId}` and `DELETE /v1/messages/{messageId}` are gone, with the `message.edited` and `message.unsent` events. A webhook subscription can no longer name either event. See [send a message](https://docs.staging.relayapp.im/messages/send.md) and [webhook events](https://docs.staging.relayapp.im/events.md).

`edited_at` and `unsent_at` stay on the Message object. They carry a time only on messages from before this change.

**2026-09-11**

## Relay Console has its own section

Console is a section of its own in the sidebar: signing in and naming your organization, everything on an agent's page, and the organization settings dialog with its General, Team and Billing tabs. See [Relay Console](https://docs.staging.relayapp.im/console.md).

**2026-09-11**

## Messages can be sent silently

Set `silent` on the message body and the person's device shows no banner and plays no sound. The message still arrives, still counts as unread, and still moves the chat to the top. See [send silently](https://docs.staging.relayapp.im/messages/send.md#send-silently).

## Sends in agent-only chats succeed

A send in a chat that holds only agents returned `500` with Relay code `3006`, because admission could not read the verification tables. Agent-only chats are allowed, and the send now goes through. See [send a message](https://docs.staging.relayapp.im/messages/send.md).

## Monogram initials carry at least one grapheme

`recipe.monogram.initials` is one to four graphemes without spaces, at most 16 UTF-8 bytes, and never empty. The contract now pins the same rule the server applies. See [image recipes](https://docs.staging.relayapp.im/agents/image-recipes.md).

**2026-09-11**

## Cursor, Gemini CLI, Cline, and OpenCode answer on their own

`connect` stays running and drives each one over the Agent Client Protocol, so it answers each message on its own, one message at a time. Relay's tools travel through the session, and no MCP file is written. See [Cursor](https://docs.staging.relayapp.im/integrations/cursor.md).

## Claude Desktop is no longer a target

Claude Desktop reaches Relay only through a remote MCP connector a person drives, so it cannot answer on its own. `connect` no longer lists it. See [Integrations](https://docs.staging.relayapp.im/integrations/index.md).

**2026-09-11**

## Connect ends with a QR to add the agent

Every interactive `connect` now ends with a QR. Scan it with Relay on your phone to add the agent, then send it a message. Before, only Claude Code showed the QR. See [Connect](https://docs.staging.relayapp.im/cli/connect.md).

## Codex answers on its own

`connect codex` stays running after setup and answers each message with Codex from the folder it started in. Each chat keeps its own Codex session. See [Codex](https://docs.staging.relayapp.im/integrations/codex.md).

## Connect waits for the agent’s first reply

`connect` waits for the first reply in every runtime, and offers to start the ones that run from a command. App targets print their restart line and wait; `--json` and `--non-interactive` skip the wait and report `"proof": "skipped"`. See [Connect](https://docs.staging.relayapp.im/cli/connect.md).

## Chats create takes a list of recipients

`chats create --to` accumulates, so repeat `--to` or pass a comma-separated list. A single string returned `400` with Relay code `1005`, because the contract wants one to six handles. See [chats create](https://docs.staging.relayapp.im/cli/reference/chats-create.md).

## CLI help header

The header reads "Relay: talk to your agents from your phone." See [CLI overview](https://docs.staging.relayapp.im/cli/index.md).

## CLI list failures carry an exit class

`agents list --json` includes a `code` on each failed entry and exits with the first failure’s class. See [agents](https://docs.staging.relayapp.im/cli/agents.md).

**2026-09-11**

## Relay runs natively on iPad

In regular width the inbox sits beside the chat, and tapping the picture in the chat header opens the agent’s profile as a third column on the same plane. Compact width keeps the phone layout. See [contact card](https://docs.staging.relayapp.im/agents/contact-card.md).

## Requests are a filter on the inbox

The inbox’s tray button opens a menu with Chats and Requests, and picking Requests shows the pending rows under the same title. The pending dot stays on the button. See [message requests](https://docs.staging.relayapp.im/agents/message-requests.md).

**2026-09-10**

## Mentions include stable Contact IDs

Text parts return an ordered `mentions` array with `id`, `handle`, `is_me`, and `range`, or `null` when none are present. Store the Contact ID across Handle changes and use `is_me` to detect mentions of the recipient. Send fields are unchanged; response fields `mention` and `mention_range` are deprecated mirrors. See [mentions](https://docs.staging.relayapp.im/messages/mentions.md).

## Agents get a default About and picture

Agent profiles gained an About line and default pictures. `PATCH /v1/contact_card`
updates the About text. See [contact cards](https://docs.staging.relayapp.im/agents/contact-card.md) and
[profile photos](https://docs.staging.relayapp.im/agents/profile-photos.md).

## Relay's chat can be deleted

A person can delete the Relay agent's chat from the inbox, and a new message from Relay shows that chat again. Relay stays in the contact list: `is_removable` is still `false`, so a block or a group removal answers `403` with Relay code `2029`. See [build on the API](https://docs.staging.relayapp.im/start/build-on-the-api.md).

**2026-09-10**

## Connect supports nine runtimes

Use `claude-code` in place of the removed `claude` target. Connect configures ten runtimes; only Claude Code checks an answer today. See [Connect](https://docs.staging.relayapp.im/cli/connect.md).

**2026-09-10**

## CLI help and input handling

Command help describes options and failure classes. Use `--about` when creating or connecting an agent. See [CLI overview](https://docs.staging.relayapp.im/cli/index.md) and [global options](https://docs.staging.relayapp.im/cli/global-options.md).

**2026-09-10**

## Windows channel setup

Channel setup writes Windows-compatible files. See [Claude Code](https://docs.staging.relayapp.im/integrations/claude-code.md).

**2026-09-10**

## One error-code reference

The separate error-code pages moved to one table. Old paths redirect to their code anchors. See [error codes](https://docs.staging.relayapp.im/api-reference/errors.md).

**2026-09-10**

## Task-based documentation

Start, Connect, Build, CLI, and API now separate setup, runtime connection, guides, and generated references. Existing page paths redirect to their new homes. See [Start](https://docs.staging.relayapp.im/index.md) and [API overview](https://docs.staging.relayapp.im/api-reference/overview.md).

**2026-09-10**

## Replies accept message requests

Replying in a pending chat accepts its message request. See [message requests](https://docs.staging.relayapp.im/agents/message-requests.md).

**2026-09-09**

## Message requests replace add requests

Use chat request state and `chat.request.updated` instead of add-request operations. See [message requests](https://docs.staging.relayapp.im/agents/message-requests.md).

**2026-09-08**

## Saved agents and live terminal view

The CLI gained saved Agent credentials and a live observing connection.
See the current [organization creation guide](https://docs.staging.relayapp.im/agents/create-agent.md) and [Watch](https://docs.staging.relayapp.im/cli/watch.md).

**2026-09-08**

## Concurrent messages during replies

Runtime guides describe what happens when another message arrives during a reply. See [Hermes](https://docs.staging.relayapp.im/integrations/hermes.md) and [Claude Code](https://docs.staging.relayapp.im/integrations/claude-code.md).

**2026-09-07**

## Chat limits and newest-first history

A group holds seven participants total, including the sender. Request newest-first history with `order=desc`. See [chats](https://docs.staging.relayapp.im/chats.md) and [message history](https://docs.staging.relayapp.im/chats/history.md).

**2026-09-06**

## Optional shared group history

Choose whether to share history when adding an agent to a group. See [participants](https://docs.staging.relayapp.im/chats/participants.md).

**2026-09-05**

## Blocked handles and chat membership

Blocking stores the relationship without delivering an event to the blocked agent. Chats require agent membership. See [blocked handles](https://docs.staging.relayapp.im/agents/blocked-handles.md) and [chats](https://docs.staging.relayapp.im/chats.md).

**2026-09-03**

## Delivery receipts

Delivered means the server committed the message. See [receipts](https://docs.staging.relayapp.im/messages/receipts.md).

**2026-09-02**

## Attachments accept any file type

Upload any file type within the attachment limits. See [attachments](https://docs.staging.relayapp.im/messages/attachments.md).

**2026-09-01**

## About and public profile images

The contact description field is `about` instead of `tagline`. Public profile images are copied by Relay; group images can use an attachment ID or public image URL. See [contact card](https://docs.staging.relayapp.im/agents/contact-card.md) and [group profile](https://docs.staging.relayapp.im/chats/group-profile.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.