developerUpdated 2026-05-19

Embed API

What this covers

The Embed API lets third-party applications embed Tessallite's conversational agent or query capabilities inside their own products. Instead of requiring users to log in to Tessallite directly, the host application requests a scoped, time-limited token from its backend, then passes it to the embedded component. The end user never sees Tessallite credentials.

How embedding works

  1. The ISV backend authenticates to Tessallite as a tenant admin and calls POST /api/v1/auth/embed-token.
  2. Tessallite returns a signed JWT with restricted scope (tenant, persona, models, capabilities, expiry).
  3. The ISV backend passes the token to the browser (in page props, a cookie, or via a server-rendered attribute).
  4. The browser-side embed component (iframe or React component) uses the token for all Tessallite API calls.
  5. When the token nears expiry, the component fires a callback; the ISV backend requests a fresh token.

No Tessallite login page is shown. The end user's identity comes from the user_identity field in the token request, which appears in Tessallite's audit log.

Requesting an embed token

Endpoint: POST /api/v1/auth/embed-token

Authentication: Requires a tenant admin or system admin JWT (via cookie or Bearer header).

FieldTypeRequiredDefaultDescription
tenant_idstringyes-Target tenant slug
user_identitystringyes-Display name for audit trail
persona_idstringnonullLock to this persona's permissions
model_idsstring[]nonullRestrict visible models
capabilitiesstring[]noallAllowed features: query, chat, explore
expiry_minutesintegerno180Token lifetime (min 5, max 1440)

Scope fields

persona_id locks the session to a specific persona. All row-level security filters and measure/dimension access rules for that persona apply. If omitted, the embedded user sees the default (unfiltered) view.

model_ids restricts which models the token can access. Any query or chat request targeting a model not in the list returns 403. If omitted, all models in the tenant are accessible.

capabilities controls which features the embed can use:

If a capability is excluded, API calls to the corresponding service return 403.

Token lifetime

The default token lifetime is 3 hours (180 minutes), long enough for demos and presentations without interruption. The maximum is 24 hours (1440 minutes). The minimum is 5 minutes.

For production embedding, set the expiry shorter (30-60 minutes) and implement token refresh via the onTokenExpiring callback in the embed component.

CORS configuration

Embedded components load from the ISV's domain. Set the ALLOWED_EMBED_ORIGINS environment variable (comma-separated):

ALLOWED_EMBED_ORIGINS=https://app.customer.com,https://portal.customer.com

This is merged with the standard CORS_ORIGINS setting. Both model-service and agent-service read it.

Example: Python

import requests

TESSALLITE_URL = "http://localhost:3000"

# 1. Log in as tenant admin
login = requests.post(f"{TESSALLITE_URL}/api/v1/auth/login", json={
    "tenant_id": "acme-demo",
    "email": "admin@acme-demo.com",
    "password": "acme-demo",
})
cookies = login.cookies

# 2. Request an embed token
resp = requests.post(
    f"{TESSALLITE_URL}/api/v1/auth/embed-token",
    json={
        "tenant_id": "acme-demo",
        "user_identity": "viewer@customer.com",
        "capabilities": ["chat"],
        "expiry_minutes": 60,
    },
    cookies=cookies,
)
embed_token = resp.json()["token"]

Example: curl

# Get admin session cookie
curl -s -c cookies.txt -X POST http://localhost:3000/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"tenant_id":"acme-demo","email":"admin@acme-demo.com","password":"acme-demo"}'

# Request embed token
curl -s -b cookies.txt -X POST http://localhost:3000/api/v1/auth/embed-token \
  -H 'Content-Type: application/json' \
  -d '{
    "tenant_id": "acme-demo",
    "user_identity": "demo-viewer",
    "capabilities": ["query", "chat"],
    "expiry_minutes": 180
  }'

Security considerations

Related