Developers Authentication

Authentication.

Two kinds of credential, one header.

Send Authorization: Bearer <credential> on every call. There are two kinds of credential.

Mayfair ID access tokenService key
ForApps where people sign in with Mayfair ID, in a browser or on a serverYour own servers and back-end jobs
Looks likeA signed JWT (type at+jwt)mfk_live_ plus 43 random characters
Usage counts againstThat person's plan, the same daily and weekly allowance as the Artemii appThe key's own daily and monthly token caps
Browser useYes. This is the right choiceNo. Never put a key in a browser, a mobile app or a repository
LimitsPer-person request limit (30 a minute by default) and the plan allowanceRequests 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 as mayfair-mail.
  • If it has a scope claim, the scope must include ai.
  • 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_day and limit_week, and 403 no_plan when 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:

JavaScript
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.