Bots
Create and manage your agents - their prompt, model, voice settings, and call controls - over the HTTP API. Read endpoints need bots:read; create/update/delete need bots:write.
Endpoints
| Method & path | Ability | Notes |
|---|---|---|
GET /api/v1/bots | bots:read | List bots (no pagination; ?metadata.<key>=<value> filters) |
POST /api/v1/bots | bots:write | Create → returns { id } |
GET /api/v1/bots/{id} | bots:read | Full bot object |
PUT /api/v1/bots/{id} | bots:write | Partial update → message only |
DELETE /api/v1/bots/{id} | bots:write | Soft-delete (status → inactive) |
POST /api/v1/bots/discover | bots:write | AI draft (SSE; JSON with Accept: application/json) - does not persist |
PATCH /api/v1/bots/{id}/metadata | bots:write | Raw metadata object (string values, ≤ 8 KB) |
The bot object
Fields returned by GET /api/v1/bots/{id}:
| Field | Type | Notes |
|---|---|---|
id, tenant_id | uuid | |
name, description | string | |
system_prompt | string | The assembled instructions. |
prompt_builder, settings | string | JSON-encoded strings (parse client-side). |
status | string | active | inactive |
bot_type | string | chatbot (an Agent) | agent (an Autonomous Agent) |
schedule, next_run_at, last_run_at | string | Agent scheduling. |
agent_goal, output_config, max_iterations, timeout_seconds | mixed | Agent-mode controls. |
metadata | object | Your own key/value data. |
created_at, updated_at | string | RFC 3339. |
conversation_count / tool_count are dashboard-computed and are not part of the v1 bot object.List bots
GET /api/v1/bots returns all your bots. There's no pagination; narrow the set with metadata filters, e.g. ?metadata.team=support.
curl https://app.hania.ai/api/v1/bots \
-H "Authorization: Bearer $HANIA_API_KEY"
Create a bot
POST /api/v1/bots creates a bot and returns { "id": "…" }. Provide a name and either a system_prompt or a prompt_builder to assemble one from. Creation is plan-capped: it returns 402 if the workspace's bot limit is reached, and 502 if the voice provider (Cartesia) sync fails. Common body fields:
| Field | Notes |
|---|---|
name | Required. |
system_prompt | Required unless assembled from prompt_builder. |
model, temperature | LLM model id and sampling. |
chat_greeting | Opener for chat conversations. |
tts_provider, tts_voice, voice_greeting | Voice output (tts_provider ∈ cartesia | deepgram). |
end_call_enabled, call_transfer_enabled, call_transfer_number | In-call controls. call_transfer_number is an E.164 number or a SIP URI, and is required when call_transfer_enabled is true. It isn't stored while transfer is off: saving with call_transfer_enabled false removes it. See In-call controls. |
outbound_calls_enabled, max_call_seconds | Outbound voice controls. |
prompt_builder.call_features | The prompt half of the call controls: end_call_enabled, call_transfer_enabled, outbound_calls_enabled. Set each to the same value as the matching top-level field, so the agent has both the tool and the instructions for using it. |
enable_agent_tracing, enable_confidence_scoring, enable_response_validation | Per-bot response-quality flags (booleans, off by default). See Response quality. |
bot_type, status, metadata | Type, state, and your own data. |
PUT), nullable fields follow an "omit to leave unchanged" rule - send only what you want to change. The three response-quality flags are the exception; see below.Response quality
Three optional booleans switch on per-bot quality checks. They sit alongside model and temperature in the bot body, and come back inside the bot's settings object on GET (an absent key means off). All three are off by default and opt-in per bot.
| Field | What it does |
|---|---|
enable_confidence_scoring | Grades each reply with an extra LLM call before it's sent, and replaces a low-confidence answer with a safe "I don't have enough reliable information" message. The grade runs on the bot's own model, so it adds latency (around 700 ms) and cost on the critical path before every reply. The refusal threshold is fixed at 0.3 and isn't configurable. |
enable_response_validation | A passive, background hallucination check that runs only when the turn used sources (knowledge or tool results). It adds no user-facing latency and never changes or blocks the answer; findings go to logs and traces. |
enable_agent_tracing | Records per-step execution traces for the trace view and analytics. Observability only; it doesn't affect replies and adds no AI cost. |
true or false for all three on every save, or a toggle set earlier will be cleared.Completion check
For an Autonomous Agent (bot_type="agent"), two settings control the completion check on its runs. They go in the bot body on create and update, and come back inside settings on GET.
| Field | What it does |
|---|---|
goal_check_enabled | Boolean. false turns the check off, so a run ends on the agent's reply. Absent means on. |
goal_check_model | A model id to run the check on. Empty or absent uses the agent's own model. |
goal_check_enabled turns the check back on, so send false on every save for an agent that should run without it.Hania Code
These fields give an agent Hania Code and control it. Like the quality flags, they go in the bot body on create and update, and come back inside the bot's settings object on GET. What each one does, and how rules and hooks match, is explained in Hania Code settings.
| Field | Type | What it does |
|---|---|---|
code_enabled | boolean | Gives the agent Hania Code. Missing means off. |
code_permission_mode | string | How much runs without asking: manual (the default), accept_edits, plan, or auto. An unknown value returns 400 with field code_permission_mode. |
code_auto_model | string | The model auto mode's safety check runs on. Empty means the agent's own model. |
code_permissions | array of {permission, pattern, action} | Rules applied after the built-in defaults; the last matching rule wins. action is allow, ask, or deny. |
code_hooks | object | {"PreToolUse": [...], "PostToolUse": [...]}, each item {matcher, command, timeout}. Commands that run before or after each change, on the computer the conversation is working on. |
- Saves replace the whole set of settings, so with Hania Code on, send
code_enabledandcode_permission_modeon every save, along with the safety-check model, rules and hooks you want kept. A save that leaves them out switches Hania Code off, or clears that setting. - When
code_enabledisfalseor missing, the others are dropped on save. code_auto_approvewas removed on 2026-09-20. An agent that had it on now hascode_permission_modeset toauto. Sending the old field does nothing.- An empty
code_permissionsorcode_hooksisn't stored, which is the same as leaving it out. Don't send an event with an empty list, such as{"PreToolUse": []}; that is stored as written and does nothing. Send{}or leave the key out. - While Hania Code is on, an invalid mode, rule, or hook is refused with
400,codeVALIDATION_FAILED, andfieldset tocode_permission_mode,code_permissions, orcode_hooks. Theerrornames the rule or hook and what's wrong with it.
When confidence scoring or response validation is on, each graded turn's outcome (the score, whether the answer was refused, the validation verdict, and any unsupported claims) is available to operators in the console's per-bot Quality tab. It's an operator-only review view, scoped to your workspace; see Reviewing graded turns. Scores and verdicts are never shown to end customers.
Draft a bot with AI
POST /api/v1/bots/discover generates a draft bot configuration from a short description (and optional sources). It streams as Server-Sent Events by default, or returns JSON if you send Accept: application/json. The draft is returned, not saved - review it, then create the bot with POST /api/v1/bots. It returns 503 if no LLM is configured, or 502 on an upstream LLM failure.
Metadata
PATCH /api/v1/bots/{id}/metadata sets the bot's metadata object. Values are strings; the object must be ≤ 8 KB. Use it to attach your own identifiers, then filter lists with ?metadata.<key>=<value>.
Post-call hooks
Hooks run a configured tool after a call ends. They're gated by the same bots:read / bots:write abilities.
| Method & path | Ability |
|---|---|
GET /api/v1/bots/{botID}/post-call-hooks | bots:read |
POST /api/v1/bots/{botID}/post-call-hooks | bots:write → { id } |
PUT /api/v1/bots/{botID}/post-call-hooks/{hookID} | bots:write |
DELETE /api/v1/bots/{botID}/post-call-hooks/{hookID} | bots:write |
Hook object: id, bot_id, tool_configuration_id, tool_type, tool_name, run_order, enabled, params_template (object), created_at, updated_at. To create one, send tool_configuration_id (required), plus optional run_order, enabled (default true), and params_template. A hook is unique per (bot, tool configuration).