SDKs
One generated client per language for the whole /v1 surface, plus the hand-written AI and per-service libraries for TypeScript. What each one is called on its registry, and the same first call in each.
Every Hanzo capability answers on one host under /v1, so a client for Hanzo is
a client for all of it. There is one such client per language, and it is
generated from the API's own OpenAPI document rather than written by hand —
which is why the class and the method you call follow from the operation instead
of from someone's taste, and why a capability that shipped this morning is in
the client without anyone adding it.
Beside those sit three hand-written TypeScript libraries that exist because they are not projections of the document: an AI-shaped client, a per-service one, and the IAM one. They are listed below with what each is for.
The generated clients
The coordinate is the stable thing — the version moves every time cloud
releases, so it is not repeated here. Every one of these is cut from the same
document at a ref its own .spec-lock names.
| Language | Coordinate | Install |
|---|---|---|
| TypeScript | hanzoai on npm | npm i hanzoai |
| Python | hanzoai on PyPI | pip install "hanzoai>=8" |
| Go | github.com/hanzoai/go-sdk/v8 | go get github.com/hanzoai/go-sdk/v8 |
| Rust | hanzo-client on crates.io | cargo add hanzo-client |
| Swift | hanzo-swift/sdk, product Hanzo | SwiftPM, from the git URL |
| Kotlin | ai.hanzo:hanzo-kotlin-cloud | Gradle, built from source |
| Java | ai.hanzo:hanzo-java-cloud on Maven Central | Gradle or Maven, from mavenCentral() |
| C++ | hanzo-cpp/sdk | CMake, from a tag |
Swift, Kotlin and C++ are tagged and buildable but not on a package manager that resolves them by name alone — Swift and C++ because neither ecosystem has a central registry, Kotlin because its Maven Central publication has not landed. Each page says exactly what the coordinate looks like in the meantime.
The same first call, everywhere
GET /v1/models is the catalogue of models the gateway currently serves. It is
a read, and it is one of the few routes that does not authenticate — the header
below is read only to annotate models your account has standing for, so the call
answers before you have a key. That makes it the honest first thing to run.
curl https://api.hanzo.ai/v1/models \
-H "Authorization: Bearer $HANZO_API_KEY"hanzo models listimport { AiApi, Configuration } from 'hanzoai'
const ai = new AiApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }))
const { data } = await ai.getModels()import os
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import AiApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
models = AiApi(client).get_models()cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
models, _, err := client.ModelsAPI.AiListModels(context.Background()).Execute()use hanzo_client::apis::{ai_api, configuration::Configuration};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let models = ai_api::get_models(&cfg).await?;import Hanzo
let hanzo = HanzoAPIConfiguration(
basePath: "https://api.hanzo.ai",
customHeaders: ["Authorization": "Bearer \(key)"]
)
try await AiAPI.getModels(apiConfiguration: hanzo)import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.AiApi;
import ai.hanzo.cloud.model.AiModelList;
ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));
AiModelList models = new AiApi(client).getModels();A client is a projection of the document at its own lock, and the locks move
independently — so two clients can be cut from different releases of the same
document and both be current. Go says AiListModels; the rest still say
getModels. The reference prints the name per operation and
says on the operation when a published client has not caught up, which is why it
is the place to check rather than a page like this one.
The hand-written TypeScript libraries
Three packages that are not generated, because what they offer is not in the document: a shape, a grouping, and a browser flow.
| Package | What it is |
|---|---|
@hanzo/ai | The AI client — chat.completions, messages, models, agents, sandboxes, tools, sessions. Takes secretKey on a server or publishableKey in a browser. |
@hanzo/sdk | One typed client per service — IAM, KMS, Commerce, Billing, MPC, PaaS, Team — with subpath imports so a bundle carries only what it uses. |
@hanzo/iam | Identity — OIDC, JWT validation, browser PKCE, org switching, and React bindings. |
@hanzo/ai is the one to reach for when the job is inference or agents:
import { Hanzo } from '@hanzo/ai'
const hanzo = new Hanzo({ secretKey: process.env.HANZO_API_KEY })
const answer = await hanzo.chat.completions.create({
model: 'zen6',
messages: [{ role: 'user', content: 'Explain quantum computing' }],
})The key field is named for the key: an sk- goes in secretKey on a server, a
pk- goes in publishableKey in a browser, and the two are not
interchangeable. Authentication is the whole rule.
Any OpenAI-shaped client also works
The chat, embeddings and messages routes are OpenAI- and Anthropic-compatible on
purpose, so a language with no Hanzo client yet is not blocked. Point the client
you already have at https://api.hanzo.ai/v1 with your Hanzo key and the
request body does not change — this is the same edit the migration
guides describe. The native clients add the rest of /v1
on top of that.
Where to go next
- Quickstart — install, log in, and run the call above.
- Authentication — the two key types and which one may ship in a browser.
- Reference — every operation, each shown as CLI, SDK, HTTP and MCP.
- CLI — the same capabilities as command groups.