Skip to main content

Why the API

A channel is for a person. The API is for a system: a CI pipeline that wants a failure analysed, a ticketing system that hands a case to an agent, a nightly job in your own scheduler, a product that embeds an agent behind its own interface. The run is the same governed conversation as one started in Xpander Chat, with the agent’s skills, approvals, budget and record, and the caller gets the result back in a shape it can parse. Choose the webhook instead when the caller cannot hold a key.

Start a run

Three endpoints share one handler and one body: Authenticate with x-api-key and an organization API key from Settings > API keys; a key can be limited to named agents. The agent’s Developer access row shows a second address, POST /v1/agents/{agent_id}/gateway/invoke. That one runs a single turn of a conversation and returns the reply; it is the conversation API Xpander Chat itself uses. By contrast, /invoke starts a task and returns the task record. Both take the same key. The body needs only the input:
Behind a load balancer with an idle timeout, an AWS ALB answers 504 after 60 seconds by default, a synchronous call whose turn runs longer never returns. Use /invoke/async and poll the task, or the streaming endpoint, for turns that may take more than a minute. Useful fields beside input.text:
  • input.files: URLs the agent reads
  • input.user: who the run is for, so the record and any per-person credential resolve to them
  • id: an existing conversation id, to continue it
  • additional_context, instructions_override, title
  • llm_model_provider and llm_model_name for this run
  • tool_call_limit
  • sub_tasks_mode: sync, async or auto
  • version=draft as a query parameter, to run the staged version of the agent
A dropped stream does not stop the run; the answer lands in the task. On a self-hosted location the host is that location’s API address.

Read tasks

GET /v1/tasks lists tasks with filters for agent, user, parent task, status and dates. GET /v1/tasks/{task_id} returns the task, /thread its messages and skill calls, /thread/full the same including every sub-task, /llm_usage its model calls with cost. POST /v1/tasks/{task_id}/stop stops it. Task statuses are pending, executing, paused, error, failed, completed and stopped. The full reference is under REST API.

Get told when a run ends

An agent’s notification_settings, set with PATCH /v1/agents/{agent_id}, send the outcome on success, on error and on budget events to email, Slack or a webhook of yours. The webhook receives the task’s name, subject, body, type, duration, result and a link to the task, with any headers you configured:

Structured output

Four mechanisms, from the one to reach for first:
  1. The agent’s output format. In Agent settings, Output > Structured output takes a JSON Schema; Generate with AI drafts one from a sentence. Every answer is validated against it and repaired when it can be, on every channel, and the API returns the JSON as result. In Slack and the other chat channels the same answer is rendered as prose for the reader; the record keeps the JSON. This is the setting to use when a downstream system parses the answer.
Agent settings Output section with Default, Markdown and Structured output options, a JSON schema editor holding a seeded AI Agent Result schema, and a Generate with AI button

Output > Structured output on a new agent, with the seeded schema.

  1. The required sections in the instructions. For a human-readable answer that must always carry the same sections, write them into the agent’s static prompt as a contract. Every turn’s prompt carries the instructions, and they are never trimmed.
  2. A format per channel. A Slack channel routed to the agent can carry its own format instructions, which override the agent’s output format for that channel only; see Channels.
  3. A schema per call. The invoke body accepts output_format and output_schema for one run. It applies to runs the API starts directly; a turn that goes through the agent’s conversation uses the agent-level schema instead, so prefer the agent setting when both are in play.
Over the webhook, a structured result is returned as JSON rather than a string, and ?getter=result.<field> extracts one field.

The same run from the SDK

The Python SDK wraps these calls (Tasks.create, events, Agents) against the same endpoints; see SDK. Everything on this page also applies to a workflow, at POST /v1/workflows/{workflow_id}/invoke.