Overview
API Keys
Keys authenticate your API requests via the X-API-Key header.
Contact raunak@sataklela.com to generate or revoke keys.
| Prefix | Label | Created | Status |
|---|
Usage (last 30 days)
Daily breakdown
| Date | API calls | CVT consumed |
|---|
Billing
Balances
Exemption code
Sataklela core devs only — redeem a Basic (waives billing) or AW (waives the Academic Weapon business-domain check) exemption code.
API Reference
Base URL: https://untxt.uk
Authentication
All API calls must include your API key in the X-API-Key header:
X-API-Key: untxt_your_key_here
POST /api/external/v1/detect
Run AI-text detection on a document. By default, returns the full Analysis verdict — the same Academic Weapon (M13) debate the webapp runs. Pass legacy: true for the cheaper, faster heuristic score other AI detectors show: fast flags, not adjudication.
Auth: X-API-Key | Billing: Analysis (default) is metered — see GET /api/external/v1/portal's apiAnalysisEnabled. legacy: true is 1 CVT per 75 words (min 1).
Breaking change: the old useM13 flag is removed. It used to blend a heuristic score with M13 (30/70) when set to true; that blend is gone. Analysis is now the unflagged default, and the old heuristic-only behaviour is legacy: true.
Request
{
"text": "string // 50–100 000 characters, required",
"legacy": false, // optional, default false — true runs the cheap heuristic score instead of Analysis
"rewrite": null // optional — a style name from /tharoorifier.json; admin-cleared access only
}
Response 200 — default (Analysis / M13)
{
"requestId": "uuid",
"score": 0.0–1.0, // M13 consensus AI likelihood
"isAI": boolean, // true if score ≥ 0.20
"confidence": "low|medium|high",
"cvtCharged": number, // 0 during free trial
"isTrial": boolean,
"modules": {
"m13": { "score": 0.0–1.0, "segments": number, "debateRounds": number, "apiError": bool }
}
}
Response 200 — legacy: true
{
"requestId": "uuid",
"score": 0.0–1.0, // heuristic composite AI likelihood
"isAI": boolean, // true if score ≥ 0.20
"confidence": "low|medium|high",
"cvtCharged": number,
"isTrial": boolean,
"modules": {
"syntacticRegularity": { "score": 0.0–1.0, "apiError": bool },
"forensicStylometry": { "score": 0.0–1.0, "apiError": bool },
"advancedSyntactic": { "score": 0.0–1.0, "apiError": bool, "requiresApiKey": bool }
}
}
Response 200 — with rewrite set
Adds a rewritten field alongside whichever response above applies — admin-cleared accounts only. rewritten.demo is true when no Anthropic key is configured server-side and the text is canned placeholder output, not a real rewrite (not billed in that case).
{
"rewritten": { "style": "Lexical Flourish", "text": "The proposition collapses…" }
}
Example
curl -X POST https://untxt.uk/api/external/v1/detect \
-H "Content-Type: application/json" \
-H "X-API-Key: untxt_your_key_here" \
-d '{"text": "In conclusion, it is important to note that..."}'
# cheaper, faster heuristic score instead of Analysis
curl -X POST https://untxt.uk/api/external/v1/detect \
-H "Content-Type: application/json" \
-H "X-API-Key: untxt_your_key_here" \
-d '{"text": "In conclusion, it is important to note that...", "legacy": true}'
GET /api/external/v1/balance
Check your current CVT balance and billing status.
Response 200
{
"balance": number, // available CVT
"isTrialActive": boolean,
"trialEndsAt": "ISO 8601 date | null"
}
Error codes
| Code | Meaning |
|---|---|
401 | Missing or invalid X-API-Key |
402 | Insufficient CVT balance — top up via your portal dashboard |
403 metered_billing_required | Analysis (default) needs metered billing enabled — see "Enable Analysis" on this page, or retry with legacy: true |
403 tharoorizer_required | Not cleared for the rewrite flag — contact your account manager |
400 | Bad request (text missing, too short, or invalid JSON) |
413 | Text exceeds 100 000 character limit |
429 | Rate limit exceeded (fair-use policy) |
500 | Internal server error |
CVT billing
1 CVT ≈ 75 words. Purchase CVT through your UnTXT account — contact your account manager for bulk pricing.