Give your customer a portal
Create a branded portal link so your customer can set up domains and read activity in their namespace without a Samva account.
Give your customer a hosted portal for their namespace. They open a private link, without signing up for Samva, to add a domain, inspect DNS records, re-check verification, and remove a suppression. Senders, activity, usage, and mailboxes are read-only. Mailboxes show names, addresses, and sending readiness; the portal never shows message content. Shared organization domains and senders are read-only.
The portal uses your organization's default brand. Your customer can return to your platform through
the link's redirectUrl.
Create a link
Use an organization-wide credential with permission to manage namespaces. A namespace credential or a member restricted to one namespace cannot create portal links.
import { createClient } from "samva";
const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! });
const link = await samva.namespaces.createPortalLink({
id: process.env.SAMVA_NAMESPACE_ID!,
redirectUrl: "https://app.example.com/settings/email",
metadata: { customerId: "cus_123" },
});
// Deliver link.url privately to your customer.The URL is returned only when you create the link. Keep it private: anyone holding it can open the portal until it expires or is revoked. Its token stays in the URL fragment. Metadata is yours to label the link, for example with your customer ID.
Set expiresIn to choose the link's lifetime in seconds. The create portal link API
reference defines the default and maximum lifetime.
The link can be opened repeatedly while valid; each visit opens a short-lived portal session.
You can also create the link in Namespaces → your namespace → Portal links, or through the
namespaces_create_portal_link MCP tool.
samva namespaces portal-links create "$SAMVA_NAMESPACE_ID" \
--redirect-url https://app.example.com/settings/email \
--metadata customerId=cus_123 --jsonList and revoke links
Listing returns link details and expiry, without the secret URL. Keep the link's ID if you need to revoke it later.
import { createClient } from "samva";
const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! });
const page = await samva.namespaces.listPortalLinks({
id: process.env.SAMVA_NAMESPACE_ID!,
});
for (const link of page.items) {
console.log(link.id, link.expiresAt, link.revokedAt);
}
await samva.namespaces.revokePortalLink({
id: process.env.SAMVA_NAMESPACE_ID!,
linkId: process.env.SAMVA_PORTAL_LINK_ID!,
});samva namespaces portal-links list "$SAMVA_NAMESPACE_ID" --json
samva namespaces portal-links revoke "$SAMVA_NAMESPACE_ID" "$SAMVA_PORTAL_LINK_ID" --yesRevoking a link also ends its live sessions. A creator who leaves your organization or loses the required permissions ends access through their links. Revoking the API key or OAuth authorization that created a link also ends access. Deleting the namespace removes its links.
When your customer opens a different link while a portal is already open, they confirm the destination before switching. They can keep their current portal instead.
What your customer can reach
The portal is confined to its namespace and the creator's current permissions. It has no People, keys, webhooks, templates, billing, or organization settings pages. Usage shows message analytics; your organization remains responsible for billing. A portal link cannot create another portal link.