BoaVoz
Documentação · API

Fontes

Mande para o chatbot o que ele precisa saber: texto, perguntas frequentes, uma página ou um PDF. Com o contexto, cada documento vale só para quem é dele, como o regulamento de um condomínio para os moradores daquele condomínio.

Permissão da chavesourcesPacoteIntegrações (R$ 49 por mês, por conta). Sem ele, a API responde 403 plan_not_allowed.
RotaO que faz
POST /v1/bots/{id}/sourcesGrava a fonte e lê na hora: a resposta já diz quantos trechos entraram.
GET /v1/bots/{id}/sourcesAs fontes do chatbot, as mais novas primeiro, com o filtro pelo contexto.
DELETE /v1/bots/{id}/sources/{source}Tira a fonte e os trechos dela.
PUT /v1/bots/{id}/noticePõe o aviso do momento: um texto com prazo (uma queda, uma manutenção) que a IA usa quando perguntam.

Fontes por contexto

Uma fonte com context (por exemplo {"workspace_id": "ws_abc"}) vale só nas conversas em que o contexto ativo tem todos esses pares, com o mesmo valor e o mesmo tipo ("42" e 42 são diferentes). A fonte sem context vale em todas as conversas do chatbot.

O contexto ativo vem do token do widget ou do pareamento, ou do contexto fixo do chatbot (painel, aba Ações), que vai por cima dos outros. Sem nenhum deles, a conversa só usa as fontes gerais. É assim que um SaaS com um chatbot só manda os documentos de cada cliente dele: cada um com o próprio contexto.

A fonte com contexto passa pelo portão de itens proibidos e regulamentados, como as outras, mas não refaz a análise do chatbot (ela é sobre o negócio do chatbot, não sobre os documentos de cada cliente). No painel, a base mostra só a contagem dessas fontes.

POST/v1/bots/{id}/sources

Texto que vale só num contexto
curl -X POST "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/sources" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3b9f2c8e-5a1d-4e7b-9c6f-2d8a4e1b7c90" \
  -d '{
  "kind": "text",
  "title": "Regulamento do Condomínio Jardim",
  "content": "Mudanças só de segunda a sábado, das 8h às 18h, com aviso de 48 horas à portaria. O salão de festas é reservado pelo aplicativo, com até 30 dias de antecedência.",
  "context": {
    "workspace_id": "ws_abc"
  }
}'
Resposta · 201
{
  "id": "src_3f2a9c1e-5b7d-4e8a-9c21-7d4e5f6a8b90",
  "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "kind": "text",
  "title": "Regulamento do Condomínio Jardim",
  "url": null,
  "status": "ready",
  "chunks": 2,
  "pages": 1,
  "error": null,
  "context": {
    "workspace_id": "ws_abc"
  },
  "created_at": "2026-10-19T15:10:42.118Z"
}
PDF por URL (vale em todas as conversas)
curl -X POST "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/sources" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3b9f2c8e-5a1d-4e7b-9c6f-2d8a4e1b7c90" \
  -d '{
  "kind": "pdf",
  "url": "https://condominio.exemplo.com.br/docs/regulamento.pdf"
}'
Resposta · 201
{
  "id": "src_7b6a5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
  "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "kind": "pdf",
  "title": "regulamento.pdf",
  "url": "https://condominio.exemplo.com.br/docs/regulamento.pdf",
  "status": "ready",
  "chunks": 1,
  "pages": 1,
  "error": null,
  "context": null,
  "created_at": "2026-10-19T15:11:05.402Z"
}
Planilha CSV (o texto do arquivo em content)
curl -X POST "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/sources" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3b9f2c8e-5a1d-4e7b-9c6f-2d8a4e1b7c90" \
  -d '{
  "kind": "csv",
  "title": "Tabela de preços",
  "content": "Serviço;Preço;Duração\nCorte masculino;R$ 45;30 min\nBarba;R$ 35;20 min\nCorte e barba;R$ 70;50 min",
  "columns": [
    {
      "name": "Preço",
      "type": "preco"
    }
  ]
}'
Resposta · 201
{
  "id": "src_9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
  "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "kind": "csv",
  "title": "Tabela de preços",
  "url": null,
  "status": "ready",
  "chunks": 3,
  "pages": 1,
  "error": null,
  "context": null,
  "created_at": "2026-10-19T15:11:30.215Z",
  "columns": [
    {
      "name": "Serviço",
      "type": "texto"
    },
    {
      "name": "Preço",
      "type": "preco"
    },
    {
      "name": "Duração",
      "type": "texto"
    }
  ]
}
CampoRegraErro
kindtext, faq, csv (planilha), page (uma página) ou pdf (por URL). O site inteiro e os posts do Instagram ficam no painel (na lista, aparecem como site e instagram).400 kind
titleOpcional (até 120 caracteres). Sem ele: Texto, Perguntas frequentes, Planilha, o domínio da página ou o nome do arquivo.400 title
contentEm text e faq: de 20 a 30 mil caracteres (o corpo vai até 32 KB). Para mais, um PDF por URL. Em csv: o texto do arquivo, até 30 mil caracteres, com a primeira linha de cabeçalho e separador ; ou ,; cada linha vira um trecho com o nome das colunas.400 content
urlEm page e pdf: http ou https. O PDF vai até 15 MB e precisa ter texto (PDF só de imagem não é lido).400 url; 422 source_unreadable ou source_too_large
contextOpcional: até 5 pares, com chaves de letras, números, _, . e - e valores texto (até 200), número ou verdadeiro/falso.400 context
columnsOpcional, só em csv: o tipo de cada coluna, numa lista de {name, type}, com type texto, numero, preco, quantidade ou link (até 60 colunas). A coluna que não vier ganha o tipo adivinhado pelo nome e pelos valores. Com preço e quantidade marcados, a IA acha o item pelo nome ou pelo código e filtra ("até R$ 100", "só com estoque"). A resposta traz columns com o tipo de todas.400 columns

