Skip to content

Agents

name is the immutable slug; displayName is the label you set. Setting model on a custom agent selects the model that agent runs on: an id from List available models. null is Automatic, where oHallo chooses the model.

Agents perform specific tasks in the conversation pipeline. System agents handle core pipeline steps (orchestration, message composition, reply validation, learning extraction). Custom agents handle domain-specific tasks: you create them, bind them to MCP server connections, and give them instructions.

People signed in to the dashboard need the owner or admin role to create, change, delete or restore an agent. The agents oHallo provides are listed for reference, and a change to one through these endpoints answers 403 with "code": "platform_agent".

An API key’s scopes and its brand or workspace restriction decide what it can do:

ActionScopesBrand or workspace restriction
Create an agentagents:write and mcp:write, since every agent is created with MCP connectionsThe agent’s connections must be ones the restriction covers
Update an agentagents:write, and mcp:write when the body carries mcpConnectionsEvery connection the agent uses, and every connection it is given, must be one the restriction covers
Update an agent’s instructionsagents:writeEvery connection the agent uses must be one the restriction covers
Assign a connection’s tools to an agent, with PUT /api/mcp-connections/{connectionId}/assignmentsmcp:write and agents:writeEvery connection the agent uses must be one the restriction covers
Detach an agent from a connection, with DELETE /api/agent-definitions/{id}/mcp-connections/{connectionId}mcp:write and agents:writeThe connection must be one the restriction covers
Delete an agentagents:writeA key without a restriction: a delete cannot be undone
Restore an agent versionagents:write and mcp:write, since a restore sets the agent’s connections to the version’sA key without a restriction

An assignment and a detach act on an agent created in the account, whoever calls: an agent oHallo provides answers 403 with "code": "platform_agent", and an agent the account does not have answers 404. A key without a required scope receives 403 with the scopes it lacks in missing_scopes. A restricted key receives 403 with "code": "key_lock" for every delete and restore, and when it changes an agent that uses a connection outside its restriction; a detach needs only the connection to be inside it. In mcpConnections, a connection outside the restriction answers 422 as an unknown one does, and a key restricted to a workspace receives 403 with "code": "key_lock" for a connection its brand shares across workspaces. A restricted key reads every agent.

Retrieve all agent definitions for your account, including both system and custom agents.

Required scope: agents:read

Terminal window
curl "https://api.ohallo.eu/api/agent-definitions" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Response (trimmed to the main fields):

[
{
"id": "00000001-0000-4000-8000-000000000001",
"name": "conversation-orchestrator",
"displayName": "Conversation Orchestrator",
"description": "Analyses customer messages, dispatches specialist agents, evaluates results",
"agentRole": "system",
"roleSlug": "agent.orchestrator",
"model": null,
"customInstructions": null,
"acceptsGuidance": true,
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
},
{
"id": "abcdef12-3456-4890-abcd-ef1234567890",
"name": "order_lookup_agent_k3n8de",
"displayName": "Order Lookup Agent",
"description": "Retrieves order details, tracking information, and delivery status from the order management system",
"agentRole": "specialist",
"roleSlug": "agent.specialist_llm",
"model": null,
"systemPrompt": "You look up orders. Always include the expected delivery date and current tracking status.",
"customInstructions": null,
"mcpConnections": [
{ "connectionId": "11111111-2222-4788-9444-555555555555", "allowedTools": ["get_order", "track_shipment"] }
],
"createdAt": "2026-02-01T10:00:00.000Z",
"updatedAt": "2026-03-10T14:00:00.000Z"
}
]

An agent created in the account keeps its instructions in systemPrompt. customInstructions carries instructions added to an agent oHallo provides: on a system agent, the ones your account adds in the dashboard; on oHallo’s other agents, oHallo’s own. On a system agent, acceptsGuidance says whether that guidance reaches the agent’s instructions: it is false for the agents that check replies before they are sent and that learn from resolved conversations, which work from oHallo’s instructions alone.

With ?workspaceId=, each agent also carries dispatchableChannels: the types of the workspace’s active, enabled channels, on an agent the assistant in that workspace hands tasks to, and an empty list on any other agent. A workspace outside the key’s brand or workspace restriction answers 404.

Retrieve only the custom (admin-defined) specialist agents.

Required scope: agents:read

