---
title: "Knowledge API"
description: "Add knowledge to your minds through files, keywords, or links. List, update, and delete items that are embedded and retrieved automatically in chats."
---

# Knowledge API

Add knowledge to your minds via three methods: **File**, **Keyword**, or **Link**. Knowledge is processed, embedded, and automatically retrieved during conversations.

**Note:** List, add, and delete are available via the v1 API. Knowledge enrichment via keyword search is also supported through the same add endpoint.

---

## List Knowledge Items

Retrieve all knowledge items for a mind.

**Endpoint:** `GET /api/v1/minds/{mindId}/knowledge`

**Headers:**

```text
Authorization: Bearer minds_your_api_key
```

**Example:**

```bash
curl -X GET "https://getminds.ai/api/v1/minds/{mindId}/knowledge" \
  -H "Authorization: Bearer minds_your_api_key"
```

**Response:**

```json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "description": "Company Employee Handbook 2025",
        "link": null,
        "filePath": "portfolio/user-id/1234567890_handbook.pdf",
        "isWatched": false,
        "createdAt": "2025-12-10T12:00:00.000Z",
        "updatedAt": "2025-12-10T12:00:00.000Z"
      }
    ],
    "total": 1
  }
}
```

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        data.items
      </code>
    </td>
    
    <td>
      array
    </td>
    
    <td>
      Array of knowledge item objects
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        data.total
      </code>
    </td>
    
    <td>
      number
    </td>
    
    <td>
      Total count of knowledge items for this mind
    </td>
  </tr>
</tbody>
</table>

---

## File Upload

Upload documents or images directly to a mind.

**Endpoint:** `POST /api/v1/minds/{mindId}/knowledge`

**Content-Type:** `multipart/form-data`

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        file
      </code>
    </td>
    
    <td>
      file
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      File to upload (max 50MB)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      string
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      Description of the content
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        regeneratePrompt
      </code>
    </td>
    
    <td>
      boolean
    </td>
    
    <td>
      No
    </td>
    
    <td>
      Regenerate the Mind prompt only after embeddings and patterns finish successfully. Default: <code>
        false
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

**Supported formats:**

- Documents: PDF, DOCX, DOC, TXT, MD, RTF, CSV, JSON, XML
- Images: JPG, JPEG, PNG, GIF, WEBP

**Example:**

```bash
curl -X POST "https://getminds.ai/api/v1/minds/{mindId}/knowledge" \
  -H "Authorization: Bearer minds_your_api_key" \
  -F "file=@./handbook.pdf" \
  -F "description=Company Employee Handbook 2025"
```

API and MCP clients that already have a public, signed, or Minds workspace upload URL can submit the same file as JSON. The server applies SSRF protection and the same 50MB limit before queuing the canonical ingestion workflow:

```json
{
  "file": {
    "name": "handbook.pdf",
    "url": "https://files.example.com/signed/handbook.pdf",
    "type": "application/pdf"
  },
  "description": "Company Employee Handbook 2025",
  "regeneratePrompt": false
}
```

**Response:** `202 Accepted`

```json
{
  "success": true,
  "data": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "description": "Company Employee Handbook 2025",
    "filePath": "portfolio/user-id/1234567890_handbook.pdf",
    "createdAt": "2025-12-10T12:00:00.000Z",
    "processing": { "status": "queued", "regeneratePrompt": false },
    "statusUrl": "/api/v1/minds/{mindId}/knowledge/660e8400-e29b-41d4-a716-446655440001/status"
  }
}
```

---

## Keyword Search

Add knowledge by searching the web for keywords. Searches Exa and YouTube, extracts content, and adds it to the mind's knowledge base.

**Endpoint:** `POST /api/v1/minds/{mindId}/knowledge`

**Content-Type:** `application/json`

Send a JSON body with a `keywords` array (instead of `link`/`file`) to trigger web search enrichment.

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        keywords
      </code>
    </td>
    
    <td>
      string<span>
        
      </span>
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      Keywords to search (the first 15 are used; extra keywords are dropped)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        regeneratePrompt
      </code>
    </td>
    
    <td>
      boolean
    </td>
    
    <td>
      No
    </td>
    
    <td>
      Regenerate system prompt after (default: true)
    </td>
  </tr>
