
# Model aliases

An alias is a named pointer to a concrete route — a
(provider, model, region) triple from the
[model catalogue](available). You create alias `big` pointing at
`aws-bedrock/mistral/ministral-3-3b-instruct/br-gru`, then call the
API with:

```json
{
  "model": "alias/big",
  "messages": [{ "role": "user", "content": "Hello" }]
}
```

The gateway resolves `big` to its stored route at request time and
routes exactly as if you had sent the full model ID. When you change
your mind about which model "big" is, repoint the alias in the
dashboard — every client configured with `alias/big` picks up the new
route on its very next request, with zero reconfiguration. That is the
point: a coding agent or chat client gets configured once.

Aliases are account-wide. Every API key on your account resolves the
same aliases.

## Creating and managing aliases

Three surfaces:

- **Model catalogue.** Every provider/region row on a model page has
  an **Alias** button — point an existing alias at that exact route or
  create a new one from it.
- **Dashboard → Aliases.** List, create, rename, repoint, and delete,
  with a copyable `alias/<name>` for each. Each alias has a detail
  page with its usage stats and full change history.
- **The API.** Manage aliases programmatically with the same API key
  you call inference with (below).

## Managing aliases via the API

All endpoints take your regular `Authorization: Bearer <api key>`
and address aliases by name:

| Method | Path | Does |
|---|---|---|
| GET | `/v1/aliases` | List aliases + quota |
| POST | `/v1/aliases` | Create — body `{name, provider, canonical_id, locode}` |
| GET | `/v1/aliases/{name}` | Get one alias |
| PATCH | `/v1/aliases/{name}` | Rename (`name`) and/or repoint (full target triple) |
| DELETE | `/v1/aliases/{name}` | Hard delete |
| GET | `/v1/aliases/{name}/stats?days=30` | Usage totals + per model/provider/region breakdown |
| GET | `/v1/aliases/{name}/history` | Change history, newest first |

Create an alias and immediately use it:

```bash
curl -X POST https://api.lowrouter.ai/v1/aliases \
  -H "Authorization: Bearer $LOWROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "big", "provider": "aws-bedrock",
       "canonical_id": "mistral/ministral-3-3b-instruct", "locode": "br-gru"}'

curl -X POST https://api.lowrouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $LOWROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "alias/big", "messages": [{"role": "user", "content": "Hello"}]}'
```

Repointing takes the **full target triple** — send all of `provider`,
`canonical_id`, and `locode`, not just the field you are changing.

## Stats and history

Every request through an alias is attributed to it: the stats endpoint
(and the alias detail page in the dashboard) breaks usage down by the
model, provider, and region the alias resolved to at the time —
request counts, prompt/completion/total tokens, plus cost and carbon
totals. Every create, rename, and repoint is recorded with its old and
new values.

Two things to know:

- Stats follow the **alias**, not its name: renaming keeps history and
  stats; deleting and recreating a name starts fresh.
- Attribution starts when this feature shipped — earlier traffic is
  not retroactively assigned.

Alias names are 1–64 characters: lowercase letters, digits, `-` and
`_`, starting with a letter or digit. Names are lowercased when
created and when looked up, so `alias/Big` and `alias/big` are the
same alias.

Each account can hold **5 aliases** by default. The limit is visible
on the aliases page; contact support if you need more.

## Resolution semantics

- **Billed like the target.** An aliased request is billed at the
  target route's per-region pricing — exactly what an explicit request
  for that model ID would cost. The alias adds no fee.
- **The response echoes the resolved model.** `model` in the response
  carries the resolved full model ID, not the alias — so logs and
  downstream tooling always see what actually served the request. The
  alias you sent is echoed in
  [`lowrouter_metadata.requested_alias`](per-request-metadata).
- **Fail-closed.** If an alias does not exist (or was deleted), the
  request fails with `404 alias_not_found`. If an alias's target can
  no longer be routed — the model left the catalogue or its region is
  unavailable — the request fails with the same error the explicit
  model ID would produce. The gateway never silently substitutes a
  different model, provider, or region.
- **Deletes are immediate.** Deleting an alias frees its name for
  reuse right away, and requests still using it get
  `404 alias_not_found`. If live clients depend on an alias, repoint
  it instead of deleting it.

## Errors

| Case | Status | `error.code` |
|---|---|---|
| Malformed alias name in `model` | 400 | `invalid_alias_name` |
| Alias does not exist on this account | 404 | `alias_not_found` |
| Alias target no longer routable | 404 / 503 | the explicit-mode code for that failure |
| Create: name already taken | 409 | `alias_exists` |
| Create: account alias limit reached | 422 | `alias_limit_reached` |
| Create/repoint: target invalid or unroutable | 422 | `invalid_alias_target` |

## Worked scenario: repointing through a provider outage

Your coding agents all call `alias/big`, which points at
`mistral/mistral/mistral-large/fr-par`. The provider has a bad
afternoon and calls start failing with 503s. Instead of redeploying
every client:

1. Pick a healthy substitute in the [catalogue](available) — say the
   same model served by another provider.
2. Repoint the alias (the full triple, as always):

   ```bash
   curl -X PATCH https://api.lowrouter.ai/v1/aliases/big \
     -H "Authorization: Bearer $LOWROUTER_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"provider": "scaleway",
          "canonical_id": "mistral/mistral-large", "locode": "fr-par"}'
   ```

3. The very next `alias/big` request routes to the new target. When
   the outage ends, repoint back the same way.

Billing follows the target from the next request on. And you traded
reproducibility for flexibility: responses before and after the
repoint came from different routes. That's why repointing is a named,
recorded action — `GET /v1/aliases/big/history` shows exactly when it
happened, and every response's `model` and `lowrouter_metadata` say
who actually served it, so the audit trail survives the flexibility.

## What aliases are not

- They are not a fallback or load-balancing mechanism — one alias
  points at exactly one route.
- They do not pin pricing. Repointing an alias changes what you are
  billed to the new target's rate from the next request on.
- They are per-account, not per-key. There is no way to give two API
  keys different meanings for the same alias name.
