Skip to main content
A page that embeds a Devic widget has to carry an API key, and anyone who opens the browser’s developer tools can read it. If the tenant travels alongside that key as a plain parameter, anyone holding the key can claim to be any of your customers:
A tenant session closes that. Your backend mints a short-lived token that contains the tenant, signed by Devic; the browser uses that token instead of the key, and the tenant is no longer something the caller declares.

The flow

1

Your backend asks for a session

With a server-side API key, naming the tenant it has already authenticated in your own system. With @devicai/sdk:
Or against the endpoint directly:
Take the identity from your own session, never from the request body. An endpoint that mints a session for whatever tenant the caller names has reintroduced the problem it was built to solve.
2

You hand the token to the page

In the response to your own login, in a cookie, wherever your session already lives.
3

The widget uses it

Every Devic call carries the session token. The tenant comes from inside it, so no parameter can override it.
/api/v1/tenant-sessions is the one public route where the /api prefix is required — the gateway serves this endpoint itself instead of proxying it. The SDK handles that for you.

What the token can and cannot do

A session is a narrowed copy of the API key’s own token: same account, same role, plus the tenant it is confined to. Everything downstream behaves as it did with the key — only the reach changes, which is what a session should be. What it reaches is an explicit list, closed by default:

Allowed

Talk to an assistant, read its own conversations, follow a run, upload attachments, dictate, read and edit the assistant’s memory about it, see its own usage, manage its own connected apps.

Refused

Create assistants or agents, read costs, manage tool servers or projects, administer tenants, touch workspace integrations or the account’s plans.
The list matches segment by segment, not by prefix. A rule over /v1/assistants/* written as a prefix would also grant DELETE /v1/assistants/{id} — precisely what the list exists to prevent. A new public endpoint is therefore born closed until it is deliberately added.

Lifetime

One hour by default, clamped to between 60 seconds and 12 hours. Asking for a year gets you twelve hours rather than an error. The upper bound is a working day on purpose. The useful pattern is not always “refresh every few minutes”: you can issue the session inside your own login and hand it over in a cookie, with no endpoint to refresh it from — and then it has to last as long as the work session does.

Two rules that keep it honest

A session cannot issue another session. Otherwise the shortest-lived credential on the platform could renew itself forever, and an expiry the holder can extend is not an expiry.A session cannot be issued from a browser. A request carrying an Origin header, or made with a key configured for browser domains, is refused. A page that could mint its own session could mint one for anybody.

Revocation

Sessions are signed and expire on their own, but you do not have to wait for that. Every call made with a session re-checks that the key that issued it is still active, so disabling the key ends its sessions within seconds. Deleting a key does the same — otherwise deletion would be a suggestion.
Usage made with a session is attributed to the key that issued it, so moving from raw keys to sessions does not empty your usage metrics.

In the widget

@devicai/ui takes a session instead of an API key, and can refresh it before it expires:
The provider renews the session on its own before it expires. There is no apiKey in that snippet, and there should not be: a page using sessions has no reason to carry a key. See Embedding in your product.

Making it impossible to get wrong

Everything above is a convention until the key cannot do anything else. An API key has an identity mode: Put the session-minting key on signed and the mistake stops being possible: nobody can paste that key into a page and reach a customer’s data with it, because the only thing it can do is ask for a token that pins the customer. Anything else your server does needs a second key left on open — two keys, two jobs. See API keys.

Reference