Skip to content

EMBED

Auth stays on your host.

Mint a scoped embed token per visitor. The browser never holds your host key. Optional host MCP credentials are stored per visitor_id when you pass them together.

sveda_embed_

token prefix

visitor_id

scope

HMAC

token kind

The problem

Shipping a host API key to the browser is the default mistake. A shared embed secret for every visitor is the next one. MCP credentials then leak on a third channel. Auth should stay on the host; the client should only send a scoped token.

Host key in JavaScript

Anything compiled into the widget is public. The host mints via POST /sveda/embed/token with x-sveda-host-key. The browser never sees that key.

One token, every visitor

A global embed string cannot isolate histories or MCP creds. Tokens are scoped to visitor_id and prefixed sveda_embed_.

MCP on a side channel

Passing a host MCP URL in frontend config exposes the tool server. URL and token go on the mint, together, stored per visitor.

How Sveda does it

Your backend calls POST /sveda/embed/token. The runtime returns a sveda_embed_ token and the visitor_id. SvedaClient sends that token as x-sveda-embed-token, or as Authorization: Bearer sveda_embed_….

Mint on the host

The product’s authenticated route talks to sveda-server. The page only receives the embed token.

  • POST /sveda/embed/token
  • x-sveda-host-key on the mint
  • response: token, visitor_id, expires_in

Two header forms

The stream POST accepts the dedicated header or a Bearer that still uses the sveda_embed_ prefix.

  • x-sveda-embed-token
  • Authorization: Bearer sveda_embed_…
  • prefix is part of the contract

MCP on the same handshake

Optional host_mcp_url and host_mcp_token must both be present. They are stored for that visitor_id, not in localStorage.

  • pair required together
  • http or https
  • Bearer on outbound MCP
ID

visitor_id

scoped embed token

x-sveda-embed-token

sveda_embed_…

or Authorization: Bearer sveda_embed_…

The browser only sends the token.

Construct SvedaClient with headers that return the mint result. Prefer a function so you can rotate. GET /sveda/embed/config is how the host reads embed settings from the runtime without putting them in the frontend bundle.

This is not chatbot SaaS login. There is no Sveda account in the widget. Your session cookie still gates the mint route. Histories and document extract use the same visitor-scoped token when those endpoints are configured on the client.

Handshake fields are in the embed token docs. Product copilot covers mint-then-attach. Host MCP covers the optional credential pair.

headers.ts SvedaClient
new SvedaClient({
  endpoints: { stream: "/sveda/stream" },
  headers: () => ({
    "x-sveda-embed-token": token,
  }),
});

// equivalent:
// Authorization: Bearer sveda_embed_…

Related

Mint on the host. Send from the client.

POST /sveda/embed/token. Prefix sveda_embed_. Header x-sveda-embed-token or Bearer. Keep the host key off the page.

Get started