Captain (IA)
Endpoints em torno do assistente de IA Captain: reportar uma resposta problemática, inspecionar de onde saiu uma resposta (qual assistente, quais FAQs e cenários usou, em qual modelo e a que custo), e triar as sugestões de FAQ que o assistente derivou das conversas da conta.
Requer o recurso captain_ai
Sem o recurso captain_ai habilitado na conta, os endpoints abaixo respondem 403 com { error: "FEATURE_NOT_AVAILABLE", feature: "captain_ai" }.
Autorização
Reportar uma mensagem e ver a sessão por trás dela não são ações de administrador — são trabalho de quem atende. A guarda que importa é a da conversa: quem não pode abrir a conversa a que a mensagem pertence recebe 403, mesmo tendo acesso à conta. Triar sugestões de FAQ segue a mesma lógica: um agente sem papel de administrador só vê sugestões sustentadas por conversas que ele já pode ler — o filtro acontece no servidor, não é um parâmetro que se omite.
Reportar Mensagem
Registra que uma resposta do assistente foi sinalizada como problemática.
/api/v1/accounts/{account_id}/captain/message_reportsCria um relatório sobre uma mensagem gerada pela IA.
Body
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
message_id | integer | Sim | ID da mensagem reportada |
report_reason | string | Sim | incorrect_information, inappropriate_response, incomplete_response, outdated_information ou other |
description | string | Nao | Detalhe livre sobre o problema |
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/captain/message_reports" \
-H "api_access_token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message_id": 4821,
"report_reason": "incorrect_information",
"description": "O prazo informado nao bate com o SLA contratado"
}'{
"id": 12,
"message_id": 4821,
"conversation_id": 340,
"report_reason": "incorrect_information",
"description": "O prazo informado não bate com o SLA contratado",
"created_at": 1755878400
}ID de mensagem de outra conta
Um message_id que não pertence à conta autenticada retorna 404, nunca 403 — a existência da mensagem não é confirmada para quem não tem acesso a ela.
Sessão do Assistente
Mostra qual assistente do Captain respondeu uma mensagem, com quais FAQs e cenários de guardrail ele se apoiou, em qual modelo e a que custo em créditos.
/api/v1/accounts/{account_id}/captain/agent_sessions/{id}O id na rota é o ID DA MENSAGEM respondida pela IA, não o id da sessão.
{
"id": 58,
"session_type": "assistant",
"llm_model": "gpt-4.1-mini",
"credits_consumed": 0.42,
"created_at": 1755878400,
"assistant": { "id": 3, "name": "Assistente de Suporte" },
"citations": [
{ "id": 91, "question": "Qual o prazo de entrega?", "answer": "...", "documentable_type": "Noovi::Ai::FaqSuggestion", "documentable_id": 91 }
],
"scenarios": [
{ "id": 4, "title": "Cliente pedindo reembolso" }
]
}Nem toda mensagem tem sessão
Uma mensagem que não foi produzida pela IA responde 404 aqui — ausência de sessão, não erro. O dashboard usa isso para decidir se mostra o painel de explicação da resposta.
Sugestões de FAQ
Fila de triagem das FAQs que o assistente sugeriu a partir de conversas reais: listar, abrir com as conversas que a sustentam, editar, aprovar (vira resposta indexada que o assistente passa a usar) ou descartar.
/api/v1/accounts/{account_id}/captain/faq_suggestionsLista sugestões de FAQ, paginada.
Query params
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
assistant_id(query) | integer | Nao | Filtra por assistente |
status(query) | string | Nao | open, approved ou dismissed |
search(query) | string | Nao | Busca (case-insensitive) em question/answer |
page(query) | integer | Nao | Padrão 1 |
{
"meta": { "total_count": 3, "page": 1 },
"payload": [
{
"id": 91,
"question": "Qual o prazo de entrega para o interior?",
"answer": "O prazo padrão e de 5 a 7 dias úteis.",
"language": "pt-BR",
"status": "open",
"source_count": 4,
"assistant_id": 3,
"assistant_name": "Assistente de Suporte",
"created_at": 1755878400,
"updated_at": 1755878400
}
]
}/api/v1/accounts/{account_id}/captain/faq_suggestions/{id}Detalhe de uma sugestão, com as conversas (observações) que a originaram.
{
"id": 91,
"question": "Qual o prazo de entrega para o interior?",
"answer": "O prazo padrão e de 5 a 7 dias úteis.",
"language": "pt-BR",
"status": "open",
"source_count": 4,
"assistant_id": 3,
"assistant_name": "Assistente de Suporte",
"created_at": 1755878400,
"updated_at": 1755878400,
"observations": [
{
"id": 210,
"generated_question": "Até quando demora pra chegar no interior?",
"generated_answer": "...",
"status": "grouped",
"conversation_id": 340,
"conversation_display_id": 340,
"conversation": { "id": 340, "display_id": 340 },
"created_at": 1755878400
}
]
}Observações seguem a mesma visibilidade
As conversas que sustentam a sugestão só aparecem se o chamador também pode lê-las — abrir uma sugestão não é um atalho para ler uma conversa que a tela principal esconderia.
/api/v1/accounts/{account_id}/captain/faq_suggestions/{id}Edita a pergunta/resposta antes de aprovar ou descartar. Body envolto em faq_suggestion.
Body (faq_suggestion)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
question | string | Nao | Pergunta sugerida |
answer | string | Nao | Resposta sugerida |
Só funciona enquanto a sugestão está open
Uma sugestão já approved ou dismissed é imutável: editar, aprovar ou descartar de novo retorna 404, não 422.
/api/v1/accounts/{account_id}/captain/faq_suggestions/{id}/approveAprova a sugestão: ela vira uma resposta indexada que o assistente passa a usar em conversas futuras. Aceita opcionalmente question/answer editados, no mesmo formato do PATCH.
{
"id": 91,
"status": "approved",
"...": "demais campos da sugestao",
"assistant_response": {
"id": 55,
"question": "Qual o prazo de entrega para o interior?",
"answer": "O prazo padrão e de 5 a 7 dias úteis.",
"status": "approved"
}
}/api/v1/accounts/{account_id}/captain/faq_suggestions/{id}/dismissDescarta a sugestão sem criar resposta indexada.