Create artifacts — POST /v1/train/artifacts
Records rows the org is about to upload, named by the SHA-256 of their bytes, and answers the same grant an executor's artifact gets: a presigned PUT S3 accepts only with that checksum and length, encrypted under the org's key — a PUT per 64 MiB part over 64 MiB — or stored: true when the org already holds those bytes.
POST /v1/train/artifacts
| Address | https://api.hanzo.ai/v1/train/artifacts |
| Method | POST |
| Operation | post_train_artifacts |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Records rows the org is about to upload, named by the
SHA-256 of their bytes, and answers the same grant an executor's artifact
gets: a presigned PUT S3 accepts only with that checksum and length, encrypted
under the org's key — a PUT per 64 MiB part over 64 MiB — or stored: true when
the org already holds those bytes. A job names them as dataset.uri
artifact:<sha256>, and its create reads the upload back before it is
accepted. Storage is billed by the GB-month while the org keeps them, so an
upload is refused 402/503 when the uploader's wallet cannot pay a month of
keeping these bytes with what it already keeps in the org and what the org has
pending.
Request
4 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
kind | body | string | — | Kind is dataset: JSON Lines rows a job reads as artifact:<sha256>. |
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. |
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.postTrainArtifacts({ kind: "<kind>", name: "<name>" });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_artifacts(kind="<kind>", name="<name>")cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.TrainAPI.PostTrainArtifacts(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_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).postTrainArtifacts();curl -X POST https://api.hanzo.ai/v1/train/artifacts \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "<kind>",
"name": "<name>"
}'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.