Falhou a leitura (a página não abriu, o PDF não tem texto): 422 source_unreadable, com o motivo, e a fonte não fica gravada. Até 300 fontes novas por hora com a mesma chave (429 rate_limited). Aceita Idempotency-Key.

GET/v1/bots/{id}/sources

context (o JSON da etiqueta) traz só as fontes com essa etiqueta; tagged=false, só as gerais; tagged=true, só as com contexto. Paginação com cursor e limit (até 100), como nas outras listas.

As fontes de um contexto
curl "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/sources?context=%7B%22workspace_id%22%3A%22ws_abc%22%7D" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY"
Resposta · 200
{
  "data": [
    {
      "id": "src_3f2a9c1e-5b7d-4e8a-9c21-7d4e5f6a8b90",
      "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "kind": "text",
      "title": "Regulamento do Condomínio Jardim",
      "url": null,
      "status": "ready",
      "chunks": 2,
      "pages": 1,
      "error": null,
      "context": {
        "workspace_id": "ws_abc"
      },
      "created_at": "2026-10-19T15:10:42.118Z"
    }
  ],
  "next_cursor": null
}

DELETE/v1/bots/{id}/sources/{source}

Responde 204. Fonte que não é do chatbot, ou id que não é src_…: 404. Quando um cliente sai do seu sistema, apague as fontes do contexto dele.

Apagar uma fonte
curl -X DELETE "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/sources/src_3f2a9c1e-5b7d-4e8a-9c21-7d4e5f6a8b90" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY"
Resposta · 204
(sem corpo)

Aviso do momento

O mesmo aviso do painel (aba Base de conhecimento): um texto com prazo, como "Instabilidade na fibra no bairro Centro; previsão de volta às 18h.". A IA usa quando o contato pergunta ou quando o assunto tem a ver, nunca como instrução; vencido, some sozinho. Um aviso por chatbot: o novo troca o anterior. Bom para o seu sistema avisar uma queda sem ninguém entrar no painel. Vale também com a permissão provisioning.

PUT/v1/bots/{id}/notice

Pôr (ou trocar) o aviso do momento
curl -X PUT "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/notice" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "text": "Instabilidade na fibra no bairro Centro; previsão de volta às 18h.",
  "until": "2026-10-22T18:00:00-03:00"
}'
Resposta · 200
{
  "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "notice": {
    "text": "Instabilidade na fibra no bairro Centro; previsão de volta às 18h.",
    "until": "2026-10-22T21:00:00.000Z",
    "set_by": "API (Sistema do provedor)"
  }
}
CampoRegraErro
textDe 5 a 500 caracteres.400 text
untilData e hora em ISO 8601 com o fuso (2026-10-22T18:00:00-03:00 ou com Z), de 10 minutos a 30 dias à frente.400 until

GET/v1/bots/{id}/notice

O aviso que vale agora, ou notice: null (sem aviso ou vencido). set_by diz quem pôs: o nome da chave, a agência ou o e-mail de quem é do cliente.

O aviso que vale agora
curl "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/notice" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY"
Resposta · 200
{
  "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "notice": {
    "text": "Instabilidade na fibra no bairro Centro; previsão de volta às 18h.",
    "until": "2026-10-22T21:00:00.000Z",
    "set_by": "API (Sistema do provedor)"
  }
}

DELETE/v1/bots/{id}/notice

Tirar o aviso antes do prazo
curl -X DELETE "https://boavoz.com/api/v1/bots/bot_7c9e6679-7425-40de-944b-e07fc1f90ae7/notice" \
  -H "Authorization: Bearer $BOAVOZ_API_KEY"
Resposta · 200
{
  "bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "notice": null,
  "removed": true
}