Create artifacts — POST /v1/train/jobs/{id}/artifacts
Records an output its executor is about to store, named by the SHA-256 of its bytes, and answers a presigned PUT for exactly that object under the org's prefix — S3 accepts it only with the checksum and encrypts it under the org's key — or, over 64 MiB, a presigned PUT per 64 MiB part, or stored: true when the org already holds those bytes.
POST /v1/train/jobs/{id}/artifacts
| Address | https://api.hanzo.ai/v1/train/jobs/{id}/artifacts |
| Method | POST |
| Operation | post_train_jobs_by_id_artifacts |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Records an output its executor is about to store, named by the SHA-256 of its bytes, and answers a presigned PUT for exactly that object under the org's prefix — S3 accepts it only with the checksum and encrypts it under the org's key — or, over 64 MiB, a presigned PUT per 64 MiB part, or stored: true when the org already holds those bytes. The executor then reports an artifact event naming it, and the object is read back, those bytes and sealed under the org's key, before it counts as stored.
Request
10 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID names the job, from the path. |
id | body | string | — | ID names the job, from the path. |
kind | body | string | — | Kind is checkpoint, lora, capability, basis or merged. |
lease | body | string | — | Lease is the task's lease. |
meta | body | object | — | Meta describes it: its base and revision, its modules, a basis's address. |
meta.* | body | any | — | |
name | body | string | — | Name labels it. |
sha256 | body | string | — | SHA256 is the hex digest of the bytes. |
size | body | integer (int64) | — | Size is the byte count. |
task | body | string | — | Task is the reporting task. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | train.registerOut | ok |
default | problem-details | refused |
200 body — 15 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
sha256 | body | string | — | SHA256 names the artifact. |
stored | body | boolean | — | Stored says the org already holds these bytes: nothing to upload. |
upload | body | train.upload | — | |
upload.expires | body | integer (int64) | — | Expires is when the grant stops being accepted, unix seconds. |
upload.headers | body | object | — | Headers must be sent verbatim with the single PUT; the signature covers them. |
upload.headers.* | body | string | — | |
upload.method | body | string | — | Method is PUT. |
upload.parts | body | train.part[] | — | Parts are the object's consecutive byte ranges, each PUT to its own address. |
upload.parts[].headers | body | object | — | Headers must be sent verbatim; the signature covers them. |
upload.parts[].headers.* | body | string | — | |
upload.parts[].number | body | integer (int64) | — | Number orders the part from 1. |
upload.parts[].offset | body | integer (int64) | — | Offset is the part's first byte in the object. |
upload.parts[].size | body | integer (int64) | — | Size is the part's byte count. |
upload.parts[].url | body | string | — | URL is the presigned address to PUT the range to. |
upload.url | body | string | — | URL is the presigned address of a single PUT; empty when Parts is given. |
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.postTrainJobsByIdArtifacts({ id: 'id', id: "<id>", kind: "<kind>" });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_jobs_by_id_artifacts(id='id', id="<id>", kind="<kind>")cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.TrainAPI.PostTrainJobsByIdArtifacts(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_jobs_by_id_artifacts(&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).postTrainJobsByIdArtifacts();curl -X POST https://api.hanzo.ai/v1/train/jobs/<id>/artifacts \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "<id>",
"kind": "<kind>"
}'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.