# Base de conhecimento



<ToolHero tool="base-de-conhecimento" />

## Visão geral

Uma **base** (collection) guarda documentos de texto ou Markdown. Cada documento é dividido em **seções** (pelos títulos) e **trechos** (pedaços de \~96 tokens), que são indexados de duas formas: por significado (embeddings) e por palavras-chave. A busca combina as duas e devolve os trechos mais relevantes, prontos para você passar a um modelo de linguagem (RAG) ou mostrar ao usuário.

<Steps>
  <Step>
    **Crie uma base** com o idioma dos documentos (melhora a busca por palavras-chave).
  </Step>

  <Step>
    **Alimente a base.** Envie texto ou Markdown, importe arquivos (PDF, Office, imagens) ou conecte uma fonte que se sincroniza sozinha (site, sitemap, repositório do GitHub, pasta do Google Drive). A indexação é assíncrona: acompanhe o `status` até `ready`. Reenviar com o mesmo `external_id` substitui a versão anterior sem tirar a base do ar.
  </Step>

  <Step>
    **Busque** com a pergunta do usuário e use os trechos devolvidos como contexto da resposta.
  </Step>

  <Step>
    **Responda com citações** (opcional): `answer` devolve um texto em que cada afirmação aponta para o trecho de origem, ou diz que não sabe. Para o seu site, embuta o [widget](#widget).
  </Step>

  <Step>
    **Registre feedback** (opcional): trechos confirmados sobem nas próximas buscas parecidas e os rejeitados somem.
  </Step>
</Steps>

<EndpointList tool="base-de-conhecimento" />

## Custos

<PricingTable tool="base-de-conhecimento" group="per-use" />

<PricingTable tool="base-de-conhecimento" group="free-quota" />

<PricingTable tool="base-de-conhecimento" group="blocks" />

<PricingTable tool="base-de-conhecimento" group="volume" />

<PricingTable tool="base-de-conhecimento" group="storage" />

<Callout title="Como funcionam os blocos">
  Buscas e rerank têm uma franquia grátis por dia. Depois dela, a chamada que abre um bloco debita o bloco inteiro de uma vez (10 chamadas no primeiro, depois 20, 50 e 100 conforme o uso pago do dia), e as próximas do mesmo bloco não cobram de novo. Os contadores zeram à meia-noite UTC, e as chamadas não usadas de um bloco expiram sem estorno. A ferramenta MCP `rag_get_usage` e o `dry_run` das buscas mostram quanto a próxima chamada cobra. Consultar bases, documentos e feedback é grátis e não entra na [franquia diária de leituras](/cobranca-e-limites#franquia-diaria).
</Callout>

A ingestão é cobrada **quando termina**, pelo número real de trechos; o `estimate` da resposta é uma aproximação. Conteúdo idêntico ao já indexado não é cobrado de novo. Use `X-Dry-Run: true` no envio de documento para ver a estimativa sem enviar nada.

## Bases

### Criar base

<Endpoint
  id="rag.collections.create"
  example={{ body: `{
"name": "Central de ajuda",
"description": "Artigos públicos de suporte",
"language": "portuguese",
"default_mode": "fast"
}` }}
>
  * `name` (obrigatório, até 120 caracteres) e `description` (até 1.000).
  * `language`: `simple` (padrão), `portuguese`, `english`, `spanish` ou `french`. Define o dicionário da busca por palavras-chave.
  * `default_mode`: `fast` (padrão) ou `accurate` (rerank extra, mais preciso e um pouco mais caro).
  * Ajustes avançados: `chunk_size_tokens` (16–480, padrão 96), `chunk_overlap_tokens` (padrão 16), `section_max_tokens` (padrão 768), `max_per_document` (0–20, padrão 2), `dense_weight` e `lexical_weight` (0–10, padrão 1; não podem ser os dois 0) e `feedback_enabled` (padrão `true`).
</Endpoint>

### Listar bases

<Endpoint id="rag.collections.list">
  Devolve também o uso da conta em relação aos limites (`usage`).
</Endpoint>

### Consultar base

<Endpoint id="rag.collections.get" />

### Filtros disponíveis

<Endpoint id="rag.collections.facets">
  Lista as chaves de metadados dos documentos da base e os valores mais comuns de cada uma, para você saber o que pode usar em `filters` nas buscas. `documents` é quantos documentos prontos com metadados foram analisados e `keys` é o total de chaves filtráveis. Se `sampled` for `true`, a base tem mais de 5000 documentos e a contagem vem só dos 5000 mais recentes. Em `facets`, cada item traz a `key`, os `documents` que a têm, `distinct` (total de valores distintos) e `values[]` (os valores mais comuns, cada um com `value` e `documents`). `array: true` indica que a chave guarda uma lista; filtre com `{"chave": ["valor"]}`.
</Endpoint>

### Alterar base

<Endpoint id="rag.collections.update" example={{ body: `{ "default_mode": "accurate" }` }}>
  Envie só os campos que quer mudar. O modelo de embeddings não pode ser trocado depois da criação. Mudanças no tamanho dos trechos só valem para documentos enviados depois; para aplicar à base inteira, use a reindexação.
</Endpoint>

### Reindexar base

<Endpoint id="rag.collections.reindex">
  Reprocessa todos os documentos com as configurações atuais da base. Cada trecho é cobrado como numa ingestão nova.
</Endpoint>

### Painel de saúde da base

<Endpoint id="rag.collections.overview" example={{ query: { rows: 'categoria', days: '30' } }}>
  Resumo para manter a base em ordem, sem custo: contagem de documentos por `status`, quantos estão desatualizados (`stale`), nunca foram consultados ou não têm metadados; uma matriz de documentos por metadado (`rows` e `cols` são chaves de metadado, até 20 valores por eixo); a atividade dos últimos `days` dias (1 a 180, padrão 30); e `attention`, com até 5 exemplos de documentos com falha, desatualizados, duplicados ou contraditórios e com feedback negativo. A resposta fica em cache por 60 s.
</Endpoint>

### Índice dos documentos

<Endpoint id="rag.collections.index" example={{ query: { fields: 'categoria', order: 'title' } }}>
  Lista compacta dos documentos `ready`, sem conteúdo, para o agente escolher o que ler. `filters` (JSON de metadados), `fields` (até 20 chaves de metadado a copiar), `order` (`updated_at_desc`, padrão, ou `title`) e `max_bytes` (padrão 4096, máximo 32768). `omitted` conta os documentos cortados pelo limite.
</Endpoint>

### Achar duplicados e contradições

<Endpoint id="rag.collections.lint" example={{ body: `{ "limit": 20 }` }}>
  Compara os 500 documentos mais recentes (opcionalmente filtrados por `filters`) com os embeddings que já existem; não chama modelo e não escreve nada. `duplicate` aparece com similaridade a partir de 0,75; `possible_contradiction`, entre 0,4 e 0,75 quando os dois têm o mesmo metadado `tipo`. Cada achado diz qual documento manter (`keep`, o mais novo) e o que fazer (`action`). `limit` vai de 1 a 100 (padrão 20) e `include_content: true` devolve o início de cada documento.
</Endpoint>

### Trocar o modelo de embeddings

<Endpoint id="rag.collections.model" example={{ body: `{ "embedding_model": "BAAI/bge-m3" }` }}>
  Troca entre `intfloat/multilingual-e5-small` (padrão) e `BAAI/bge-m3` (Alta precisão) reindexando a base **em segundo plano**; você não precisa chamar a reindexação. A troca custa 50% do preço normal de ingestão, e voltar ao modelo anterior é grátis enquanto ela roda e por 24 h depois, uma vez. Use `X-Dry-Run: true` para ver a estimativa. Durante a troca a busca continua funcionando (a consulta é embutida com os dois modelos) e documentos novos são recusados com `rag.model_switch_in_progress`. Acompanhe pelo campo `model_switch` da base (`running`, `paused` ou `done`); se o saldo acabar, ela pausa com `paused_reason: insufficient_credits` e retoma quando você recarregar.
</Endpoint>

### Marcar documentos como desatualizados

<Endpoint id="rag.collections.changes" example={{ body: `{ "paths": ["docs/api/", "src/auth.ts"], "commit": "a1b2c3d" }` }}>
  Para bases ligadas a código ou a arquivos: informe os `paths` que mudaram (arquivo exato ou prefixo `dir/`, até 1000) e os documentos que declararam esses `paths` ao serem enviados ficam com `stale: true`. Nada é reindexado nem cobrado; reenviar o documento limpa a marca. Use `exclude_stale` na busca para ignorá-los. `commit` (até 64 caracteres) evita marcar o que já foi conferido naquele commit.
</Endpoint>

### Excluir base

<Endpoint id="rag.collections.delete">
  A exclusão é assíncrona e apaga documentos, trechos e feedback.
</Endpoint>

## Documentos

### Adicionar ou substituir documento

<Endpoint
  id="rag.documents.add"
  example={{ body: `{
"external_id": "artigo-42",
"title": "Como trocar a senha",
"content": "# Conta\\n\\n## Como trocar a senha\\n\\nAcesse Configurações > Segurança…",
"source_uri": "https://ajuda.example.com/artigos/42",
"metadata": { "categoria": "conta" }
}` }}
>
  * `content` (obrigatório): texto puro ou Markdown em UTF-8, até <Limit name="ragDocumentMax" />. Para PDF, Office e imagens, use [Importar arquivo](#rag-documents-file).
  * `external_id` (opcional, até 200 bytes): o seu identificador. Reenviar com o mesmo valor **substitui** o documento; a versão anterior continua respondendo às buscas (`processing: true`) até a nova ficar pronta.
  * `paths` (até 50) e `commit`: os arquivos de onde o documento vem, para [marcá-lo como desatualizado](#rag-collections-changes) quando mudarem.
  * Segredos reconhecidos no texto (chaves de API, tokens) são trocados por `[REDACTED:tipo]` antes de indexar; `redactions` conta quantos.
  * `metadata`: objeto com até 50 chaves (4 KB, até 3 níveis), usado nos filtros da busca. Não é criptografado; não coloque dados sensíveis.
  * Acompanhe com [Consultar documento](#rag-documents-get) até `status: ready` (ou `failed`, com `error_code`). Antes de aceitar, a API confere se o saldo cobre a estimativa.
</Endpoint>

### Importar arquivo (PDF, Office, imagem)

<Endpoint id="rag.documents.file">
  Envio `multipart/form-data` com `file` (obrigatório, até 50 MB) e, opcionalmente, `title`, `external_id`, `source_uri`, `metadata` (objeto JSON em texto) e `ocr` (padrão `true`; desligue para PDFs que já têm texto). Formatos: `.pdf`, `.docx`, `.pptx`, `.xlsx`, `.html`, `.md`, `.csv`, `.asciidoc` e imagens (`.png`, `.jpg`, `.tiff`, `.bmp`, `.webp`). O arquivo é convertido em Markdown (tabelas preservadas, imagens só pelo texto do OCR) e depois indexado como qualquer documento, com o mesmo limite de <Limit name="ragDocumentMax" /> para o texto resultante. A resposta é `202` com o `id` da importação; consulte-a até `completed` (traz o `document_id`) ou `failed`. Sem conversão disponível, a resposta é `503` (`rag.service_unavailable`).
</Endpoint>

### Consultar importação de arquivo

<Endpoint id="rag.imports.get" />

### Listar documentos

<Endpoint id="rag.documents.list" example={{ query: { status: 'ready', limit: '20' } }}>
  Filtro opcional por `status` (`pending`, `processing`, `ready`, `failed`, `deleting`). Paginação por cursor: passe o `next_cursor` recebido em `after`. `limit` padrão 20, máximo 100.
</Endpoint>

### Consultar documento

<Endpoint id="rag.documents.get" />

### Alterar título ou metadados

<Endpoint id="rag.documents.update" example={{ body: `{ "metadata": { "categoria": "seguranca" } }` }}>
  Não reprocessa o conteúdo e não cobra nada.
</Endpoint>

### Ver seções indexadas

<Endpoint id="rag.documents.sections">
  Mostra como o documento foi dividido, útil para ajustar títulos e tamanho dos trechos.
</Endpoint>

### Reprocessar documento com falha

<Endpoint id="rag.documents.retry">
  Só para documentos com `status: failed`; os demais respondem `rag.document_not_failed`.
</Endpoint>

### Excluir documento

<Endpoint id="rag.documents.delete" />

## Fontes sincronizadas

Uma **fonte** importa páginas de fora e as mantém em dia: a cada sincronização, páginas novas ou alteradas são reindexadas, as inalteradas (mesmo conteúdo) não são cobradas de novo, e as que sumiram da origem são removidas da base. Cada página vira um documento comum (`external_id` `src:<id da fonte>:…`, com `source_id` e `source_url` nos metadados), cobrado por trecho como numa ingestão manual; se faltar saldo ou cota, a sincronização falha e mostra o motivo.

| `kind`    | `start_url`                      | O que importa                                                                                                                                                             |
| --------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `site`    | página inicial                   | Rastreia links do mesmo host até `max_depth`, respeitando o `robots.txt`; HTML vira Markdown e arquivos PDF/Office linkados são convertidos.                              |
| `sitemap` | URL do sitemap (ou índice)       | Importa as páginas listadas, até `max_pages`. `max_depth` não se aplica.                                                                                                  |
| `github`  | `https://github.com/dono/repo`   | Repositório **público**; `config.ref` (padrão `HEAD`) e `config.paths` (prefixos) filtram. Lê `.md`, `.mdx`, `.txt`, `.rst` e converte os formatos de arquivo suportados. |
| `gdrive`  | URL de uma pasta `/folders/<id>` | Pasta compartilhada como "qualquer pessoa com o link"; Docs viram Markdown. Só existe se o servidor tiver a integração ligada.                                            |

### Listar fontes sincronizadas

<Endpoint id="rag.sources.list" />

### Criar fonte sincronizada

<Endpoint
  id="rag.sources.create"
  example={{ body: `{
"kind": "site",
"name": "Central de ajuda",
"start_url": "https://ajuda.example.com",
"max_pages": 100,
"max_depth": 3,
"frequency_hours": 24
}` }}
>
  * `name` (até 200) e `start_url` (http ou https) são obrigatórios; `kind` padrão `site`.
  * `max_pages`: 1 a 1000 (padrão 100). `max_depth`: 1 a 10 (padrão 3).
  * `frequency_hours`: `0` (só manual), `6`, `24` (padrão) ou `168`.
  * A primeira sincronização começa na hora. Páginas e arquivos de até 20 MB cada; um arquivo que não converte é pulado sem falhar a sincronização.
</Endpoint>

### Alterar fonte

<Endpoint id="rag.sources.update" example={{ body: `{ "frequency_hours": 168, "enabled": true }` }}>
  Todos os campos são opcionais. Com `enabled: false` ou `frequency_hours: 0`, `next_sync_at` fica nulo.
</Endpoint>

### Sincronizar agora

<Endpoint id="rag.sources.sync">
  Responde `409` se a fonte já estiver sincronizando. `pages_total`, `pages_new`, `pages_changed` e `pages_removed` resumem a execução.
</Endpoint>

### Histórico de sincronizações

<Endpoint id="rag.sources.syncs" />

### Excluir fonte

<Endpoint id="rag.sources.delete" />

## Busca

### Modos de busca e reranker

* **`fast`** (padrão): combina a busca por significado e a por palavras-chave. O `score` é uma fusão de posições (valores pequenos, perto de 0,03), bom para ordenar, não para comparar com um limiar.
* **`accurate`**: depois da fusão, um **reranker** relê os 20 melhores candidatos junto com a pergunta e devolve um `score` calibrado de 0 a 1; só nele `min_score` tem efeito. Cobra o adicional de rerank. Se o rerank estiver indisponível, a busca cai para `fast` sem o adicional (`mode_used`).
* **Reranker**: `rerank_provider` da base (e `provider` no rerank avulso e no `decide`) escolhe entre `bge` (padrão, cross-encoder) e `laya`, o juiz de relevância da Respawn, que pergunta se o trecho responde à consulta e devolve a probabilidade. O Laya costuma separar melhor trechos que só se parecem com a pergunta, mas é mais lento e, se estiver fora do ar, o `accurate` cai para `fast` e o rerank avulso responde `503` (`rag.service_unavailable`). O preço é o mesmo do `bge`.
* Se o serviço de embeddings falhar, a busca ainda responde só por palavras-chave (`mode_used: lexical`), cobrada como cache.

### Buscar na base

<Endpoint
  id="rag.query"
  example={{ body: `{
"query": "como mudo minha senha?",
"top_k": 5,
"filters": { "categoria": "conta" }
}` }}
>
  * `query` (obrigatório, até <Limit name="ragQueryCharsMax" /> caracteres).
  * `top_k`: quantos trechos devolver (padrão 5, máximo <Limit name="ragTopKMax" />).
  * `mode`: `fast` ou `accurate`; sem ele, vale o padrão da base. Se o rerank do modo `accurate` estiver indisponível, a busca cai para `fast` sem cobrar o adicional; `mode_used` mostra o que foi usado.
  * `filters`: só trechos de documentos cujos metadados contêm estes valores.
  * `min_score` (só no `accurate`) e `max_per_document` (0–20) refinam o resultado.
  * `updated_after` e `updated_before` (RFC 3339) filtram pela data de atualização do documento, e `exclude_stale: true` ignora os marcados como desatualizados. Cada resultado traz `updated_at`, `stale`, `paths`, `commit`, `source_uri` e `also_in` (outros documentos com o mesmo texto, colapsados num só resultado).
  * `highlights` marca, em posições de caractere Unicode, os termos encontrados em `content`. Consultas repetidas em até <Limit name="ragQueryCacheTtl" /> vêm do cache (`cached: true`) e custam menos.

  <Callout type="warn" title="Conteúdo do usuário">
    Os trechos devolvidos são conteúdo dos seus documentos. Ao passá-los a um modelo de linguagem, trate-os como dados, não como instruções.
  </Callout>
</Endpoint>

## Feedback de relevância

### Registrar feedback de relevância

<Endpoint
  id="rag.feedback.add"
  example={{ body: `{
"query": "como mudo minha senha?",
"section_id": "b2c4d6e8-0a1b-4c3d-8e5f-6a7b8c9d0e1f",
"label": "positive",
"end_user_ref": "usuario-123"
}` }}
>
  * `label`: `positive` (o trecho responde à pergunta) ou `negative`.
  * `end_user_ref` (opcional): identifica quem avaliou, quando o voto vem do seu usuário final. É guardado só como hash.
  * Até <Limit name="ragFeedbackPerMinute" /> votos por minuto. Perguntas parecidas são agrupadas, e o voto passa a valer para todo o grupo.
</Endpoint>

### Listar feedback

<Endpoint id="rag.feedback.list" />

### Apagar um grupo de feedback

<Endpoint id="rag.feedback.delete" />

## Rerank avulso

### Reordenar textos (rerank)

<Endpoint
  id="rag.rerank"
  example={{ body: `{
"query": "prazo de reembolso",
"documents": ["Entregas em até 5 dias úteis.", "Frete grátis acima de R$ 200.", "Reembolso em até 7 dias após a devolução."],
"top_k": 2
}` }}
>
  Ordena **a sua** lista de textos pela relevância à pergunta, sem base envolvida. Até <Limit name="ragRerankDocumentsMax" /> textos por chamada (cada um é cortado em 2.000 caracteres). `index` aponta para a posição no array enviado.
</Endpoint>

## Resposta com citações

### Responder com citações

<Endpoint
  id="rag.answer"
  example={{ body: `{
"query": "como mudo minha senha?",
"top_k": 5,
"min_score": 0.35,
"generate": false
}` }}
>
  Faz uma busca `accurate` e responde **só** com trechos de `score` igual ou acima de `min_score` (0 a 1, padrão 0,35, um ponto de partida que vale calibrar na sua base).

  * Com resposta, `answered: true` e cada `[n]` do texto aponta para uma `citations[]` (`section_id`, `document_id`, `title`, `heading_path`, `source_uri`, `score`, `excerpt`). Nunca há resposta sem citação.
  * Sem trecho acima do limiar, `answered: false`, `reason: no_passage_above_threshold`, nenhuma citação, e o webhook `rag.question.unanswered` é disparado. Se o rerank não pôde conferir a relevância, `reason: relevance_unverified` (não afirma nada e não dispara o webhook).
  * `generate: false` (padrão) monta a resposta citando os 3 melhores trechos. Com `generate: true`, o provedor de IA padrão da plataforma escreve o texto a partir dos trechos; sem marcador de citação válido ou sem provedor, volta ao modo extrativo (`generated: false`). Com texto gerado, os trechos da base seguem para o provedor de IA da plataforma.
  * Com `Accept: text/event-stream`, a resposta vem em SSE: `citations`, vários `delta` (pedaços do texto) e `done` (o resultado completo). O texto é gerado inteiro antes, o SSE só o fatia.
  * Cobrança de uma busca `accurate`; a geração não tem cobrança à parte. Use o `query_id` no [feedback](#rag-feedback-add) para alimentar o CTR do analytics.
</Endpoint>

## Widget de chat embutível

O widget é um botão de chat em JavaScript puro (sem CDN, em shadow DOM, só escreve texto) que responde com citações usando a sua base. Ele usa uma **chave pública** (`rpk_…`) que só consegue perguntar numa base: não lê outras, não escreve nada.

```html
<script src="https://api.respawntech.dev/widget/rag.js" data-key="rpk_..." async></script>
```

Atributos: `data-key` (obrigatório), `data-title`, `data-placeholder` e `data-dont-know` (texto quando não há resposta). As perguntas feitas pelo widget são cobradas do dono da base, como o `answer`.

### Criar chave pública (widget)

<Endpoint
  id="rag.publickeys.create"
  example={{ body: `{
"name": "Site institucional",
"allowed_origins": ["https://www.example.com", "https://*.example.com"],
"rate_per_minute": 30,
"generate": false
}` }}
>
  * `allowed_origins` (obrigatório, 1 a 20): `https://site.com` ou `https://*.site.com`, sem caminho. O servidor recusa pedidos cujo `Origin` não esteja na lista.
  * `rate_per_minute`: 1 a 600 (padrão 30), por chave. `generate` liga o texto gerado por IA nas respostas dessa chave.
  * Até 20 chaves por base. A `key` aparece **uma única vez**; guardamos só o hash.

  <Callout type="warn" title="Origin não é autenticação">
    Só o navegador respeita o `Origin`; um cliente fora dele pode forjá-lo. O que limita o abuso é o limite por minuto da chave, e o custo recai sobre você. Revogue a chave se vir uso estranho.
  </Callout>
</Endpoint>

### Listar chaves públicas

<Endpoint id="rag.publickeys.list" />

### Revogar chave pública

<Endpoint id="rag.publickeys.revoke" />

### Responder pelo widget (rota pública)

<Endpoint id="rag.public.answer" example={{ body: `{ "query": "como mudo minha senha?" }` }}>
  Sem token de API: envie a chave no header `X-Respawn-Public-Key` e o navegador manda o `Origin`. A base vem da chave, e `top_k`, `min_score` e `generate` não são aceitos no pedido. Responde como o `answer` (JSON ou SSE), com CORS liberado para a origem permitida. Erros: `401` (chave ausente, desconhecida ou revogada), `403` (origem não permitida) e `429` (limite por minuto).
</Endpoint>

### Script do widget

<Endpoint id="rag.widget" />

## Analytics de perguntas

### Analytics das perguntas

<Endpoint id="rag.analytics" example={{ query: { days: '30' } }}>
  Mostra o que os usuários perguntam e o que a base não sabe responder, a partir das chamadas de `answer` e do widget. `days` vai de 1 a 90 (padrão 30).

  * `answer_rate`: respondidas ÷ total de perguntas.
  * `feedback_ctr`: respondidas que receberam voto (pelo `query_id`) ÷ respondidas.
  * `positive_rate`: votos positivos ÷ votos.
  * `top_questions` e `unanswered_questions`: até 20 perguntas agrupadas cada, para você descobrir o que escrever na base.

  As perguntas ficam cifradas com a chave da base. O widget não tem voto próprio: o CTR só conta votos enviados pela API.
</Endpoint>

## Roteamento

### Decidir entre opções (roteamento)

<Endpoint
  id="rag.decide"
  example={{ body: `{
"text": "quero cancelar minha assinatura",
"options": [
  { "label": "cobranca", "description": "pagamentos, faturas e cancelamentos" },
  { "label": "suporte", "description": "problemas técnicos" }
],
"threshold": 0.5,
"min_margin": 0.1
}` }}
>
  Classifica um texto entre 2 e 50 opções sem usar um LLM, pontuando cada `label: description` com o reranker (`provider`: `bge` ou `laya`). Serve para rotear pedidos. Se a melhor opção não passar de `threshold` (padrão 0,5) ou não ficar `min_margin` (padrão 0,1) à frente da segunda, `decided` é `false`: trate como "não sei". O `ranking` completo vem sempre. Preço e franquia do rerank avulso.
</Endpoint>

## Preços e limites da conta

### Consultar preços

<Endpoint id="rag.pricing" />

### Consultar limites

<Endpoint id="rag.limits" />

Valores vigentes da sua conta (já com o bônus do plano), úteis para validar um envio antes de fazê-lo.

## Eventos (webhooks)

Cadastre um endpoint no dashboard para receber:

* `rag.document.ready` e `rag.document.failed`: `collection_id`, `document_id`, `external_id` e `version`; o de falha traz também `error_code`. Valem para documentos enviados, importados de arquivo e vindos de fontes.
* `rag.question.unanswered`: `collection_id`, `question`, `query_id` e `source` (`api` ou `widget`), quando nenhum trecho passou do `min_score`. Bom para alimentar uma fila de "o que escrever".

O envio é de melhor esforço, como nos demais eventos. Veja a [lista de eventos](/webhooks).

## Usar pelo MCP

As mesmas operações estão disponíveis como ferramentas MCP do grupo `rag` ([lista completa](/agentes-de-ia)): `rag_answer`, `rag_decide`, `rag_index`, `rag_lint`, `rag_mark_changed` e `rag_retry_document` são as novas. As de leitura (`rag_index`, `rag_lint`) são gratuitas; use `rag_access=query` na conexão para esconder as que alteram a base.

## Erros

<ErrorTable tool="base-de-conhecimento" />

Os códigos sem status HTTP aparecem no campo `error_code` de um documento com `status: failed`.

## Limites

| Limite                                     | Valor                                        |
| ------------------------------------------ | -------------------------------------------- |
| Tamanho de um documento                    | <Limit name="ragDocumentMax" />              |
| Bases por conta                            | <Limit name="ragCollectionsMax" />           |
| Trechos indexados por conta                | <Limit name="ragChunksMax" />                |
| Documentos em processamento ao mesmo tempo | <Limit name="ragPendingMax" />               |
| Tamanho da pergunta                        | <Limit name="ragQueryCharsMax" /> caracteres |
| Trechos por busca (`top_k`)                | <Limit name="ragTopKMax" />                  |
| Textos por rerank avulso                   | <Limit name="ragRerankDocumentsMax" />       |
| Votos de feedback por minuto               | <Limit name="ragFeedbackPerMinute" />        |
| Arquivo importado                          | 50 MB                                        |
| Páginas por fonte                          | 1.000 (padrão 100)                           |
| Chaves públicas por base                   | 20                                           |

As rotas da base de conhecimento ignoram o header `X-Idempotency-Key`: elas já são idempotentes (conteúdo repetido não é reindexado nem cobrado). Uma chave restrita a bases específicas só enxerga essas bases e não pode criar novas (`forbidden`).
