Image Detector API
Try it Out
You can test out the API without code by going to the FastAPI link with your web browser: https://ai-image-detect.undetectable.ai/docs
Authentication
Undetectable.AI uses API keys to allow access to the API. You can get your API key at the top of the page in our developer portal.
UD expects for the API key to be included in all API requests to the server in a request body that looks like the following:
key: YOUR API KEY GOES HERE
YOUR API KEY GOES HERE with your personal API key.AI Image Detector
Detect (3-Step Process)
The AI Image Detection workflow consists of the following steps:
- Obtain a Pre-signed Upload URL
- Upload the Image
- Submit the Image for Detection
1. Obtain a Pre-signed Upload URL
Begin by requesting a pre-signed URL from the API. This URL allows you to securely upload your image file to the storage server.
Supported File Formats: JPG, JPEG, PNG, WebP, JFIF, HEIC, HEIF, AVIF, BMP, TIFF, TIF , GIF , SVG, PDF
Note: It is necessary to remove spaces from the image filename when requesting a pre-signed URL.
PDF note: For PDF files, only the first image will be detected.
https://ai-image-detect.undetectable.ai/get-presigned-url?file_name=example.jpgExample Request
curl -X GET 'https://ai-image-detect.undetectable.ai/get-presigned-url?file_name=example.jpg' \
--header 'apikey: YOUR API KEY GOES HERE'
Example Response
{
"status": "success",
"presigned_url": "https://nyc3.digitaloceanspaces.com/ai-image-detector-dev/uploads/581d47c7-3ef4-42af-88d9-6dab6bf69389_20250611-121955_example.jpg...",
"file_path": "uploads/example.jpg"
}
2. Upload the Image
Use the provided presigned_url to upload your image via a PUT request. Ensure the correct content type is set according to your image format.
Example Request
curl -X PUT 'https://nyc3.digitaloceanspaces.com/ai-image-detector-dev/uploads/581d47c7-3ef4-42af-88d9-6dab6bf69389_20250611-121955_example.jpg...' \
--header 'Content-Type: image/jpeg' \
--header 'x-amz-acl: private' \
--data-binary '@example.jpg' # Attachment
Set the Content-Type header to match your file extension exactly:
- image/jpeg: jpg, jpeg, jfif
- image/png: png
- image/webp: webp
- image/heic: heic
- image/heif: heif
- image/avif: avif
- image/bmp: bmp
- image/tiff: tiff, tif
- image/gif: gif
- image/svg+xml: svg
- application/pdf: pdf
# PNG example
curl -X PUT '<PRESIGNED_URL_FOR_example.png>' \
--header 'Content-Type: image/png' \
--header 'x-amz-acl: private' \
--data-binary '@example.png'
# PDF example
curl -X PUT '<PRESIGNED_URL_FOR_example.pdf>' \
--header 'Content-Type: application/pdf' \
--header 'x-amz-acl: private' \
--data-binary '@example.pdf'
# SVG example
curl -X PUT '<PRESIGNED_URL_FOR_example.svg>' \
--header 'Content-Type: image/svg+xml' \
--header 'x-amz-acl: private' \
--data-binary '@example.svg'
Common mistakes to avoid:
- Do not use
image/jpg(incorrect). Useimage/jpeg. - Do not mismatch file and header (e.g.,
.pngfile withimage/jpeg). - Do not change the extension without updating the header (or vice versa).
- Do not include spaces in filenames when requesting/uploading.
Note: It is necessary to remove spaces from the image filename when uploading the image.
Ensure that the file format remains consistent during the upload process. A successful upload will return a status code of 200.
File Size Limits:
- Minimum file size: 1KB
- Maximum file size: 10MB
3. Submit Image for AI Detection
After uploading, submit the image for AI detection by referencing the file_path from the previous step.
For PDF uploads, only the first image will be analyzed/detected.
https://ai-image-detect.undetectable.ai/detectExample Request
curl -X 'POST' \
'https://ai-image-detect.undetectable.ai/detect' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"key": "YOUR-API-KEY-GOES-HERE",
"url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/<FILE_PATH>",
"generate_preview": false
}'
The FILE_PATH refers to the path obtained from the response in the initial step, "Obtain a Pre-signed Upload URL".
Optional Parameters:
generate_preview: Set totrueto generate a preview URL for the image (default:false)document_type: Type of document (default:Image)email: Email address for processinggenerate_analysis_details: Set tofalseto skip generating detailed analysis result (default:True)
Example Response
{
"id": "77565038-9e3d-4e6a-8c80-e20785be5ee9",
"status": "pending"
}
The response includes a unique image ID for tracking the detection status.
Query Detection Status and Results
To check the status and retrieve the results, use the /query endpoint with the image ID.
https://ai-image-detect.undetectable.ai/queryExample Request
curl -X 'POST' \
'https://ai-image-detect.undetectable.ai/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": "IMAGE-ID-GOES-HERE"
}'
Example Response
{
"id": "00fee5ff-a55b-42fb-b7c7-d14f05ae0769",
"status": "done",
"result": 90.2371538185235,
"result_details": {
"is_valid": true,
"detection_step": 3,
"final_result": "AI Generated",
"metadata": [
"No Information Detected for Real/AI",
"Could not find anything from ExifTool and Pillow metadata"
],
"metadata_basic_source": "null",
"ocr": [
"OCR did not detect AI",
0.0
],
"ml_model": [
"AI Generated",
90.2371538185235
],
"confidence": 90.2371538185235,
"heatmap_status": "ready",
"heatmap_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/uploads/....",
"analysis_result_status":"pending",
"analysis_result":null
},
"preview_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/previews/..."
}
Notes:
- Heatmap generation is asynchronous. Initially,
heatmap_statuswill bependingandheatmap_urlmay be absent or null. When ready,heatmap_statusbecomesreadyandheatmap_urlis populated. - Analysis result detail generation (unless turned off in detect query) is asynchronous. Initially,
analysis_result_statuswill bependingandanalysis_resultmay be absent or null. When ready,analysis_result_statusbecomesreadyandanalysis_resultis populated.
Tip: You have poll again even after initial result settles to get the pending updates like heatmap & analysis_results
Example Response when anaylsis result
{
"id": "00fee5ff-a55b-42fb-b7c7-d14f05ae0769",
"status": "done",
"result": 90.2371538185235,
"result_details": {
"is_valid": true,
"detection_step": 3,
"final_result": "AI Generated",
"confidence": 90.2371538185235,
"heatmap_status": "ready",
"heatmap_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/uploads/....",
"analysis_results_status": "done",
"analysis_results": {
"imageTag": [
"person",
"portrait",
"outdoor",
"vineyard",
"smiling"
],
"agreement": "strong",
"confidence": 92,
"keyIndicators": [
"Unnaturally smooth skin texture",
"Consistent lighting anomalies"
],
"detailedReasoning": "The image shows clear signs of AI generation with unnaturally smooth textures and consistent lighting patterns not typical of real photography.",
"visualPatterns": [
"Uniform noise pattern typical of diffusion models"
],
"recommendations": [
"Cross-reference with original source if available",
"Check for metadata inconsistencies",
"Compare with known AI generation patterns"
]
}
},
"preview_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/previews/..."
}
Result Details
- is_valid: Indicates if the image file is valid (true/false)
- detection_step: Indicates the stage at which detection was completed.
- 1: Only
metadatais returned. - 2: Returns
metadataandocrresults. - 3: Returns
metadata,ocr, andml_modelresults. - final_result: The overall determination (e.g., "AI Generated", "Real", "Digitally Edited, "AI Edited").
- confidence: The confidence score of the detection.
- metadata: Information extracted from image metadata using ExifTool and Pillow.
- metadata_basic_source: This information may indicate whether the image was captured using a specific mobile camera model, generated by an AI tool, or modified using photo-editing software.
- ocr: Results from Optical Character Recognition analysis for watermark detection.
- ml_model: Results from the machine learning model.
- preview_url: URL to the preview image (if
generate_previewwas set to true). - heatmap_status: Status of heatmap generation (
pendingorready). - heatmap_url: URL to the heatmap image, available when
heatmap_statusisready. - analysis_result_status: Status of analysis result generation (
pendingorreadyWhen you sendgenerate_analysis_details=truein detect request), (nullwhen you don't sendgenerate_analysis_detailsor send it asgenerate_analysis_details=false) in the /detect request. - analysis_results: Explained below
Analysis Result Explanation
The analysis_result_status field will be one of:
pending: Processing is queuedanalyzing: AI detection is in progressdone: Results are availablefailed: Processing failed
analysis_resultWhen not ready, it will be null, otherwise will have structure like this:- 1.
agreement: type: string, values: "strong" | "moderate" | "weak" | "disagreement" - 2.
imageTagsstring[] (array of 5 tags for this image) - 3.
confidence: number (0-100) - 4.
keyIndicators: string[] (array of specific, concrete audio anomalies and technical artifacts that directly suggest AI generation - focus on discrete, identifiable issues like "unnatural breath patterns", "synthetic voice characteristics", "inconsistent speech rhythm", "artificial prosody", "compression artifacts affecting voice", etc.), - 5.
detailedReasoning: string (comprehensive explanation 2-4 sentences explaining why the score is accurate), - 6.
audioPatterns: string[] (array of broader stylistic and compositional patterns that characterize the audio - focus on overall trends like "synthetic voice generation signatures", "unnatural speech cadence", "artificial prosody patterns", "inconsistent background noise integration", "audio compression characteristics", etc.), - 7.
recommendations: string[] (3-5 actionable recommendations for understanding or verifying the audio)
Check User Credits
This endpoint accepts the users apikey via the header. And returns users credit details.
https://ai-image-detect.undetectable.ai/check-user-creditsExample Request
curl -X 'GET' \
'https://ai-image-detect.undetectable.ai/check-user-credits' \
-H 'apikey: YOUR API KEY GOES HERE' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
Example Response
{
"baseCredits": 10000,
"boostCredits": 1000,
"credits": 11000
}
Note: For external integrations, only the credits field will be populated.
Health Check
Check the health status of the API server.
https://ai-image-detect.undetectable.ai/healthExample Request
curl -X 'GET' \
'https://ai-image-detect.undetectable.ai/health' \
-H 'accept: application/json'
Example Response
{
"status": "healthy"
}
Errors
The generic error codes we use conform to the REST standard:
Error Code | Meaning |
|---|---|
400 | Bad Request -- Your request is invalid. |
403 | Forbidden -- The API key is invalid, or there aren't sufficient credits (0.1 per word). |
404 | Not Found -- The specified resource doesn't exist. |
405 | Method Not Allowed -- You tried to access a resource with an invalid method. |
406 | Not Acceptable -- You requested a format that isn't JSON. |
410 | Gone -- The resource at this endpoint has been removed. |
422 | Invalid Request Body -- Your request body is formatted incorrectly or invalid or has missing parameters. |
429 | Too Many Requests -- You're sending too many requests! Slow it down! |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Common Issues and Solutions
Authentication Issues
"User verification failed" (403)
- Cause: Invalid or expired API key
- Solution:
- Verify your API key is correct
- Check if your API key is active in your account
- Try regenerating your API key
"Not enough credits" (403)
- Cause: Insufficient credits for image processing
- Solution:
- Check your remaining credits using
/check-user-credits - Purchase additional credits if needed
Input Validation Issues
"Input URL cannot be empty" (400)
- Cause: Empty or invalid URL submitted
- Solution:
- Ensure your url input is not empty
- Remove any leading/trailing whitespace in image names
- Check if url encoding is correct
"Input email is empty" (400)
- Cause: Missing email for URL processing
- Solution:
- Provide a valid email address when submitting URLs
- Check email format is correct
"Unsupported image type" (400)
- Cause: File format not supported
- Solution:
- Convert image to supported format (JPG, PNG, WebP, HEIC, HEIF, AVIF, BMP, TIFF, GIF, SVG, PDF)
- Check file extension is correct
"File size is too small" (400)
- Cause: Image file is below minimum size requirement
- Solution:
- Use a larger image file (minimum 1KB)
- Check if image was corrupted during upload
"File size exceeds limit" (400)
- Cause: Image file is too large
- Solution:
- Compress or resize image (maximum 50MB)
- Use a different image format
"Invalid file type" (400)
- Cause: File type validation failed
- Solution:
- Ensure file is a valid image format
- Check file is not corrupted
- Verify MIME type matches file extension
Processing Issues
Image Status "failed"
- Cause: Processing failed for various reasons
- Solution:
- Verify URL is in a supported format
- Check image file is valid and not corrupted
- Ensure image meets size requirements
- Contact support if issue persists
"User not found"
- Cause: Invalid user ID
- Solution:
- Verify user ID is correct
- Ensure user account is active
- Re-authenticate if needed
"File metadata could not be fetched" (500)
- Cause: Unable to access uploaded file
- Solution:
- Verify file was uploaded successfully
- Check file URL is accessible
- Try re-uploading the file
Environment Variables
- BYPASS_OCR: When set to
true, the worker will bypass the OCR watermark detection step and only use metadata and the ML model. Default isfalse.
Updated on: 24/02/2026
Thank you!
