Form
Mounts forms (github.com/hanzoai/form) at /v1/form, the way apps/iam mounts hanzoai/iam: the module owns every route and every rule of a form, and this package hands it what only cloud knows.
Also for this capability: API · CLI · MCP · SDKs
Mounts forms (github.com/hanzoai/form) at /v1/form, the way apps/iam mounts hanzoai/iam: the module owns every route and every rule of a form, and this package hands it what only cloud knows.
| Base URL | https://api.hanzo.ai |
| Operations | 27 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Specification
Specification pending — no HIP in hanzoai/hips declares capability: form yet. What this capability serves is below, from the API document; what it is — the store it owns, how it meters, what it publishes — is written as a HIP under HIP-0139.
Four surfaces
| Surface | Reaches this capability as | Coverage |
|---|---|---|
| REST | form at its own prefix | 27 operations |
| CLI | hanzo form … | 27 of 27 |
| SDK | — | no published client declares one yet — regenerating the clients is what adds them |
| MCP | tool form on https://api.hanzo.ai/v1/mcp | 27 operations |
Quickstart
export HANZO_API_KEY=sk-... # console.hanzo.ai → API keysThen the first call — a read that needs nothing but the key. GET /v1/form/forms, operation list_forms:
hanzo form forms listimport { Configuration, FormApi } from 'hanzoai';
const api = new FormApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.listForms();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import FormApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = FormApi(client).list_forms()cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.FormAPI.ListForms(context.Background()).Execute()
if err != nil {
return err
}use hanzo_client::apis::{configuration::Configuration, form_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = form_api::list_forms(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.FormApi;
ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));
var result = new FormApi(client).listForms();The method above is the one at the current release of the document. [email protected] (npm) and [email protected] (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →
curl https://api.hanzo.ai/v1/form/forms \
-H "Authorization: Bearer $HANZO_API_KEY"Tool form, op list_forms — 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": "form",
"arguments": {
"op": "list_forms",
"input": {}
}
}
}'Answers 200 with object — ok.
Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/form/forms/{id}/export | Exports a form's responses as JSON or CSV, a page of up to 5000 at a time under the same filter a listing takes; next is the page to ask for after it, 0 at the end. |
POST /v1/form/forms/{id}/import | Brings responses made elsewhere into a form, keeping when each was made, a batch of at most 500 at a time. |
POST /v1/form/forms/{id}/responses/{response}/file | Files a completed response on the CRM's timeline now, and answers the response with whether it is filed and, when it is not, why. |
GET /v1/form/forms/{id}/responses/{response} | Reads one response of a form. |
DELETE /v1/form/forms/{id}/responses/{response} | Deletes one response of a form, and its webhook deliveries. |
GET /v1/form/forms/{id}/responses | Lists a form's responses, newest first, a page at a time: since and until bound when they were made, completed keeps the finished or the open ones, query keeps the ones whose answers hold it, and included_response_ids and excluded_response_ids keep or drop named ones. |
GET /v1/form/forms/{id}/summary | Sums up a form's responses: how many were begun and completed, and for each field how many answered it, the distribution of what was said (choices, points, yes and no), the mean, least and most of a number, and how many open responses stopped in front of it. |
POST /v1/form/forms/{id}/webhooks/{webhook}/deliveries/{delivery}/retry | Posts a delivery's response to its webhook again, now, and answers how it went. |
GET /v1/form/forms/{id}/webhooks/{webhook}/deliveries | Lists a webhook's deliveries, newest first: each response posted, how many attempts it took, the last status the address answered and why it failed. |
GET /v1/form/forms/{id}/webhooks/{webhook} | Reads one webhook of a form. |
PUT /v1/form/forms/{id}/webhooks/{webhook} | Replaces a webhook's tag, address and whether it is enabled. |
DELETE /v1/form/forms/{id}/webhooks/{webhook} | Deletes a webhook, its deliveries and its secret. |
GET /v1/form/forms/{id}/webhooks | Lists a form's webhooks. |
POST /v1/form/forms/{id}/webhooks | Adds a webhook to a form: every completed response is posted to its https address as JSON, signed with Hanzo-Signature: t=<unix seconds>,sha256=<base64 of HMAC-SHA256(secret, "<seconds>." + body)>; a receiver refuses a timestamp older than five minutes and an event_id it has seen. |
GET /v1/form/forms/{id} | Reads one form of the caller's org, by its id or its slug. |
PUT /v1/form/forms/{id} | Replaces a form whole and answers it as stored. |
PATCH /v1/form/forms/{id} | Changes the parts of a form the body names and keeps the rest, then answers it as stored. |
DELETE /v1/form/forms/{id} | Deletes a form with every response, webhook and delivery it has, and the webhooks' signing secrets. |
GET /v1/form/forms | Lists the caller org's forms, newest first, a page at a time; search keeps the forms whose title holds it and tag the ones carrying it. |
POST /v1/form/forms | Makes a form in the caller's org and answers it as stored, its fields' ids assigned and its defaults filled: kind form, visibility public, language en, one question at a time, and the platform's default sinks when it names none. |
POST /v1/form/public/{id}/responses | Answers a published form. |
GET /v1/form/public/{id} | Reads a published form as its page draws it: the questions, the screens, the hidden values it takes, how it is answered and its theme. |
GET /v1/form/themes/{id} | Reads one theme of the caller's org. |
PUT /v1/form/themes/{id} | Replaces a theme whole; every form drawn in it is drawn in the new one. |
DELETE /v1/form/themes/{id} | Deletes a theme. |
GET /v1/form/themes | Lists the caller org's themes by name. |
POST /v1/form/themes | Makes a theme in the caller's org: a name, four colours (#rrggbb), a font family and an https background image, each optional but the name. |