POST /api/v1/analyze
Analisa um texto em busca de sinais de condutas irregulares. O endpoint é stateless: cada requisição é independente e não armazena o texto enviado. O resultado é uma avaliação de risco que o chamador pode usar para tomar decisões de triagem ou escalonar para revisão jurídica.
Autenticação
Requer uma API key ativa com o escopo analyze:run.
Authorization: Bearer vario_SUA_API_KEY
A API key é gerada no portal de desenvolvedores. Para gerar ou rotacionar uma key, consulte Autenticação e API keys.
Rate limit
Consulte Erros e rate limits para os limites por tier e o comportamento do header Retry-After.
Corpo da requisição
Content-Type: application/json
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
text | string | Sim | Texto a analisar. Máximo 8.000 caracteres (aproximadamente 1.300 palavras). Para documentos mais longos, divida o conteúdo em chunks e envie requisições separadas. |
language | string | Sim | Idioma do texto. Valores: "es" (espanhol) ou "pt" (português). |
playbook | string | Sim | Tipo de conduta a detectar. Valores: "price_fixing" · "bid_rigging" · "bribery" · "market_manipulation" · "information_exchange" · "group_boycott". Consulte GET /api/v1/playbooks para a lista atualizada e os idiomas suportados por cada tipo. |
mode | string | Não | Modo de análise. "screening": apenas camada L1 (keyword + embedding, sem LLM) — 1 crédito, o mais econômico, para varredura massiva. "fast": L1 + L2 (LLM leve) — 2 créditos, precisão moderada. "full" (padrão): L1 + L2 + L3 (LLM profundo) — 3 créditos, máxima precisão com raciocínio completo. |
thread_context | array[string] | Não | Até 10 mensagens anteriores do thread, em ordem cronológica. Cada elemento tem máximo de 500 caracteres. Fornecer contexto do thread melhora a precisão da análise. Padrão: []. |
external_id | string | Não | Identificador do seu sistema para essa mensagem (por exemplo, o ID do e-mail no seu banco de dados). O vario não processa esse valor — ele o retorna exatamente na resposta para facilitar a rastreabilidade na sua integração. |
Resposta
Content-Type: application/json · HTTP 200 OK
| Campo | Tipo | Descrição |
|---|---|---|
combined_score | float [0–10] | Score de risco de 0 a 10. Valores mais altos indicam maior sinal de risco. |
should_alert | boolean | true se a análise detectou um sinal de risco suficiente para requerer revisão. |
severity | string | Categoria de risco: "critical" · "high" · "medium" · "low". |
reasoning | string | Explicação do resultado no idioma da análise. Pode estar vazio se a análise profunda não esteve disponível nessa chamada. |
key_phrases | array[string] | Fragmentos exatos do texto que o sistema identificou como evidência da conduta avaliada. |
regulatory_frameworks | array[string] | Marcos regulatórios aplicáveis ao tipo de conduta analisada. |
conduct_type | string | Conduta detectada pelo pipeline. Classificação aberta: pode diferir do playbook solicitado. Domínio fechado de 7 valores: "price_fixing" · "bid_rigging" · "bribery" · "market_manipulation" · "information_exchange" · "group_boycott" · "none". Sempre "none" quando processing_path="l1_discard". Ausente no modo screening. |
recommended_action | string | Ação sugerida. Domínio fechado dependente do tier — modos fast/l2_pass/degradado: "no_action" · "monitoring" · "legal_review"; modo full (L3 completo): adiciona "open_case" · "dismiss" · "immediate_escalation". É uma recomendação do sistema; o revisor decide. |
confidence | string | Nível de confiança do resultado: "high" · "medium" · "low". |
processing_path | string | null | Etapa do pipeline que produziu esta resposta. Campo não-breaking: clientes que não o conhecem ignoram-no sem erro. Veja a tabela abaixo. |
mode_used | string | Confirma o modo executado nessa chamada: "screening", "fast" ou "full". No modo screening o schema da resposta é diferente — veja a seção abaixo. |
analyzed_at | string | Timestamp ISO 8601 UTC do momento da análise. |
pipeline_version | string | Versão do motor de detecção (string opaca). Útil para rastreabilidade caso o comportamento mude entre versões. |
bedrock_available | boolean | Indica se a análise profunda esteve disponível nessa chamada. Se false, a resposta é parcial. |
processing_path — comportamento do pipeline
O pipeline aplica gates de saída antecipada para evitar invocações desnecessárias. O campo processing_path identifica qual etapa produziu a resposta.
| Valor | Quando | Bedrock invocado | Latência |
|---|---|---|---|
"l1_discard" | Score L1 abaixo do limiar mínimo de sinal. combined_score=0.0. O texto não foi analisado por nenhum LLM. | Não | < 200 ms |
"screening" | Modo screening — apenas scores L1. | Não | 20–150 ms |
"l2_pass" | L2 confiável (score baixo ou alto), sem sinal urgente. L3 não necessário. | L2 | < 1,5 s |
null | Modo fast concluído (L2, sem gate L3 por design do modo). Também retornado quando o Bedrock falhou no L2 (caminho degradado) — nesse caso bedrock_available=false. Desambiguar com bedrock_available. | L2 | 200–800 ms |
| (valores adicionais) | O modo full pode retornar valores adicionais que identificam a profundidade da análise profunda. Pendente de documentação — use .unknown() ou allow-unknown-enum-values para compatibilidade futura. | L2 + L3 | 2–8 s |
Resposta no modo screening
Quando mode é "screening", a resposta tem um schema diferente dos modos fast e full. Inclui apenas resultados da camada L1 (keyword + embedding). Os campos L2/L3 (combined_score, should_alert, severity, reasoning, etc.) não estão presentes.
| Campo | Tipo | Descrição |
|---|---|---|
mode_used | string | "screening" |
l1_score | float [0–1] | Pontuação agregada da camada L1: max(l1_keyword_score, l1_embedding_score). |
l1_keyword_score | float [0–1] | Score de detecção por palavras-chave. |
l1_embedding_score | float [0–1] | Score de similaridade semântica por embeddings. |
l1_matched_terms | array[string] | Termos do texto que ativaram a detecção na L1. |
l1_embedding_available | boolean | true se o serviço de embeddings esteve disponível nessa chamada. |
playbook | string | Echo do playbook da requisição. |
playbook_version | string | Versão do playbook utilizado. |
pipeline_version | string | Versão do motor de análise. |
analyzed_at | string (ISO 8601) | Timestamp UTC da análise. |
external_id | string | null | Echo do external_id enviado na requisição. |
Exemplo de resposta no modo screening:
{
"mode_used": "screening",
"l1_score": 0.82,
"l1_keyword_score": 0.75,
"l1_embedding_score": 0.82,
"l1_matched_terms": ["combinamos não mexer no preço", "preço"],
"l1_embedding_available": true,
"playbook": "price_fixing",
"playbook_version": "1.0",
"pipeline_version": "1.0",
"analyzed_at": "2026-06-04T10:15:00Z",
"external_id": "email-msg-00842"
}
Comportamento em degradação
Se o serviço de análise profunda não estiver disponível, o endpoint responde com HTTP 200 e bedrock_available: false. Nesse caso, reasoning pode estar vazio e combined_score reflete apenas a análise local.
Se preferir receber um erro explícito em vez de uma resposta parcial, adicione o header:
Prefer: deep-analysis-required
Com esse header, o endpoint responde 503 DEEP_ANALYSIS_UNAVAILABLE quando a análise profunda não estiver disponível.
Exemplo completo
Requisição
curl -X POST https://api.vario.lat/v1/analyze \
-H "Authorization: Bearer vario_SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Acordamos no bajar de $450 la unidad. Los demás van a hacer lo mismo esta semana.",
"language": "es",
"playbook": "price_fixing",
"mode": "full",
"thread_context": [
"La reunión de ayer salió bien, creo que todos están alineados.",
"Confirmo que el acuerdo sigue en pie para el trimestre."
],
"external_id": "email-msg-00842"
}'
Resposta
{
"combined_score": 7.7,
"should_alert": true,
"severity": "critical",
"reasoning": "El mensaje contiene una referencia directa a un precio acordado entre partes que actúan como competidores, con indicios de coordinación horizontal. El contexto del hilo refuerza la señal al mostrar continuidad de un acuerdo previo.",
"key_phrases": [
"no bajar de $450 la unidad",
"los demás van a hacer lo mismo"
],
"regulatory_frameworks": [
"Lei 12.529/2011 Art. 36",
"DL 211 Art. 3",
"COFECE Lineamientos de colusión"
],
"recommended_action": "legal_review",
"confidence": "high",
"mode_used": "full",
"analyzed_at": "2026-06-02T18:45:00Z",
"pipeline_version": "1.0",
"bedrock_available": true,
"external_id": "email-msg-00842"
}
Erros específicos deste endpoint
Para a referência completa de códigos de erro e rate limits, consulte Erros e rate limits.
| HTTP | Código | Causa |
|---|---|---|
400 | INVALID_PLAYBOOK | O valor de playbook não existe no catálogo. |
400 | INVALID_LANGUAGE | O idioma especificado não é suportado para esse playbook. |
400 | INVALID_MODE | O valor de mode não é válido. Valores aceitos: "screening", "fast", "full". |
400 | TEXT_TOO_LONG | O campo text excede 8.000 caracteres. |
400 | CONTEXT_TOO_LONG | thread_context excede 10 elementos, ou algum deles excede 500 caracteres. |
401 | INVALID_API_KEY | A API key é inválida, está inativa ou expirou. |
401 | MISSING_AUTH | O header Authorization não está presente. |
402 | INSUFFICIENT_CREDITS | O saldo de créditos do tenant é 0. |
403 | INSUFFICIENT_SCOPE | A API key não tem o escopo analyze:run. |
422 | VALIDATION_ERROR | O corpo da requisição não está em conformidade com o schema. |
429 | RATE_LIMIT_EXCEEDED | O limite de chamadas foi excedido. |
503 | DEEP_ANALYSIS_UNAVAILABLE | Retornado apenas se Prefer: deep-analysis-required foi enviado e a análise profunda não está disponível. |
500 | PIPELINE_ERROR | Erro interno do sistema de detecção. |
Notas de uso
- Chunking: Para textos que excedam 8.000 caracteres, divida o conteúdo em fragmentos e envie uma requisição por fragmento. Use
thread_contextpara passar o contexto do thread, não para fragmentar o campotext. - Funil de três etapas: Quando o volume é alto, use
mode: "screening"para descartar texto sem sinal L1 (1 crédito),mode: "fast"para os que superaram o limiar (2 créditos), emode: "full"para os alertas reais (3 créditos). Veja Créditos e modos. - Rastreabilidade: Use
external_idpara correlacionar cada resposta com o registro correspondente no seu sistema sem precisar armazenar o texto. - O resultado não é uma determinação legal. O vario detecta sinais de risco; o CCO e a equipe jurídica avaliam e decidem.