Guide
Package guide is a step-by-step checklist that gets your business running on AI.
Package guide is a step-by-step checklist that gets your business running on AI.
| Base URL | https://api.hanzo.ai |
| Operations | 19 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Specification
HIP-1130 · Guide — The Launch Journey — Draft · read the specification →
/v1/guide is the Business AI Guide: an interactive launch checklist every org
completes on-site — a checklist engine over a machine-readable curriculum, a
Business AI agent that can execute a step through the caller's own tool plane,
and a versioned brand blueprint the whole journey is projected from. It is
implemented in hanzoai/cloud at apps/guide (HIP-0106).
Motivation
Onboarding advice that lives in prose goes stale and cannot be acted on. A
journey that is data — steps with dependencies, done-criteria mapped to real
signals, tools bound to steps — can be auto-marked when the org has demonstrably
done the work, and executed by an agent when the org asks. The three concerns
are kept orthogonal on purpose: the engine is pure functions over plain data,
the agent acts only through the caller's own authority, and the blueprint is
content a SuperAdmin authors live (apps/guide/curriculum.go:6-31).
Specification
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.
§1 Two stores, two tiers
Per-org progress and the org's own curriculum override live in that org's own
database, opened through cloud.OrgStore — one file per org, resolved through
the one namespace door (apps/guide/guide.go:47-63). The shared brand blueprint
is a second, deployment-wide store (apps/guide/blueprint_store.go:45), seeded
idempotently from embedded fixtures — the base journey plus one YAML file per
brand (apps/guide/brands.go) — after which the database is authoritative and
the fixture is only the fail-safe fallback. A redeploy MUST NOT clobber a live
edit; seeding is if-absent (apps/guide/guide.go:78-88).
§2 The address
Nineteen operations under /v1/guide. All are typed except six, each declared
with prose beside its route (apps/guide/guide.go:262-360) because its body has
no declarable shape: the curriculum and blueprint writes accept YAML or JSON
as a raw body (the canonical parsed form is what is stored); the blueprint PATCH
is a shallow merge whose keys are the patched item's, not the route's; and
steps/{id}/do answers either JSON or a Server-Sent-Event stream of the agent's
actions. Every declared description renders only while the router serves the
route, so the prose can never invent a path.
A step transition is dependency-gated: a blocked start or done is 409 carrying
blockedBy naming the exact steps in the way. A write that does not parse or
does not validate (unique ids, acyclic dependencies) is 422 and the journey in
force is untouched.
§3 Tenancy, and the gate that differs by tier
The tenant is principal.Org — the org minted from the validated bearer
(HIP-0026), never a header (apps/guide/guide.go:382-385). The per-org
curriculum override is any validated member's surface. The brand blueprint is
platform content: authoring it requires SuperAdmin (apps/guide/admin.go:39),
a per-org admin is 403, and every write is audited and versioned with the prior
versions kept as a recovery trail.
§4 Money
Guide is free (cloud.Free, plugin/guide/main.go). The one executing path —
"do it for me" — runs the step's tool through the calling principal's own MCP
plane (automations.InvokeTool), so the work is metered and audited by the
plane that owns it, against the caller's ledger (apps/guide/agent.go:61).
Guide itself debits nothing and MUST NOT acquire an authority the caller does
not hold.
§5 Events and observability
It publishes nothing on the bus. It emits nothing beyond the request span every route gets; the audit trail for blueprint authoring is the shared audit plane, not a telemetry stream.
§6 Stage
beta: a vertical application — a guided launch product over the core planes,
not one of them.
§7 Upstream
It derives from none. The curriculum fixtures are embedded YAML authored here;
the growth signals are injected read seams bound at the composition root, so
guide imports none of the subsystems it observes (apps/guide/signals.go).
Rationale
The alternative to a data blueprint is a hard-coded journey, which makes every white-label brand and every content edit a code change. The alternative to executing through the caller's own tool plane is a service identity that acts for orgs — which is an escalation surface, and the reason the agent runs AS the caller instead.
Security Considerations
The two tiers are the exposure. If the per-org gate could reach the shared blueprint, one tenant would edit every org's journey — including which MCP tools the Business AI runs for a step, which is a lever over agents in every org; the SuperAdmin gate and the audit trail on that tier exist for exactly this. On the executing path, the wrong implementation runs tools under an authority wider than the caller's; here the invocation is per-principal, so a step can never do what its asker could not.
Four surfaces
| Surface | Reaches this capability as | Coverage |
|---|---|---|
| REST | guide at its own prefix | 19 operations |
| CLI | hanzo guide … | 19 of 19 |
| SDK | GuideApi in every published client | 19 methods |
| MCP | tool guide on https://api.hanzo.ai/v1/mcp | 19 operations, 6 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/guide, operation get_guide:
hanzo guide getimport { Configuration, GuideApi } from 'hanzoai';
const api = new GuideApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getGuide();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import GuideApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = GuideApi(client).get_guide()cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.GuideAPI.GetGuide(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, guide_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = guide_api::get_guide(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.GuideApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new GuideApi(client).getGuide();curl https://api.hanzo.ai/v1/guide \
-H "Authorization: Bearer $HANZO_API_KEY"Tool guide, op get_guide — 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": "guide",
"arguments": {
"op": "get_guide",
"input": {}
}
}
}'Answers 200 with object — ok.
Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/guide/actions | Returns the caller org's Business AI action ledger, most recent first: every "do it for me" tool call, the arguments it ran with, its result and… |
GET /v1/guide/analytics | Analytics returns the caller org's funnel from the analytics lens plus the GTM recommendations derived from it. |
PATCH /v1/guide/blueprint/{collection}/{id} | Edit — or retire — one item of the brand blueprint |
GET /v1/guide/blueprint/versions | Returns the brand blueprint's version history — every stored version's number and edit time, newest first — which is the point-in-time-recovery and… |
GET /v1/guide/blueprint | Returns the FULL authored brand blueprint — every principle, section, step, strategy and template WITH its enabled flag made explicit, including the… |
PUT /v1/guide/blueprint | Publish a new version of the brand blueprint |
POST /v1/guide/chat | Chat answers a founder's question about their launch journey as the Business AI coach: it grounds the reply in the org's REAL progress, its ranked… |
GET /v1/guide/curriculum | Returns the journey the caller's org is actually running, and whether it comes from the org's OWN override (custom) or from the platform default —… |
PUT /v1/guide/curriculum | Replace your org's journey with a curriculum you author |
DELETE /v1/guide/curriculum | Clears the caller org's curriculum override and returns the journey it falls back to — the brand blueprint, else the embedded fixture. |
GET /v1/guide/profile | Profile returns the caller org's OBSERVED growth profile — the signal set, the classified growth stage, and the org's own key metrics. |
POST /v1/guide/steps/{id}/do | Have the Business AI actually do the step for you |
POST /v1/guide/steps/{id}/done | Mark a step of your org's journey finished |
POST /v1/guide/steps/{id}/reset | Returns one step of the caller org's journey to todo — clearing a manual mark or a skip — and returns the refreshed journey. |
POST /v1/guide/steps/{id}/skip | Marks one step of the caller org's journey skipped and returns the refreshed journey. |
POST /v1/guide/steps/{id}/start | Mark a step of your org's journey started |
GET /v1/guide/strategies | Strategies returns the ENABLED tactics corpus for the caller's org: the tactics library narrowed by the explicit category/workload filters AND by the… |
GET /v1/guide/suggest | Suggest returns the caller org's next-best quests: the available, non-terminal steps of its journey ranked by how much downstream work each unblocks,… |
GET /v1/guide | Overview returns the caller org's launch journey: the active curriculum's version and title, every step with its state, whether it is available, what… |
How is this guide?