Terminal window
curl "https://api.ohallo.eu/api/agent-definitions/custom" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Create a new specialist agent and bind it to one or more MCP server connections. Each call creates a new agent, so a repeated call creates a second one.

Required scopes: agents:write and mcp:write

Terminal window
curl -X POST "https://api.ohallo.eu/api/agent-definitions/custom" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \
-H "Content-Type: application/json" \
-d '{
"displayName": "Returns Agent",
"description": "Handles return requests, checks eligibility, and initiates return labels",
"systemPrompt": "You handle product return requests. Always verify the order number and check that the item is within the return window (30 days from delivery). If eligible, use the create_return tool to initiate the return and provide the customer with a return label.",
"mcpConnections": [
{ "connectionId": "11111111-2222-4788-9444-555555555555", "allowedTools": ["create_return"] }
]
}'

Request body:

FieldTypeRequiredDescription
displayNamestringYesDisplay name for the agent (1 to 255 characters)
descriptionstringYesWhat this agent does; the orchestrator reads this to decide when to dispatch it
systemPromptstringNoThe agent’s instructions: its system prompt, how it does its work
modelstring | nullNoAn id from List available models. Send null (or omit) for Automatic, where oHallo chooses the model
voiceExecutionstringNoHow the agent works on a voice call. worker: the voice assistant hands the task to the agent and keeps talking with the caller while it works, telling the caller what it finds. direct (when omitted): the voice assistant calls the agent’s tools itself
mcpConnectionsarrayYesThe MCP connections this agent can call tools on, each { connectionId, allowedTools }, each connection once. At least one is required. allowedTools names tools the connection declares, and may be empty to allow every tool on that connection

Response (201, trimmed to the main fields):

{
"id": "99887766-5544-4322-9100-ffeeddccbbaa",
"displayName": "Returns Agent",
"description": "Handles return requests, checks eligibility, and initiates return labels",
"agentRole": "specialist",
"model": null,
"systemPrompt": "You handle product return requests. Always verify the order number and check that the item is within the return window (30 days from delivery). If eligible, use the create_return tool to initiate the return and provide the customer with a return label.",
"createdAt": "2026-03-15T16:00:00.000Z",
"updatedAt": "2026-03-15T16:00:00.000Z"
}

The description field is critical. The Orchestrator reads agent descriptions to decide which agents to dispatch for each conversation turn. Write a clear, specific description of what the agent handles.

Both create and update check every connection in mcpConnections before anything is saved:

StatusBodyMeaning
422{ "error": "Invalid request", "details": {...} }A field is missing or invalid, such as a create without a connection; details names the field.
422{ "error": "An MCP connection is listed more than once", "connectionId": "..." }The same connection appears twice.
422{ "error": "Unknown MCP connection", "connectionId": "..." }No such connection, or it is outside the API key’s brand or workspace restriction.
422{ "error": "The MCP connection does not declare these tools", "connectionId": "...", "undeclaredTools": [...], "declaredTools": [...] }A name in allowedTools is not a tool of that connection.
422{ "error": "The Identity Verification connection cannot be assigned to an agent", "connectionId": "..." }The connection is Identity Verification, whose tools oHallo calls itself when it verifies a customer.

Both create and update validate the model against the models available to your account:

StatusBodyMeaning
422{ "error": "Model is not available" }The model is not one List available models returns.
503{ "error": "Model catalog unavailable, try again shortly" }The models available to your account could not be read. The write is rejected rather than applied with an unverified model — retry.
503{ "error": "Model registry unavailable, try again shortly" }The agent was saved but the model choice could not be applied. The body names the agent and carries "modelApplied": false — retry the model.

On create, a failure to apply the model after the agent row was written returns the error status with the agent identified, so you retry the model rather than the create (a blind create retry would make a second agent):

{
"error": "Model registry unavailable, try again shortly",
"agentId": "99887766-5544-4322-9100-ffeeddccbbaa",
"agentCreated": true,
"modelApplied": false
}

Update a custom agent’s configuration. It takes the same fields as create, and only the fields you include are changed. mcpConnections replaces the agent’s connections and tools entirely, and "systemPrompt": null clears its instructions. To return an agent to Automatic model selection, send "model": null.

Required scope: agents:write, and mcp:write when the body carries mcpConnections

