Pricing
The price list: what every model, provider, GPU tier, tool and hosting plan costs.
Also for this capability: API · CLI · MCP · SDKs
The price list: what every model, provider, GPU tier, tool and hosting plan costs.
| Base URL | https://api.hanzo.ai |
| Operations | 28 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Specification
HIP-1222 · Pricing — The Price List and Who May See It — Draft · read the specification →
/v1/pricing is the price list — what every model, provider, GPU tier, tool and
hosting plan costs — and the enablement registry that decides which of those
entries a caller may even see. It is hanzoai/cloud apps/pricing
(apps/pricing/pricing.go:1-6). This HIP absorbs HIP-1003 (Enablement):
enablement is served by pricing over pricing's one overlay store, so a
standalone enablement capability would be two apps on one store — the split
HIP-0139 §7.2 refuses — and it is specified here as an address instead.
Motivation
Which models an org may see is a question every plane asks; answered separately
it becomes registries that disagree, visible to customers as a feature present
in one surface and absent from another. One registry, one resolver
(apps/pricing/enablement.go:3-7). The registry's own address and the two
admin roots sit outside the app's prefix today (manifest/apps.go:126); they
come home.
Specification
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.
§1 Addresses
/v1/pricing/*— the catalog: the gated model plane and the fifteen fixed sections (plan, infrastructure, tool, GPU, policy) that carry no model identity and so pass ungated (apps/pricing/sections.go:3-10). Keeps./v1/pricing/enablement{,/optin,/optout}— the registry and self-service opt-in (from/v1/enablement)./v1/admin/pricing/{catalog,enablement}— the SuperAdmin overlay editor and enablement mutations (from/v1/admin/{catalog,enablement}). HIP-0139 §3.2 fixes the depth: the capability segment must readpricing—catalognames a different app entirely.
Where the router still serves the old spellings, the pairs are the pricing
lines in cloud's openapi/misfiled.txt. Every operation is typed except one,
held raw by a measured document fact — a greedy-wildcard model id the document
and the router cannot key the same way — on the closed list
apps/pricing/typed_wire_test.go:44-58 re-verifies against the live router.
§2 The store it owns
The enablement overlay: its own SQLite/Base store laying per-entry
{enabled, betaOrgs, overrides} over the static bundle
(apps/pricing/catalog.go:3-15). The bundle stays authoritative for catalog
content and shape; Go only hides entries and merges an admin override patch, so
an empty overlay leaves the catalog exactly as shipped. The overlay is a
security control, so a persistent data dir is a boot requirement — a
non-persistent overlay would re-expose admin-hidden models on restart, a
fail-open the mount refuses (apps/pricing/pricing.go:117-125).
§3 Three states, and off is absolute
An entry resolves to exactly one of ga, beta, off
(apps/pricing/catalog.go:94-103): ga visible to everyone, beta only to
orgs on its grant list, off to no one — a grant list MUST NOT re-open it
(apps/pricing/catalog.go:113-123). An untouched entry is absent from the
registry and generally available; absence is not a denial, and the candidate
list comes from the live catalog, never from the registry.
§4 Two scopes, one of them global
Global state — setting off/beta/ga, replacing a grant list — is admitted
only by the SuperAdmin claim the identity boundary mints
(apps/pricing/ops.go:120-132). Self-service opt-in is org-scoped and
beta-only: a caller may add or remove its own org from a beta entry's list and
nothing else — a ga entry needs no opt-in, an off entry is a kill switch
(apps/pricing/catalog.go:566-570, :601-614). The self-service path can
never bypass off.
§5 The subject is the validated tenant
Opt-in and opt-out key on the org the identity boundary validated (HIP-0026),
never a raw header (apps/pricing/enablement.go:243-249); a caller with no
validated principal is refused on write and shown the public view on read
(apps/pricing/enablement.go:178-182). Enforced, not asserted:
apps/pricing/enablement_attack_test.go drives an off-gateway request with a
forged tenant header at both paths and fails if the grant lands. The item
namespace is closed to model, provider, feature
(apps/pricing/enablement.go:36), and the catalog gate, the admin surface and
the caller's own view MUST all resolve through the one resolver.
§6 The prices are the module's
Handlers are the @hanzo/pricing bundle's pure transforms, run in-process via
goja; the markup math runs in the same bundle, and the only Go part is the live
network fetch the JS engine cannot perform, fed raw into applyMarkup
(apps/pricing/pricing.go:12-22). No pricing data or markup math is
reimplemented in Go. Eight sections share the @hanzo/plans catalog with the
plans capability and answer the same data (apps/pricing/pricing.go:8-10).
§7 Price, events, observability
It is free, in those words: Price: cloud.Free (plugin/pricing/main.go:22).
Reads are open to any authenticated caller — it is the public price list. It
publishes no events on the platform bus, so a customer's webhooks (HIP-1310)
receive nothing from it, and it emits nothing to observability beyond the
request span every route gets.
§8 Stage and upstream
The stage is ga — the manifest row declares none, and absent is ga
(HIP-0139 §8).
It derives from hanzoai/pricing (pinned v1.4.10 in cloud's go.mod:29),
dual-licensed MIT / Apache-2.0 — the bundle and its markup logic survive whole
as the goja payload — executed by dop251/goja (MIT, go.mod:13), the ES
engine it runs in. The Express transport upstream ships is dropped; native zip
routes replace it.
Rationale
A boolean flag plus an allow-list was the obvious enablement shape and has a
hole: nothing states which wins, so "off but granted" is a race between two
readers. Three ordered states make off unambiguous. Letting an org admin flip
global state would make rollout self-service — until an org turns on a model
the platform has withdrawn; the split in §4 is the smallest division that gives
each party what it needs. And enablement lives in this HIP rather than its own
because the store decides: one overlay, one capability.
Security Considerations
An enablement grant is a cross-tenant write if the subject can be forged: an off-gateway caller who could name a tenant could opt a stranger into a beta or deny them one they were granted — §5 closes both directions, and the attack tests exist because the read and write paths once resolved their tenant differently. The SuperAdmin claim is a header only the identity boundary can mint; a deployment that lets a client set it hands over the global kill switch for every model and provider. The third exposure is the overlay itself: run without persistence it silently re-exposes what an admin hid, which is why §2 makes that a refusal to boot.
Four surfaces
| Surface | Reaches this capability as | Coverage |
|---|---|---|
| REST | pricing at its own prefix | 28 operations |
| CLI | hanzo pricing … | 25 of 28 — the CLI pins the document on its own clock |
| SDK | PricingApi in every published client | 25 of 28 — the clients are generated at their own release |
| MCP | tool pricing on https://api.hanzo.ai/v1/mcp | 33 operations, 14 under the document's own id — ask describe for the rest |
Quickstart
export HANZO_API_KEY=sk-... # console.hanzo.ai → API keysThen the first call — a read that needs nothing but the key. GET /v1/pricing, operation get_pricing:
hanzo pricing getimport { Configuration, PricingApi } from 'hanzoai';
const api = new PricingApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getPricing();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import PricingApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = PricingApi(client).get_pricing()cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.PricingAPI.GetPricing(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, pricing_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = pricing_api::get_pricing(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.PricingApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new PricingApi(client).getPricing();curl https://api.hanzo.ai/v1/pricing \
-H "Authorization: Bearer $HANZO_API_KEY"Tool pricing, op get_pricing — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "pricing",
"arguments": {
"op": "get_pricing",
"input": {}
}
}
}'Answers 200 with object — ok.
Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/pricing/base | Returns the Hanzo Base plans — the managed-instance tiers, each with its monthly and annual price, storage and request allowances and feature list. |
GET /v1/pricing/blockchain | Returns the blockchain access plans — the RPC and node tiers, each with its monthly price, compute-unit allowance and feature list. |
GET /v1/pricing/cloud/plans | Returns just the cloud instance plans — each with its vCPU, memory, disk, CPU type, VM allowance, feature list and monthly and hourly price. |
GET /v1/pricing/cloud/regions | Returns the regions a cloud instance can be placed in, each with its id, display name and physical location. |
GET /v1/pricing/cloud/storage | Returns the block-storage prices of the cloud section: the per-GB monthly rate and the volume size bounds a caller may ask for. |
GET /v1/pricing/cloud | Returns the public cloud section of the catalog in one document: its instance plans, its regions and its block-storage prices. |
GET /v1/pricing/compute/presets | Returns just the named compute sizes — the short, human-labelled list ("Starter", "Pro") a size picker renders, each carrying its provider slug,… |
GET /v1/pricing/compute | Returns the compute section of the catalog: the cloud provider and region the prices are quoted for, the monthly markup applied to them, the full… |
GET /v1/pricing/datastore | Returns the Hanzo Datastore rate card: the tier list, the per-GB storage and egress usage rates, the annual discount and the trial. |
POST /v1/pricing/enablement/optin | Opts the caller's OWN org into a beta item. |
POST /v1/pricing/enablement/optout | Removes the caller's OWN org from a beta item's grant list, the reverse of OptIntoBeta and idempotent. |
GET /v1/pricing/enablement | Returns what the caller's org can actually use: every managed item with its global state, whether it is effective here, whether this org is already… |
GET /v1/pricing/featured | Returns the models the catalog highlights, filtered to what the caller's org may see. |
GET /v1/pricing/free | Returns the models that cost nothing to call, filtered to what the caller's org may see. |
GET /v1/pricing/gpu | ListGPUTiers returns the rentable GPU configurations, each with its accelerator count and model, VRAM, vCPU, host memory and hourly price. |
GET /v1/pricing/health | Health reports that the pricing subsystem is mounted and serving. |
GET /v1/pricing/iam | ListIAMPlans returns the identity plans — the Hanzo IAM tiers, each with its monthly and annual price, monthly-active-user allowance and feature list. |
GET /v1/pricing/model/{name} | Returns one model's catalog entry — its pricing, context window and capabilities as the pricing source records them. |
GET /v1/pricing/models | Returns the whole model catalog — every model the gateway serves, Zen and third-party alike — filtered to what the caller's org may see. |
GET /v1/pricing/paas | ListPaaSPlans returns the application-hosting plans — the deploy-and-host tiers, each with its monthly and annual price, app and memory allowances… |
GET /v1/pricing/policy | Returns the pricing policy document: the revenue-sharing terms (the idle-resale share and the open-source share, each with its percentage and who is… |
GET /v1/pricing/providers | Returns the model providers the catalog knows, each with its info object, filtered to what the caller's org may see. |
GET /v1/pricing/services | Returns the managed-service rate cards — Search, Crawl, Vector, Console and Managed Services — each with its own tiers, and some with usage rates or… |
GET /v1/pricing/subscriptions | Returns the API subscription plans — the account-level tiers a customer subscribes to, each with its monthly and annual price, included credit, rate… |
GET /v1/pricing/summary | Returns the catalog's headline statistics — model counts by family and the provider directory. |
POST /v1/pricing/sync | Refreshes the third-party section of the catalog from its upstream listings and returns the time the refreshed catalog was stamped with. |
GET /v1/pricing/tools | Returns the per-use tool prices — web search, code interpreter, file storage, image generation, speech-to-text and text-to-speech — each with the… |
GET /v1/pricing | Returns the whole pricing catalog in one document: Zen and third-party models, providers, model families, the free-model list, plan and… |
How is this guide?