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

# Refreshing Content

> Re-index a knowledge base and replace updated documents

A source is indexed once, when you add it. **Nothing re-crawls or re-reads it on a
schedule.** If a web page is edited or a document is revised after it was added, the
agent keeps answering from the version that was indexed until you refresh it.

## Which operation do I need?

| What changed | Use |
| - | - |
| A web page behind a **URL source** was edited | [Re-index the knowledge base](#re-index-a-knowledge-base), or [re-ingest that one source](/api-reference/knowledge-bases/source-actions#re-ingest-a-source) |
| A **document you uploaded** was revised | [Replace the source file](#replace-a-source-file) |
| You added brand-new content | Nothing — [creating a source](/api-reference/knowledge-bases/sources) indexes it automatically |

<Warning>
  Re-indexing a **file** source re-reads the copy already stored for it, which does not
  change. It cannot pick up edits you made to the document on your own systems — use
  [Replace a Source File](#replace-a-source-file) for that.
</Warning>

## Re-index a Knowledge Base

`POST /v1/knowledge-bases/{knowledgeBaseId}/reingest`

Queues a rebuild for every source in the knowledge base in one call. Takes no request
body. URL sources are re-fetched from their live page; file sources are re-processed
from their stored copy.

Sources that already have a recent queued or running job are left alone and listed in
`skipped`, so calling this twice in a row is safe.

A source keeps its existing vectors through the slow part of the run — download,
extraction, chunking and embedding — and swaps them only at the end, so the window in
which it is not searchable is brief rather than instant. Other sources in the knowledge
base are unaffected, since the worker processes one source at a time.

<ParamField path="knowledgeBaseId" type="string" required>
  Knowledge base ID (UUID).
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.telzino.com/v1/knowledge-bases/11111111-1111-1111-1111-111111111111/reingest \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "sourceCount": 3,
      "jobs": [
        { "sourceId": "22222222-2222-2222-2222-222222222222", "jobId": "33333333-3333-3333-3333-333333333333" },
        { "sourceId": "44444444-4444-4444-4444-444444444444", "jobId": "55555555-5555-5555-5555-555555555555" }
      ],
      "skipped": [
        { "sourceId": "66666666-6666-6666-6666-666666666666", "reason": "already_in_progress" }
      ]
    }
  }
  ```
</ResponseExample>

A knowledge base with no sources returns `sourceCount: 0` and empty arrays.

A knowledge base with **more than 100 sources** returns `400` with code
`too_many_sources`; re-ingest those sources individually instead. The limit exists
because ingestion is processed one job at a time. Nothing is queued when this happens —
the call fails rather than silently refreshing the first 100.

```json 400 theme={null}
{
  "error": "too_many_sources",
  "error_description": "This knowledge base has 137 sources; a single refresh is limited to 100. Re-ingest sources individually instead."
}
```

### Following progress

Poll each returned `jobId` with [Job Status](/api-reference/knowledge-bases/job-status),
or poll [List Sources](/api-reference/knowledge-bases/sources) and wait for every source
to leave `pending`. A finished source returns to `active` with a fresh `last_synced_at`;
one that failed becomes `error` with the reason on its job.

<Warning>
  **A refresh that extracts no text is reported as a failure, and the old content keeps
  serving.** The job ends `failed` with the reason in `error_text`, and the source becomes
  `error` — it does **not** return to `active`.

  The previously indexed content is deliberately left in place, so the agent keeps
  answering from the older version rather than losing the knowledge base to a temporary
  fetch problem. Because nothing was re-indexed, `chunk_count` and `last_synced_at` keep
  their previous values and continue to describe the content that is actually being used.

  Common causes: a URL that now returns 404 or blocks crawlers, a page whose content could
  not be summarised, or a replacement document that is a scanned image with no text layer.
  Fix the source and refresh again — an `error` source stays eligible for future refreshes.
</Warning>

## Replace a Source File

`POST /v1/knowledge-sources/{sourceId}/replace`

Uploads a new version of an existing file source's document, overwriting the stored
copy. The source keeps its id, so anything referencing it keeps working, and no
outdated duplicate is left indexed alongside the new version.

Only **file** sources can be replaced. A URL source returns `400` — re-ingest it
instead, which re-fetches the live page.

<ParamField body="fileName" type="string" required>
  Name of the replacement file. Becomes the source's new display name.
</ParamField>

<ParamField body="fileMime" type="string" required>
  MIME type of the replacement file. May differ from the original — you can replace a
  PDF with a DOCX. Must be one of the [supported types](/api-reference/knowledge-bases/sources):
  `application/pdf`, the DOCX type, `text/plain`, `text/markdown`, `text/html` or
  `text/csv`. Anything else returns `400`.
</ParamField>

<ParamField body="fileSize" type="integer" required>
  Size in bytes. Maximum 50 MB.
</ParamField>

<ParamField body="contentHash" type="string">
  Optional hash of the new contents, stored for later duplicate detection.
</ParamField>

Three steps, mirroring file source creation:

<Steps>
  <Step title="Request the upload">
    `POST` here to get a `presignedUrl` and a `jobId`. This immediately renames the
    source to `fileName` and marks it `pending`, so complete all three steps — stopping
    after this one leaves the source described by metadata that does not match its
    stored content.
  </Step>

  <Step title="Upload the file">
    `PUT` the file bytes to `presignedUrl`, sending a `Content-Type` header matching
    `fileMime` — the signature is bound to it and S3 rejects a mismatch. The URL is
    valid for **5 minutes**. Until this succeeds the previous bytes stay in place and
    searchable.
  </Step>

  <Step title="Rebuild the vectors">
    `POST /v1/knowledge-sources/{sourceId}/enqueue` with that `jobId` and
    `forceReindex: true`.
  </Step>
</Steps>

<RequestExample>
  ```bash 1. Request the upload theme={null}
  curl -X POST https://api.telzino.com/v1/knowledge-sources/22222222-2222-2222-2222-222222222222/replace \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "fileName": "handbook-v2.pdf",
      "fileMime": "application/pdf",
      "fileSize": 248112
    }'
  ```

  ```bash 2. Upload the bytes theme={null}
  curl -X PUT "PRESIGNED_URL_FROM_RESPONSE" \
    -H "Content-Type: application/pdf" \
    --data-binary @handbook-v2.pdf
  ```

  ```bash 3. Rebuild theme={null}
  curl -X POST https://api.telzino.com/v1/knowledge-sources/22222222-2222-2222-2222-222222222222/enqueue \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{ "jobId": "JOB_ID_FROM_STEP_1", "forceReindex": true }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "sourceId": "22222222-2222-2222-2222-222222222222",
      "jobId": "33333333-3333-3333-3333-333333333333",
      "presignedUrl": "https://s3.amazonaws.com/...",
      "fileKey": "rag/org/kb/source/original.pdf"
    }
  }
  ```
</ResponseExample>

## In the Dashboard

The same two operations are on the knowledge base page:

* **Refresh all** above the source list re-indexes every source.
* The upload control on a file source's row replaces its document with an updated one.

Refresh all reports how many sources it queued and shows each row's **Status** as it
works. Re-ingesting or replacing a single source additionally shows that job's stage and
chunk counts.


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