Relay permissions and states
Reference Relay organization selection, Email and WhatsApp capabilities, ownership, routes, states, limits, and durable side effects.
Relay first resolves a trusted non-guest organization workspace, then applies channel-specific capabilities and record ownership. Email is organization-shared and administrator-only. WhatsApp use is available to ordinary members and administrators, but the inbox and chat records are scoped to the signed-in user’s own connections.
Guest memberships are excluded from Relay workspaces and capabilities.
The platform onboarding gate runs before Relay routes and requires a completed account profile with both first and last name. A signed-in account missing either value is redirected to account onboarding before Relay can resolve an organization or channel.
Workspace access
| Account and organization state | Relay access |
|---|---|
| Signed out or unconfirmed | Must complete authentication before Relay opens. |
| Signed in with an incomplete account profile | Must complete both first and last name through account onboarding before Relay opens. |
| Confirmed account with no non-guest organization memberships | Has no Relay workspace capability. |
| Guest-only membership | Excluded from Relay’s available organizations. A guest organization cannot be selected through the URL. |
| One available organization | Receives base Relay access; Relay selects that organization automatically and canonicalizes channel URLs under its slug. |
| Multiple available organizations, none selected | Can open the Relay root, which shows Select an organization and Open organization selector, but no channel has a current organization yet. |
| Ordinary organization member | Can open Relay and use WhatsApp for connections owned by that user. The member cannot read, send, or download attachments from Relay Email and cannot open WhatsApp settings. |
| Organization administrator | Adds shared Relay Email read, send, and attachment-download capability plus WhatsApp settings capability. WhatsApp inbox data remains current-user-owned. |
| System administrator who is also an ordinary member | Adds WhatsApp settings capability for that selected membership, but does not gain Relay Email access. System-administrator status without a non-guest membership grants no Relay workspace. |
An organization administrator therefore has Email and WhatsApp settings access; an ordinary organization member has WhatsApp inbox use but cannot open Relay Email. A system administrator does not automatically receive Relay Email capability.
Routes
| Route | Required context |
|---|---|
/ and /:org_slug | Base Relay access. The root can host explicit organization selection. |
/:org_slug/email | Current organization plus Relay Email read capability. |
/:org_slug/email/threads/:thread_id | Email read capability and a thread in an accessible assigned mailbox. |
/:org_slug/email/attachments/:attachment_id | Attachment-download capability and an available attachment chained to an accessible mailbox message and thread. |
/:org_slug/whatsapp | WhatsApp-use capability and a current organization. The list is restricted to the current user’s connection IDs. |
/:org_slug/whatsapp/:chat_id | WhatsApp-use capability and a chat from one of the current user’s owned connections. |
/:org_slug/settings/whatsapp | WhatsApp-manage capability. Current ownership inconsistencies are tracked in IO-11440. |
Legacy root and query-parameter forms canonicalize to organization-slug paths after Relay establishes a valid workspace. A mailbox, connection, or chat identifier is not trusted merely because it appears in a URL.
Channel ownership
| Channel | Reader and writer | Durable scope | Not implied |
|---|---|---|---|
| Organization administrators in the selected organization. Sending additionally requires a verified active mailbox. | Assigned organization mailbox; thread workflow state is mostly shared, while unread state and actor-owned drafts or failed sends retain the acting user. | Ordinary membership, guest access, or system-administrator status alone. | |
| Non-guest members and administrators, using only connection IDs owned by the signed-in user for the selected organization. | A connection belongs to both one organization and one user; its conversations and messages follow that connection. | A shared organization inbox or administrator access to another user’s connection. | |
| WhatsApp settings | Organization administrators and system administrators who are members of the selected organization. | Intended to manage a WhatsApp connection, but the current implementation mixes user-owned and organization-wide behavior. | A safe, stable, current-user-only recovery contract. |
Email and WhatsApp are the only registered Relay channels. Telegram is not a current route, channel, or capability.
Email mailbox selection
Relay lists active mailboxes assigned to the selected organization. It chooses a mailbox in this order when the relevant trusted context exists:
- the last selected mailbox, if it is still accessible;
- a vehicle-specific mailbox from trusted vehicle context;
- the organization’s default mailbox;
- the first accessible mailbox.
Switching mailboxes preserves the selected view but clears the search term. An inaccessible mailbox_id produces This mailbox is not available in this Relay workspace. and does not expose its threads.
Email views and thread state
| View | Current filter |
|---|---|
| Inbox | Threads in the inbox state. |
| Sent | Sent threads. |
| Drafts | Intended for saved drafts, but currently returns no thread rows and a count of zero under IO-11441. |
| Failed | The list and count include threads whose synchronized EmailMessage error state is present. This is not a list of failed local outbox items. |
| Archived | Archived threads. |
| Done | Threads marked done. |
| Unread | Inbox threads unread by the current administrator. |
| With attachments | Inbox threads with attachment records. |
Opening a thread marks it read for the current administrator and records open and view activity. Mark as read and Mark unread update that per-user state. Archive, Move to inbox, Mark as done, Reopen, custom Label membership, and Assign to update shared workflow state. Assignment accepts only a current administrator from the mailbox organization.
Provider folder or label synchronization is best effort for applicable thread actions. A provider failure does not necessarily roll back Relay’s local state. Search, filters, and counts reflect the selected mailbox and current local projections, so they are not provider-delivery receipts.
Each mailbox view or search loads at most the 50 most recent matching threads. Relay applies the view, search, and recency ordering before that limit.
Email search is a case-insensitive substring match across thread or message subjects, message text, sender names and addresses, recipient names and addresses, and attachment filenames. Switching to another view clears the search term.
Email draft and send states
| State or action | Durable effect |
|---|---|
| Open Compose, Reply, Reply all, or Forward | Creates an actor-owned draft in the selected mailbox. |
| Change a composer field | Autosaves the draft with optimistic locking. A stale lock reports that the draft changed in another session. |
| Save for later or close the composer after autosave | Keeps the durable draft. The Drafts view does not currently list it. |
| Discard | Soft-discards the acting user’s draft. |
| Send | Validates and stores or reuses one outbox item, then queues background delivery. The success message is Queued the email for delivery. |
| Retry send | Applies only to an eligible failed item and requeues it with the same idempotency key. |
| Successful provider delivery | Advances the outbox and message/thread projections independently of the initial queue response. |
The sender needs Email send capability and a mailbox with verified send status. Queued, retrying, and successfully delivered are different states. A queue success does not prove receipt, and the provider grant can still fail during the later delivery attempt. An actor-owned failed outbox item linked to an open thread can appear as Last send failed with Retry send, but that outbox state does not itself place the thread in Failed. A compose failure before an Email message projection exists need not appear in Failed or expose list-based recovery.
Email fields, attachments, and safe rendering
The composer provides From, To, CC, BCC, Reply-to, Subject, Message body, and Add attachments. To requires at least one valid recipient before sending.
A draft accepts up to 10 attachments. Each upload is limited to 25 MiB, and the combined attachment size for the draft is also limited to 25 MiB. Relay rejects an unsafe attachment before it can be queued.
The customer-facing attachment states are Available, Blocked, and Pending:
- Available: stored bytes passed the required state checks and an authorized administrator can view or download them;
- Blocked: safety checks refused the file;
- Pending: the file bytes have not finished syncing.
Save to vehicle documents appears only for an available attachment whose message already has trusted vehicle context. It registers the attachment as a source document and queues document processing. It does not guess a vehicle.
Email HTML is sanitized before rendering. Remote image elements are omitted unless the workspace’s remote-images feature is enabled; otherwise Relay shows Remote images are blocked for this workspace.
WhatsApp inbox and message states
The WhatsApp inbox uses only the current user’s connections in the selected organization. All, Unread, and Unmatched filter that set. Selecting a persisted conversation clears its local unread count, activates receipts, and can synchronize avatar or group metadata.
Mounting the inbox can resume resumable authentication and synchronize stale avatar or group metadata before the user sends anything. Treat opening it as provider-affecting behavior, not as a passive capture or inspection step.
| State | Behavior |
|---|---|
| Connected | New direct text, group creation, replies, and reactions can use the connected account. |
| Resuming | Relay is attempting to restore provider connectivity; new writes should wait. |
| Disconnected but resumable | Persisted messages remain available and the inbox can offer Resume connection. |
| Needs relink | Persisted messages remain available, but provider writes are disabled and the UI points to settings. |
| History sync pending, running, failed, or complete | Describes import progress separately from the connection and from already persisted messages. |
The current web composer sends text; it does not upload a new WhatsApp attachment. Imported messages can render text, image, video, document, audio, sticker, location, contact, reaction, and system content when the adapter has that data. A reaction is sent through the connected WhatsApp account and only after Relay rechecks connection, conversation, message, emoji, desired state, and actor ownership.
Creating a direct draft from a phone number does not itself send a message. The first successfully persisted sent message creates or updates the Relay conversation. Create group requires a nonblank name and at least one selected candidate that resolves to a valid direct-user JID. The picker returns at most 100 candidates from the current user’s owned connections and excludes group conversations and the connected account’s self-chat, but a displayed candidate can still be rejected at submission. Picker visibility does not establish that every other conversation kind is a direct chat or a valid group participant.
WhatsApp CRM link state
Unmatched contains direct conversations that are not linked to a Contacts person; it excludes group conversations and the connected account’s self-chat. An eligible row exposes Link. Link to contact searches people in the current organization by name or email after at least two characters and returns at most 10 matches. Selecting a person stores that association and reports Linked NAME. The conversation then leaves Unmatched. This local association does not send a WhatsApp message or call the provider.
WhatsApp settings warning
The inbox and chat authorization enforce current-user connection ownership. The current settings surface instead loads the latest WhatsApp connection for the organization without filtering by user, and the provider runtime is keyed by organization. Merely mounting settings can start or resume provider work.
The visible recovery controls also have wider or weaker boundaries:
- Reset connection immediately clears credentials and restarts pairing without a confirmation dialog.
- Retry history sync stops and resumes the organization-keyed connection runtime.
- Delete all WhatsApp data has a confirmation prompt, but deletes every WhatsApp connection in the organization and cascading conversations, messages, reactions, participants, and Signal sessions. CRM contact records remain.
These facts are tracked by IO-11440. They are warnings, not a supported recovery playbook. Do not promise that settings affects only the current user, and do not use those controls merely to test or document Relay.