~/docs cat detect-image.md
Detect an image
Checks a photo or a still image for AI generation and editing, and answers with one verdict and one score for the whole image.
Send the file
curl -X POST \ "https://api.scam.ai/v1/detections" \ -H "x-api-key: <YOUR_API_KEY>" \ -F "file=@/path/to/photo.jpg"
Images are sent as a file. A link to an image is fetched too; see Detect from a link.
Parameters
| Field | Type | Meaning |
|---|---|---|
file | binary | The media file. JPG, PNG or WEBP; HEIC is not accepted, at most 10 MB. |
The response
- idstring
- The detection id. Pass it to GET /v1/detections/{id} to read the run back.
- statusstring
- Always
"completed". The answer arrives in the same request. - created_atstring
- When the run finished. RFC 3339, millisecond precision, always Z.
- mediaobject
- What was checked:
type(image, video or audio),filename,mime_typeandbytes. The last three can be null when they were not known.mime_typeis what the upload declared, so a client that sends no content type seesapplication/octet-streamhere;typecomes from the bytes themselves. - modelstring
- The Eva version that answered this run,
"Eva V1.5"or"Eva V1.6". Which version answers is set per account. - verdictstring
LIKELY_REAL,ALERTorLIKELY_AI. Branch on this.- scorenumber | null
- 0 to 1, the probability the media is AI-made or manipulated. null when nothing could be scored.
- summarystring
- One sentence a person can read, matching the verdict.
- credits_usednumber
- What this run cost, an integer. 0 on a sandbox key, or when the same file was sent byte for byte from this account within 30 days.
- zero_charge_reasonstring
- Only when
credits_usedis 0:"sandbox"or"duplicate".
response · 200
{ "id": "6f1c2a3e-9b7d-4e5f-8a21-3c4d5e6f7a8b", "status": "completed", "created_at": "2026-09-15T10:12:33.123Z", "media": { "type": "image", "filename": "photo.jpg", "mime_type": "image/jpeg", "bytes": 248113 }, "model": "Eva V1.6", "verdict": "LIKELY_AI", "score": 0.92, "summary": "This image shows strong signs of being AI-generated or edited.", "credits_used": 1}
Questions
- Why did I get a 422 instead of a verdict?
- For an image it means the bytes did not decode or the format is not supported: every decodable image is scored, with or without a face. The body carries a stable
error.code; a refusal that names the content (reasons[], such asno_voice_content) happens on audio. Show it to your user; do not retry the same file. Nothing is charged. See Errors. - Do you keep the image?
- Yes. Every run keeps the file and a history row, so it can be read back by id. Retention is covered by the privacy policy and DPA.
Start building
Create an API key in the dashboard and send your first file. To go through an integration or an on-prem deployment with our team, request a demo.