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

# Chatbots

> Create and manage AI Career Chat chatbots and their configuration

## Overview

Chatbots are AI Career Chat assistants scoped to a team. Each chatbot has a configuration (tool toggles, welcome message, branding, language) and may have attached jobs and knowledge bases. This resource supports full create, read, update, archive, and unarchive operations.

The `status` field is returned as `ACTIVE` or `ARCHIVED`. By default, `GET /qsi/gather/chatbots` returns only active chatbots; pass `archived=true` to list archived ones instead.

## Create Chatbot

Create a new chatbot.

**Endpoint:** `POST /qsi/gather/chatbots`

<ParamField name="title" type="string" required>
  Internal title of the chatbot
</ParamField>

<ParamField name="displayName" type="string" required>
  Public display name shown to candidates
</ParamField>

<ParamField name="language" type="string">
  Language code (e.g., "en")
</ParamField>

<ParamField name="description" type="string">
  Internal description
</ParamField>

<ParamField name="welcomeMessage" type="string">
  First message shown to candidates
</ParamField>

<ParamField name="friendlyTone" type="boolean">
  Use a friendly tone
</ParamField>

<ParamField name="professionalTone" type="boolean">
  Use a professional tone
</ParamField>

<ParamField name="useKnowledgeBase" type="boolean">
  Enable knowledge-base answering
</ParamField>

<ParamField name="useJobMatching" type="boolean">
  Enable job matching
</ParamField>

<ParamField name="useResumeParsing" type="boolean">
  Enable resume parsing
</ParamField>

<ParamField name="enableStructuredInput" type="boolean">
  Enable structured input prompts
</ParamField>

<ParamField name="searchWebEnabled" type="boolean">
  Allow web search
</ParamField>

<ParamField name="guardrailsEnabled" type="boolean">
  Enable guardrails
</ParamField>

<ParamField name="mediaEnabled" type="boolean">
  Allow media uploads
</ParamField>

<ParamField name="guardrails" type="string[]">
  Guardrail rules
</ParamField>

<ParamField name="jobIds" type="string[]">
  Job IDs to attach
</ParamField>

<ParamField name="knowledgeBaseIds" type="string[]">
  Knowledge-base IDs to attach
</ParamField>

<ParamField name="branding" type="object">
  Branding overrides (logoUrl, accentColor, buttonColor, displayName, headerImageUrl, backgroundImageUrl)
</ParamField>

<ParamField name="allowedDomains" type="string[]">
  Domains allowed to embed the chatbot
</ParamField>

