Choosing a model
Pass an alias rather than a versioned provider id, and ask which models your app may call instead of hardcoding a list.
Two things about model are where an OpenAI habit stops being true: which ids exist, and
which of them your app is allowed to call. Neither is guessable, and both are answerable
with one request.
Pass an alias
Send a stable public name such as nova-lite rather than the versioned provider id it
resolves to (amazon.nova-lite-v1:0). Both are valid values for model, but the alias
is the one that survives the next model revision: Fleeex re-points it, and your code
doesn't change.
await client.chat.completions.create({
model: "nova-lite", // not "amazon.nova-lite-v1:0"
messages: [{ role: "user", content: "Hello!" }],
});The response echoes the resolved id, in completion.model and on every chunk of a
stream. That's what OpenAI does when a family name resolves to a dated snapshot, and it's
the only way a caller using an alias can see which model actually answered and was
charged. Your usage events record the resolved id too, so billing history stays auditable
across a re-point.
Which models you may call depends on your app
Model licences don't all permit resale, so the catalog records a resale right per model, and the proprietary families are reserved for FlexCorp's own apps. A third-party app neither sees them in the catalog nor may call them.
So if the list is shorter than you expected, that is the reason. It isn't a bug, and it isn't something a retry, a different key, or a funded wallet changes:
GET /v1/modelsomits what your app may not use, rather than listing it and refusing it. Everything it returns is callable.- Asking for a reserved model by name is a
403with codeMODEL_NOT_ENTITLED, naming the model and the remedy. It reaches no provider and reserves nothing. - A model nobody serves is a different answer: a
400on a completion, a404onGET /v1/models/{model}.
Open-weight models and Amazon Nova carry no such restriction and are open to any app,
which is why every example on this site uses nova-lite.
List the models you may call
GET /v1/models answers in OpenAI's own list shape, scoped to the app your key belongs
to. FleeexClient wraps chat completions only, so list with the OpenAI client (already a
peer dependency) pointed at the same base URL.
Unlike a completion, discovery needs no x-fleeex-user: 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.
import OpenAI from "openai";
const catalog = new OpenAI({
apiKey: process.env.FLEEEX_API_KEY!,
baseURL: "https://api.fleeex.dev/v1", // note the trailing /v1
// no x-fleeex-user: deliberately not required here
});
const page = await catalog.models.list();
for await (const model of page) {
console.log(model.id, model.owned_by); // e.g. "nova-lite" "amazon"
}Aliases are listed next to the ids they resolve to. Both are usable values for model,
the way a provider lists a family name next to a dated snapshot. Hiding the alias would
make the list wrong.
| Field | Value |
|---|---|
id | What to send as model: a catalog id, or an alias that resolves to one. |
object | "model". |
created | Always 0. Fleeex records no creation date for a catalog entry, and a fabricated one would both claim a moment nobody knows and make an otherwise identical response change on every request. |
owned_by | Derived from the provider prefix of the resolved id (anthropic.claude-… → anthropic), so an alias reports the provider that owns the model it points at. |
Nothing Fleeex-specific (price, margin, resale right) appears here. The body is OpenAI's exact key set, because a strict client decoder fails on an unknown property.
Describe one model
const model = await catalog.models.retrieve("nova-lite"); // alias or provider idThe two failure modes are deliberately different answers:
| Answer | Meaning |
|---|---|
404 | No model or alias by that name is served here. Check for a typo. |
403 MODEL_NOT_ENTITLED | The model is real, and reserved for other apps. |
The list omits the reserved one because a list is "what you can use". A caller that asks about a specific model is told which of the two situations it's in, instead of hunting for a typo that doesn't exist.