API reference

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 & pathAbilityNotes
GET /api/v1/botsbots:readList bots (no pagination; ?metadata.<key>=<value> filters)
POST /api/v1/botsbots:writeCreate → returns { id }
GET /api/v1/bots/{id}bots:readFull bot object
PUT /api/v1/bots/{id}bots:writePartial update → message only
DELETE /api/v1/bots/{id}bots:writeSoft-delete (status → inactive)
POST /api/v1/bots/discoverbots:writeAI draft (SSE; JSON with Accept: application/json) - does not persist
PATCH /api/v1/bots/{id}/metadatabots:writeRaw metadata object (string values, ≤ 8 KB)

The bot object

Fields returned by GET /api/v1/bots/{id}:

FieldTypeNotes
id, tenant_iduuid
name, descriptionstring
system_promptstringThe assembled instructions.
prompt_builder, settingsstringJSON-encoded strings (parse client-side).
statusstringactive | inactive
bot_typestringchatbot | agent
schedule, next_run_at, last_run_atstringAgent scheduling.
agent_goal, output_config, max_iterations, timeout_secondsmixedAgent-mode controls.
metadataobjectYour own key/value data.
created_at, updated_atstringRFC 3339.
The console's 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:

FieldNotes
nameRequired.
system_promptRequired unless assembled from prompt_builder.
model, temperatureLLM model id and sampling.
chat_greetingOpener for chat conversations.
tts_provider, tts_voice, voice_greetingVoice output (tts_providercartesia | deepgram).
end_call_enabled, call_transfer_enabled, call_transfer_numberIn-call controls.
outbound_calls_enabled, max_call_secondsOutbound voice controls.
enable_agent_tracing, enable_confidence_scoring, enable_response_validationPer-bot response-quality flags (booleans, off by default). See Response quality.
bot_type, status, metadataType, state, and your own data.
On update (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.

FieldWhat it does
enable_confidence_scoringGrades 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_validationA 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_tracingRecords per-step execution traces for the trace view and analytics. Observability only; it doesn't affect replies and adds no AI cost.
These flags are stored only when set, so an omitted key is read as off and any stored value is dropped - the opposite of the "omit to leave unchanged" rule. Send an explicit true or false for all three on every save, or a toggle set earlier will be cleared.

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 & pathAbility
GET /api/v1/bots/{botID}/post-call-hooksbots:read
POST /api/v1/bots/{botID}/post-call-hooksbots: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).