POST /api/v1/analyze
Analiza un texto en busca de señales de conductas irregulares. El endpoint es stateless: cada request es independiente y no almacena el texto enviado. El resultado es una evaluación de riesgo que el caller puede usar para tomar decisiones de triage o escalar a revisión legal.
Autenticación
Requiere una API key activa con el scope analyze:run.
Authorization: Bearer vario_TU_API_KEY
La API key se genera desde el portal de developers. Para generar o rotar una key, consulta Autenticación y API keys.
Rate limit
Ver Errores y rate limits para los límites por tier y el comportamiento del header Retry-After.
Request body
Content-Type: application/json
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
text | string | Sí | Texto a analizar. Máximo 8.000 caracteres (aproximadamente 1.300 palabras). Para documentos más largos, divide el contenido en chunks y envía requests separados. |
language | string | Sí | Idioma del texto. Valores: "es" (español) o "pt" (portugués). |
playbook | string | Sí | Tipo de conducta a detectar. Valores: "price_fixing" · "bid_rigging" · "bribery" · "market_manipulation" · "information_exchange" · "group_boycott". Consulta GET /api/v1/playbooks para la lista actualizada y los idiomas soportados por cada tipo. |
mode | string | No | Modo de análisis. "screening": capa L1 únicamente (keyword + embedding, sin LLM) — 1 crédito, el más económico, para barrido masivo. "fast": L1 + L2 (LLM ligero) — 2 créditos, precisión moderada. "full" (default): L1 + L2 + L3 (LLM profundo) — 3 créditos, máxima precisión con razonamiento completo. |
thread_context | array[string] | No | Hasta 10 mensajes previos del hilo, en orden cronológico. Cada elemento tiene un máximo de 500 caracteres. Proporcionar contexto del hilo mejora la precisión del análisis. Default: []. |
external_id | string | No | Identificador de tu sistema para este mensaje (por ejemplo, el ID del email en tu base de datos). vario no procesa este valor — lo devuelve tal cual en el response para facilitar la trazabilidad en tu integración. |
Response
Content-Type: application/json · HTTP 200 OK
| Campo | Tipo | Descripción |
|---|---|---|
combined_score | float [0–10] | Score de riesgo de 0 a 10. Valores más altos indican mayor señal de riesgo. |
should_alert | boolean | true si el análisis detectó una señal de riesgo suficiente para requerir revisión. |
severity | string | Categoría de riesgo: "critical" · "high" · "medium" · "low". |
reasoning | string | Explicación del resultado en el idioma del análisis. Puede ser vacío si el análisis profundo no estuvo disponible en esta llamada. |
key_phrases | array[string] | Fragmentos exactos del texto que el sistema identificó como evidencia de la conducta evaluada. |
regulatory_frameworks | array[string] | Marcos regulatorios aplicables al tipo de conducta analizado. |
conduct_type | string | Conducta detectada por el pipeline. Clasificación abierta: puede diferir del playbook solicitado. Dominio cerrado de 7 valores: "price_fixing" · "bid_rigging" · "bribery" · "market_manipulation" · "information_exchange" · "group_boycott" · "none". Siempre "none" cuando processing_path="l1_discard". Ausente en modo screening. |
recommended_action | string | Acción sugerida. Dominio cerrado dependiente del tier — modos fast/l2_pass/degradado: "no_action" · "monitoring" · "legal_review"; modo full (L3 completo): agrega "open_case" · "dismiss" · "immediate_escalation". Es una recomendación del sistema; el revisor decide. |
confidence | string | Nivel de confianza del resultado: "high" · "medium" · "low". |
processing_path | string | null | Etapa del pipeline que produjo esta respuesta. Campo no-breaking: los clientes que no lo conocen lo ignoran sin error. Ver tabla abajo. |
mode_used | string | Confirma el modo ejecutado en esta llamada: "screening", "fast" o "full". En modo screening el schema del response es diferente — ver sección a continuación. |
analyzed_at | string | Timestamp ISO 8601 UTC del momento del análisis. |
pipeline_version | string | Versión del motor de detección (cadena opaca). Útil para trazabilidad si el comportamiento cambia entre versiones. |
bedrock_available | boolean | Indica si el análisis profundo estuvo disponible en esta llamada. Si es false, el response es parcial. |
processing_path — comportamiento del pipeline
El pipeline aplica gates de salida temprana para evitar invocaciones innecesarias. El campo processing_path identifica qué etapa produjo la respuesta.
| Valor | Cuándo | Bedrock invocado | Latencia |
|---|---|---|---|
"l1_discard" | L1 score bajo el umbral mínimo de señal. combined_score=0.0. El texto no fue analizado por ningún LLM. | No | < 200 ms |
"screening" | Modo screening — solo scores L1. | No | 20–150 ms |
"l2_pass" | L2 confiable (score bajo o alto), sin señal urgente. L3 no fue necesario. | L2 | < 1.5 s |
null | Modo fast completado (L2, sin gate L3 por diseño del modo). También se devuelve null cuando Bedrock falló en L2 (camino degradado): en ese caso bedrock_available=false. Desambiguar con bedrock_available. | L2 | 200–800 ms |
| (valores adicionales) | El modo full puede devolver valores adicionales que identifican la profundidad del análisis profundo. Pendiente de documentación — usar .unknown() o allow-unknown-enum-values para compatibilidad futura. | L2 + L3 | 2–8 s |
Response en modo screening
Cuando mode es "screening", el response tiene un schema distinto al de los modos fast y full. Solo incluye los resultados de la capa L1 (keyword + embedding). Los campos L2/L3 (combined_score, should_alert, severity, reasoning, etc.) no están presentes.
| Campo | Tipo | Descripción |
|---|---|---|
mode_used | string | "screening" |
l1_score | float [0–1] | Puntuación agregada de la capa L1: max(l1_keyword_score, l1_embedding_score). |
l1_keyword_score | float [0–1] | Score de detección por palabras clave. |
l1_embedding_score | float [0–1] | Score de similitud semántica por embeddings. |
l1_matched_terms | array[string] | Términos del texto que activaron la detección en L1. |
l1_embedding_available | boolean | true si el servicio de embeddings estuvo disponible en esta llamada. |
playbook | string | Echo del playbook del request. |
playbook_version | string | Versión del playbook utilizado. |
pipeline_version | string | Versión del motor de análisis. |
analyzed_at | string (ISO 8601) | Timestamp UTC del análisis. |
external_id | string | null | Echo del external_id enviado en el request. |
Ejemplo de response en modo screening:
{
"mode_used": "screening",
"l1_score": 0.82,
"l1_keyword_score": 0.75,
"l1_embedding_score": 0.82,
"l1_matched_terms": ["acordamos no movernos del precio", "precio"],
"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"
}
Comportamiento en degradación
Si el servicio de análisis profundo no está disponible, el endpoint responde con HTTP 200 y bedrock_available: false. En ese caso, reasoning puede ser vacío y combined_score refleja únicamente el análisis local.
Si prefieres recibir un error explícito en lugar de un response parcial, agrega el header:
Prefer: deep-analysis-required
Con este header, el endpoint responde 503 DEEP_ANALYSIS_UNAVAILABLE cuando el análisis profundo no está disponible.
Ejemplo completo
Request
curl -X POST https://api.vario.lat/v1/analyze \
-H "Authorization: Bearer vario_TU_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"
}'
Response
{
"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"
}
Errores específicos de este endpoint
Para la referencia completa de códigos de error y rate limits, consulta Errores y rate limits.
| HTTP | Código | Causa |
|---|---|---|
400 | INVALID_PLAYBOOK | El valor de playbook no existe en el catálogo. |
400 | INVALID_LANGUAGE | El idioma especificado no está soportado para ese playbook. |
400 | INVALID_MODE | El valor de mode no es válido. Valores aceptados: "screening", "fast", "full". |
400 | TEXT_TOO_LONG | El campo text supera 8.000 caracteres. |
400 | CONTEXT_TOO_LONG | thread_context excede 10 elementos, o alguno supera 500 caracteres. |
401 | INVALID_API_KEY | La API key es inválida, está inactiva o expiró. |
401 | MISSING_AUTH | El header Authorization no está presente. |
402 | INSUFFICIENT_CREDITS | El balance de créditos del tenant es 0. |
403 | INSUFFICIENT_SCOPE | La API key no tiene el scope analyze:run. |
422 | VALIDATION_ERROR | El body del request no cumple el schema. |
429 | RATE_LIMIT_EXCEEDED | Se superó el límite de llamadas. |
503 | DEEP_ANALYSIS_UNAVAILABLE | Solo se retorna si se envió Prefer: deep-analysis-required y el análisis profundo no está disponible. |
500 | PIPELINE_ERROR | Error interno del sistema de detección. |
Notas de uso
- Chunking: Para textos que superen 8.000 caracteres, divide el contenido en fragmentos y envía un request por fragmento. Usa
thread_contextpara pasar el contexto del hilo, no para fragmentar el campotext. - Funnel de tres etapas: Cuando el volumen es alto, usa
mode: "screening"para descartar texto sin señal L1 (1 crédito),mode: "fast"sobre los que superaron el umbral (2 créditos), ymode: "full"para las alertas reales (3 créditos). Ver Créditos y modos. - Trazabilidad: Usa
external_idpara correlacionar cada response con el registro correspondiente en tu sistema sin necesidad de almacenar el texto. - El resultado no es una determinación legal. vario detecta señales de riesgo; el CCO y el equipo legal evalúan y deciden.