Add AI-generated content detection to your product. Create an API key, send a file, and get a clear JSON result back.
You will be asked to log in or sign up before creating a key.
curl -X POST https://aiverification.com/api/v1/verify \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@recording.mp3"One endpoint for both. Send a recording or a picture and get a verdict with a confidence score.
A single POST request with a file. Works from any language, with ready-made cURL, Python and Node.js samples.
Keys are stored hashed, always expire, and can be revoked instantly from your dashboard.
Authentication, request format, response fields, errors and limits.
Verify your first file in three steps.
Create a key
Open the dashboard, name your key and choose an expiry. Copy it right away, it is shown only once.
Send a file
POST the file as multipart/form-data to the verify endpoint with your key in the Authorization header.
Read the verdict
The JSON response tells you whether the file is AI-generated (is_ai_generated) and how confident the model is (overall_confidence).
curl -X POST https://aiverification.com/api/v1/verify \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@recording.mp3"Authenticate every request with your API key as a bearer token:
Keep your key secret
Call the API from your backend only. Never put a key in a web page, a mobile app or a public repository, because anyone who finds it can spend your credits.
| Parameter | Type | Description |
|---|---|---|
| Authorization | header | Bearer YOUR_API_KEY |
| file | file (multipart) | The audio or image file to verify. Send exactly one file. |
audio/wavaudio/mp3audio/oggaudio/mpegaudio/m4aaudio/x-m4aimage/jpegimage/pngimage/webpFiles are checked by MIME type, so make sure your HTTP client sends the correct Content-Type for the file part (for example audio/mpeg). The code samples above do this.
Every response is JSON with a success flag. On success the result is in data. A finished analysis returns HTTP 200.
| Field | Type | Description |
|---|---|---|
| id | string (uuid) | Unique id of this verification. |
| status | "initialized" | "verifying" | "verified" | "failed" | verified once the analysis has finished. |
| verification_type | "audio" | "image" | The kind of media that was analyzed. |
| is_ai_generated | boolean | The verdict. true when the file is judged to be AI-generated. |
| overall_confidence | number | null | How confident the model is in the verdict, from 0 to 100. |
| overall_score | number | null | Raw model score. The scale differs between audio and images, so base decisions on is_ai_generated and overall_confidence. |
| total_chunks | number | null | Number of chunks analyzed for audio. null for images. |
| chunk_details | array | object | null | Audio: one entry per chunk. Image: a single analysis object. See below. |
| audio_length | number | Length of the audio in seconds. Ignore this field for images. |
| flagged_by | "system" | "c2pa" | What produced the verdict: our models (system) or C2PA content credentials found in the file (c2pa). |
| feedback | "CORRECT" | "INCORRECT" | "NONE" | Feedback state of this result. NONE when no feedback has been submitted. |
| created_at | string (ISO 8601) | When the verification was created. |
| original_file_name | string | null | Name of the file you uploaded. |
Audio is analyzed in chunks and listed in order, so you can see which part of a recording was flagged.
| Field | Type | Description |
|---|---|---|
| score | number | Raw model score for this chunk. |
| threshold | number | Decision threshold the score is compared against. |
| prediction | string | Result for this chunk, for example Fake. |
| confidence | number | Confidence in the prediction, from 0 to 100. |
| chunk_size | number | Length of the chunk in seconds. |
| model_name | string | Name of the model that analyzed the chunk. |
| time_seconds | number | Time the model took to analyze the chunk. |
| Field | Type | Description |
|---|---|---|
| is_ai_generated | boolean | Verdict of the image analysis. |
| fake_probability_percent | number | Probability (0 to 100) that the image is fake. |
| real_probability_percent | number | Probability (0 to 100) that the image is real. |
| face_detected | boolean | Whether a face was found in the image. |
| face_count | number | Number of faces found. |
| face_detector | string | Face detector that was used (informational). |
| route | string | Analysis route that was used (informational). |
| processing_ms | number | Processing time in milliseconds. |
{
"success": true,
"data": {
"id": "3f2b8c1e-7a4d-4c1b-9e55-2d6f0a8b1c77",
"status": "verified",
"total_chunks": 2,
"overall_score": 0.4837,
"overall_confidence": 51.63,
"is_ai_generated": true,
"feedback": "NONE",
"chunk_details": [
{
"score": 0.4837,
"threshold": 0.5,
"chunk_size": 30,
"confidence": 51.63,
"model_name": "AVI_AUDIO_V4",
"prediction": "Fake",
"time_seconds": 0.413
},
{
"score": 0.4836,
"threshold": 0.5,
"chunk_size": 30,
"confidence": 51.64,
"model_name": "AVI_AUDIO_V4",
"prediction": "Fake",
"time_seconds": 0.336
}
],
"audio_length": 39.24,
"created_at": "2026-10-22T02:22:45.20063+00:00",
"verification_type": "audio",
"flagged_by": "system",
"original_file_name": "interview.mp3"
}
}is_ai_generated for the verdict and overall_confidence for how sure the model is.Failed requests return a non-2xx status and a message you can show or log:
{
"success": false,
"error": {
"message": "Invalid, expired or revoked API key"
}
}| Status | Meaning | What to do |
|---|---|---|
| 202 | Still processing | Analysis did not finish within the response timeout. The body holds the current state, and status is not verified. |
| 400 | Invalid request | No file, more than one file, an unsupported type, or a file that is too large. Fix the request and try again. |
| 401 | Unauthorized | The API key is missing, wrong, expired or revoked. Create a new key in the dashboard. |
| 4xx | Request rejected | The request was understood but refused, for example because your account has no credits left. Read error.message. |
| 429 | Too many requests | You exceeded the rate limit. Wait for the number of seconds in the Retry-After header. |
| 500 | Server error | Something went wrong on our side. Retry after a short delay. |
| Limit | Value | Notes |
|---|---|---|
| Rate limit | 30 requests / minute | Applied per API key. Exceeding it returns 429 with a Retry-After header. |
| Files per request | 1 | Send one file in the file field. |
| Audio file size | 40MB | Larger files are rejected with 400. |
| Image file size | 20MB | Larger files are rejected with 400. |
| Active keys | 5 | Per account. Revoked and expired keys do not count. |
| Credits | Per request | API requests use the same credits as the web app. |
Create your first API key in under a minute and make your first request.
Open the developer dashboard