Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.rhetoricaudit.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

POST /api/analyze is the core endpoint of the Rhetoric Audit API. You send article text and optional metadata; the FME V19.1 engine returns a structured forensic evaluation covering ideology classification, manipulation risk, logical fallacies, emotional resonance, source reliability, and more. Responses are cached by URL and content hash — repeated submissions of the same article return instantly at no cost.

Endpoint

POST https://www.rhetoricaudit.com/api/analyze
Content-Type: application/json

Request

text
string
required
The full text of the article to analyze. Must be between 100 and 100,000 characters. Strip HTML before submitting — the engine expects plain text.
title
string
The article title. Optional but recommended — improves classification accuracy and appears in the cached scan record.
url
string
The canonical URL of the article. Used to deduplicate identical content across requests. If omitted, deduplication falls back to a hash of the first 100 characters of text.
userId
string
Your Rhetoric Audit user ID. Required to access the signed_free or paid tier. See Authentication.
deviceId
string
A stable client-generated UUID. Required when no userId is present. At least one of userId or deviceId must be included.
source
string
default:"web"
Where the request originates. Accepted values: extension, web, api, share, popup. Pass api for third-party integrations. This value is stored in the scan event log.

Response

A successful 200 response includes all V18.6 core fields plus optional V19 additive fields when the V19 pipeline is active. The fields below are always present.

Identity and metadata

fmeVersion
string
The FME schema version used to produce this response, e.g. "V18.6" or "19.1-bridge".
aiModelUsed
string
The LLM model that produced the analysis, e.g. "openai/gpt-4o-mini".
analyzedAt
string
ISO 8601 timestamp of when the analysis was run (or when the cached scan was originally created).
title
string
The article title, echoed from the request or "Untitled" if not provided.
url
string
The normalized canonical URL, echoed from the request.
responseTime_ms
number
LLM round-trip time in milliseconds. 0 on cache hits.

Ideology classification

philosophical_frame
string
A short label describing the dominant philosophical framing of the article, e.g. "Nationalist Realism".
political_inclination
number
Score from -100 (far left) to 100 (far right).
classification_confidence
number
Confidence in the ideology classification, 0100.
ambiguity_flag
boolean
true when the article’s ideological framing is intentionally ambiguous or multi-valent.
ideology_scores
object
Scores for each of the ten FME ideology dimensions, each 0100.
winner
string
The ideology with the highest score.
second_place
string
The ideology with the second-highest score.
confidence_gap
number
The numerical gap between the winner and second_place scores. A low gap combined with ambiguity_flag: true indicates weak classification.

Manipulation and logic

manipulation_risk_score
number
Overall manipulation risk, 0100. Higher values indicate more persuasive technique density.
fallacy_density_index
number
Density of logical fallacies relative to article length, 0100.
logic_fractures
array
Array of detected logical fallacies. Empty when none are found.
evidence_validity_index
number
Quality of the evidentiary support in the article, 0100.

Emotion and narrative

emotional_resonance_triad
object
The three dominant emotional levers detected in the text.
narrative_archetype
string
The story structure the article follows, e.g. "Us vs. Them" or "Hero's Journey".
strategic_omissions
string
A prose description of information the article omits that would materially change its framing.
phd_analytical_deduction
string
A detailed analytical narrative written at doctoral level, synthesizing all FME dimensions into a single interpretive summary.

Source and credibility

intent_transparency
number
How transparent the article is about its intent and perspective, 0 (fully obfuscating) to 100 (fully informing).
intellectual_depth
string
Depth-of-knowledge rating: "DOK-1" through "DOK-4".
source_reliability
number
Publisher reliability score, 010. Derived from a known-publisher lookup table; for unknown publishers the LLM estimate is pulled toward the mean.
volatility_correlation
string
Predicted contribution to social volatility: "LOW", "MOD", or "HIGH".
publisher_name
string | null
Detected publisher name, or null if not identified.
author_name
string | null
Detected author name, or null if not identified.

Cache and quota

cached
boolean
true if this response was served from the cache. Cache hits do not consume quota or credits.
cachedScanId
string
Internal UUID of the scan record. Present on both cache hits and fresh analyses.
shortcode
string
Short alphanumeric ID for this scan. Use it to retrieve the scan later via GET /api/scans/{shortcode} or share it at https://www.rhetoricaudit.com/s/{shortcode}.
isPublic
boolean
Whether the scan is publicly accessible via its shortcode URL.
isOwner
boolean
true when the requesting deviceId matches the device that originally created the scan.
tier
string
The tier under which this request was processed: anon, signed_free, paid, or bench.
quota
object | null
Present for anon and signed_free tiers; null for paid.
creditsRemaining
number
Remaining credit balance after this request. Only present for paid tier on cache misses.

Code examples

curl -X POST https://www.rhetoricaudit.com/api/analyze \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Your article text goes here (minimum 100 characters)...",
    "title": "Example Article",
    "url": "https://example.com/article",
    "deviceId": "550e8400-e29b-41d4-a716-446655440000",
    "source": "api"
  }'

Error responses

StatusMeaningWhen it occurs
400Bad requesttext is missing, under 100 chars, or no identity fields provided
422Not an articleThe junk filter rejected the content (e.g. login pages, blank tabs)
429Rate limit exceededDaily quota exhausted for anon or signed_free tier
500Analysis failedUnexpected server error
502Invalid AI responseThe LLM returned malformed JSON that could not be parsed into the V18.6 schema
503AI service unavailableBoth the primary and fallback AI models are unavailable — retry with exponential backoff
The 422 response includes a reason field with a short string describing why the content was rejected, and rejected: true. This is normal for pages that are not news articles — for example, the Chrome extension gates on this check client-side before sending to the API.