API

Everything the web app does is available as a JSON API. Interactive reference: /docs.

Analyze a text

curl -s https://stoprop.tech/api/analyze \
  -H 'Content-Type: application/json' \
  -d '{"text": "Everyone knows the plan failed.", "sensitivity": "balanced", "private": false}'

Returns highlighted spans (start/end offsets, label, colour, confidence, plain-language explanation, reported_speech, experimental), a profile, innocent_explanations, mode (llm or heuristics_only) and token cost. sensitivity: strict (default) | balanced | broad (no confidence filter); measured trade-offs on Metrics. private: true means the text is not written to the shared cache.

Offsets are Unicode code points (Python string indices). In JavaScript, convert them before slicing strings that contain emoji or other characters outside the Basic Multilingual Plane.

Analyze a link

curl -s https://stoprop.tech/api/analyze   -H 'Content-Type: application/json'   -d '{"url": "https://news.err.ee/..."}'

Stoprop fetches public web pages only (private, local and cloud-metadata addresses are refused, every redirect is re-checked, 8 s / 2 MB limits), extracts the main text, and returns it as text together with source (title, final URL, date) and receipts for the domain.

Check a source (receipts only, no AI)

curl -s https://stoprop.tech/api/receipts   -H 'Content-Type: application/json'   -d '{"domain": "err-news.ee"}'

Each receipt: type, status (found | not_found | not_checked | error), flag (ok | warning | neutral), plain-English text, evidence_url, checked_at. Add "refresh": true to re-check items older than 15 minutes.

Swarm mode (coordinated behaviour)

curl -s -X POST https://stoprop.tech/api/swarm \
  -H 'Content-Type: text/csv' --data-binary @posts.csv

curl -s -X POST https://stoprop.tech/api/swarm -H 'Content-Type: application/json' \
  -d '{"data": "id,author,timestamp,text\n1,alice,2026-11-14T10:00:00Z,Hello", "deep": false}'

# a public post link: the post and its replies (Bluesky, Mastodon, YouTube)
curl -s -X POST https://stoprop.tech/api/swarm -H 'Content-Type: application/json' \
  -d '{"url": "https://bsky.app/profile/bsky.app/post/3mzhhvhjfwk22"}'

# up to 50 links, one post each; "stream": true sends NDJSON progress lines, then {"result": ...}
curl -s -N -X POST https://stoprop.tech/api/swarm -H 'Content-Type: application/json' \
  -d '{"urls": ["https://bsky.app/profile/…/post/…", "https://mastodon.social/@…/…"], "stream": true}'

Columns id, author, timestamp, text (optional url, author_created_at, platform), CSV or JSON, max 2000 posts / 2 MB, processed in memory and never stored. Returns clusters (groups of accounts posting the same or near-identical text), each with a verdict (likely_coordinated | worth_watching | organic_looking | insufficient_data), families (T text reuse, S timing, A accounts, M amplification), evidence_for, evidence_against, innocent_explanations, authors and a timeline; plus skipped rows with reasons. deep (embeddings) and tag_clusters (max 10 AI calls) cost credits and are off by default.

Trace a post

curl -s -X POST https://stoprop.tech/api/trace -H 'Content-Type: application/json'   -d '{"url": "https://bsky.app/profile/bsky.app/post/3mzhhvhjfwk22"}'

Body {"text": ...} or {"url": ...} (add "stream": true for progress lines). Returns the fingerprints searched, coverage (what was and was not searched), spread (first seen, timeline, websites with domain checks, accounts), the verdict and cluster evidence, and every kept result in copies. Public data only, nothing stored, 5 traces per hour.

Taxonomy

curl -s https://stoprop.tech/api/techniques

Health and AI budget

curl -s https://stoprop.tech/api/health

Rate limits

Per client IP, per hour: analyze 30, receipts 60, swarm 10, feedback 30. Over the limit you get HTTP 429 with a plain message.

Evaluation results: GET /api/metrics.