Terminal window
curl -X PATCH "https://api.ohallo.eu/api/agent-definitions/custom/99887766-5544-4322-9100-ffeeddccbbaa" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \
-H "Content-Type: application/json" \
-d '{
"systemPrompt": "You handle product return requests. Always verify the order number and check that the item is within the return window (30 days from delivery, or 60 days for premium account customers). If eligible, use the create_return tool to initiate the return and provide the customer with a return label. If the item is damaged, request a photo before processing."
}'

Response: Returns the full updated agent definition. When your account reviews agent changes before they apply, the change is saved as a version that waits for approval in the dashboard, the agent stays as it is, and the response is 202 with { "pending": true, "versionId": "..." }. mcpConnections is not part of that version; in that mode, an agent’s connections are changed with the assignment endpoints of MCP Connections.

Delete a custom agent. System agents cannot be deleted, and answer 403 with "code": "platform_agent". A delete cannot be undone, so it takes a key without a brand or workspace restriction; a restricted key receives 403 with "code": "key_lock".

Required scope: agents:write

Terminal window
curl -X DELETE "https://api.ohallo.eu/api/agent-definitions/custom/99887766-5544-4322-9100-ffeeddccbbaa" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Replace a custom agent’s instructions: its system prompt, the text set as systemPrompt on create and update. Send the new instructions as customInstructions; null clears them. System agents are provided by oHallo and answer 403 with "code": "platform_agent". A key restricted to a brand or workspace changes an agent only when every connection the agent uses is inside its restriction.

Required scope: agents:write

Terminal window
curl -X PATCH "https://api.ohallo.eu/api/agent-definitions/99887766-5544-4322-9100-ffeeddccbbaa/instructions" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \
-H "Content-Type: application/json" \
-d '{
"customInstructions": "You handle product return requests. Always verify the order number and check that the item is within the return window (30 days from delivery) before you initiate a return."
}'

Response: Returns the updated agent definition, or 202 with { "pending": true, "versionId": "..." } when your account reviews agent changes before they apply.

List the models an agent can run on. Send a model’s id as model when you create or update an agent; an agent without one runs on Automatic, where oHallo chooses the model.

Required scope: agents:read

Terminal window
curl "https://api.ohallo.eu/api/agent-definitions/available-models" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Response (trimmed to one model):

{
"models": [
{
"id": "claude-sonnet-4-6",
"label": "Claude Sonnet 4.6",
"family": "claude-sonnet",
"description": "A balanced model: strong general intelligence with quick responses. A solid choice for most agents.",
"contextWindowTokens": 1000000,
"provider": "Anthropic"
}
]
}
FieldDescription
idThe value to send as model
labelThe model’s name, as the dashboard shows it
familyThe model family
descriptionWhat the model is suited to, or null
contextWindowTokensHow many tokens the model reads in one request
providerThe provider of the model, as the dashboard names it

The models come in the order the dashboard lists them.

Report whether the assistant hands tasks to an agent in a workspace, and if not, why: the verdict check_agent_reachability gives over the tenant MCP. The answer reflects the agent’s current configuration; the assistant applies a change within five minutes.

Required scope: agents:read

Terminal window
curl "https://api.ohallo.eu/api/agent-definitions/99887766-5544-4322-9100-ffeeddccbbaa/reachability?workspaceId=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Response:

{
"agentId": "99887766-5544-4322-9100-ffeeddccbbaa",
"workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "custom",
"reachable": false,
"reasons": [{ "code": "mcp_connection_unavailable", "connectionIds": ["c3d4e5f6-7890-4abc-8ef0-1234567890ab"] }]
}

reasons is empty when reachable is true. no_mcp_connections: the agent has no connection. mcp_connection_unavailable: the connections in connectionIds do not serve the workspace, each scoped to another workspace or brand, inactive, or removed; a connection serves a workspace when it is scoped to the workspace, its brand or the whole account. required_capability_unavailable, not_a_specialist and excluded_from_registry concern the agents oHallo provides. An agent or a workspace the account does not have answers 404, and a key restricted to a brand or workspace checks a workspace inside its restriction.

Every change to a custom agent is saved as a version. GET /api/agent-definitions/{id}/versions lists an agent’s versions, and a restore publishes the configuration of one of them as a new version, connections included. When that configuration matches the current one, no new version is created.

Required scopes: agents:write and mcp:write, since a restore sets the agent’s connections to the version’s. A restore takes a key without a brand or workspace restriction; a restricted key receives 403 with "code": "key_lock".

