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

# Knowledge base

> Create, update, list, and delete knowledge base articles, and upload PDFs and documents, through the Support API.

The knowledge base holds the articles your AI agent answers from and your human agents read in the inbox. Articles are grouped into **collections**. You can manage them in Clarity or keep them in sync from your own content system with these endpoints.

Every request goes to `https://back.leap.onclarity.com` with `Authorization: Bearer $CLARITY_API_KEY` (see [Authentication](/authentication.md)).

| Endpoint | Does |
| - | - |
| `POST /api/kb/articles/list` | List and search articles |
| `GET /api/kb/articles/detail?article_id=…` | Read one article with its content |
| `POST /api/kb/articles/create` | Create an article |
| `PATCH /api/kb/articles/update?article_id=…` | Replace an article |
| `DELETE /api/kb/articles/delete?article_id=…` | Delete an article |
| `POST /api/kb/articles/upload` | Upload a PDF or document to become an article |
| `GET /api/kb/meta` | List the collections and values in use |

## The article object

```json theme={null}
{
  "id": 482913570216,
  "collection_id": "kb_42",
  "title": "How to return an item",
  "content": "You can return any item within 30 days of delivery...",
  "collection": "Returns",
  "status": "published",
  "source": "manually",
  "is_public": true,
  "tags": ["returns", "shipping"],
  "expiration_date_start": null,
  "expiration_date_end": null,
  "created_by": "ai-agent",
  "created_at": "2026-10-20T08:14:02.118374+00:00",
  "updated_at": "2026-10-21T11:40:55.901223+00:00",
  "usage_count": 14
}
```

| Field | Meaning |
| - | - |
| `id` | The article id, an integer. |
| `title`, `content` | The article. `content` is Markdown text. |
| `collection` | The collection name. |
| `status` | `draft` or `published` for articles you write. Uploads also pass through `uploading` and `processing`, and end in `error` if conversion fails. Only `published` articles are used by the AI agent. |
| `source` | `manually`, `ai`, `pdf`, or `file`. |
| `is_public` | Whether customers can read the article on your public help page. Separate from `status`: a published article stays internal until this is `true`. |
| `expiration_date_start`, `expiration_date_end` | Optional validity window (ISO 8601). The end must be after the start. |
| `created_by` | The author's name. Articles created with an API key get `ai-agent` unless you send your own `created_by`. |
| `usage_count` | How often the article has been used. |

Articles accept other fields too (for example `tags`, `confidence`, `criticality`); Clarity stores whatever you send with the article.

## Create an article

```bash Request theme={null}
curl -X POST https://back.leap.onclarity.com/api/kb/articles/create \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "How to return an item",
    "content": "You can return any item within 30 days of delivery. Open **Orders**, pick the order, and choose **Return**.",
    "collection": "Returns",
    "status": "published",
    "is_public": true
  }'
```

```json Response (201) theme={null}
{
  "id": 482913570216,
  "collection_id": "kb_42",
  "content": "You can return any item within 30 days of delivery. Open **Orders**, pick the order, and choose **Return**.",
  "title": "How to return an item",
  "collection": "Returns",
  "status": "published",
  "source": "manually",
  "is_public": true,
  "expiration_date_start": null,
  "expiration_date_end": null,
  "created_by": "ai-agent",
  "created_at": "2026-10-22T10:02:11.483920+00:00",
  "updated_at": "2026-10-22T10:02:11.483951+00:00",
  "usage_count": 0
}
```

**title** `string`

The article title.

**content** `string`

The article body in Markdown.

**collection** `string`

The collection to file it in.

**status** `string` (default: draft)

`draft` or `published`.

**is\_public** `boolean` (default: false)

Show the article on the public help page.

**source** `string` (default: manually)

Where the article came from.

**expiration\_date\_start** `string`

When the article becomes valid.

**expiration\_date\_end** `string`

When the article stops being valid.

Creating an article fires the `kb_article_created` [webhook](/support/webhooks.md).

## Update an article

`PATCH /api/kb/articles/update?article_id=…` takes the same body as create.

