Skip to content
HaneDOCS日本語

API reference

API overview

Conventions shared by every Hane public API endpoint — authentication, idempotency, optimistic concurrency, errors and pagination — and how to read the endpoint reference.

Everything in Hane is available through the public API (HTTP and JSON). The console, the reference app and hanectl all call the same API through the TypeScript SDK (@hane/sdk). This page covers the conventions every endpoint shares. Open Endpoints in the sidebar for the details of each one.

Base URL and how the organization is chosen

Section titled “Base URL and how the organization is chosen”

The API lives under /v1/ on your organization’s Hane endpoint (https://<your-hane-endpoint>). Organizations, projects and environments are never part of the URL. The credential you send decides which organization and environment a request acts on.

Send Authorization: Bearer <token> on every request. <token> is one of:

Credential When to use it
API key (hane_<env>_...) Server-to-server calls as a service account. The key is bound to an organization, project, environment and scopes
Access token Calls on behalf of a user. Your app’s BFF exchanges the user’s id_token and an API key at POST /v1/auth/token

See Authentication and token exchange for details.

POST requests with side effects require an Idempotency-Key header. A retried request with the same key is processed only once. A missing key returns IDEMPOTENCY_KEY_REQUIRED; reusing a key with a different body returns IDEMPOTENCY_CONFLICT. The SDK adds a key automatically when you don’t.

Some updates require the version you read, sent as If-Match. If someone updated the resource first you get PRECONDITION_FAILED; read it again and retry. The SDK’s ifMatch(version) builds the header value.

import { createHaneClient, ifMatch, unwrap } from "@hane/sdk";
const record = await unwrap(hane.GET("/v1/data/records/{id}", { params: { path: { id } } }));
await unwrap(
hane.PATCH("/v1/data/records/{id}", {
params: { path: { id }, header: { "If-Match": ifMatch(record.version) } },
body: { values: { status: { value: "returned" } } },
}),
);

Failed requests return an HTTP status and a JSON body in this shape (Problem). Branch on code; when retryable is true you can retry after a pause. Include request_id when you contact support.

{
"type": "about:blank",
"title": "Precondition failed",
"status": 412,
"code": "PRECONDITION_FAILED",
"detail": "...",
"request_id": "...",
"retryable": false
}
code Meaning
VALIDATION_FAILED Input doesn’t match the schema or definition. errors lists per-field reasons
UNAUTHENTICATED / FORBIDDEN Missing or invalid credential / insufficient scope or permission
NOT_FOUND / CONFLICT No such resource / not allowed in the current state
IDEMPOTENCY_KEY_REQUIRED / IDEMPOTENCY_CONFLICT Missing idempotency key / same key, different request
PRECONDITION_REQUIRED / PRECONDITION_FAILED Missing If-Match / stale version
RATE_LIMITED / BUDGET_EXCEEDED Rate limit / usage budget exceeded. Wait for Retry-After
TENANT_SUSPENDED The organization is under emergency suspension
NOT_SUPPORTED The feature isn’t offered in this environment
BAD_GATEWAY / GATEWAY_TIMEOUT An upstream (such as your own API) failed or timed out
INTERNAL An internal Hane failure

The SDK’s unwrap() throws a HaneError (status, code, problem, retryAfterSeconds) on failure.

List endpoints accept limit and cursor and return items and next_cursor. Pass next_cursor back as cursor until it is null.

let cursor: string | undefined;
do {
const page = await unwrap(
hane.GET("/v1/data/records", { params: { query: { type: "LeaseContract", limit: 100, cursor } } }),
);
for (const record of page.items) console.log(record.id);
cursor = page.next_cursor ?? undefined;
} while (cursor);

Progress of an embedded chat conversation (reply generation, tool start and finish, pending approvals) is available as Server-Sent Events from GET /v1/agents/conversations/{id}/events. If the connection drops, reconnect to the same endpoint; you’ll receive the history and current state and continue from there. For a single AgentRun, poll GET /v1/agents/runs/{id} or receive webhooks (see Embed agents).