> ## Documentation Index
> Fetch the complete documentation index at: https://hadiqio.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> Create and manage agents (personas) that define assistant behavior, knowledge sources, and tools.

Agents — called *personas* in the API — configure how Hadiq.io responds to users. Each agent can have a custom system prompt, access to specific document sets, and a set of enabled tools. Agents are the `persona_id` you pass when creating a chat session.

***

## Create an agent

```
POST /api/persona
```

Creates a new agent. Any authenticated user with basic access can create agents.

### Request body

<ParamField body="name" type="string" required>
  Display name for the agent.
</ParamField>

<ParamField body="description" type="string" required>
  Short description shown in the agent picker UI.
</ParamField>

<ParamField body="system_prompt" type="string" required>
  The system prompt injected before every conversation. Use this to set tone, persona, constraints, and capabilities.
</ParamField>

<ParamField body="task_prompt" type="string" required>
  Additional task-level instructions appended to the system prompt.
</ParamField>

<ParamField body="datetime_aware" type="boolean" required>
  When `true`, injects the current date and time into the system prompt.
</ParamField>

<ParamField body="replace_base_system_prompt" type="boolean" default="false">
  When `true`, the `system_prompt` fully replaces the default Onyx base system prompt instead of prepending to it.
</ParamField>

<ParamField body="is_public" type="boolean" required>
  When `true`, the agent is visible to all users in your tenant.
</ParamField>

<ParamField body="document_set_ids" type="array" required>
  IDs of document sets this agent searches. Pass an empty array for a general-purpose agent with no scoped knowledge.
</ParamField>

<ParamField body="tool_ids" type="array" required>
  IDs of tools enabled for this agent (e.g. search tool, image generation tool). Pass an empty array to disable tools.
</ParamField>

<ParamField body="llm_model_provider_override" type="string">
  Override the LLM provider (e.g. `openai`, `anthropic`).
</ParamField>

<ParamField body="llm_model_version_override" type="string">
  Override the model version (e.g. `gpt-4o`, `claude-3-5-sonnet-20241022`).
</ParamField>

<ParamField body="starter_messages" type="array">
  Suggested starter prompts shown to users when opening a new chat with this agent.

  <Expandable title="starter message fields">
    <ParamField body="name" type="string">
      Short label shown on the button.
    </ParamField>

    <ParamField body="description" type="string">
      Longer description shown in a tooltip.
    </ParamField>

    <ParamField body="message" type="string">
      The actual message sent when the user clicks the starter.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="users" type="array">
  UUIDs of users who can access this agent when `is_public` is `false`.
</ParamField>

<ParamField body="groups" type="array">
  Group IDs that can access this agent when `is_public` is `false`.
</ParamField>

<ParamField body="search_start_date" type="string (ISO 8601)">
  Only search documents updated after this date.
</ParamField>

<ParamField body="label_ids" type="array">
  Label IDs to tag this agent with for organization.
</ParamField>

<ParamField body="is_featured" type="boolean" default="false">
  Feature this agent prominently in the UI.
</ParamField>

<ParamField body="display_priority" type="integer">
  Sort order in the agent list. Lower values appear first.
</ParamField>

<ParamField body="hierarchy_node_ids" type="array">
  IDs of hierarchy nodes (folders, spaces, channels) to scope search to.
</ParamField>

<ParamField body="document_ids" type="array">
  IDs of individual documents to attach for scoped search.
</ParamField>

<ParamField body="user_file_ids" type="array">
  IDs of user-uploaded files to attach.
</ParamField>

### Response

Returns a `PersonaSnapshot` with the created agent's full details.

<ResponseField name="id" type="integer">
  Unique agent ID. Use this as `persona_id` when creating chat sessions.
</ResponseField>

<ResponseField name="name" type="string">
  Agent name.
</ResponseField>

<ResponseField name="description" type="string">
  Agent description.
</ResponseField>

<ResponseField name="is_public" type="boolean">
  Whether the agent is publicly visible.
