Create clients
Loads base_model on the engine with a LoRA adapter and answers the client, loading; poll it until ready.
POST /v1/train/clients
| Address | https://api.hanzo.ai/v1/train/clients |
| Method | POST |
| Operation | post_train_clients |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Loads base_model on the engine with a LoRA adapter and answers the client, loading; poll it until ready. The wire is the engine's own create → forward_backward → optim_step → sample → save_weights loop, so a loop written against the engine runs here with only the path changed. The capability fields are validated as a job's are: adaptation is lora, protect is refused, and kai is not a client base. A client holds a model in the memory every org's inference shares, so only a SuperAdmin creates one until the engine isolates orgs. An org holds at most TRAIN_CLIENTS live clients and the engine at most TRAIN_ENGINE_CLIENTS across every org; past that the answer is 503 engine_full.
Request
22 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
adaptation | body | train.Adaptation | — | |
adaptation.alpha | body | number (double) | — | Alpha is an adapter's scale. |
adaptation.basis | body | string | — | Basis is a basis artifact, by sha256 or basis://<base>/<name>. |
adaptation.chose | body | train.Chose | — | |
adaptation.chose.mode | body | string | — | Mode is the mode the job runs. |
adaptation.chose.why | body | string | — | Why says what decided it. |
adaptation.mode | body | string | — | Mode is full, readout (the head alone, over the frozen base), lora, qlora, basis or auto. |
adaptation.rank | body | integer (int64) | — | Rank is an adapter's rank, or how many of a basis's directions are used. |
adaptation.residual_rank | body | integer (int64) | — | ResidualRank is the rank of an orthonormal residual learned beside a basis's coefficients; 0 trains the coefficients alone. |
adaptation.sources | body | string[] | — | Sources are lora artifacts (sha256) a basis is built from, in place of Basis. |
adaptation.targets | body | string[] | — | Targets are the modules an adapter or a basis attaches to. |
base_model | body | string | — | BaseModel is a model the engine loads: a Hugging Face repo id or a local path. |
lora_config | body | any | — | LoraConfig is the adapter's shape, as the engine's wire takes it. |
protect | body | train.Protect | — | |
protect.budget | body | train.Budget | — | |
protect.budget.accuracy | body | number (double) | — | Accuracy is the largest accuracy drop allowed. |
protect.budget.ece | body | number (double) | — | ECE is the largest calibration-error rise allowed. |
protect.capabilities | body | string[] | — | Capabilities are capability artifacts, by sha256. |
protect.distillation | body | boolean | — | Distillation adds KL to the base's answers on a preservation set drawn from the suites. |
protect.projection | body | train.Projection | — | |
protect.projection.strength | body | number (double) | — | Strength is λ in [0, 1]; absent is 1, the whole of P g removed. |
protect.suites | body | string[] | — | Suites are capabilities the base already has, by suite. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | ok | |
default | problem-details | refused |
200 body — 1 field.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
(body) | body | any | yes |
Failure carries the platform error shape — see Errors.
Examples
hanzo has no subcommand for this operation — the CLI serves only what cloud's live route table confirms. Use HTTP or an SDK.
import { Configuration, TrainApi } from 'hanzoai';
const api = new TrainApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postTrainClients({ adaptation: {"alpha":0,"basis":"<basis>","chose":{"mode":"<mode>","why":"<why>"},"mode":"<mode>"}, base_model: "<base_model>" });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import TrainApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = TrainApi(client).post_train_clients(adaptation={"alpha":0,"basis":"<basis>","chose":{"mode":"<mode>","why":"<why>"},"mode":"<mode>"}, base_model="<base_model>")cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.TrainAPI.PostTrainClients(context.Background()).Execute()
if err != nil {
return err
}use hanzo_client::apis::{configuration::Configuration, train_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = train_api::post_train_clients(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.TrainApi;
ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));
var result = new TrainApi(client).postTrainClients();curl -X POST https://api.hanzo.ai/v1/train/clients \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"adaptation": {
"alpha": 0,
"basis": "<basis>",
"chose": {
"mode": "<mode>",
"why": "<why>"
},
"mode": "<mode>"
},
"base_model": "<base_model>"
}'MCP declares no tool for train — tools/list on https://api.hanzo.ai/v1/mcp names the products it does reach. Use HTTP or an SDK.