Skip to main content

AI gateway features

End-user identifier

AI Gateway can attribute a generation to the end user on whose behalf you called it. The same identifier decides whether the request is allowed (force_user) and which per-user budget or request cap applies — so it feeds tracing, access control and limits at once. It works the same way on every endpoint.

Where it comes from

At request time the identifier is resolved in this order — first match wins.

  • the X-User request header (see Custom headers);
  • the body user field on the OpenAI endpoints (/v1/chat/completions, /v1/responses, /v1/embeddings, /v1/images/*), or metadata.user_id on the Messages API.

If neither is present, the generation is attributed to the API key's default user when the key has one configured. That fallback only fills in attribution — it does not satisfy force_user, and per-user budgets/caps still key off the header/body value.

example.ts
import { client } from "./client"; // Body field (OpenAI convention)… await client.chat.completions.create({ model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello" }], user: "user_42", }); // …or the header — works on every endpoint and wins over the body: await client.chat.completions.create( { model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello" }] }, { headers: { "X-User": "user_42" } }, );

Requiring an identifier (force_user)

A key can be set to reject any request that does not carry an end-user identifier.

warning · force_user — the identifier can be mandatory

An API key can be set to require an end-user identifier on every request. When force_user is on and a request carries neither X-User nor a body user / metadata.user_id, AI Gateway rejects it with 400 before it reaches a provider. A key that does not force the user must instead carry a default user, so every generation resolves to some identifier.

Per-user budgets & request caps

The identifier is also the key for per-user spend and rate limits.

note · Per-user budgets & request caps

A budget or request cap on a key can be key-level (all traffic) or per-user (one identifier). When a request resolves to a user, both the key-level limit and that user's per-user limit are enforced — either one over the limit returns 429. Per-user limits only bind when the request carries a user / X-User; without one, only the key-level limits apply.