~/docs cat detect-audio.md
Detect audio
Checks a recording for synthetic or cloned voice, and answers with one verdict for the recording plus a timeline with a value for every window of speech.
Send the file
curl -X POST \ "https://api.scam.ai/v1/detections" \ -H "x-api-key: <YOUR_API_KEY>" \ -F "file=@/path/to/voicemail.mp3"
Recordings are sent as a file. A link to a recording is fetched too; see Detect from a link.
Parameters
| Field | Type | Meaning |
|---|---|---|
file | binary | The media file. MP3, WAV, FLAC, M4A, AAC or OGG, at most 50 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". - duration_msnumber
- The end of the last window in milliseconds, scored or not. Audio is billed by length.
- segmentsarray
- One entry per window:
start_ms,end_msandvalue(0 to 1, the probability that window is synthetic, or null when the window was not scored). - segments[].statusstring
scoredwhen the window has a value,abstainedwhen it does not.- segments[].reason_codesstring[]
- Only on an abstained window: why it was not scored, for example
no_voice_content.
response · 200
{ "id": "c3a9e1d0-7f24-4b6a-8e15-9d0c2b7a4f61", "status": "completed", "created_at": "2026-09-15T10:21:40.088Z", "media": { "type": "audio", "filename": "voicemail.mp3", "mime_type": "audio/mpeg", "bytes": 131072 }, "model": "Eva V1.6", "verdict": "LIKELY_AI", "score": 0.96, "summary": "This recording shows strong signs of synthetic or cloned voice.", "credits_used": 1, "duration_ms": 8000, "segments": [ { "start_ms": 0, "end_ms": 4000, "value": 0.9612, "status": "scored" }, { "start_ms": 4000, "end_ms": 8000, "value": null, "status": "abstained", "reason_codes": ["no_voice_content"] } ]}
Questions
- What is a window?
- The recording is scored in fixed-length windows. Each entry in
segments[]is one window, with its start and end in milliseconds and its ownvalue. Thescoreat the top of the response is the verdict for the whole recording. - Why is a window's value null?
- Nothing was scored there:
statusisabstainedandreason_codessays why, for exampleno_voice_contentwhen the window holds no speech. A null is never a 0. - Why does audio never answer ALERT?
- A recording is judged on one line, so it answers
LIKELY_REALorLIKELY_AI. Your code should still handle all three words, because the same integration will seeALERTon images and videos.
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.