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

# AI Knowledge Tools

> Reference for the knowledge:manage tools — curate the FAQs, products, and promos your AI answers from, and tune the always-on business profile.

These eight tools sit under the `knowledge:manage` scope. They let a coding agent curate the two things your AI answers from: the **knowledge entries** it retrieves (FAQs, products, promos) and the always-on **business profile** that shapes every reply. In Sapot Chat this is the same AI Knowledge subsystem the dashboard authors into and the flow-agent runtime retrieves from.

<Info>
  All tools require the `knowledge:manage` scope. A key without it gets `Access token is missing the required scope: knowledge:manage` — grant the scope in **Settings → API & Agents**, or see [Authentication & Scopes](/ai-agents/authentication).
</Info>

## The knowledge model

Knowledge is authored as **entries**, each in exactly one **category**:

| Category  | What it is                    | Category-specific fields                                                 |
| --------- | ----------------------------- | ------------------------------------------------------------------------ |
| `faq`     | A question the AI can answer  | —                                                                        |
| `product` | A product the AI can describe | `price_cents` (minor units, e.g. `1999`), `currency` (ISO, e.g. `"MYR"`) |
| `promo`   | A time-bounded offer          | `valid_from`, `valid_until` (ISO8601)                                    |

<Warning>
  **Category is fixed at creation.** `update_knowledge_entry` cannot change an entry's category — create a new entry (and delete the old one) to move content between categories.
</Warning>

<Note>
  **Agent-created entries are created already approved**, so the AI can use them immediately — there is no pending step to clear. `approve_knowledge_entry` exists for entries that arrived pending from another source.
</Note>

***

## Entry tools

### list\_knowledge\_entries

List knowledge entries (25 per page) — the content the AI answers from.

| Argument   | Type   | Description                                           |
| ---------- | ------ | ----------------------------------------------------- |
| `category` | string | Filter to `faq`, `product`, or `promo`. Omit for all. |
| `status`   | string | Filter to `approved` or `pending`. Omit for all.      |
| `search`   | string | Substring match on question OR answer.                |
| `page`     | int    | 1-based page number (default `1`).                    |

**Returns** `{data: [entry, …], meta: {total_count, page}}`. Each entry carries `id`, `category`, `question`, `answer`, `remarks`, `status`, `embedded`, `price_cents`, `currency`, `valid_from`, `valid_until`.

### search\_knowledge

Semantic search over **approved** knowledge — a preview of what the AI would actually retrieve for a question.

| Argument   | Type   | Description                                          |
| ---------- | ------ | ---------------------------------------------------- |
| `query`    | string | The natural-language question to search for.         |
| `category` | string | Optionally restrict to `faq`, `product`, or `promo`. |

**Returns** `{text_context: str, entries: [...]}`.

<Tip>
  This is the **same retrieval the runtime uses**, not a separate index. Run it to sanity-check that a new or edited entry is discoverable for the questions customers actually ask, before trusting it in production.
</Tip>

### create\_knowledge\_entry

Create a knowledge entry (created already approved, so the AI can use it immediately).

| Argument      | Type   | Description                                                           |
| ------------- | ------ | --------------------------------------------------------------------- |
| `category`    | string | **Required.** `faq`, `product`, or `promo`.                           |
| `question`    | string | **Required.** The FAQ question, or the product/promo name/title.      |
| `answer`      | string | **Required.** The answer text, or the product/promo description.      |
| `price_cents` | int    | **Product only.** Price in minor units (e.g. `1999`).                 |
| `currency`    | string | **Product only.** ISO currency code (e.g. `"MYR"`).                   |
| `valid_from`  | string | **Promo only.** ISO8601 timestamp — when the promo starts.            |
| `valid_until` | string | **Promo only.** ISO8601 timestamp — when the promo ends.              |
| `remarks`     | string | Optional extra notes folded into the embedding (useful for products). |

**Returns** the created entry.

### update\_knowledge\_entry

Update a knowledge entry. Only the fields you pass are changed.

| Argument      | Type   | Description                                                   |
| ------------- | ------ | ------------------------------------------------------------- |
| `entry_id`    | int    | **Required.** The entry's id (from `list_knowledge_entries`). |
| `question`    | string | New question / name.                                          |
| `answer`      | string | New answer / description.                                     |
| `price_cents` | int    | Product price in minor units.                                 |
| `currency`    | string | Product ISO currency code.                                    |
| `valid_from`  | string | Promo start (ISO8601).                                        |
| `valid_until` | string | Promo end (ISO8601).                                          |
| `remarks`     | string | Notes folded into the embedding.                              |

