API reference

Agents

Trigger a goal-driven agent to run on demand from your own backend. The run is detached - the call returns immediately, and the agent works its goal in the background. Read the outcome later as a conversation.

Runs vs. chat. Use this endpoint for an Autonomous Agent (bot_type="agent") - the goal-driven, multi-step runners described in Scheduled agents. For a turn-by-turn conversational reply from any agent, use the Chat API instead.

Trigger an agent

Method & pathAbility
POST /api/v1/agents/{id}/triggeragents:trigger

{id} is the agent's bot id. It must be an Autonomous Agent (bot_type="agent"); triggering an Agent (bot_type="chatbot") is rejected. The agent runs with its own configured goal, prompt, tools, and output settings - see the bot object (agent_goal, max_iterations, timeout_seconds, output_config).

Request body

The body is optional JSON. Send nothing and the agent runs its stored goal exactly as a scheduled tick would.

FieldTypeWhat it does
payloadstring, optionalContext for this run, appended to the agent's stored goal. It shows up in the run's logged user message under a Trigger payload: heading. Typically a relayed webhook body, but any text works.
max_iterationsinteger, optionalOverrides the agent's stored iteration cap for this run only when greater than zero. Zero, negative, or absent means the agent's default.

payload is the same mechanism as the optional instructions box in the dashboard's Run now dialog. The names differ because one is usually a machine-relayed event and the other is typed by a person, but the run treats them identically.

A body that is present but malformed is rejected with 400, as is anything over 64 KiB. That strictness is deliberate: for webhook callers the payload is the point, and silently running without the event data would look like success while acting on nothing.
curl -X POST https://app.hania.ai/api/v1/agents/b1f2c3d4-…/trigger \
  -H "Authorization: Bearer $HANIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"payload": "New ticket #4521: customer cannot log in"}'

Response

A successful trigger returns 202 Accepted - the run has been accepted and started, not finished:

{
  "success": true,
  "data": {
    "conversation_id": "c9a8b7c6-…",
    "status": "accepted"
  },
  "message": "Agent run accepted"
}

Persist the returned conversation_id. The run executes detached, with a 24-hour safety-net deadline, so neither the result nor a run failure appears in this response - both land on that conversation, which you poll for progress and the final outcome. For an agent with Persistent conversation turned on, the id you get back is its existing thread rather than a fresh one.

Errors: 400 for a malformed or oversize body, or when the bot isn't an agent; 404 when the id doesn't match an active agent in your workspace; 403 when the key lacks the agents:trigger ability.

Reading the outcome

An agent run surfaces as a conversation with channel=agent. Fetch it with conversations:read:

  • GET /api/v1/conversations/{conversation_id} - messages and final output.
  • GET /api/v1/conversations/{conversation_id}/trace - the step-by-step execution trace (model turns and tool calls), useful for debugging a run.

A run does not finish just because the agent says so. Before it is accepted as complete, a separate step checks the goal against what the tools actually returned during the run, and sends the agent back if something was described but never confirmed. With tracing on, that appears in the trace as a Goal Completion Check step with its verdict, so a caller reading the trace can see the reasoning behind the outcome. See how a run knows it's done.