Frontend integration guide: REST payloads, WebSockets, secret_key authentication, field semantics, and polar-chart
radar_axes[] on both scan endpoints. Relative API prefix: /api/v1.
Every REST request must include secret_key matching the server
SECRET_KEY in .env. Invalid or missing key: 403.
secret_key in the body alongside text.secret_key as a form field with file.WebSockets: include secret_key in the first JSON frame.
| Method | Path | Purpose |
|---|---|---|
| GET | / | This integration page (HTML) |
| GET | /api/v1/discovery.json | Discovery JSON (machine-readable index) |
| POST | /api/v1/scan/ai-scan | Passage-level Human / AI / Uncertain — scores, radar_axes[], optional source_attribution |
| POST | /api/v1/scan/deep-scan | Sentence-level windows — dual verdicts, radar_axes[] (passage-aligned), scores, labels |
| POST | /api/v1/scan/extract-document-text | Extract plain text from PDF / DOCX / txt |
| POST | /api/v1/scan/document-forensics | Document metadata forensics (PDF / DOCX) |
| WS | /api/v1/explanation/ws/explain-text | Streaming forensic text explanation |
| GET | /docs | Swagger UI |
| GET | /api/v1/openapi.json | OpenAPI JSON |
Polar charts: POST …/ai-scan and POST …/deep-scan both return radar_axes[] — five heuristic dimensions (integer 0–100 each) keyed for stable UI bindings. Derived from submitted text, passage ai_score, and the verdict probability inferred on the server (same basis as Dashboard confidenceValue). Axis semantics and a reference table → Radar axes.
/api/v1/scan/ai-scan — Full-passage classification: Human, AI, or Uncertain. Legacy field
confidence is passage-level P(AI) (same numeric value as ai_score).
Response includes radar_axes[] for polar charts (passage-aligned heuristics). Optional
source_attribution when the passage is flagged AI (vendor hints: OpenAI, Gemini, Claude).
{
"secret_key": "<server SECRET_KEY from .env>",
"text": "Your passage …",
"config": null
}
SECRET_KEY.ParameterConfig (threshold, batch_size, context_sentences, …).{
"prediction": "AI",
"confidence": 0.71,
"is_mixed": false,
"is_ai": true,
"ai_score": 0.71,
"mixed_score": 0.0,
"human_score": 0.29,
"radar_axes": [
{"key": "ai_signal", "label": "AI Signal", "value": 71},
{"key": "uniformity", "label": "Uniformity", "value": 62},
{"key": "confidence", "label": "Confidence", "value": 71},
{"key": "perplexity", "label": "Perplexity", "value": 54},
{"key": "burstiness", "label": "Burstiness", "value": 58}
],
"source_attribution": {
"status": "ok",
"likely_source": "openai",
"likely_label": "OpenAI",
"confidence": 0.42,
"margin": 0.11,
"candidates": [
{"source": "openai", "label": "OpenAI", "score": 0.42},
{"source": "gemini", "label": "Google Gemini", "score": 0.28}
],
"source_display": {
"kind": "single",
"options": [{"source": "openai", "label": "OpenAI · ChatGPT"}],
"show_confidence": true
},
"evidence": ["HF RoBERTa ChatGPT-detector affinity ≈ 62%"],
"method": "hf_chatgpt_roberta+lmscan",
"word_count": 312,
"detail": null
}
}
0 on AI-only passage scan.key, label, integer value); see Radar axes./api/v1/scan/deep-scan — Sentence windows with neighbor context; each row exposes
prediction, ai_probability (P(AI)), and optional model fields when enabled.
Passage-level P(AI) appears as ai_score (alongside human_score).
Dual verdicts: passage_verdict + distribution_verdict; distribution_confidence tiers the sentence-mix label.
radar_axes[] mirrors the passage headline (same inputs as AI scan)—not recomputed from raw sentence-frequency counts alone.
{
"secret_key": "<server SECRET_KEY from .env>",
"text": "Your document …",
"config": null
}
{
"sentences": [
{
"sentence": "…",
"prediction": "AI",
"ai_probability": 0.94
}
],
"distribution_confidence": 0.72,
"passage_verdict": "AI",
"distribution_verdict": "AIWrittenHumanModified",
"deep_labels": ["AI", "AIWrittenHumanModified"],
"overall_prediction": "AI",
"is_mixed": false,
"mixed_ratio": 0.45,
"ai_score": 0.71,
"mixed_score": 0.12,
"uncertain_sentence_ratio": 0.12,
"human_score": 0.29,
"radar_axes": [
{"key": "ai_signal", "label": "AI Signal", "value": 71},
{"key": "uniformity", "label": "Uniformity", "value": 62},
{"key": "confidence", "label": "Confidence", "value": 68},
{"key": "perplexity", "label": "Perplexity", "value": 54},
{"key": "burstiness", "label": "Burstiness", "value": 58}
],
"source_attribution": { }
}
[passage_verdict, distribution_verdict].Multipart: secret_key (form) + file — PDF, DOCX, txt, md. Returns text, word_count, filename.
Multipart: secret_key (form) + file — Metadata forensics (AI-tool fingerprints, editing anomalies, timestamps, fonts). No neural text classifier.
{
"doc_type": "docx",
"filename": "report.docx",
"suspicion_score": 0.34,
"verdict": "Inconclusive",
"signals": [ ],
"editing_behaviour": { },
"summary": "…"
}
Open WebSocket → send one JSON text frame. Use wss: when API is HTTPS.
POST …/deep-scan){
"secret_key": "…",
"prediction": "AI",
"overall_prediction": "AI",
"passage_verdict": "AI",
"distribution_verdict": "AIWrittenHumanModified",
"confidence": 0.71,
"distribution_confidence": 0.72,
"text": "",
"ai_score": 0.71,
"human_score": 0.29,
"mixed_score": 0.12,
"radar_axes": [
{"key": "ai_signal", "label": "AI Signal", "value": 71},
{"key": "uniformity", "label": "Uniformity", "value": 62},
{"key": "confidence", "label": "Confidence", "value": 68},
{"key": "perplexity", "label": "Perplexity", "value": 54},
{"key": "burstiness", "label": "Burstiness", "value": 58}
],
"sentences": [
{
"sentence": "…",
"prediction": "Human",
"ai_probability": 0.19
}
]
}
confidence (same number as scan ai_score); include distribution_prediction when using deep-scan mode.POST …/deep-scan (same shape as REST), including radar_axes — the WS handler ignores facets it does not need.content, partial_textfinal_textmessage| Field | Meaning |
|---|---|
prediction / passage_verdict | Human · AI · Uncertain (passage-level) |
distribution_verdict | Sentence-mix label (see table below) |
deep_labels | [passage_verdict, distribution_verdict] |
is_ai | True when passage is AI or Uncertain (AI scan only) |
distribution_confidence | Blended 0–1 score for distribution verdict (deep scan) |
confidence (AI scan) | Passage P(AI); same numeric value as ai_score |
ai_score | Passage P(AI) (recommended for new clients) |
mixed_ratio | Fraction of sentences classified AI |
mixed_score / uncertain_sentence_ratio | Fraction of sentences with 0.45 ≤ P(AI) ≤ 0.55 |
source_attribution | Vendor hints when passage is AI (≥50 words) |
sentence[].* | sentence, prediction, ai_probability (and optional extras when the model returns them) |
radar_axes[] | AI scan & deep scan: five objects { key, label, value } with integer value 0–100 for polar charts; see axis table |
Privacy: scans processed in memory; benchmarks only under evaluation_results/.
From passage P(AI) vs server threshold ± mixed_offset (default 0.5 ± 0.05):
is_mixed: true on AI scan)On AI scan responses, confidence and ai_score are the same passage-level P(AI) (kept under both names only for backwards compatibility).
Derived from distribution_confidence (0.6 × passage certainty + 0.4 × sentence AI rate):
| Band | AI passage | Human passage |
|---|---|---|
| ≥ 0.75 | AI | Human |
| 0.55 – 0.75 | AIWrittenHumanModified | HumanWrittenAIModified |
| 0.45 – 0.55 | Uncertain | |
| < 0.45 | HumanWrittenAIModified | AIWrittenHumanModified |
When passage verdict is AI and text has ≥ 50 words: fused lmscan stylometrics + optional HF ChatGPT-detector.
UI should prefer source_display (single, dual, or uncertain) over raw candidates.
prediction — AI or Human (argmax).ai_probability — P(AI) for that window; 0.45–0.55 counts toward uncertain_sentence_ratio.radar_axes[])Five deterministic 0–100 integers for polar / spider charts—not extra classifier endpoints.
Derived from submitted text, passage-scale ai_score (P(AI)) and
the headline verdict probability produced during inference on the wire (aligned with Dashboard confidenceValue rounding).
key | Label | Interpretation |
|---|---|---|
ai_signal | AI Signal | Passage AI tendency: ai_score × 100, capped 0–100. |
uniformity | Uniformity | Similarity of sentence lengths (inverse of coefficient of variation). Higher = more regular lengths; lower = more human-like variation. |
confidence | Confidence | Verdict-facing facet from headline probability, scaled to one decimal percent then 0–100 (matches product radar). |
perplexity | Perplexity (proxy) | Lexical heuristic (CTTR-style diversity plus average English token length), not token-level LM perplexity. |
burstiness | Burstiness | Spacing variance of repeated words (gap variance vs average gap). Higher suggests more “bursty” natural rhythm vs flat repetition. |
For UI parity, render radar_axes alongside headline verdict, deep labels (when present), and sentence tallies so charts stay in sync with copy and meters.
/docs · Schema /api/v1/openapi.json