Agents and users
An agent is the identity a user messages. Its external backend runs the model, tools, and memory. See Your agent for creation, identity, distribution, and installation.Conversations and participants
A conversation has a stablechat_id and a set of participants. A
direct conversation normally contains one user and one agent.
The backend can send only while its agent remains installed and active in the
conversation.
Use the chat_id from message.received for replies and history reads.
See Conversation lifecycle for how direct threads begin, remain authorized, and recover.
Messages and ordered parts
One send is one message. A message carries 1 to 32 ordered parts, of six types, and text and media handed over together stay together inside it.
Every committed part is given a permanent
part_id. A reply or a reaction
names that id, so a target never depends on a position.
Exact shapes and limits are in Sending messages.
Stored messages include:
text is the plain-language representation used by notifications, search, and clients that cannot render a part. Relay derives it, in this order: the first text part, then the first link preview, then the first data part’s fallback, then Voice memo or [attachment]. A sender-supplied text replaces the derived one.
is_from_me states direction for the caller the payload was projected for. Relay resolves it on the server against the authenticated identity.
Read direction from that field alone. Comparing sender_handle.id against your own id is ambiguous before a client knows its own identity, and wrong for every other participant in a group.
group_event separates the two things a conversation stores. A message
without one is something someone sent. A message with one is a notice: a group
membership or metadata change, committed by the person who caused it, carrying
no parts. group_event.fallback_text is the line to render. Render a notice
as a centered line, not as a bubble.
Messages do not change
A committed message is immutable. There is no edit, no unsend, and no delete, so a message a client has stored never changes underneath it. Two things about a message do move. Its receipt stamps advance as the other party receives and reads it, and itsreactions array changes as people react.
Both are separate writes with their own events.
This is why a reply is a pointer rather than a copy. reply_to names a
message_id and optionally one part_id, and the client draws the quote from
the target itself.
Delivery and recovery
message.sequence orders messages inside one conversation’s stored history.
Webhook deliveries use event_id for deduplication; Linq’s webhook envelope
does not carry Relay’s history sequence.
See Delivery model for webhook acknowledgement,
deduplication, receipt, and recovery rules.
Socket mode and calls are specified for Relay and ship after the v0 developer
API. See API availability for the full matrix.

