X-RAY API Reference
Integrate AI image detection directly into your applications. A single POST request returns a full forensic verdict in under 2 seconds.
https://xray-ai.xyzIntroduction
The X-RAY API allows you to programmatically analyze images for AI-generated content. All requests must be authenticated with an API key. API access is available on Pro and Enterprise plans.
Authentication
Pass your API key in the Authorization header as a Bearer token. Generate keys from your cabinet under the API tab.
Authorization: Bearer xray_sk_your_api_key_herecurl -X POST https://xray-ai.xyz/analyze \
-H "Authorization: Bearer xray_sk_your_api_key_here" \
-H "Content-Type: multipart/form-data" \
-F "[email protected]"Analyze Image
/analyzeAnalyze an image for AI-generated contentSubmit an image file and receive a full forensic analysis result. The response includes a verdict, confidence score, and per-signal breakdown.
Request
imageFileImage file to analyze (required)Response
{
"verdict": "Real Photo",
"is_ai": false,
"confidence": 56.5,
"composite": 51.4,
"signals": [
{
"name": "Primary Neural",
"key": "primaryNeural",
"level": "hi",
"score": 51.1,
"model": "· DINOv2 + EfficientNet",
"desc": "Deep neural network trained on millions of real and AI-generated images. Primary verdict driver.",
"interp": "Model is highly confident this image was generated by an AI system."
},
{
"name": "Secondary Neural",
"key": "secondaryNeural",
"level": "hi",
"score": 69.3,
"model": "· ViT",
"desc": "Vision Transformer trained on GAN, diffusion, and real image datasets. Cross-validates the primary model.",
"interp": "Secondary model confirms AI generation — double consensus detected."
},
{
"name": "Frequency Anomaly",
"key": "frequencyAnomaly",
"level": "lo",
"score": 45.4,
"model": "FFT spectrum analysis",
"desc": "FFT spatial frequency analysis. AI images have smoother spectra. JPEG compression can mimic this.",
"interp": "Natural frequency distribution consistent with real camera optics."
},
{
"name": "Noise Distribution",
"key": "noiseDistribution",
"level": "lo",
"score": 23.9,
"model": "Block-wise variance analysis · 16×16 px",
"desc": "Measures spatial unevenness of pixel noise. Real cameras produce scene-dependent noise.",
"interp": "Natural, scene-dependent noise variance — strong real-camera indicator."
},
{
"name": "Color Coherence",
"key": "colorCoherence",
"level": "lo",
"score": 32.0,
"model": "Pearson cross-channel RGB correlation",
"desc": "Measures R/G/B channel correlation. AI generators often produce overly correlated channels.",
"interp": "Natural channel independence consistent with real photography."
}
],
"meta": {
"width": 1280,
"height": 720,
"file_size": 115335,
"format": "image/jpeg",
"filename": "photo.jpg"
},
"usage": {
"used": 4,
"limit": 500,
"role": "pro"
}
}Examples
import requests
API_KEY = "xray_sk_your_api_key_here"
BASE = "https://xray-ai.xyz"
with open("photo.jpg", "rb") as f:
resp = requests.post(
f"{BASE}/analyze",
headers={"Authorization": f"Bearer {API_KEY}"},
# Content-Type: multipart/form-data (with boundary) is set by requests automatically.
# Do NOT set it manually — the boundary would be lost and the request would fail.
files={"image": ("photo.jpg", f, "image/jpeg")},
)
data = resp.json()
print(f"Verdict: {'AI' if data['is_ai'] else 'Real'}")
print(f"Confidence: {data['confidence']:.1f}%")const API_KEY = "xray_sk_your_api_key_here";
const BASE = "https://xray-ai.xyz";
async function analyzeImage(file) {
// FormData automatically sets Content-Type: multipart/form-data with boundary
const form = new FormData();
form.append("image", file);
const resp = await fetch(`${BASE}/analyze`, {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
// Do NOT set Content-Type manually — browser sets it with the correct boundary
body: form,
});
const data = await resp.json();
console.log(`Verdict: ${data.is_ai ? "AI" : "Real"}`);
console.log(`Confidence: ${data.confidence.toFixed(1)}%`);
return data;
}Check Usage
Query your current subscription plan, monthly check limit, and remaining checks. Useful for building usage dashboards or enforcing client-side quotas.
/me/usageGet current plan and check usagecurl https://xray-ai.xyz/me/usage \
-H "Authorization: Bearer xray_sk_your_api_key_here"Response
{
"plan": "pro",
"checks_used": 47,
"checks_limit": 500,
"remaining": 453
}planstringSubscription role: pro, enterprise, adminchecks_usedintegerChecks consumed this monthchecks_limitintegerMonthly limit (0 = unlimited)remaininginteger | nullChecks left this month (null = unlimited)import requests
resp = requests.get(
"https://xray-ai.xyz/me/usage",
headers={"Authorization": "Bearer xray_sk_your_api_key_here"},
)
data = resp.json()
print(f"Plan: {data['plan']}")
print(f"Used: {data['checks_used']} / {data['checks_limit'] or '∞'}")
if data['remaining'] is not None:
print(f"Remaining: {data['remaining']}")Errors
The API uses standard HTTP status codes. Error responses include a detail field.
400Bad RequestInvalid file type or missing field401UnauthorizedMissing or invalid API key403ForbiddenPlan does not include API access413Too LargeImage exceeds 20 MB limit429Rate LimitedMonthly check quota exceeded500Server ErrorInternal error — retry after a moment{
"detail": "Monthly check limit reached"
}Rate Limits
Check limits are shared between dashboard usage and API calls.
Check limits are shared between dashboard and API usage. Use GET /me/usage to query your current quota in real time.