> [!WARNING]
>
> An update **replaces** the article's fields. Only `content`, `is_public`, and the usage counters are kept when you leave them out. Any other field you omit, including `title` and `collection`, is removed, and `status` falls back to `draft`. Read the article with `GET /api/kb/articles/detail` first and send every field back with your change.

```bash theme={null}
curl -X PATCH "https://back.leap.onclarity.com/api/kb/articles/update?article_id=482913570216" \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "How to return an item",
    "content": "You can return any item within 45 days of delivery.",
    "collection": "Returns",
    "status": "published"
  }'
```

The response is the updated article.

## Read, list, and delete

### Read one article

```bash theme={null}
curl "https://back.leap.onclarity.com/api/kb/articles/detail?article_id=482913570216" \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

An unknown id answers `404 article_not_found`.

### List articles

`POST /api/kb/articles/list` returns `{"list": [...], "total": N}`. Listed articles do not include `content`; read an article to get it.

```bash theme={null}
curl -X POST https://back.leap.onclarity.com/api/kb/articles/list \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "return",
    "filter": { "status": ["published"], "collection": ["Returns"] },
    "sort": { "key": "updated_at", "direction": "desc" },
    "limit": 50
  }'
```

**query** `string`

Text to search for in titles and content.

**filter** `object`

Field filters. A list matches any of its values. The keys Clarity's own Knowledge Base page uses are `status`, `collection`, `source`, `tags`, `updated_at` (`{"gte": "...", "lte": "..."}`), and `validity_status` (any of `active`, `scheduled`, `expired`).

**sort** `object`

`{"key": "updated_at", "direction": "desc"}`. `direction` is `asc` or `desc`.

**limit** `integer` (default: 1000)

How many articles to return.

**retrieved\_ids** `integer[]`

Ids you already have. They are excluded, so sending the ids of the previous pages returns the next page.

**group\_by\_collection** `boolean` (default: false)

Order by collection name first, then by `sort` within each collection.

### Delete an article

```bash theme={null}
curl -X DELETE "https://back.leap.onclarity.com/api/kb/articles/delete?article_id=482913570216" \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

The response has a `status` and an optional `message`.

## Upload a file

`POST /api/kb/articles/upload` takes a file as multipart form data, creates an article with `status: "processing"`, and converts the file to Markdown in the background. Poll the article with `GET /api/kb/articles/detail` until its status leaves `processing`. A converted PDF lands as a `draft`, or `error` if the conversion failed; publish it with an [update](#update-an-article).

```bash Request theme={null}
curl -X POST https://back.leap.onclarity.com/api/kb/articles/upload \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -F "file=@returns-policy.pdf" \
  -F "collection_name=Returns"
```

```json Response theme={null}
{
  "qdrant_article_id": 731004928811,
  "attachment_id": 88240,
  "original_file_name": "returns-policy.pdf",
  "s3_file_name": "9a7e1c0d2b4f4e8a.pdf",
  "download_url": "https://example-storage.invalid/kb/9a7e1c0d2b4f4e8a.pdf"
}
```

**file** `file` *required*

A PDF, or one of `.docx`, `.pptx`, `.xlsx`, `.xls`, `.csv`, `.tsv`, `.txt`, `.html`.

**collection\_name** `string` *required*

The collection for the new article.

`qdrant_article_id` is the new article's `id`. The request body can be up to 150 MB.

| Code | Status | Meaning |
| - | - | - |
| `kb_unsupported_file` | 400 | The file type is not supported. |
| `kb_documents_unavailable` | 422 | Your organization can upload PDFs but not other documents. `GET /api/kb/meta` tells you which (`documents_upload_available`). |

## Collections and values in use

`GET /api/kb/meta` returns:

```json theme={null}
{
  "field_info": {
    "confidence": { "unique_values": [] },
    "criticality": { "unique_values": [] },
    "tags": { "unique_values": ["returns", "shipping"] },
    "collection": { "unique_values": ["Returns", "Billing"] }
  },
  "collections": [
    { "value": "Returns", "count": 12 },
    { "value": "Billing", "count": 7 }
  ],
  "documents_upload_available": true
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.