API

One POST, one probability score. No infrastructure required.

Scope. The API is built for English natural-language LLM responses. Source code, structured output (JSON, XML), and non-English text are outside the trained range and may produce unreliable scores. See Performance for the regimes covered.

How to read the result

p_hallucination(0–1) is how likely the text contains a made-up or wrong “fact” — higher means more suspect. Use flag for a ready-made yes/no, or threshold the score yourself. top_regime is the kind of error: FABRICATED (invented facts), NEAR_FALSE (misleading but technically true), CF_AUTH (fake/misattributed citations), FALSE_REFUSAL (refusing a reasonable request), NORMAL (clean), or Other.

Base URL

https://api.komplexai.io/api

Send your API key as an Authorization: Bearer <key> header. Public sign-ups open at launch.

POST /detect

Runs hallucination detection on a single LLM response.

Request

{
  "response": "The Eiffel Tower was built in 1887 by Gustav Eiffel..."
}
FieldTypeRequiredDescription
responsestringyesLLM response text to evaluate. Example: "The Eiffel Tower is in Paris."
promptstringnoOptional prompt context. Including it enables the prompt+response (pr) head, which is more accurate when context matters. Example: "Where is the Eiffel Tower?"
taskstringnobinary or multiclass. Default multiclass (per-regime breakdown). Pass binary for the headline-score-only path.
input_modestringnoOverride the auto-detect: pr forces the prompt+response head;ro forces response-only. Default: auto (pr if prompt non-empty, else ro).
top_k_regimesintnoNumber of regime scores to return, 1–10 (default: 6 —NORMAL + the 5 advertised hallucination regimes (FABRICATED, NEAR_FALSE,CF_AUTH, FALSE_REFUSAL) and Other, after the v1 server-side collapse policy).

Response

{
  "p_hallucination": 0.73,
  "flag": true,
  "top_regime": "FABRICATED",
  "regime_scores": [
    {"regime": "FABRICATED",    "p": 0.61},
    {"regime": "CF_AUTH",       "p": 0.18},
    {"regime": "NEAR_FALSE",    "p": 0.09},
    {"regime": "NORMAL",        "p": 0.06},
    {"regime": "Other",         "p": 0.05},
    {"regime": "FALSE_REFUSAL", "p": 0.01}
  ],
  "request_id": "req_a1b2c3d4e5f6a7b8",
  "detections_billed": 1,
  "mode": "short",
  "latency_ms": 210,
  "model_version": "nl-v1",
  "calibrator_version": "platt_v1:<cell>",
  "input_mode_used": "ro",
  "task_used": "multiclass",
  "warnings": []
}

Response fields

FieldTypeDescription
p_hallucinationfloat 0–1Calibrated hallucination probability
flagboolConvenience flag — true when p_hallucination crosses the server-side decision threshold for the active (task_used, input_mode_used) cell. The threshold is model-dependent and is NOT a fixed 0.5; the active build's threshold is reflected via calibrator_version. Clients that need a different operating point should re-threshold from p_hallucination directly.
top_regimestringHighest-probability regime code (e.g. FABRICATED, NORMAL).
regime_scoresarrayTop-k regimes with individual scores, sorted descending. Items are {regime, p}. Multiclass sums to ≈1.0.
request_idstringServer-minted ID. Also returned on the X-Request-Id header.
detections_billedintDetections consumed by this call. At v1 each short call is 1.
modestringshort (single-pass) or long (sliding-window; paid-tier, not at v1).
latency_msintServer-side inference time in ms (excludes network).
model_versionstringDetector build identifier. Stable per Modal deployment.
calibrator_versionstringProbability calibrator identifier (Platt / isotonic build).
input_mode_usedstringpr (prompt+response) or ro (response-only). Auto-detected from whether prompt was supplied.
task_usedstringEchoes the task that actually produced p_hallucination. Equals the request's task when explicitly set; otherwise the public /api/detect proxy supplies multiclass (its own default), so omitting task yields multiclass through the public API.
warningsstring[]Advisory codes for this call. Always present; usually []. See the Warnings section for the closed enum and forward-compat rules.