**Returns** the updated entry. Category cannot be changed here — create a new entry instead.

### approve\_knowledge\_entry

Approve a pending knowledge entry so the AI starts using it.

| Argument   | Type | Description                   |
| ---------- | ---- | ----------------------------- |
| `entry_id` | int  | **Required.** The entry's id. |

**Returns** the updated (approved) entry.

### delete\_knowledge\_entry

Delete a knowledge entry permanently.

| Argument   | Type | Description                   |
| ---------- | ---- | ----------------------------- |
| `entry_id` | int  | **Required.** The entry's id. |

**Returns** `{}` on success.

***

## Profile tools

The **profile** is the always-on business and AI-behaviour layer — one row per account, not retrieved per-question. It is injected into the AI's system prompt on every reply, so a small change here affects every conversation.

### get\_knowledge\_profile

Get the account's always-on business + AI-behaviour profile. Takes no arguments.

**Returns** `business_name`, `identity`, `hours`, `location`, `contact`, `tone_preset`, `formality`, `emoji_enabled`, `use_shortform`, `custom_instructions`, `content_languages`, `prohibitions`, and a read-only `compiled_prompt` — a preview of exactly what gets injected into the AI's system prompt.

<Note>
  `compiled_prompt` is **read-only**. It is derived from the other fields; edit the inputs (tone, prohibitions, business info) and read it back to see the result — you cannot set it directly.
</Note>

### update\_knowledge\_profile

Update the business + AI-behaviour profile. Only the fields you pass are changed.

| Argument              | Type          | Description                                                                  |
| --------------------- | ------------- | ---------------------------------------------------------------------------- |
| `business_name`       | string        | The business name.                                                           |
| `identity`            | string        | Who the AI is / how it should present itself.                                |
| `tone_preset`         | string        | One of `friendly`, `professional`, `casual`, `caring`, `playful`, `concise`. |
| `formality`           | string        | `formal` or `casual`.                                                        |
| `emoji_enabled`       | bool          | Whether the AI may use emoji.                                                |
| `use_shortform`       | bool          | Whether the AI may use short-form / abbreviated replies.                     |
| `custom_instructions` | string        | Free-form extra guidance.                                                    |
| `hours`               | dict          | Free-form key/value object, e.g. `{"mon_fri": "9am-6pm"}`.                   |
| `location`            | dict          | Free-form key/value object.                                                  |
| `contact`             | dict          | Free-form key/value object.                                                  |
| `content_languages`   | list\[string] | Languages the AI should reply in, e.g. `["en", "ms"]`.                       |
| `prohibitions`        | list\[string] | Things the AI must never do or say.                                          |

**Returns** the updated profile, with a fresh `compiled_prompt` preview.

***

## What is deliberately not here

<Warning>
  This scope is **plain CRUD + approve, on purpose.** AI-generation, bulk operations, and document import are intentionally **not** exposed to agent tokens — they carry LLM cost and a large blast radius. An agent authors and curates entries one at a time; generate-from-documents and bulk import stay in the dashboard.
</Warning>

## Recipe: keep the knowledge base fresh

<Steps>
  <Step title="Mine resolved conversations">
    Read recent resolved threads for questions that keep recurring.
  </Step>

  <Step title="Create the entry">
    `create_knowledge_entry(category="faq", question, answer)` — it is live immediately (already approved). For a product, use `category="product"` with `price_cents` and `currency`.
  </Step>

  <Step title="Verify retrieval">
    `search_knowledge(query="…")` with the phrasing a customer would use — confirm your new entry comes back in `entries` and lands in `text_context`.
  </Step>
</Steps>

## Related

<CardGroup cols={3}>
  <Card title="Authentication & Scopes" icon="key" href="/ai-agents/authentication">
    The default-deny scope model behind `knowledge:manage`.
  </Card>

  <Card title="The Agent Skill" icon="sparkles" href="/ai-agents/agent-skill">
    A companion skill so the agent drives these tools correctly.
  </Card>

  <Card title="REST API" icon="book" href="/api-reference/introduction">
    Call the same endpoints directly with a scoped key.
  </Card>
</CardGroup>