</tbody>
</table>

**Example:**

```bash
curl -X POST "https://getminds.ai/api/v1/minds/{mindId}/knowledge" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["solar panel efficiency", "photovoltaic trends"]}'
```

**Response:** `202 Accepted`

```json
{
  "success": true,
  "data": {
    "sparkId": "660e8400-e29b-41d4-a716-446655440000",
    "keywords": ["solar panel efficiency", "photovoltaic trends"],
    "queued": true,
    "regeneratePrompt": true,
    "message": "Knowledge enrichment queued with 2 keyword(s)."
  }
}
```

**Note:** This is asynchronous. Processing runs in background and may take several minutes.

---

## Link

Add knowledge from a URL. Supports web pages, YouTube videos, and research papers.

**Endpoint:** `POST /api/v1/minds/{mindId}/knowledge`

**Content-Type:** `application/json`

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        link
      </code>
    </td>
    
    <td>
      string
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      URL to web content
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      string
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      Description of the content
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        regeneratePrompt
      </code>
    </td>
    
    <td>
      boolean
    </td>
    
    <td>
      No
    </td>
    
    <td>
      Regenerate the Mind prompt only after ingestion succeeds. Default: <code>
        false
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

**Example:**

```bash
curl -X POST "https://getminds.ai/api/v1/minds/{mindId}/knowledge" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"link": "https://example.com/article", "description": "Industry trends article"}'
```

**Response:** `202 Accepted`

```json
{
  "success": true,
  "data": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "link": "https://example.com/article",
    "description": "Industry trends article",
    "createdAt": "2025-12-10T12:00:00.000Z",
    "processing": { "status": "queued", "regeneratePrompt": false },
    "statusUrl": "/api/v1/minds/{mindId}/knowledge/660e8400-e29b-41d4-a716-446655440001/status"
  }
}
```

**Supported link types:**

- Web pages (content extracted via scraping)
- YouTube videos (transcripts extracted automatically)
- Research papers (arxiv, etc.)

---

## Processing Status

File and link uploads are accepted durably and processed by the background worker. Poll the returned `statusUrl` before using `sourcePolicy: "knowledge_only"`.

**Endpoint:** `GET /api/v1/minds/{mindId}/knowledge/{itemId}/status`

```json
{
  "data": {
    "itemId": "660e8400-e29b-41d4-a716-446655440001",
    "sparkId": "550e8400-e29b-41d4-a716-446655440000",
    "description": "Company Employee Handbook 2025",
    "status": "completed",
    "readyForRetrieval": true,
    "embeddings": 12,
    "patterns": 5,
    "promptRegenerated": true,
    "updatedAt": "2026-08-05T15:30:00.000Z"
  }
}
```

Statuses are `queued`, `running`, `completed`, `failed`, or `unknown` for legacy items without recorded processing metadata. A completed item is retrieval-ready only when it has at least one embedding.

The readiness fields have distinct meanings:

- `data.status` is the durable background-processing state.
- `data.readyForRetrieval` is `true` only when processing completed and at least one embedding exists. Use this as the chat readiness gate.
- `data.embeddings` is the number of stored retrieval embeddings for this item.
- `data.patterns` is the number of thinking-pattern rows extracted from this item. It can be `0` even when retrieval is ready.
- `data.error` contains processing failure detail when `status` is `failed`, if the worker recorded one.
- `data.promptRegenerated` reports whether the optional prompt-regeneration step completed. It is present only when recorded by processing.

The endpoint returns `401` for a missing or invalid API key, `403` when the caller cannot access the Mind, and `404` when the knowledge item does not belong to that Mind.

---

## Watch (Auto-Update)

Link-based knowledge items can be "watched" to automatically check for content updates on a weekly cycle. When changes are detected, knowledge is reprocessed and re-embedded.

Watch is managed through the product UI. Watch status is visible when listing knowledge items via the API (`isWatched` field).

**Note:** Watch is only available for link-based knowledge, not files or keyword searches.

---

## Update Knowledge Item

Update the description of an existing knowledge item.

**Endpoint:** `PUT /api/v1/minds/{mindId}/knowledge/{itemId}`