Terminal window
curl -X POST "https://api.ohallo.eu/api/agent-definitions/99887766-5544-4322-9100-ffeeddccbbaa/versions/55443322-1100-4988-8776-655443322110/restore" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

View the execution history for agents on a specific conversation. This is useful for debugging and understanding how the platform processed a conversation.

Required scope: conversations:read

The conversationId query parameter is required; without it the endpoint returns 400. The response is a bare JSON array of every execution for the conversation. The endpoint takes no pagination parameters.

Terminal window
curl "https://api.ohallo.eu/api/agent-executions?conversationId=c9f8e7d6-b5a4-3210-fedc-ba9876543210" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Response:

[
{
"id": "fff66666-7777-4888-9999-aaa000000000",
"agentId": "abcdef12-3456-4890-abcd-ef1234567890",
"agentName": "Order Lookup Agent",
"agentRole": "specialist",
"status": "completed",
"terminationReason": "final_answer",
"toolCallCount": 2,
"modelId": "provider-model-id",
"messageId": "d4e5f6a7-b8c9-4d0e-8f1a-2b3c4d5e6f70",
"input": {
"task": "Look up order NP-2026-0142 and its delivery status",
"agentName": "Order Lookup Agent"
},
"output": {
"success": true,
"findings": {
"orderId": "ord_998877",
"status": "processing",
"expectedDelivery": "2026-03-20"
},
"entryIds": [],
"summary": "Order NP-2026-0142 is processing, label created, expected delivery 2026-03-20.",
"error": null
},
"durationMs": 4120,
"createdAt": "2026-03-15T09:12:08.000Z"
}
]
FieldDescription
statuspending, running, completed, or failed
terminationReasonWhy the run ended: final_answer, max_iterations, parse_failure, or error. null until the run ends.
modelIdIdentifier of the model that served the execution
messageIdThe message that triggered the execution, or null
durationMsMilliseconds from creation to completion, or null while the execution has not completed

View the individual MCP tool calls made during an agent execution.

Required scope: conversations:read

Pass either executionId, for the tool calls of one execution, or conversationId, for the tool calls of every execution in the conversation. Without either the endpoint returns 400. The response is a bare JSON array, oldest call first.

Terminal window
curl "https://api.ohallo.eu/api/tool-calls?executionId=fff66666-7777-4888-9999-aaa000000000" \
-H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"

Response (trimmed to the main fields):

[
{
"id": "11112222-3333-4788-9555-666677778888",
"executionId": "fff66666-7777-4888-9999-aaa000000000",
"toolName": "get_order",
"connectionId": "11111111-2222-4788-9444-555555555555",
"input": {
"orderNumber": "NP-2026-0142"
},
"output": {
"orderId": "ord_998877",
"status": "processing",
"expectedDelivery": "2026-03-20",
"items": [
{ "sku": "BRG-4420", "name": "Precision Bearing 4420", "quantity": 50 }
]
},
"error": null,
"policyDecision": "allow",
"durationMs": 890,
"createdAt": "2026-03-15T09:12:09.000Z"
},
{
"id": "99998888-7777-4788-9555-444433332222",
"executionId": "fff66666-7777-4888-9999-aaa000000000",
"toolName": "track_shipment",
"connectionId": "11111111-2222-4788-9444-555555555555",
"input": {
"orderId": "ord_998877"
},
"output": {
"trackingNumber": "TRK-2026-88776655",
"status": "label_created",
"estimatedDelivery": "2026-03-20"
},
"error": null,
"policyDecision": "allow",
"durationMs": 1240,
"createdAt": "2026-03-15T09:12:10.000Z"
}
]

A null error means the MCP server answered; a populated error means it returned an error or timed out.

When a customer message arrives, the agent pipeline executes in sequence:

  1. Orchestrator (plans and dispatches). Analyses the message, classifies the intent, and decides which specialist agents to dispatch. It reads the description field of every available agent to make this decision. The Orchestrator runs in a loop, dispatching agents and evaluating their results until it determines enough information has been gathered.

  2. Specialist Agents execute in the order determined by the Orchestrator. Each agent calls tools on its bound MCP connections to gather data or perform actions.

  3. Message Agent receives the combined results from all specialist agents and composes the final reply.

  4. Validation Agent checks the drafted reply for factual accuracy and policy compliance before delivery.

Custom agents participate in step 2. The better your agent’s description matches the customer’s intent, the more reliably the Orchestrator will dispatch it.