Skip to main content

Hosted model aliases

A hosted model is a stable project-local alias for a training job that produced an artifact — one that succeeded, or one you stopped after it had trained. Aliases are routing identities over a shared serving pool; creating one does not allocate a dedicated GPU.

Model lifecycle endpoints

GET /api/projects/{owner_slug}/{project_slug}/models
POST /api/projects/{owner_slug}/{project_slug}/models
PUT /api/projects/{owner_slug}/{project_slug}/models/{model_slug}
POST /api/projects/{owner_slug}/{project_slug}/models/{model_slug}/disable
POST /api/projects/{owner_slug}/{project_slug}/models/{model_slug}/enable

The create/update operation must point to a training job with a promoted artifact. Re-pointing an alias lets an owner publish a new training result without changing the client-facing model slug. The update body carries only the new job reference; the alias name and slug remain stable:

{
"training_job_id": 87
}

The owner can select this operation from the project Models screen. A retired base or a job with no promoted artifact is rejected with 409.

Listing and pagination

Project aliases keep the legacy raw-array response when no pagination parameters are supplied. Product clients should opt into the bounded cursor contract:

GET /api/projects/{owner_slug}/{project_slug}/models?pagination=cursor&limit=25
GET /api/projects/{owner_slug}/{project_slug}/models?pagination=cursor&limit=25&cursor=<next_cursor>

Cursor responses are {data, next_cursor, total_count}. The default limit is 25 and the maximum is 100. Cursors are opaque, ordered by immutable alias id, and must be sent back unchanged. Authorization and filters are applied before the page, so following next_cursor reaches every alias the caller is allowed to see.

The cross-project registry is the separate GET /api/models endpoint. It uses the same cursor shape and 25-row default/100-row maximum; access, status and archive visibility filters are server-side. Its totals object contains usage rollups, not a client-derived total of registry rows.

Access

An alias can be owner-only, shared with selected accounts, or public according to the model sharing fields. The OpenAI model list is caller-aware and only returns aliases the bearer can invoke. A caller who cannot access a model gets the same model_not_found response as an unknown alias; this prevents model slug enumeration.

Serving a hosted alias

Use the alias directly:

{
"model": "support-assistant",
"messages": [{"role": "user", "content": "Hello"}]
}

The control plane resolves the alias to its owner and payer, verifies the promoted LoRA artifact, and dispatches a signed descriptor to the serving unit. A missing or invalid adapter never silently falls back to the base model.

For a stopped source job, cancelled is the terminal attempt state, not a signal that the adapter is absent. Serving uses the promoted artifact and model_available; a cancelled attempt without a promoted artifact is rejected.

Deprecation

The catalog is authoritative. A fine-tune trained on a retired base is marked deprecated: true in training/model payloads, cannot be newly published or re-pointed, and returns 410 with error.code = "model_deprecated" when served. Existing artifact downloads remain available so owners can migrate or audit their data.

Project archives

Archiving is reversible and does not delete chats, jobs, aliases, or artifacts. Archived projects are read-only: writes return the regular project-archive conflict, while OpenAI inference returns:

{
"error": {
"type": "invalid_request_error",
"code": "project_archived"
}
}

The OpenAI response is 404 with no Retry-After, because an archive is a deliberate owner action rather than a transient outage. Unarchive the project from project settings before serving again.