Warnings

The response body always carries a warnings: string[] field (usually []) with advisory codes the proxy attaches based on quota, subscription, and calibration state. Useful for surfacing "you're near your limit" in your app without polling /api/usage/summary.

CodeWhen emitted
quota_80pctUser has used ≥80% of the monthly quota (free + paid tiers both).
quota_95pct≥95%. Last warning before hard-stop on free, or before overage on paid.
overage_activePaid tier with usage above the included limit; this call is billed at the overage rate.
calibration_uncalibratedActive calibrator is an uncalibrated:* placeholder. Rare; should only appear during a model rollout.
input_truncatedInput was truncated to fit the per-call character cap. Reserved — not currently emitted at v1.
subscription_inactiveUser has subscription_status != "active" but is still calling the API.

Forward-compatibility: clients MUST ignore unknown codes. Future model / billing revisions may add codes here without bumping the API version.

Response headers

Every /detect response carries usage and rate-limit headers. Use them to track spend without polling /api/usage/summary.

HeaderTypeDescription
X-Detections-BilledintDetections consumed by this call. At v1 every short call (≤ 2,048 characters) is 1 detection. Long-document detection is planned for a later release and will return values > 1.
X-Quota-RemainingintUnits left in your current billing period.
X-Quota-PeriodstringCurrent billing period in YYYY-MM form (e.g. 2026-05).
X-Request-IdstringServer-minted ID for this request. Quote it in support tickets and dispute audits.

Suggested thresholds

The wire response carries the raw p_hallucination and a convenience flag (server-side threshold; model-dependent, not a fixed 0.5). The bucket cuts below are demo-UI buckets only, not the server flag cut. Clients are free to pick their own thresholds.

Bucketp_hallucination
LOW≤ 0.40
MODERATE0.40 – 0.70
HIGH> 0.70

Example — curl

curl -X POST https://api.komplexai.io/api/detect \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $HALU_API_KEY" \
  -d '{
    "response": "The Eiffel Tower is in Paris, France.",
    "prompt": "Where is the Eiffel Tower?",
    "task": "multiclass"
  }'

Example — Python

import halu

result = halu.detect(
    response="The Eiffel Tower is in Paris, France.",
    prompt="Where is the Eiffel Tower?",
    task="multiclass",
)
print(result.p_hallucination, result.flag, result.top_regime)

For higher-level integration patterns — detect_or_raise (gate output), detect_or_warn (annotate), and regenerate_until_clean (LLM-informed retry) — see the Guide.

Example — JavaScript / TypeScript

const response = await fetch("https://api.komplexai.io/api/detect", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.HALU_API_KEY}`,
  },
  body: JSON.stringify({
    response: "The Eiffel Tower is in Paris, France.",
    prompt: "Where is the Eiffel Tower?",
    task: "multiclass",
  }),
});

if (!response.ok) {
  const err = await response.json();
  throw new Error(`Detect failed: ${err.error || err.detail}`);
}

const result = await response.json();
console.log(`p_hallucination: ${result.p_hallucination}`);
console.log(`flag: ${result.flag}`);
console.log(`top_regime: ${result.top_regime}`);

Use fetch in any JS/TS environment (Node, browser, Vercel, Cloudflare Workers, etc.). An official @komplexai/halu Node package is planned post-launch.

Caveats

  • Input mode is auto-detected. The detector runs in prompt+response (pr) mode when prompt is non-empty, otherwise response-only (ro). In ro mode the detector never sees the prompt, so factual hallucinations that require prompt context may be missed — include the prompt for best accuracy when context matters.
  • Probabilistic output. Scores are calibrated probabilities, not ground truth. See Performance for per-regime accuracy.
  • Max 2,048 characters per field. Longer inputs are rejected with an input_too_long error (HTTP 400) — not truncated.
  • English natural-language only. Code, structured output (JSON, XML), and non-English text are outside the trained range — see Scope above.

Rate limits

Free tier requires a key — sign up with Google to get one instantly. Free tier: 3,700 API requests/month plus 300 web-app detections/month. Higher limits via paid plan — see Pricing.

Have questions? See the FAQ →