Fleeexdocs

Authentication

The two credentials every Fleeex call carries, your app API key and the end-user id you vouch for.

Every call the SDK makes carries two pieces of identity. Getting them right is what makes metering correct and per-user.

CredentialSDK optionSent asIdentifies
API keyapiKeyAuthorization: Bearer <key>Your app.
End-user iduserIdx-fleeex-user: <id>The end user the call is for.
const client = new FleeexClient({
  apiKey: process.env.FLEEEX_API_KEY!, // flx_…
  userId: "user-123",
});

The API key (flx_…)

  • It authenticates your app. Issue and rotate keys from your Fleeex account (the dashboard, or control plane).
  • It's a server-side secret. A leaked key impersonates your app, so never ship it in a browser, mobile bundle, or public repo. Keep it in an environment variable or a secrets manager.

A key is minted for one of two worlds, decided when it is issued and never changed. A live key (flx_…) spends real money; a test key (flx_test_…) spends a fake balance and calls no model provider. The prefix tells you which, and no gesture promotes one to the other. See Sandbox.

The user id (x-fleeex-user)

  • This is your own identifier for the end user, whatever your app already uses. Fleeex trusts your app for its own users' identity, and the id never crosses your app boundary.
  • It's what makes usage and billing per user: each (app, user) pair maps to a wallet identity.

The value becomes part of a storage key, so it is bounded. Send something that fits, or the request is a 400 that names the rule (and never echoes your value back):

RuleValue
Length1 to 256 characters, trimmed; blank counts as absent
Charsetprintable ASCII, no whitespace

An email (254 characters at most), a UUID, or any opaque provider id all fit comfortably.

Which routes need it: the proxy, getBalance(), getConnection() and getUsageSummary() all require it, and answer their own 400 when it's absent. GET /v1/models deliberately does not, because the catalog is a property of your app rather than of one of its end users, so a client can enumerate models before it has a user. See Choosing a model.

One FleeexClient is bound to one userId. Handling many users? Create a client per user (they're cheap), or set the header per request with the raw OpenAI SDK (see Drop back to raw OpenAI).

Control plane vs. data plane

The SDK operates on the data plane: proxied AI calls and read-only billing helpers, authenticated by the app API key. Managing the account itself (funding the wallet, creating apps, issuing keys) is a separate control plane, the dashboard. So an app key can spend against a wallet but can never top it up or mint new keys.

Tracing a call

Every response carries an x-correlation-id, and the same id appears in the error envelope. Send your own to tie a Fleeex call to a request in your own logs:

const client = new FleeexClient({
  apiKey,
  userId,
  defaultHeaders: { "x-correlation-id": requestId },
});

It's the only handle that ties a failure you saw to the server-side record of it, so log it whenever you catch an error.

Your value is kept only if it's at most 64 characters of A–Z a–z 0–9 _ . : -; anything else is silently replaced by a fresh id. So read the id back off the response rather than assuming the one you sent was used. A UUID or a trace id fits; a URL or a JSON blob does not.

Next