</ResponseField>

<ResponseField name="builtin_persona" type="boolean">
  Whether this is a built-in Hadiq.io agent (cannot be deleted).
</ResponseField>

<ResponseField name="tools" type="array">
  Tools enabled for this agent.
</ResponseField>

<ResponseField name="document_sets" type="array">
  Document sets this agent searches.
</ResponseField>

<ResponseField name="system_prompt" type="string">
  The agent's system prompt.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://cloud.hadiq.io/api/persona \
    -H "Authorization: Bearer hadiqk-..." \
    -H "Content-Type: application/json" \
    -d '{
      "name": "HR Assistant",
      "description": "Answers questions about HR policies and benefits.",
      "system_prompt": "You are a helpful HR assistant with access to company HR policies.",
      "task_prompt": "Always cite the specific policy section when answering.",
      "datetime_aware": true,
      "replace_base_system_prompt": false,
      "is_public": true,
      "document_set_ids": [3, 7],
      "tool_ids": [1]
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://cloud.hadiq.io/api/persona",
      headers={"Authorization": "Bearer hadiqk-..."},
      json={
          "name": "HR Assistant",
          "description": "Answers questions about HR policies and benefits.",
          "system_prompt": "You are a helpful HR assistant with access to company HR policies.",
          "task_prompt": "Always cite the specific policy section when answering.",
          "datetime_aware": True,
          "replace_base_system_prompt": False,
          "is_public": True,
          "document_set_ids": [3, 7],
          "tool_ids": [1],
      },
  )
  agent = resp.json()
  print("Created agent ID:", agent["id"])
  ```
</CodeGroup>

***

## Update an agent

```
PATCH /api/persona/{persona_id}
```

Updates an existing agent. Accepts the same fields as the create request. You can only update agents you own or have edit access to.

<Note>
  This endpoint cannot update `display_priority` or `builtin_persona`. Use the admin display-priority endpoint to reorder agents.
</Note>

### Path parameters

<ParamField path="persona_id" type="integer" required>
  ID of the agent to update.
</ParamField>

### Request body

Same as [create an agent](#create-an-agent). All fields may be updated.

<CodeGroup>
  ```bash curl theme={null}
  curl -X PATCH https://cloud.hadiq.io/api/persona/12 \
    -H "Authorization: Bearer hadiqk-..." \
    -H "Content-Type: application/json" \
    -d '{
      "name": "HR Assistant v2",
      "description": "Updated HR assistant with broader document access.",
      "system_prompt": "You are a helpful HR assistant.",
      "task_prompt": "",
      "datetime_aware": true,
      "is_public": true,
      "document_set_ids": [3, 7, 9],
      "tool_ids": [1]
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.patch(
      "https://cloud.hadiq.io/api/persona/12",
      headers={"Authorization": "Bearer hadiqk-..."},
      json={
          "name": "HR Assistant v2",
          "description": "Updated HR assistant with broader document access.",
          "system_prompt": "You are a helpful HR assistant.",
          "task_prompt": "",
          "datetime_aware": True,
          "is_public": True,
          "document_set_ids": [3, 7, 9],
          "tool_ids": [1],
      },
  )
  print(resp.json())
  ```
</CodeGroup>

***

## Get an agent

```
GET /api/persona/{persona_id}
```

Returns the full details of a single agent.

### Path parameters

<ParamField path="persona_id" type="integer" required>
  The agent to retrieve.
</ParamField>

### Response

Returns a `FullPersonaSnapshot`, which extends `PersonaSnapshot` with `search_start_date`.

<CodeGroup>
  ```bash curl theme={null}
  curl https://cloud.hadiq.io/api/persona/12 \
    -H "Authorization: Bearer hadiqk-..."
  ```

  ```python Python theme={null}
  import requests

  resp = requests.get(
      "https://cloud.hadiq.io/api/persona/12",
      headers={"Authorization": "Bearer hadiqk-..."},
  )
  print(resp.json())
  ```
</CodeGroup>

***

## List agents

```
GET /api/agents
```

Returns a paginated list of agents available to the authenticated user.

### Query parameters

<ParamField query="page_num" type="integer" default="0">
  Page number (0-indexed).
</ParamField>

<ParamField query="page_size" type="integer" default="10">
  Items per page. Maximum `1000`.
</ParamField>

<ParamField query="include_deleted" type="boolean" default="false">
  Include soft-deleted agents.
</ParamField>

<ParamField query="get_editable" type="boolean" default="false">
  When `true`, only returns agents you can edit.
</ParamField>

<ParamField query="include_default" type="boolean" default="true">
  Include the built-in default agents.
</ParamField>

### Response

<ResponseField name="items" type="array">
  Page of `MinimalPersonaSnapshot` objects.

  <Expandable title="snapshot fields">
    <ResponseField name="id" type="integer">
      Agent ID.
    </ResponseField>

    <ResponseField name="name" type="string">
      Agent name.
    </ResponseField>

    <ResponseField name="description" type="string">
      Agent description.
    </ResponseField>

    <ResponseField name="is_public" type="boolean">
      Whether the agent is publicly visible.
    </ResponseField>

    <ResponseField name="is_listed" type="boolean">
      Whether the agent appears in the agent picker.
    </ResponseField>

    <ResponseField name="is_featured" type="boolean">
      Whether the agent is featured.
    </ResponseField>

    <ResponseField name="builtin_persona" type="boolean">
      Whether this is a built-in agent.
    </ResponseField>

    <ResponseField name="tools" type="array">
      Tools available to the agent.
    </ResponseField>

    <ResponseField name="document_sets" type="array">
      Document sets the agent searches.
    </ResponseField>

    <ResponseField name="llm_model_version_override" type="string">
      Model override, if set.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="total_items" type="integer">
  Total number of agents matching the query.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null}
  curl "https://cloud.hadiq.io/api/agents?page_num=0&page_size=20" \
    -H "Authorization: Bearer hadiqk-..."
  ```

  ```python Python theme={null}
  import requests

  resp = requests.get(
      "https://cloud.hadiq.io/api/agents",
      headers={"Authorization": "Bearer hadiqk-..."},
      params={"page_num": 0, "page_size": 20},
  )
  data = resp.json()
  print(f"Total agents: {data['total_items']}")
  for agent in data["items"]:
      print(agent["id"], agent["name"])
  ```
