docs.vario.lat
This page was machine-translated and is pending human review.

POST /api/v1/analyze

Analyzes a text for signals of irregular conduct. The endpoint is stateless: each request is independent and does not store the submitted text. The result is a risk assessment that the caller can use to make triage decisions or escalate to legal review.


Authentication

Requires an active API key with the analyze:run scope.

Authorization: Bearer vario_YOUR_API_KEY

The API key is generated from the developer portal. To generate or rotate a key, see Authentication & API keys.


Rate limit

See Errors & rate limits for per-tier limits and the behavior of the Retry-After header.


Request body

Content-Type: application/json

FieldTypeRequiredDescription
textstringYesText to analyze. Maximum 8,000 characters (approximately 1,300 words). For longer documents, split the content into chunks and send separate requests.
languagestringYesLanguage of the text. Values: "es" (Spanish) or "pt" (Portuguese).
playbookstringYesType of conduct to detect. Values: "price_fixing" · "bid_rigging" · "bribery" · "market_manipulation" · "information_exchange" · "group_boycott". Query GET /api/v1/playbooks for the current list and the languages supported by each type.
modestringNoAnalysis mode. "screening": L1 layer only (keyword + embedding, no LLM) — 1 credit, the most economical, for mass corpus sweep. "fast": L1 + L2 (light LLM) — 2 credits, moderate precision. "full" (default): L1 + L2 + L3 (deep LLM) — 3 credits, maximum precision with full reasoning.
thread_contextarray[string]NoUp to 10 previous messages in the thread, in chronological order. Each element has a maximum of 500 characters. Providing thread context improves analysis precision. Default: [].
external_idstringNoYour system's identifier for this message (for example, the email ID in your database). vario does not process this value — it returns it as-is in the response to facilitate traceability in your integration.

Response

Content-Type: application/json · HTTP 200 OK

FieldTypeDescription
combined_scorefloat [0–10]Risk score from 0 to 10. Higher values indicate a stronger risk signal.
should_alertbooleantrue if the analysis detected a risk signal sufficient to require review.
severitystringRisk category: "critical" · "high" · "medium" · "low".
reasoningstringExplanation of the result in the language of the analysis. May be empty if deep analysis was not available for this call.
key_phrasesarray[string]Exact fragments of the text that the system identified as evidence of the evaluated conduct.
regulatory_frameworksarray[string]Regulatory frameworks applicable to the analyzed conduct type.
conduct_typestringConduct detected by the pipeline. Open classification: may differ from the requested playbook. Closed domain of 7 values: "price_fixing" · "bid_rigging" · "bribery" · "market_manipulation" · "information_exchange" · "group_boycott" · "none". Always "none" when processing_path="l1_discard". Absent in screening mode.
recommended_actionstringSuggested action. Closed domain, tier-dependent — fast/l2_pass/degraded: "no_action" · "monitoring" · "legal_review"; full mode (L3 passthrough): adds "open_case" · "dismiss" · "immediate_escalation". This is a system recommendation; the reviewer decides.
confidencestringConfidence level of the result: "high" · "medium" · "low".
processing_pathstring | nullPipeline stage that produced this response. Non-breaking field: clients that do not know it ignore it without error. See table below.
mode_usedstringConfirms the mode executed in this call: "screening", "fast", or "full". In screening mode the response schema is different — see the section below.
analyzed_atstringISO 8601 UTC timestamp of the analysis moment.
pipeline_versionstringVersion of the detection engine (opaque string). Useful for traceability if behavior changes between versions.
bedrock_availablebooleanIndicates whether deep analysis was available for this call. If false, the response is partial.

processing_path — pipeline behavior

The pipeline applies early-exit gates to avoid unnecessary invocations. The processing_path field identifies which stage produced the response.

ValueWhenBedrock invokedLatency
"l1_discard"L1 score below minimum threshold. combined_score=0.0. Text was not analyzed by any LLM.No< 200 ms
"screening"screening mode — L1 scores only.No20–150 ms
"l2_pass"L2 reliable (low or high score), no urgent signal. L3 not necessary.L2< 1.5 s
nullfast mode completed (L2, no L3 gate by design). Also returned when Bedrock failed in L2 (degraded path) — in that case bedrock_available=false. Disambiguate with bedrock_available.L2200–800 ms
(additional values)full mode may return additional values identifying the depth of deep analysis. Pending documentation — use .unknown() or allow-unknown-enum-values for forward compatibility.L2 + L32–8 s
ℹ