**Headers:**

```text
Authorization: Bearer minds_your_api_key
Content-Type: application/json
```

**Request Body:**

```json
{
  "description": "Updated description for this knowledge item"
}
```

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      string
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      Updated description (must not be empty)
    </td>
  </tr>
</tbody>
</table>

**Example:**

```bash
curl -X PUT "https://getminds.ai/api/v1/minds/{mindId}/knowledge/{itemId}" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"description": "Updated handbook description"}'
```

**Response:**

```json
{
  "success": true,
  "data": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "description": "Updated handbook description",
    "link": null,
    "filePath": "portfolio/user-id/1234567890_handbook.pdf",
    "isWatched": false,
    "createdAt": "2025-12-10T12:00:00.000Z",
    "updatedAt": "2025-12-15T08:30:00.000Z"
  }
}
```

### Error Responses

**400 Bad Request** - No valid fields to update or empty description

**401 Unauthorized** - Invalid or missing API key

**404 Not Found** - Knowledge item or mind not found

---

## Enrich via Keywords (Convenience)

Convenience alias for keyword-based knowledge enrichment.

**Endpoint:** `POST /api/v1/minds/{mindId}/knowledge/enrich`

This is equivalent to `POST /api/v1/minds/{mindId}/knowledge` with a `keywords` body. See [Keyword Search](#keyword-search) for full details.

**Example:**

```bash
curl -X POST "https://getminds.ai/api/v1/minds/{mindId}/knowledge/enrich" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["solar panel efficiency", "photovoltaic trends"]}'
```

---

## Delete Knowledge Item

Permanently delete a knowledge item and all associated data (embeddings, patterns, files).

**Endpoint:** `DELETE /api/v1/minds/{mindId}/knowledge/{itemId}`

**Headers:**

```text
Authorization: Bearer minds_your_api_key
```

**Example:**

```bash
curl -X DELETE "https://getminds.ai/api/v1/minds/{mindId}/knowledge/{itemId}" \
  -H "Authorization: Bearer minds_your_api_key"
```

**Response:** `204 No Content` (empty body on success)

### What Gets Deleted

- The knowledge item record
- All associated vector embeddings
- All associated patterns
- Uploaded file from storage (if file-based)

**Warning:** This action cannot be undone.

---

## How Processing Works

1. **Upload** - Content is stored and API returns success
2. **Extraction** - Background processing extracts text (scraping, transcripts, OCR, vision)
3. **Embedding** - Content is converted to vector embeddings
4. **Retrieval** - During chat, relevant knowledge is automatically retrieved by semantic search

---

## Errors

<table>
<thead>
  <tr>
    <th>
      Code
    </th>
    
    <th>
      Message
    </th>
    
    <th>
      Cause
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      400
    </td>
    
    <td>
      <code>
        Link and description are required
      </code>
    </td>
    
    <td>
      Missing required fields
    </td>
  </tr>
  
  <tr>
    <td>
      400
    </td>
    
    <td>
      <code>
        keywords array is required and must not be empty
      </code>
    </td>
    
    <td>
      Empty or missing keywords
    </td>
  </tr>
  
  <tr>
    <td>
      400
    </td>
    
    <td>
      <code>
        File too large
      </code>
    </td>
    
    <td>
      File exceeds 50MB limit
    </td>
  </tr>
  
  <tr>
    <td>
      400
    </td>
    
    <td>
      <code>
        Can only watch link-based knowledge
      </code>
    </td>
    
    <td>
      Tried to watch a file
    </td>
  </tr>
  
  <tr>
    <td>
      404
    </td>
    
    <td>
      <code>
        Mind not found or access denied
      </code>
    </td>
    
    <td>
      Invalid Mind ID or no access
    </td>
  </tr>
  
  <tr>
    <td>
      415
    </td>
    
    <td>
      <code>
        Unsupported Content-Type
      </code>
    </td>
    
    <td>
      Wrong Content-Type header
    </td>
  </tr>
</tbody>
</table>

---

## Next Steps

- [Chat with your mind](/docs/api/chat)
- [Create minds](/docs/api/minds)
- [API errors and limits](/docs/api/errors)
