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

# POST /v1/knowledge/documents

> Create a document from Markdown. The content is converted to BlockNote and reindexed for search.

Creates a document in the knowledge base from Markdown. The API converts the Markdown to BlockNote (the editor format used by the portal) and triggers a reindex of the vector store and the full-text index so the document becomes immediately available in [`POST /v1/knowledge/search`](/dev/endpoints/knowledge-search).

The reindex is enqueued asynchronously in the processing service; the endpoint returns as soon as the document is persisted. Search may take a few seconds to surface the new content (depends on the queue).

## Endpoint

```
POST https://api.keebai.com/v1/knowledge/documents
```

## Required scope

`knowledge:write`

## Headers

| Header          | Required | Value                    |
| --------------- | -------- | ------------------------ |
| `Authorization` | Yes      | `Bearer kbai_pk_<token>` |
| `Content-Type`  | Yes      | `application/json`       |

## Body

| Field       | Type     | Required | Description                                                                                               |
| ----------- | -------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `title`     | `string` | Yes      | Document title. Max. 200 characters.                                                                      |
| `parent_id` | `string` | No       | `ObjectId` of the parent folder. Omit to create at the root.                                              |
| `markdown`  | `string` | Yes      | Markdown content. Supports headings (`# ##  ###`), lists (bulleted, numbered, and task lists) and tables. |

## Example request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.keebai.com/v1/knowledge/documents \
    -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Política de devolución",
      "parent_id": "65f3a1b2c3d4e5f6a7b8c9d0",
      "markdown": "# Política de devolución\n\nLas devoluciones se aceptan dentro de los **10 días** posteriores a la compra.\n\n## Pasos\n\n1. Contactar a soporte.\n2. Adjuntar la boleta.\n3. Enviar el producto."
    }'
  ```

  ```js JavaScript theme={null}
  const resp = await fetch("https://api.keebai.com/v1/knowledge/documents", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KEEBAI_API_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: "Política de devolución",
      parent_id: "65f3a1b2c3d4e5f6a7b8c9d0",
      markdown: "# Política de devolución\n\nLas devoluciones se aceptan dentro de los **10 días** posteriores a la compra.",
    }),
  });
  const document = await resp.json();
  ```

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

  resp = requests.post(
      "https://api.keebai.com/v1/knowledge/documents",
      headers={
          "Authorization": f"Bearer {os.environ['KEEBAI_API_TOKEN']}",
          "Content-Type": "application/json",
      },
      json={
          "title": "Política de devolución",
          "parent_id": "65f3a1b2c3d4e5f6a7b8c9d0",
          "markdown": "# Política de devolución\n\nLas devoluciones se aceptan dentro de los **10 días** posteriores a la compra.",
      },
      timeout=15,
  )
  resp.raise_for_status()
  document = resp.json()
  ```
</CodeGroup>

## Response

### 201 Created

```json theme={null}
{
  "id": "65f3a1b2c3d4e5f6a7b8c9d3",
  "title": "Política de devolución",
  "node_type": "document",
  "parent_id": "65f3a1b2c3d4e5f6a7b8c9d0",
  "position": 0,
  "path_cache": "/Soporte/Política de devolución",
  "created_at": "2026-04-27T15:35:00.000Z",
  "updated_at": "2026-04-27T15:35:00.000Z"
}
```

| Field        | Type     | Description                         |
| ------------ | -------- | ----------------------------------- |
| `id`         | `string` | `ObjectId` of the created document. |
| `node_type`  | `string` | Always `document`.                  |
| `path_cache` | `string` | Absolute path computed at creation. |

### 400 / 401 / 403 / 404 / 429

* `400 BAD_REQUEST`: `title` or `markdown` empty, `parent_id` points to a document.
* `403 FORBIDDEN` with `code: INSUFFICIENT_SCOPE`: the PAT doesn't have `knowledge:write`.
* `404 NOT_FOUND`: `parent_id` doesn't exist or belongs to another company.

<Tip>
  To make sure the document is available to assistants, assign it with [`POST /v1/knowledge/assignments`](/dev/endpoints/knowledge-assign). The content is always searchable via the `knowledge:query` scope even if it isn't assigned to any assistant.
</Tip>


## OpenAPI

````yaml POST /v1/knowledge/documents
openapi: 3.0.0
info:
  title: Keebai Public API
  description: Superficie pública REST autenticada con Personal Access Tokens (PAT).
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.keebai.com
    description: Production
security: []
tags: []
paths:
  /v1/knowledge/documents:
    post:
      tags:
        - knowledge
      summary: >-
        Crear un documento desde markdown. El contenido se convierte a BlockNote
        y se reindexa para búsquedas.
      operationId: PublicKnowledgeController_createDocument
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDocumentDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KnowledgeNodeDto'
      security:
        - PAT: []
components:
  schemas:
    CreateDocumentDto:
      type: object
      properties:
        title:
          type: string
          description: Título del documento.
          example: Política de devolución
          maxLength: 200
        parent_id:
          type: string
          description: ObjectId de la carpeta padre. Omitir para crear en la raíz.
        markdown:
          type: string
          description: Contenido en Markdown. Se convierte a BlockNote JSON al guardar.
          example: |-
            # Política

            Texto de la política...
      required:
        - title
        - markdown
    KnowledgeNodeDto:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        node_type:
          type: string
          enum:
            - folder
            - document
        parent_id:
          type: object
          nullable: true
        position:
          type: number
        path_cache:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - title
        - node_type
        - position
        - path_cache
  securitySchemes:
    PAT:
      scheme: bearer
      bearerFormat: kbai_pk_<hex>
      type: http
      description: >-
        Personal Access Token con prefijo `kbai_pk_`. Generar desde el portal
        con permiso `developer.manage_tokens`.

````