A cross-browser extension + local backend for detecting AI-generated images, videos, and articles — with built-in fact-checking powered by Google Gemini and web search grounding.
AI-generated media is increasingly realistic and widespread. Slop-Detector gives users instant, on-demand detection scores and fact-checks for any image, video, or article — right from their browser. It combines the AI-or-Not API for confidence scoring with Gemini-powered analysis for deeper inspection, running everything through a local FastAPI backend so API keys never touch the browser.
Target users: Journalists, researchers, educators, fact-checkers, and anyone who wants to verify the authenticity of online media.
- Right-click any image to scan it instantly via context menu
- Page picker — interactively select any image with a visual overlay
- File upload — upload an image from your device
- Batch scan — scan every image on the current page at once with configurable sensitivity
- Auto-scan — optionally scan images automatically on page load
- Inline badges — color-coded confidence badges appear directly on the page
- URL analysis — paste any YouTube, TikTok, or direct video URL
- File upload — upload a video from your device (max 200 MB, 30 seconds)
- Gemini analysis — AI detection + structured fact-check of key claims with verdicts
- Too-long handling — videos over 60 seconds return a download token for a trimmed clip
- Grab current page — extracts article text from the active tab automatically
- Paste text — paste any article, headline, or content directly
- AI detection — score (0–100), writing pattern signals, and plain-English summary
- Fact-check — extracts claims, verifies them via Gemini with Google Search grounding, returns a verdict and source articles
- Scan history — up to 50 past results with thumbnails, scores, and timestamps
- Result caching — 7-day TTL per URL so repeated scans are instant
- Backend fallback — if the local backend is unreachable, falls back directly to the AI-or-Not API
- Connection indicator — live status dot shows whether the backend is reachable
AI_Slop_Detector/
├── backend/
│ ├── main.py # FastAPI app, CORS, health endpoint
│ ├── helper.py # API key loading from apikeys.env
│ ├── apikeys.env # API keys (not committed)
│ ├── pyproject.toml # Python dependencies (uv)
│ ├── routes/
│ │ ├── image.py # /image endpoints
│ │ ├── video.py # /video endpoints
│ │ ├── text.py # /text endpoints
│ │ └── factcheck.py # /factcheck endpoints
│ └── services/
│ ├── image_service.py # AI-or-Not + Gemini image logic
│ ├── video_service.py # AI-or-Not + Gemini video logic
│ ├── text_service.py # Gemini text AI detection
│ └── factcheck_service.py# Gemini claim extraction + web-grounded fact-check
└── frontend/
├── manifest.json # MV3 extension manifest
├── background/
│ └── background.js # Service worker, message bus, context menu
├── content/
│ ├── content.js # Page badges, element picker, image collection
│ └── content.css # Badge and overlay styles
├── popup/
│ ├── popup.html # Popup UI — Image, Video, Article tabs
│ ├── popup.js # Tab logic, API calls, result rendering
│ └── popup.css # Popup styles with dark mode support
└── utils/
└── api.js # Fetch utilities, score normalization, caching
- Python 3.10+
- uv (or pip)
- Chrome or Firefox
- AI-or-Not API key
- Google Gemini API key
cd backend
uv venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
uv syncCreate backend/apikeys.env:
AIORNOT_KEY=your_aiornot_api_key
GEMINI_API_KEY=your_gemini_api_keyStart the server:
uvicorn main:app --reloadConfirm it's running: http://localhost:8000/health
Optional: Install
ffprobe(part of FFmpeg) to enable video duration enforcement on uploads. Installyt-dlpfor downloading YouTube/TikTok/Instagram videos for fact-checking.
Chrome / Chromium:
- Go to
chrome://extensions - Enable Developer mode
- Click Load unpacked and select the
frontend/folder
Firefox:
- Go to
about:debugging#/runtime/this-firefox - Click Load Temporary Add-on
- Select
frontend/manifest.json
Open the extension popup. Settings are accessible via the browser's extension settings or the Settings tab (if present):
| Setting | Description | Default |
|---|---|---|
| AI-or-Not API Key | Direct fallback key used when the backend is unreachable | — |
| Backend Endpoint | URL of the local FastAPI server | http://localhost:8000 |
| Auto-scan on page load | Proactively scan images when a page loads | Off |
| Sensitivity | Minimum image size included in batch/auto scans (High: 0px, Medium: 150px, Low: 350px) | Medium |
Keyboard shortcut: Ctrl+Shift+U / Cmd+Shift+U — open the popup
| Method | Path | Description |
|---|---|---|
GET |
/health |
Returns {"status": "ok", "timestamp": "..."} |
| Method | Path | Body | Description |
|---|---|---|---|
POST |
/image/ |
file: UploadFile |
Detect AI in uploaded image (AI-or-Not) |
POST |
/image/url |
{"url": "..."} |
Detect AI in image by URL (AI-or-Not) |
POST |
/image/gemini/upload |
file: UploadFile |
Describe uploaded image with Gemini |
POST |
/image/gemini/url |
{"url": "..."} |
Describe image by URL with Gemini |
POST |
/image/gemini/youtube |
{"url": "..."} |
Analyze YouTube video with Gemini |
| Method | Path | Body | Description |
|---|---|---|---|
POST |
/video/ |
file: UploadFile |
Detect AI in uploaded video (max 200 MB, 30s) |
POST |
/video/url |
{"url": "..."} |
Detect AI in video by URL (AI-or-Not) |
POST |
/video/gemini/upload |
file: UploadFile |
Upload video → Gemini AI detection + fact-check |
POST |
/video/gemini/url |
{"url": "..."} |
Video URL → Gemini AI detection + fact-check |
| Method | Path | Body | Description |
|---|---|---|---|
POST |
/text/analyze |
{"text": "...", "url": "...?"} |
AI detection on text — returns score, signals, claims, summary |
| Method | Path | Body | Description |
|---|---|---|---|
POST |
/factcheck/text |
{"text": "..."} |
Extract claims + web-grounded fact-check |
POST |
/factcheck/video/url |
{"url": "..."} |
Download video → extract claims → fact-check (returns download token if >60s) |
POST |
/factcheck/video |
file: UploadFile |
Upload video → extract claims → fact-check |
GET |
/factcheck/video/download/{token} |
— | Download a trimmed video clip |
{
"verdict": "likely_real | uncertain | likely_ai",
"ai_score": 42,
"ai_signals": ["no named sources", "generic list structure"],
"claims": [{"text": "...", "assessment": "supported | contradicted | unverifiable", "explanation": "..."}],
"summary": "Plain English summary of findings."
}{
"claims": ["Claim one", "Claim two"],
"factuality_score": 75,
"verdict": "Mostly True",
"explanation": "2–3 sentence summary.",
"articles": [{"title": "...", "url": "...", "snippet": ""}]
}Scores represent the likelihood the content is real (not AI-generated):
| Score | Label | Meaning |
|---|---|---|
| 61–100% | Likely Real | Low AI signal |
| 31–60% | Uncertain | Mixed signals |
| 0–30% | Likely AI-Generated | High AI signal |
For fact-check verdicts:
| Verdict | Factuality Score |
|---|---|
| True | 86–100 |
| Mostly True | 61–85 |
| Uncertain | 31–60 |
| False | 0–30 |
| Layer | Technology |
|---|---|
| Browser extension | Vanilla JS, Manifest V3 |
| Backend framework | Python, FastAPI, Uvicorn |
| Image/video detection | AI-or-Not API v2 |
| AI analysis & fact-check | Google Gemini 2.5 Flash |
| Web search grounding | Gemini Google Search tool |
| Video download | yt-dlp |
| Video metadata | ffprobe (optional) |
| HTTP client (backend) | httpx |
| HTTP client (frontend) | fetch API |
| Image processing | Pillow |
| Data validation | Pydantic v2 |
