You are building a SaaS assistant for many customers. Each customer should be able to send and receive RelayLink briefings, but your backend has one deployment and one job queue. The dangerous shortcut is to place one RelayLink key in the service and attach a tenant ID to each call.
For application architects and integration engineers, the correct design starts with a separate RelayLink identity for every application user who sends, owns an inbox, or connects an assistant. A person who only receives and replies by email does not need an account.
Map one application user to one RelayLink account
Treat RelayLink authentication as user delegation, not service authentication. An OAuth access token or API key identifies one person's RelayLink account. It determines the inbox, drafts, threads, and contacts the request can reach.
Your tenant ID does not override that identity. Do not accept relaylinkUserEmail from application code and combine it with a shared credential. The shared key still belongs to one account, so every request would act as that person regardless of the email your app labels it with.
Keep an explicit mapping:
- Your signed-in application user
- Their RelayLink connection
- The credential or token reference stored inside that tenant's secret boundary
- The RelayLink account identity returned by
whoami
Use whoami during connection verification so the user can see which account and server they connected.
Prefer delegated sign-in, isolate key fallback
When your client supports OAuth, send the person through RelayLink sign-in and consent. Store tokens against that application user. Refresh and revoke them as delegated credentials, and do not move them between tenants.
If your integration cannot support OAuth, the person can issue a named API key in the browser and enter it into a connector settings field. Issuing is not an assistant tool. Give the key a name tied to the integration and store it in your application secret system, never in a model prompt or conversation transcript.
Use one key per user integration. A key shared by several customers makes those customers indistinguishable to RelayLink and turns one revocation into an outage for all of them.
Keep the approval boundary visible
RelayLink is not a single-call delivery API. Your app calls draft_package, presents the returned preview to the authenticated user, and calls confirm_send only after that user approves.
Do not hide those steps behind an “automatic outreach” switch. The user should know which account is sending, who will receive the package, and what wording is crossing. If your app supports several personas, personas may shape drafts, but they do not replace the RelayLink account identity.
The same user scoping applies on reads. Call inbox and thread operations with the credential belonging to the user whose screen or agent is requesting them. Do not fetch into a common cache and filter by tenant afterward.
Webhooks wake the right tenant
Where the RelayLink host offers outbound webhooks, registration is a human portal action at /account/webhooks. It is not an MCP tool or a public provisioning API, so your backend must not imply that it can register a receiver for the user. The account holder chooses the HTTPS endpoint and receives the signing secret once.
One account registers its own endpoint. A shared receiver deployment must not give every tenant one identical URL and expect the POST body to identify the owner: neither the body nor the headers contain a recipient id or subscription id. Generate an opaque route for the user or subscription, map that route to the user's RelayLink connection, and have the account holder register that URL in the portal. Store the one-time signing secret with the same tenant-scoped integration record. Do not put a RelayLink credential in the webhook URL.
The POST is an envelope, not the briefing. It includes a delivery identifier, package and thread identifiers, sender information, topic, time, reply status, and the host's MCP address. Resolve the endpoint route to the expected tenant and signing secret, verify the timestamp and signature, deduplicate on the delivery identifier, then call get_package with that user's credential.
Outbound webhooks explains why content stays out of the POST. A successful webhook delivery only means your receiver accepted the envelope. The authenticated package fetch is the content step.
Fit and non-fit
This architecture fits a SaaS assistant that acts for identifiable people, keeps tenant credentials apart, and asks each person to approve outgoing correspondence.
It does not fit a bulk messaging engine, a shared service bot, or a queue where your company wants one key to speak as many customers. If the user-owned model is right, connect through the live reference page, verify identity, and keep every subsequent operation inside that user's boundary.