Development: http://localhost:8000
Production: https://api.spkia.org
No authentication required. The service is publicly accessible.
- General API: 10 requests/second
- Upload endpoint: 2 requests/second
POST /api/verify
Upload a media file for authenticity verification.
Request:
- Content-Type:
multipart/form-data - Body:
file(image or video file)
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending"
}Status Codes:
200 OK: File accepted413 Payload Too Large: File exceeds 100MB limit400 Bad Request: Invalid file type500 Internal Server Error: Server error
cURL Example:
curl -X POST http://localhost:8000/api/verify \
-F "file=@/path/to/image.jpg"POST /api/verify-url
Verify a media file from a URL.
Request:
{
"url": "https://example.com/image.jpg"
}Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending"
}Status Codes:
200 OK: URL accepted400 Bad Request: Invalid URL or download failed413 Payload Too Large: File exceeds 100MB limit500 Internal Server Error: Server error
cURL Example:
curl -X POST http://localhost:8000/api/verify-url \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/image.jpg"}'GET /api/verify/{job_id}
Retrieve verification results for a job.
Parameters:
job_id(path): Job identifier from upload response
Response (Processing):
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"reasons": [],
"created_at": "2025-10-02T10:30:00Z",
"updated_at": "2025-10-02T10:30:05Z"
}Response (Completed - Authentic Camera):
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"label": "authentic_camera",
"confidence": 0.95,
"reasons": [
"Valid sensor-PKI signature from Sony Alpha 7R V",
"C2PA manifest verified"
],
"details": {
"c2pa": {
"valid": true,
"issuer": "Sony",
"trust_chain_valid": true
},
"sensor_pki": {
"valid": true,
"manufacturer": "Sony",
"camera_model": "Alpha 7R V",
"sensor_id": "IMX989-12345",
"signature_algorithm": "ES256"
},
"ml_detection": null
},
"created_at": "2025-10-02T10:30:00Z",
"updated_at": "2025-10-02T10:30:08Z"
}Response (Completed - AI Generated):
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"label": "likely_ai_generated",
"confidence": 0.88,
"reasons": [
"ML classifiers indicate AI-generated (probability: 0.85)",
"CNN detected high artifact probability",
"PRNU pattern inconsistent with real camera"
],
"details": {
"c2pa": {
"valid": false,
"error": "No C2PA manifest found"
},
"sensor_pki": {
"valid": false,
"error": "No sensor-PKI signature found"
},
"ml_detection": {
"ai_probability": 0.85,
"cnn_score": 0.92,
"prnu_score": 0.78,
"metadata_anomaly_score": 0.65,
"ensemble_confidence": 0.88,
"detected_generator": "Stable Diffusion",
"artifacts_found": [
"CNN detected high artifact probability",
"PRNU pattern inconsistent with real camera"
]
}
},
"created_at": "2025-10-02T10:30:00Z",
"updated_at": "2025-10-02T10:30:12Z"
}Status Codes:
200 OK: Results retrieved404 Not Found: Job not found500 Internal Server Error: Server error
cURL Example:
curl -X GET http://localhost:8000/api/verify/550e8400-e29b-41d4-a716-446655440000Polling Recommendation:
Poll every 2-3 seconds until status is completed or failed.
DELETE /api/verify/{job_id}
Force immediate deletion of verification job and data.
Parameters:
job_id(path): Job identifier
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"deleted": true,
"message": "Job and associated data deleted successfully"
}Status Codes:
200 OK: Successfully deleted404 Not Found: Job not found500 Internal Server Error: Server error
cURL Example:
curl -X DELETE http://localhost:8000/api/verify/550e8400-e29b-41d4-a716-446655440000GET /health
Check service health status.
Response:
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2025-10-02T10:30:00Z",
"database": "connected",
"ml_models_loaded": true
}Status Codes:
200 OK: Service is healthy
cURL Example:
curl -X GET http://localhost:8000/healthGET /api/metrics?days=7
Get aggregated anonymized metrics.
Parameters:
days(query, optional): Number of days to aggregate (default: 7)
Response:
{
"total_verifications": 1523,
"authentic_camera": 892,
"authentic_c2pa": 245,
"ai_generated": 312,
"unknown": 74,
"avg_processing_time": 1847.5
}Status Codes:
200 OK: Metrics retrieved
type VerificationStatus = 'pending' | 'processing' | 'completed' | 'failed';type AuthenticityLabel =
| 'authentic_camera' // Sensor-PKI verified
| 'authentic_c2pa' // C2PA verified (no sensor-PKI)
| 'likely_ai_generated' // ML detection > threshold
| 'unknown' // Inconclusive
| 'error'; // Verification error- Range:
0.0to1.0 - Higher values indicate stronger confidence
authentic_cameratypically: 0.95-0.98authentic_c2patypically: 0.85-0.92likely_ai_generatedtypically: 0.70-0.95unknowntypically: 0.40-0.60
All error responses follow this format:
{
"error": "Error message",
"detail": "Detailed explanation (optional)",
"job_id": "job_id (optional)"
}Common Errors:
400 Bad Request: Invalid request parameters404 Not Found: Resource not found413 Payload Too Large: File exceeds size limit429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server error
- Polling: Poll
/api/verify/{job_id}every 2-3 seconds - Cleanup: Call
DELETE /api/verify/{job_id}after retrieving results - File Size: Keep files under 100MB
- Rate Limiting: Respect rate limits (2 req/s for uploads)
- Error Handling: Implement retry logic with exponential backoff
Swagger UI: http://localhost:8000/docs
ReDoc: http://localhost:8000/redoc
- 📧 Email: api@spkia.org
- 🐛 Issues: https://github.com/your-org/spkia/issues
- 📖 Docs: https://docs.spkia.org