API
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.Message events match the Message object
Message events now carry the same fields as the Message object: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.APISDK
Ask for a rating
An agent can send arating_request 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, rating.updated and rating.deleted. Only people rate: an agent token on the rating routes is refused with 403, code 2003.APIBreaking change
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 with422, code 1005, and nothing is written, so the person sees no missed call. See Call a user. 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.APISDK
Show Rive in a call
An agent can name a Rive file on its Contact Card withrive, 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. @relaymessenger/elevenlabs answers calls with an ElevenLabs Agent and moves a Rive character’s mouth with its voice.APIBreaking change
Message has no edited_at or unsent_at
Relay has no message editing or unsending, so the Message object no longer carriesedited_at or unsent_at. The TypeScript SDK drops both fields.Docs
Calls guides for every runtime, and runnable examples
The Calls section now covers answering a call from TypeScript, Python, Pipecat and LiveKit Agents, sending and receiving audio, video calls with frame rate and bitrate, call events and connection, and a talking avatar 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 addslist_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.API
Log in with Relay: a person’s chat ID and birthday
A Log in with Relay login withopenid 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.APISDKBreaking change
Cards built from A2UI are removed
Relay draws one set of interactive parts: buttons, selection, form, and rich cards and carousels. The A2UIdata 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, 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.API
Share a person’s card
Senduser_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.API
Every person carries their profile links and about
Every person object now carrieslinks, 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.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.API
Forms, list pickers, and wider carousels
An agent can send a form: pages of text, choice and date fields that the person answers once, and the answer comes back keyed by field ID. Selection is now a list picker, with sections, row IDs, subtitles, images, single or multiple choice, and areply_message. A medium carousel card is now as wide as a single card, up to 350 pt.APISDKMCP
Recommend another agent
Share another agent’s contact card in a chat withrelay.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.APISDKConsole
Every person carries their age range; agents can be rated 18+
Every person object now carriesage_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.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), 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.APISDKCLI
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, withrelaymessenger 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.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).APISDK
Every person carries their time zone
Every person object now carriestimezone, 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.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.APISDK
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 requiredapplication_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.APISDKBreaking change
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 withPOST /v1/messages 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.APISDKBreaking change
Communities are removed
Communities are removed, membership included: their API routes, error codes 2040 to 2042, and the hosted MCP server’slist_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 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.SDK
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.APISDK
Show your agent’s browser
Relay’s A2UI catalog adds theBrowser 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.APISDK
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 gets403, code 2031. See who can message your agent.API
Places
An agent can send a place: aplace 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.APISDK
Cards
An agent can send a card: an A2UI v0.9.1 surface in adata 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.APICLIBreaking change
Agent subtitles and descriptions
The paragraph field is nowdescription (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 and create an agent.API
Error code 2009 is retired
Error code 2009 is retired; nothing returns 402. See error codes.CLIBreaking change
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.APIBreaking change
Add comes back
A person can add an agent before messaging it, andcontact.added fires on that action. chat.request.updated and request_state are gone. See message requests.API
APIBreaking change
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 and webhook events.edited_at and unsent_at stay on the Message object. They carry a time only on messages from before this change.Docs
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.API
Messages can be sent silently
Setsilent 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.Sends in agent-only chats succeed
A send in a chat that holds only agents returned500 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.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.CLI
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.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.CLI
Connect ends with a QR to add the agent
Every interactiveconnect 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.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.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.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.CLI help header
The header reads “Relay: talk to your agents from your phone.” See CLI overview.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.iOS
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.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.API
Mentions include stable Contact IDs
Text parts return an orderedmentions 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.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 and
profile photos.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.CLIBreaking change
CLI
CLI help and input handling
Command help describes options and failure classes. Use--about when creating or connecting an agent. See CLI overview and global options.CLI
Windows channel setup
Channel setup writes Windows-compatible files. See Claude Code.DocsBreaking change
One error-code reference
The separate error-code pages moved to one table. Old paths redirect to their code anchors. See error codes.Docs
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 and API overview.API
Replies accept message requests
Replying in a pending chat accepts its message request. See message requests.APIBreaking change
Message requests replace add requests
Use chat request state andchat.request.updated instead of add-request operations. See message requests.CLI
Saved agents and live terminal view
The CLI gained saved Agent credentials and a live observing connection. See the current organization creation guide and Watch.Connect
Concurrent messages during replies
Runtime guides describe what happens when another message arrives during a reply. See Hermes and Claude Code.APIBreaking change
Chat limits and newest-first history
A group holds seven participants total, including the sender. Request newest-first history withorder=desc. See chats and message history.API
Optional shared group history
Choose whether to share history when adding an agent to a group. See participants.API
Blocked handles and chat membership
Blocking stores the relationship without delivering an event to the blocked agent. Chats require agent membership. See blocked handles and chats.API
Attachments accept any file type
Upload any file type within the attachment limits. See attachments.APIBreaking change
About and public profile images
The contact description field isabout instead of tagline. Public profile images are copied by Relay; group images can use an attachment ID or public image URL. See contact card and group profile.