Note for forensic tools: "l1_discard" is not a deep verdict of innocence — the text was not analyzed by any LLM. If certainty is required, re-send in screening mode to get L1 scores and decide whether to escalate.

ℹ

Charge on l1_discard: the credit is deducted before the analysis. If text does not pass the L1 threshold in fast or full mode, the credit is still charged. To protect credits in corpora with trivial text, use mode: "screening" first (see Credits & modes).

ℹ

Privacy: vario does not store or retain the text submitted to this endpoint. Analysis is ephemeral.


Response in screening mode

When mode is "screening", the response has a different schema from fast and full modes. It only includes L1 layer results (keyword + embedding). The L2/L3 fields (combined_score, should_alert, severity, reasoning, etc.) are not present.

FieldTypeDescription
mode_usedstring"screening"
l1_scorefloat [0–1]Aggregated L1 score: max(l1_keyword_score, l1_embedding_score).
l1_keyword_scorefloat [0–1]Keyword detection score.
l1_embedding_scorefloat [0–1]Semantic similarity score via embeddings.
l1_matched_termsarray[string]Terms in the text that triggered L1 detection.
l1_embedding_availablebooleantrue if the embedding service was available for this call.
playbookstringEcho of the playbook in the request.
playbook_versionstringVersion of the playbook used.
pipeline_versionstringVersion of the analysis engine.
analyzed_atstring (ISO 8601)UTC timestamp of the analysis.
external_idstring | nullEcho of the external_id sent in the request.

Example response in screening mode:

{
  "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"
}
ℹ

Documents with a low l1_score (e.g. < 0.3) can be discarded without further analysis. Those that exceed the threshold should proceed to fast or full mode for a complete analysis.


Degradation behavior

If the deep analysis service is not available, the endpoint responds with HTTP 200 and bedrock_available: false. In that case, reasoning may be empty and combined_score reflects only the local analysis.

If you prefer to receive an explicit error instead of a partial response, add the header:

Prefer: deep-analysis-required

With this header, the endpoint responds 503 DEEP_ANALYSIS_UNAVAILABLE when deep analysis is not available.


Complete example

Request

curl -X POST https://api.vario.lat/v1/analyze \
  -H "Authorization: Bearer vario_YOUR_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"
}

Errors specific to this endpoint

For the complete reference of error codes and rate limits, see Errors & rate limits.

HTTPCodeCause
400INVALID_PLAYBOOKThe playbook value does not exist in the catalog.
400INVALID_LANGUAGEThe specified language is not supported for that playbook.
400INVALID_MODEThe mode value is not valid. Accepted values: "screening", "fast", "full".
400TEXT_TOO_LONGThe text field exceeds 8,000 characters.
400CONTEXT_TOO_LONGthread_context exceeds 10 elements, or one of them exceeds 500 characters.
401INVALID_API_KEYThe API key is invalid, inactive, or expired.
401MISSING_AUTHThe Authorization header is not present.
402INSUFFICIENT_CREDITSThe tenant's credit balance is 0.
403INSUFFICIENT_SCOPEThe API key does not have the analyze:run scope.
422VALIDATION_ERRORThe request body does not conform to the schema.
429RATE_LIMIT_EXCEEDEDThe call limit was exceeded.
503DEEP_ANALYSIS_UNAVAILABLEOnly returned if Prefer: deep-analysis-required was sent and deep analysis is not available.
500PIPELINE_ERRORInternal error in the detection system.

Usage notes

  • Chunking: For texts exceeding 8,000 characters, split the content into fragments and send one request per fragment. Use thread_context to pass thread context, not to fragment the text field.
  • Three-stage funnel: When volume is high, use mode: "screening" to discard text without L1 signal (1 credit), mode: "fast" for those that pass the threshold (2 credits), and mode: "full" for real alerts (3 credits). See Credits & modes.
  • Traceability: Use external_id to correlate each response with the corresponding record in your system without needing to store the text.
  • The result is not a legal determination. vario detects risk signals; the CCO and legal team evaluate and decide.
The API output is a risk signal, not a legal determination. It does not substitute a lawyer's review and does not constitute evidence before regulators on its own.