<ParamField name="jobPageUrlPattern" type="string">
  URL pattern used to detect job pages
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST https://api.prod.qualifi.hr/qsi/gather/chatbots \
      -H "x-api-key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "title": "Careers Bot",
        "displayName": "Careers Assistant",
        "language": "en",
        "useJobMatching": true,
        "welcomeMessage": "Hi! How can I help with your job search?"
      }'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch('https://api.prod.qualifi.hr/qsi/gather/chatbots', {
      method: 'POST',
      headers: {
        'x-api-key': apiKey,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Careers Bot',
        displayName: 'Careers Assistant',
        language: 'en',
        useJobMatching: true
      })
    })
    const { data } = await response.json()
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.prod.qualifi.hr/qsi/gather/chatbots',
        headers={'x-api-key': api_key, 'Content-Type': 'application/json'},
        json={
            'title': 'Careers Bot',
            'displayName': 'Careers Assistant',
            'language': 'en',
            'useJobMatching': True
        }
    )
    data = response.json()['data']
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Request theme={null}
  {
    "title": "Careers Bot",
    "displayName": "Careers Assistant",
    "language": "en",
    "useJobMatching": true,
    "welcomeMessage": "Hi! How can I help with your job search?"
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "chatbot": {
        "id": "uuid",
        "title": "Careers Bot",
        "displayName": "Careers Assistant",
        "status": "ACTIVE",
        "language": "en",
        "welcomeMessage": "Hi! How can I help with your job search?",
        "useJobMatching": true,
        "jobIds": [],
        "knowledgeBaseIds": [],
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2026-01-01T00:00:00Z",
        "updatedAt": "2026-01-01T00:00:00Z"
      }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```
</CodeGroup>

## List Chatbots

List chatbots with pagination. `archived=true` to get archived only (`true` returns archived chatbots; default `false` returns active only).

**Endpoint:** `GET /qsi/gather/chatbots`

<ParamField query="page" type="number">
  Page number (default: 1)
</ParamField>

<ParamField query="pageSize" type="number">
  Items per page (default: 50)
</ParamField>

<ParamField query="archived" type="boolean">
  Return archived chatbots instead of active (default: false)
</ParamField>

<ParamField query="search" type="string">
  Search by title or display name
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "chatbots": [
        {
          "id": "uuid",
          "title": "Careers Bot",
          "displayName": "Careers Assistant",
          "status": "ACTIVE",
          "language": "en",
          "organizationId": "org-uuid",
          "teamId": "team-uuid",
          "createdById": "user-uuid",
          "createdAt": "2026-01-01T00:00:00Z",
          "updatedAt": "2026-01-01T00:00:00Z"
        }
      ],
      "pagination": { "total": 12, "page": 1, "totalPages": 1, "pageSize": 50 }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```
</CodeGroup>

<Note>
  The list response omits per-chatbot configuration, attached `jobIds`, and `knowledgeBaseIds`. Fetch a single chatbot with `GET /qsi/gather/chatbots/{chatbotId}` to retrieve the full configuration and attachments.
</Note>

## Get Chatbot

Retrieve a chatbot with its configuration and attached jobs/knowledge bases.

**Endpoint:** `GET /qsi/gather/chatbots/{chatbotId}`

<ParamField path="chatbotId" type="string" required>
  UUID of the chatbot
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "chatbot": {
        "id": "uuid",
        "title": "Careers Bot",
        "displayName": "Careers Assistant",
        "status": "ACTIVE",
        "language": "en",
        "welcomeMessage": "Hi! How can I help with your job search?",
        "friendlyTone": true,
        "useJobMatching": true,
        "useKnowledgeBase": true,
        "guardrails": ["Stay on topic"],
        "branding": { "accentColor": "#0000CC" },
        "allowedDomains": ["careers.example.com"],
        "jobPageUrlPattern": "/jobs/*",
        "jobIds": ["job-uuid-1", "job-uuid-2"],
        "knowledgeBaseIds": ["kb-uuid-1"],
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2026-01-01T00:00:00Z",
        "updatedAt": "2026-01-01T00:00:00Z"
      }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```
</CodeGroup>

## Update Chatbot

Update a chatbot's configuration. Any field accepted on create may be updated. Supplying `jobIds` or `knowledgeBaseIds` replaces the entire attached set.

**Endpoint:** `PATCH /qsi/gather/chatbots/{chatbotId}`

<ParamField path="chatbotId" type="string" required>
  UUID of the chatbot to update
</ParamField>

<ParamField name="welcomeMessage" type="string">
  Updated welcome message
</ParamField>

<ParamField name="useJobMatching" type="boolean">
  Toggle job matching
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  {
    "welcomeMessage": "Welcome! Ask me about open roles.",
    "useJobMatching": false
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "chatbot": {
        "id": "uuid",
        "title": "Careers Bot",
        "status": "ACTIVE",
        "welcomeMessage": "Welcome! Ask me about open roles.",
        "useJobMatching": false,
        "updatedAt": "2026-01-02T00:00:00Z"
      }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-02T00:00:00Z" }
  }
  ```
</CodeGroup>

## Update Attached Jobs

Replace the full set of jobs attached to a chatbot.

**Endpoint:** `PATCH /qsi/gather/chatbots/{chatbotId}/jobs`

<ParamField path="chatbotId" type="string" required>
  UUID of the chatbot
</ParamField>

<ParamField name="jobIds" type="string[]" required>
  Complete set of job IDs to attach (replaces existing attachments)
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  { "jobIds": ["job-uuid-1", "job-uuid-2"] }
  ```

  ```json Response theme={null}
  {
    "data": {
      "chatbot": {
        "id": "uuid",
        "status": "ACTIVE",
        "jobIds": ["job-uuid-1", "job-uuid-2"]
      }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-02T00:00:00Z" }
  }
  ```
</CodeGroup>

## Update Attached Knowledge Bases

Replace the full set of knowledge bases attached to a chatbot.

**Endpoint:** `PATCH /qsi/gather/chatbots/{chatbotId}/knowledge-bases`

<ParamField path="chatbotId" type="string" required>
  UUID of the chatbot
</ParamField>

<ParamField name="knowledgeBaseIds" type="string[]" required>
  Complete set of knowledge-base IDs to attach (replaces existing attachments)
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  { "knowledgeBaseIds": ["kb-uuid-1"] }
  ```

  ```json Response theme={null}
  {
    "data": {
      "chatbot": {
        "id": "uuid",
        "status": "ACTIVE",
        "knowledgeBaseIds": ["kb-uuid-1"]
      }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-02T00:00:00Z" }
  }
  ```
</CodeGroup>

## Archive Chatbot

Archive a chatbot. Archived chatbots are excluded from the default list.

**Endpoint:** `DELETE /qsi/gather/chatbots/{chatbotId}`

<ParamField path="chatbotId" type="string" required>
  UUID of the chatbot to archive
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "chatbot": {
        "id": "uuid",
        "status": "ARCHIVED",
        "archivedAt": "2026-01-03T00:00:00Z"
      }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-03T00:00:00Z" }
  }
  ```
</CodeGroup>

## Unarchive Chatbot

Restore an archived chatbot to active status.

**Endpoint:** `POST /qsi/gather/chatbots/{chatbotId}/unarchive`

<ParamField path="chatbotId" type="string" required>
  UUID of the chatbot to unarchive
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "chatbot": { "id": "uuid", "status": "ACTIVE" }
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-03T00:00:00Z" }
  }
  ```
</CodeGroup>

## Error Responses

Errors use the standard envelope: a nested `error` object (`code`, `message`, and an optional `details`) alongside a `meta` block.

<CodeGroup>
  ```json 400 Bad Request theme={null}
  {
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "Missing or invalid fields in request body"
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "code": "UNAUTHORIZED",
      "message": "Missing or invalid API key"
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```

  ```json 404 Not Found theme={null}
  {
    "error": {
      "code": "NOT_FOUND",
      "message": "Chatbot not found"
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```

  ```json 500 Internal Server Error theme={null}
  {
    "error": {
      "code": "INTERNAL_ERROR",
      "message": "Failed to process request"
    },
    "meta": { "requestId": "uuid", "timestamp": "2026-01-01T00:00:00Z" }
  }
  ```
</CodeGroup>

## Related Resources

<CardGroup cols={2}>
  <Card title="Conversations" icon="comments" href="/api-reference/conversations">
    Read chatbot conversations and messages
  </Card>

  <Card title="Analytics" icon="chart-line" href="/api-reference/analytics">
    Chatbot engagement and funnel metrics
  </Card>
</CardGroup>
