Spaces:
Running
title: BitCheck Image Verification API
sdk: docker
app_port: 7860
pinned: false
BitCheck Image Verification Backend
BitCheck is a multi-signal image verification API. It does not claim that an image is definitely fake or definitely real. It combines validation, metadata, provenance, visible watermark checks, lightweight forensics, a PyTorch classifier, and Grad-CAM explainability into a risk-based JSON report.
Architecture
POST /verify/image runs these signals where available:
- File validation for JPG, JPEG, PNG, and WEBP uploads.
- SHA256 hash, dimensions, mode, MIME type, and file size extraction.
- Filename analysis for AI-generation keywords.
- EXIF, XMP, PNG text chunks, software, creator, camera, lens, exposure, ISO, and GPS metadata analysis.
- AI-tool metadata marker detection.
- Optional C2PA / Content Credentials analysis through
c2patool. - Visible watermark OCR using
pytesseract. - Visible watermark template matching with OpenCV templates in
templates/watermarks/. - CPU-friendly forensic checks for sharpness, noise, compression, blur, edge density, and brightness/contrast anomalies.
- PyTorch EfficientNet classifier inference.
- Grad-CAM heatmap, overlay, and boxed high-influence regions.
- Dynamic weighted trust scoring.
The classifier is one signal, not the final authority.
Model
BitCheck first looks for:
models/bitcheck_efficientnet_b0_production.pth
For local compatibility it can fall back to the included EfficientNet-B0 checkpoints under models/. If no model is available, the API still returns a partial report from the other modules.
Run Locally
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 7860
Dependencies are pinned to CPU-only PyTorch and TorchVision wheels. BitCheck does not require CUDA or GPU runtime packages.
Open:
http://127.0.0.1:7860/docs
Browser test console:
http://127.0.0.1:7860/test-client
API
GET /returns service info.GET /healthreturns classifier, OCR, C2PA, and device status.GET /test-clientopens a browser test console for manual uploads.POST /verify/imageaccepts multipart image uploads.GET /reports?user_email=user@example.comlists persisted report summaries for one user.GET /reports/{verification_id}returns a persisted report.GET /outputs/{filename}serves generated Grad-CAM and forensic output images.
Example request:
curl -X POST "http://127.0.0.1:7860/verify/image" \
-F "user_email=user@example.com" \
-F "file=@sample.jpg" \
-F "run_explainability=true" \
-F "run_ocr=true" \
-F "run_forensics=true" \
-F "run_c2pa=true"
Required fields:
user_emailfile
Optional fields:
thresholdrun_explainabilityrun_ocrrun_forensicsrun_c2pa
Example Response Shape
{
"verification_id": "uuid",
"service": "BitCheck",
"file_type": "image",
"status": "completed",
"processing_time_ms": 1234.5,
"user_email": "user@example.com",
"input": {
"filename": "example.png",
"sha256": "...",
"width": 1024,
"height": 1024,
"format": "PNG",
"mode": "RGB",
"mime_type": "image/png",
"file_size_bytes": 123456
},
"filename_analysis": {},
"metadata": {},
"provenance": {},
"visible_watermark_ocr": {},
"visible_watermark_template": {},
"synthid": {
"checked": false,
"status": "not_available",
"reason": "No official SynthID detector/API integrated."
},
"classifier": {},
"forensics": {},
"explainability": {},
"trust": {},
"risk_flags": [],
"recommended_actions": [],
"limitations": []
}
Grad-CAM
When the classifier is loaded and run_explainability=true, BitCheck writes:
/outputs/{verification_id}_gradcam_heatmap.jpg/outputs/{verification_id}_gradcam_overlay.jpg/outputs/{verification_id}_gradcam_boxes.jpg
Grad-CAM shows regions that influenced the model prediction. It is not proof of manipulation.
Hugging Face Spaces
Create a Docker Space and push this repository. The Dockerfile:
- uses
python:3.11-slim - installs
tesseract-ocr,libgl1, andlibglib2.0-0 - installs Python dependencies from
requirements.txt - exposes port
7860 - runs
uvicorn main:app --host 0.0.0.0 --port 7860
Limitations
BitCheck is honest by design:
- Missing metadata is a weak signal, not proof.
- Missing C2PA provenance is not proof of AI generation.
- OCR can miss or misread visible text.
- Template matching only works when templates are provided.
- Forensic checks are lightweight indicators.
- The classifier is probabilistic.
- No official SynthID detector/API is integrated.