> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqwish.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Families, models and datasets

> How a family grows beside its dataset, which family or model answers a call, switches, moves, keep warm, rollback and deleting.

A family is a line of models for one task, such as `support-router`. Each model in it was trained from the one before, on one dataset that grows in versions beside the line. A model is always called by its number, such as `support-router@3`, and only a model that passed its gate gets one.

| Word | Meaning |
| - | - |
| Family | A named line of models for one task. It owns its dataset, its switch and its keep warm |
| Model | One point on the line, `support-router@3`. Its number is never given again |
| Latest model | The newest model of the line. A family that is switched on serves it, and the next fine-tune trains from it |
| Dataset version | The dataset as it stood after one addition. A version never changes |
| Switch | A family's or a model's control for answering calls |
| Place | One model that answers calls. Your tier sets how many you have |
| Move | A family starting to serve its new latest model |
| Rollback | Taking a family back to an older model, which discards every newer one |

## How a family grows

1. [Build a dataset](/guides/datasets), then [start a family](/guides/fine-tuning) with its first fine-tune. The family is bound to that dataset for good.
2. If the model passes its gate, it joins the family as `support-router@1`. A model that fails its gate joins nothing and answers nothing.
3. A family that is switched on [moves](#how-a-family-moves) to each model that joins.
4. When you have more labelled rows, [add them](/guides/datasets#add-rows) as the dataset's next version, then [continue the family](/guides/fine-tuning#continue-a-family). The next model trains from the latest one, on the new rows with earlier ones mixed in. A family never trains again on rows a finished job has used.

Read a family to see where it stands:

```bash theme={null}
curl --fail-with-body https://console.sqwish.ai/v1/families/support-router \
  -H "Authorization: Bearer $SQWISH_API_KEY"
```

`served` is the model calls to `support-router` get, and `latest` the newest model of the line. They differ until the family moves. `models` lists the line, oldest first: each model's status, switch, keep warm, gate and held-out metrics. A [deleted model](#delete-a-model) shows only where it stood. `jobs` lists the family's fine-tunes with their outcome and charge, and `continue` says whether the family can train again now. `dataset_id` is the dataset it grows on, and `origin` the base model or model it started from. `GET /v1/families` lists every family, without `jobs`.

## Call a family or a model

| You call | Answered when | Otherwise |
| - | - | - |
| `support-router` | The family is switched on: the model it serves answers | `409 family_off`, `409 family_empty` before it serves a model, or `410 family_deleted` once you deleted it |
| `support-router@3` | That model's own switch is on | `409 model_off` |
| A base model such as `sqwish-d1-core` | Its catalogue `status` is `ready` | [Fallback](/guides/models-and-fallback), or the error |

A call names a model through its family or its number, never by its adapter id. Anything after `@` but a number, such as `support-router@latest`, gets `422 invalid_reference`, as does an adapter id: either could name another model by the time a retry arrives. A model that failed its gate has no number, and answers nothing. Switching a model on loads it. One left unused for a while is unloaded to make room, so its next request may answer `model_warming` or a fallback once. A family serves another model only when it [moves](#how-a-family-moves) to it.

## Switch a family or a model on

A family starts switched on, and stays on until you switch it off or nobody uses it for a while ([see below](#switches-nobody-uses-turn-off)). A model answers calls to its number only once you switch it on:

```bash theme={null}
curl --fail-with-body https://console.sqwish.ai/v1/models/support-router@3/switch \
  -H "Authorization: Bearer $SQWISH_API_KEY" -H 'Content-Type: application/json' \
  -d '{"on": true}'
```

Switching on loads and checks the model first, and a model that fails the check stays off with `503 deployment_not_ready`. A family switches on as described in [how a family moves](#how-a-family-moves). A model's switch takes its number only: its id gets `422 invalid_reference`, and switching a deleted model on gets `410 model_deleted`, or `410 model_discarded` when a rollback discarded it. `POST /v1/families/support-router/switch` switches the family. Send `{"on": false}` to switch either off: calls stop at once, and its keep warm stops too. Each model that answers takes one place, however many ways it answers, and your tier sets how many places you have (`answering` in `effective_limits` on `/v1/account`). `places` on `/v1/account` counts the places you use, as the switches count them: `answering`, and `kept_warm` for the models kept warm. A switch that would take one more gets `409 live_limit`, whose details list what would answer once its `switch_off` is applied, the one used longest ago first, each with `used_at`, the latest call, evaluation or switch-on of the switches it answers through: send `switch_off`, a list of families and models such as `["support-router@2"]`, to switch them off in the same step. A limit lowered below what answers switches nothing off. Send `served`, the id of the model the family serves as you saw it, or `adapter`, the model's id, and the switch is refused with `409 served_changed` or `409 model_changed` if that changed. The same codes answer, whether or not you sent `served` or `adapter`, when a newer model joined while the switch was loading a latest model the family didn't serve, or when a model, or a family serving one, that the switch read as on was switched off before the switch took hold: look at it and switch it on again. `GET /v1/families` and `GET /v1/families/support-router` show each family's switch (`switched_on`), the model it serves and its models' own switches (`on_at`, the time the switch went on, or `null` while it is off).

A response to a family or a model reports both the name you requested and, as `version`, the exact model that answered, such as `support-router@3`. During evaluation, set `fallback: "none"` if another model's result would invalidate the comparison.

### Switches nobody uses turn off

A switch nobody uses turns itself off after a number of days, so models nobody calls don't hold your places. Use means a production call with an API key to `/v1/decide`, `/v1/systemone` or `/v1/hooks/claude-code` whose `model` is the family or the model, or an evaluation, Compare included, that names it. A name that appears only in `fallback` doesn't count. Tries in the console playground don't count. The two switches keep separate clocks: calls to `support-router` keep the family on, but don't keep `support-router@3`'s own switch on. Switching on starts a fresh clock, and so does your account becoming active again after a suspension. Keep warm on a family or a model keeps its switch on however long it goes unused, and the clock starts again when keep warm stops. A family that serves no model yet holds no place, so it stays on, and its clock starts when its first model joins.

Families and models show `used_at`, the clock, and `switches_off_at`, when idling switches it off unless it's used. `switches_off_at` is `null` while the switch is off or kept warm, and when idling switches nothing off. A switch that idling turned off says `idle` in `off_reason` and when in `off_at`, and an email tells you. One you turned off says `owner`. Switching on again needs a place, as any switch-on does. A call accepted before the switch-off keeps the switch on. One already on its way when the switch goes off is still answered, but the switch stays off.

## How a family moves

A family that is switched on serves its latest model: the highest-numbered one that isn't deleted or discarded. When a fine-tune passes its gate, its model joins the family as the next number. The server checks every 30 seconds, loads and probes the newest model, and moves the family to it. It loads the new model first on every engine that has the model the family serves, or on every engine of its size when the family is kept warm, so calls after the move find it loaded. An engine that takes longer than two minutes doesn't hold the move up once another has it. The model the family left stays loaded for a few minutes, so rolling back straight after is fast. The gate decided whether the model joined, so a move checks nothing more. A model that fails its gate joins nothing, and its job's `/events` say `gate_failed`.

`GET /v1/families/support-router` shows where the family is: `served` is the model it serves, and `latest` its newest model. It shows the move it waits to make as `move`, such as `{"to": "support-router@5", "waiting_for": "place", "reason": "live_limit"}`, or `null` while it serves its latest model or is switched off. `waiting_for` says what holds the move. It is `place` while your account has no place left for the move, as described below. For a family kept warm, it is `warm_place` while your account keeps as many models warm as its tier allows, and `warm_capacity` while the model's size has no kept-warm place free on our engines. It is `engines` while the model loads, or waits to be tried again after a failed load. `reason` is the code of the refusal that holds the move: `live_limit` for a place, `warm_limit` for a warm place and `warm_capacity` for a full size. It is `null` while the move waits for engines. Once a family has moved by itself, `moved` says when (`at`) and the model it served before (`from`, or `null` for none), until it serves another model, as after a rollback.

We email you once for each model a family moves to by itself, naming it and the model it replaced. We also email you once for a model whose move waits, naming the model that waits and what holds it. For a place, it says how many answering models you use and your limit, and how to free one. Switch off a model, starting with the one used least recently. Switch off the old model's own switch, if no app calls it by its number. Or move to a higher tier. For a warm place, it says how many models you keep warm and your limit. Turn keep warm off on a model, or on the old model's own switch, or on the family, which then moves without it. Or move to a higher tier. For a full size, it offers turning keep warm off on the old model's own switch or on the family, or waiting until a place frees up. A rollback sends no email.

A move takes a place only when the model the family served keeps answering by its own switch, or when the family served nothing before. With no place free, the family keeps serving its current model and moves at a later check, once a place frees. Nothing is loaded while it waits. A model that fails to load, or to answer its probe, leaves the family where it was. After an outage that passes, the next check tries the move again. After any other failure, such as an engine refusing the model, it waits longer each time, up to an hour, because each try can push other models out of an engine. An engine of ours that joins or restarts ends the wait. The family keeps answering meanwhile.

A family that is switched off doesn't move. Switching it on serves its latest model, loaded and probed first. If that model fails to load and the family served another, it switches on with that one, and moves to the latest at a later check. Otherwise it stays off, and the switch answers with the load's error.

Keep warm follows the family to its new model, and so does the hour being billed. Nothing is switched off to make room. A move takes a warm place only when the model the family served stays warm on its own keep warm. With no warm place free on your account, or no kept-warm place free on the model's size, the family waits, as it does for a place, and keeps its keep warm. A rollback onto a full size goes ahead, unless it would leave our engines no slot for models that aren't kept warm.

A family moves only to a newer model. A model it has left keeps answering its number, such as `support-router@2`, while its own switch is on. To stop a family answering, [switch it off](#switch-a-family-or-a-model-on). To take it back to an older model, [roll it back](#roll-a-family-back).

## Roll a family back

```bash theme={null}
curl --fail-with-body https://console.sqwish.ai/v1/families/support-router/rollback \
  -H "Authorization: Bearer $SQWISH_API_KEY" -H 'Content-Type: application/json' \
  -d '{"to": "support-router@2", "discard": ["support-router@3", "support-router@4"]}'
```

A rollback takes a family back to one of its older models and discards every newer one for good. Name `to` by its number, such as `support-router@2`: an id, a name, an alias or another family's model gets `422 invalid_reference`, and a deleted model gets `410 model_deleted`, or `410 model_discarded` when a rollback discarded it. `discard` lists the models newer than `to` that aren't deleted or discarded, exactly as you confirmed them. If your list differs, perhaps because a model joined meanwhile, nothing changes and you get `409 rollback_changed`, whose details list what the rollback would discard and the work it would cancel. A discarded model answers nothing: its own switch and keep warm go off, its hour of keep warm is billed to the minute, and a call to it gets `410 model_discarded`, with no fallback answer. Its number is never given again, and the family lists it with status `discarded` and `discarded_at`. A fine-tune of the family that is still training is cancelled, and its hold released, and so is an evaluation of a discarded model that is still running: rows it scored stay charged.

A family that is switched on loads and probes `to` first, as a move does, then serves it, and keep warm follows. If `to` fails to load, nothing changes. It takes a place only as a move does. A rollback is never refused at your limits: with no place free, or, for a kept-warm family, no warm place, it still discards the newer models, and the family keeps serving its model while its move to `to` waits, as any move does, with its email. A kept-warm family that would leave our engines no slot for models that aren't kept warm gets `503 warm_capacity`, and nothing changes. A family that is switched off serves `to` once it is switched on, as its latest model. The dataset is unchanged: the family's next fine-tune trains from `to`, and still needs new rows. Rolling back to the latest model gets `409 nothing_to_roll_back`, unless every model `discard` names was discarded already: the same rollback sent again after a lost answer returns the family as it is. Send `served`, the id of the model the family serves as you saw it, and the rollback is refused with `409 served_changed` if that changed.

## Delete a family

```bash theme={null}
curl --fail-with-body https://console.sqwish.ai/v1/families/support-router \
  -H "Authorization: Bearer $SQWISH_API_KEY" -H 'Content-Type: application/json' \
  -X DELETE -d '{"dataset_id": "ds_...", "latest": "ft-..."}'
```

A family no model ever joined goes, and its name is free for a new family. A model that failed its gate never joined. A family given the name again starts with no jobs of its own, and the data the deleted family's jobs used counts as new for it.

A family a model joined goes with every model of its line, those a rollback discarded included, and you can't bring them back. Its name is never given again, so a call to `support-router` can never reach another model: a new family with that name gets `409 family_exists`. Calls to the family, and reading, switching, keeping warm, rolling back or continuing it, get `410 family_deleted`, and calls to its models `410 model_deleted`, with no fallback answer. `GET /v1/families` leaves it out. Its models no longer count against your storage allowance.

Switch off the family, if it serves a model, and every model of it whose own switch is on: until then the delete gets `409 family_answers`, whose details list what answers. While one of its fine-tunes is queued or running, the delete gets `409 family_training`: cancel it first. While an evaluation scores one of its models, it gets `409 version_in_use`; delete it once the evaluation ends.

Either way its dataset stays, and so do its jobs in the fine-tuning jobs list, with their charges and `family_deleted: true`. Send `dataset_id`, the dataset the family grew on as you saw it, and the delete is refused with `409 family_changed` if that changed, as it does for a family deleted and named again on another dataset. Send `latest`, the id of the family's latest model you saw (null for none), and it is refused the same way if the family has another since, so a delete never takes a model you didn't see. The answer is `{"id": "support-router", "object": "family", "deleted": true}`. Deleting a family a model joined again gives the same answer and changes nothing. An empty family is gone, so deleting it again gets `404 not_found`.

When you delete a family's dataset, the family keeps its models and they answer as before, but it can't continue: its `continue` state is `dataset_deleted`, and continuing it gets `410 dataset_deleted`. Start a new family from its latest model, such as `support-router@4`. A dataset can't be deleted while a fine-tune, an evaluation or a prompt-tuning job reads it (`409 in_use`).

## Delete a model

```bash theme={null}
curl --fail-with-body https://console.sqwish.ai/v1/models/support-router@2 \
  -H "Authorization: Bearer $SQWISH_API_KEY" -X DELETE
```

Delete a model by its number, as above. Its id, a family's name or anything after `@` but a number gets `422 invalid_reference`: each could point at another model by the time a retry arrives. Add `?adapter=ft-...`, the id you saw for that number, and the call changes nothing if the number names another model, with `409 model_changed`. Deleting a model removes it for good, with its weights, its training specification and its held-out records, and you can't bring it back. A call to it, or an evaluation or fine-tune that names it, gets `410 model_deleted`, with no fallback answer. A decision already under way on it when you delete it finishes and is charged, and a fine-tune that started from it before finishes too. The family's line keeps a place for it, with only its number (`version` and `ref`), its id (`adapter`), the model it trained from (`parent`), status `deleted` and `deleted_at`. It no longer counts against your storage allowance. A family's latest model can't be deleted (`409 latest_model`): [roll the family back](#roll-a-family-back) instead, which discards it. A model its family serves while switched on, or whose own switch is on, can't be deleted (`409 version_in_production`): switch it off if it is on; a model its family serves can be deleted once the family has moved to its latest model, or is switched off. A switched-off family whose model you delete serves its latest model once you switch it on. Nor can a model an evaluation is still scoring (`409 version_in_use`); delete it once the evaluation ends. Deleting again changes nothing, so a retry is safe.

## Keep warm

Switch keep warm with `POST /v1/families/support-router/keep-warm` and `{"enabled": true}`. It answers with the family. `keep_warm` describes whether the model the family serves is pinned to stay loaded where residency is managed, and `keep_warm_window` the hour of it being billed. To switch keep warm only while the family serves what you last read, send `served`, the `adapter` of the model it serves, or `null` for none. If it has moved since, the call changes nothing and answers `409 served_changed`. The console sends it, so a change in another tab, or a sign-in to another account with a model of the same name, is never applied by mistake. `state` can be `loaded`, `loading`, `asleep` or null when not tracked. See [models and fallback](/guides/models-and-fallback#readiness-and-cold-versions) for waking a cold model.

A model can be kept warm on its own, by its number: `POST /v1/models/support-router@2/keep-warm` with `{"enabled": true}`. It answers with the model. Its own switch must be on, or the call gets `409 model_off`, and switching the model off stops its keep warm. An app that calls `support-router@2` can keep that model loaded whichever model the family serves. Send `adapter`, the model's id as you saw it, and the call changes nothing if the number names another model, with `409 model_changed`. The model shows `keep_warm`, whether its own keep warm is on, `keep_warm_window`, the hour being billed for it, and `keep_warm_stopped_at`, when credit switched its keep warm off. A model kept warm through its family and on its own is one warm model, billed once: it stays warm until neither asks for it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.