AI Voice Detector
Upload audio to detect whether the voice is AI-generated or natural, with a per-segment timeline for longer recordings.
POST /api/voice-detector/detect/
Upload an audio file to detect whether the voice is AI-generated or natural. Short files (up to about 6 seconds) return a single overall verdict; longer files additionally return a per-segment timeline showing which parts of the audio sound AI-generated.
Authentication: X-API-Key header with voice_detector scope
Unlike the text endpoints, this endpoint accepts multipart/form-data — the audio file is sent in a form field named file.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The audio file to analyze, sent as a multipart/form-data field |
Supported Formats and Limits
| Limit | Value |
|---|---|
| Formats | WAV, FLAC, OGG, MP3, M4A, AAC |
| Maximum file size | 150 MB |
| Maximum duration | 10 minutes (600 seconds) |
For long recordings, prefer a compressed format (MP3, M4A, FLAC) — a 10-minute stereo WAV approaches the size limit, while the same audio as MP3 is a fraction of it. Video files are not accepted.
Pricing
10 credits per second of audio, rounded up to the whole second (minimum 1 second). A 10-minute file costs 6,000 credits. The exact amount charged is returned as credits_used in the response. If the detection fails, the credits are refunded automatically.
| Audio length | Credits |
|---|---|
| 4.2 seconds | 50 |
| 30 seconds | 300 |
| 10 minutes | 6,000 |
Example
Request
curl -X POST https://developer-portal.proofademic.ai/api/voice-detector/detect/ \
-H "X-API-Key: YOUR_API_KEY" \
-F "[email protected]"Response for short audio (200 OK)
Files up to about 6 seconds return a single overall verdict:
{
"status": "success",
"verdict": "ai_voice",
"ai_probability": 0.92,
"natural_probability": 0.08,
"duration_seconds": 4.2,
"segments": [],
"billed_seconds": 5,
"credits_used": 50,
"execution_time": 1.4,
"credits_remaining": 1950,
"user": {
"id": 12345
}
}Response for longer audio (200 OK)
Files longer than about 6 seconds are analyzed in segments and additionally return a timeline and statistics:
{
"status": "success",
"verdict": "ai_voice",
"ai_probability": 0.881,
"natural_probability": 0.119,
"duration_seconds": 14.2,
"segments": [
{ "start_time": "0.0s", "end_time": "6.0s", "duration": "6.0s", "verdict": "ai_voice", "ai_probability": 0.91 },
{ "start_time": "6.0s", "end_time": "12.0s", "duration": "6.0s", "verdict": "ai_voice", "ai_probability": 0.852 }
],
"statistics": {
"total_segments": 3,
"processed_segments": 2,
"ai_segments": 2,
"natural_segments": 0,
"ai_time_percentage": 100.0
},
"billed_seconds": 15,
"credits_used": 150,
"execution_time": 4.8,
"credits_remaining": 1800,
"user": {
"id": 12345
}
}Response Fields
| Field | Type | Description |
|---|---|---|
status | string | Always "success" for a completed detection |
verdict | string | ai_voice, natural_voice, or (rarely) undetermined |
ai_probability | float | Probability (0–1) that the voice is AI-generated |
natural_probability | float | Probability (0–1) that the voice is natural |
duration_seconds | float | Duration of the analyzed audio |
segments[] | array | Per-segment timeline — empty for short audio |
statistics | object | Segment statistics — present for longer audio only |
billed_seconds | integer | Whole seconds billed (duration rounded up) |
credits_used | integer | Credits charged for this request (billed_seconds × 10) |
execution_time | float | Processing time in seconds |
credits_remaining | integer | Credit balance after this request |
user.id | integer | Your user ID |
Segments
Each entry in segments[] describes one analyzed span of the audio:
| Field | Type | Description |
|---|---|---|
start_time / end_time | string | Position of the segment in the audio, e.g. "6.0s" |
duration | string | Length of the segment |
verdict | string | ai_voice or natural_voice for this segment |
ai_probability | float | AI probability (0–1) for this segment |
A trailing remainder shorter than the analysis window may be skipped; skipped spans are counted in statistics.total_segments but not listed in segments[].
Health Check
GET /api/voice-detector/health/No authentication required. Returns 200 with "status": "healthy" when the detection service is available.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_audio | The file could not be read as audio — corrupt file or unsupported codec |
400 | audio_too_long | Over the 10-minute limit — details carries limit_seconds |
400 | invalid_payload | Missing file, unsupported format, or over the 150 MB size limit |
403 | insufficient_credits | Not enough credits — details carries credits and required |
503 | service_unavailable | Detection temporarily unavailable — safe to retry shortly |
503 | service_error | Detection failed — credits were refunded |
Failed requests never charge: validation errors are rejected before any credits move, and failures after the charge are refunded automatically.
See Error Handling for the general error format.