Send Authorization: Bearer <credential> on every call. There are two kinds of credential.
| Mayfair ID access token | Service key | |
|---|---|---|
| For | Apps where people sign in with Mayfair ID, in a browser or on a server | Your own servers and back-end jobs |
| Looks like | A signed JWT (type at+jwt) | mfk_live_ plus 43 random characters |
| Usage counts against | That person's plan, the same daily and weekly allowance as the Artemii app | The key's own daily and monthly token caps |
| Browser use | Yes. This is the right choice | No. Never put a key in a browser, a mobile app or a repository |
| Limits | Per-person request limit (30 a minute by default) and the plan allowance | Requests a minute, daily and monthly token caps, set per key |
Mayfair ID access tokens (user-delegated)
The token is verified exactly as the Artemii app verifies it: ES256 signature against the Mayfair ID keys, issuer, expiry and type at+jwt.
- Its audience must be the Artemii app's client id (
mayfair-ai) or one of the client ids the gateway is configured to accept for apps, such asmayfair-mail. - If it has a
scopeclaim, the scope must includeai. - Usage counts against that person's plan and shows in their usage meter. Each event is tagged
api:<client id>. - Plan limits apply:
429 limit_dayandlimit_week, and403 no_planwhen the person has no plan. - From a browser page, the page's origin must be on the gateway's allowed origins (it supports patterns such as
https://*.mayfairmail.com). - People can switch an app off for themselves, and administrators can switch an app off for the whole organisation. You then get
403 blocked_by_permissions. See Privacy and control.
The quickest way to get a token in a web app is the Mayfair ID helper (authorization code with PKCE). Pass the token to the SDK with getToken:
import { createClient } from './artemii.js';
// In a browser use the signed-in person's Mayfair ID access token, never a service key.
const ai = createClient({
baseUrl: 'https://mayfair-ai.crelloo.workers.dev',
getToken: (forceRefresh) => mayfairId.getToken(forceRefresh), // a 401 triggers one retry with forceRefresh = true
});
const reply = await ai.chat({ model: 'arlo', messages: [{ role: 'user', content: 'Summarise this page' }] });Service keys (mfk_live_)
An administrator creates keys in the admin console. The secret is shown once; only a SHA-256 hash and a visible prefix are stored. It never appears in logs, errors or the audit trail. If you lose a key, revoke it and create another.
Each key has a name, an app, scopes (chat and read), the models it may use, a requests-a-minute limit, daily and monthly token caps, optional allowed origins and an optional expiry. Revoking takes effect on the next request.
The optional user field on a request (at most 128 characters) attributes usage to one of your own end users in the usage report.
Important
Browsers are refused (403 origin_not_allowed) unless the request Origin is on the key's allowed origins, and you should still never ship a key to a browser. The SDK and the embeddable panel both refuse to run a service key in a page.
Which should I use?
- Code runs in a browser, an extension or a mobile app: Mayfair ID token.
- Code runs on your server on behalf of a signed-in person: forward their Mayfair ID token if you have it.
- Back-end jobs with no signed-in person: a service key with the smallest scopes, models and caps it needs.