</CodeGroup>

***

## Delete an agent

```
DELETE /api/persona/{persona_id}
```

Soft-deletes an agent. The agent is hidden from users but its data is retained. You can only delete agents you own.

### Path parameters

<ParamField path="persona_id" type="integer" required>
  The agent to delete.
</ParamField>

Returns `204 No Content` on success.

<CodeGroup>
  ```bash curl theme={null}
  curl -X DELETE https://cloud.hadiq.io/api/persona/12 \
    -H "Authorization: Bearer hadiqk-..."
  ```

  ```python Python theme={null}
  import requests

  requests.delete(
      "https://cloud.hadiq.io/api/persona/12",
      headers={"Authorization": "Bearer hadiqk-..."},
  )
  ```
</CodeGroup>

***

## Admin: list agents (paginated)

```
GET /api/admin/agents
```

Admin version of the agents list endpoint, with the same query parameters as `GET /api/agents`. Returns `PersonaSnapshot` objects (more detailed than `MinimalPersonaSnapshot`). Requires admin or curator role.

***

## Error codes

| Status | Cause                                                                                                                   |
| ------ | ----------------------------------------------------------------------------------------------------------------------- |
| `400`  | User knowledge is disabled but `user_file_ids` were provided, or vector DB is disabled and document sets were provided. |
| `403`  | Insufficient permissions to create, edit, or delete the agent.                                                          |
| `404`  | Agent not found.                                                                                                        |
