Free
Try the full engine
- 25 results/month (images + PDF pages)
- Detailed indicators on every result
- Full API access
- Detection history in dashboard
- Free forever โ no trial period
- Chrome extension, unlimited seats
Complete documentation for integrating TruthScan's AI image detection API into your applications.
Try it out without code by visiting our FastAPI endpoint: https://detect-image.truthscan.com/docs
Prefer a client library? Use our official SDKs instead of calling the REST API directly. View Client SDK Documentation
Pricing & credits
Each successful image detection consumes credits. Bulk ZIP uploads bill only images that complete analysis; skipped or failed files are not charged.
Check your balance with GET /check-user-credits. View pricing plans
TruthScan 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.
TruthScan expects the API key to be included in API requests to the server in a JSON body like the following (unless an endpoint documents header-only auth, e.g. check-user-credits):
{
"key": "YOUR API KEY GOES HERE"
}You must replace YOUR API KEY GOES HERE with your personal API key.
The API enforces a per-minute request budget for each API key. Heavier write endpoints cost more than lighter read endpoints. The default limit is 60 requests per minute โ contact us if you need a higher limit.
Each call deducts its weight from your per-minute budget:
| Endpoint | Type | Weight |
|---|---|---|
| POST /detect | Write | 1 |
| POST /bulk-upload | Write | 1 |
| GET /get-presigned-url | Read | 0.2 |
| GET /check-user-credits | Read | 0.2 |
| POST /heatmap/{id} | Read | 0.2 |
| POST /preview/{id} | Read | 0.2 |
| POST /query | Read | Not rate-limited |
| GET /health | Read | Not rate-limited |
Example: with a 60/minute budget, you can send up to 60 write calls, or up to ~300 read calls, or any mix where the weighted total stays โค 60 per minute.
When you exceed your per-minute budget, the API returns:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 3
X-RateLimit-Retry-After: 3
Content-Type: application/json
{
"error": "Too many requests"
}Rate-limit response headers
Recommended client behavior
The AI Image Detection workflow consists of the following steps:
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
Filename
Remove spaces from the image filename when requesting a pre-signed URL.
For PDF files, only the first image will be detected (single-file flow).
Use a .zip filename on this endpoint when you intend to submit a ZIP via bulk upload.
Query parameters
GET https://detect-image.truthscan.com/get-presigned-url?file_name=example.jpgExample Request
curl -X GET 'https://detect-image.truthscan.com/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",
"document_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}The document_id is a new UUID generated for this upload request (for correlation/logging). The id you use for /detect or /bulk-upload is assigned when you submit those endpoints unless you pass an optional id on /detect.
HTTP responses
Required header: apikey: YOUR-API-KEY-GOES-HERE
| Status | Body | When |
|---|---|---|
| 200 | JSON: status, presigned_url, file_path, document_id | Success |
| 400 | {"error": "..."} | Unsupported file type / bad params |
| 403 | {"error": "..."} | Invalid API key |
| 404 | {"error": "..."} | TruthScan key validation failed |
| 500 | {"error": "..."} | Server error |
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.
Filename
Remove spaces from the image filename when uploading the image.
Set Content-Type to match your file extension exactly
Common mistakes to avoid
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'Additional upload examples (PNG, PDF, SVG)
curl -X PUT '<PRESIGNED_URL_FOR_example.png>' \
--header 'Content-Type: image/png' \
--header 'x-amz-acl: private' \
--data-binary '@example.png'curl -X PUT '<PRESIGNED_URL_FOR_example.pdf>' \
--header 'Content-Type: application/pdf' \
--header 'x-amz-acl: private' \
--data-binary '@example.pdf'curl -X PUT '<PRESIGNED_URL_FOR_example.svg>' \
--header 'Content-Type: image/svg+xml' \
--header 'x-amz-acl: private' \
--data-binary '@example.svg'File Size Limits
Ensure that the file format remains consistent during the upload process. A successful upload returns HTTP 200.
Storage PUT response
Step 2 is a direct PUT to object storage (presigned URL), not our API. Single-image and ZIP bulk uploads behave the same way.
Success returns HTTP 200 with an empty body โ by design. There is no JSON to parse.
After PUT to presigned_url: treat res.ok (status 200โ299) as success. Do not call response.json() on success โ an empty body is expected. Surface errors only on non-2xx responses.
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.
POST https://detect-image.truthscan.com/detectExample Request
curl -X 'POST' \
'https://detect-image.truthscan.com/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": true
}'The FILE_PATH refers to the path returned from the presigned-URL step (e.g. uploads/...). Build the full URL with your storage host as shown in the example.
Optional Parameters
id: Optional UUID string. If omitted, the server generates a new document id. If provided, it must not already exist; otherwise the API returns an error.generate_preview: Set to true to generate a preview URL for the image (default: true). Set to false to skip preview generation.document_type: Type of document (default: Image).email: Email address for processing.generate_analysis_details: Set to false to skip generating detailed analysis (default: true).generate_heatmap: When false, skip heatmap generation entirely (default: true). Heatmaps are only produced for AI-classified images when this is true. Real images never receive a heatmap.generate_heatmap_overlayed: Controls how the heatmap image is produced when a heatmap is generated (default: true). Only applies when generate_heatmap is true and the image is classified as AI-generated. When true, the heatmap is blended onto the original image (standard overlay). When false, the service returns a transparent heatmap: an RGBA image with the JET-colored activation map and alpha from the model, with a transparent background so you can composite it in your UI.generate_heatmap_normalized: When false, heatmap generation skips the normalization step used for the activation map (default: true). Only applies when generate_heatmap is true and the image is classified as AI-generated. Use together with generate_heatmap_overlayed to control heatmap appearance.model: Model or routing hint (default: generic). Supported examples include generic or instance_id/model (e.g. my-instance-id/generic) to send the job to a dedicated queue for that instance. Invalid instance_id values are rejected with 400.user_agent: Optional string stored with the document for analytics/support.Heatmap flag validation
If generate_heatmap is false, do not explicitly set generate_heatmap_overlayed or generate_heatmap_normalized to true. The API returns 422 Unprocessable Entity with messages such as "generate_heatmap_overlayed cannot be true when generate_heatmap is false." or "generate_heatmap_normalized cannot be true when generate_heatmap is false."
Example Request (heatmap enabled, default)
curl -X 'POST' \
'https://detect-image.truthscan.com/detect' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"key": "YOUR-API-KEY-GOES-HERE",
"url": "https://ai-image-detector-dev.nyc3.digitaloceanspaces.com/uploads/example.jpg",
"generate_heatmap": true,
"generate_preview": false,
"generate_analysis_details": false,
"model": "generic"
}'Example Request (heatmap disabled)
curl -X 'POST' \
'https://detect-image.truthscan.com/detect' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"key": "YOUR-API-KEY-GOES-HERE",
"url": "https://ai-image-detector-dev.nyc3.digitaloceanspaces.com/uploads/example.jpg",
"generate_heatmap": false,
"generate_preview": false,
"generate_analysis_details": false,
"model": "generic"
}'Invalid Request (422)
curl -X 'POST' \
'https://detect-image.truthscan.com/detect' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"key": "YOUR-API-KEY-GOES-HERE",
"url": "https://ai-image-detector-dev.nyc3.digitaloceanspaces.com/uploads/example.jpg",
"generate_heatmap": false,
"generate_heatmap_overlayed": true
}'Example Response
{
"id": "77565038-9e3d-4e6a-8c80-e20785be5ee9",
"status": "pending"
}The response includes a unique image ID for tracking the detection status.
HTTP responses
| Status | Body | When |
|---|---|---|
| 200 | JSON: id, status (typically "pending") | Job accepted โ this is what the API returns on success |
| 400 | {"error": "..."} | Validation (no URL, file not uploaded, size/type, duplicate id, bad model, heatmap flag conflict, etc.) |
| 403 | {"error": "..."} | Invalid key / insufficient credits |
| 422 | {"error": "..."} | Invalid request body (e.g. generate_heatmap_overlayed true when generate_heatmap is false) |
| 500 | {"error": "..."} | Server error |
Treat any 2xx response whose JSON includes id and status as success โ not only HTTP 200. Proxies or other HTTP stacks may return 201 or 202 for async-accept patterns; validate the JSON body.
To check the status and retrieve the results, use the /query endpoint with the image ID.
Authentication: The request body only includes id; the API does not send an API key on this call. Anyone who knows the UUID can poll resultsโtreat document IDs as sensitive if you need to restrict who can see scores.
HTTP responses
| Status | Body | When |
|---|---|---|
| 200 | Single-image or bulk result JSON | Found |
| 404 | Error detail | Unknown id |
| 500 | Error detail | Server error |
POST https://detect-image.truthscan.com/queryExample Request
curl -X 'POST' \
'https://detect-image.truthscan.com/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,
"final_label_confidence": 90.2371538185235,
"heatmap_status": "ready",
"heatmap_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/uploads/....",
"analysis_results_status": "pending",
"analysis_results": null,
"warnings": [
{ "type": "blur_dark", "label": "Blurred" },
{ "type": "watermark", "label": "Gemini", "confidence": 0.95 },
{ "type": "screen_recapture", "label": "screen", "metrics": { "is_screen": false }, "confidence": 99.99 }
]
},
"preview_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/previews/..."
}Example Response (/query, secure URLs enabled on the org)
{
"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,
"final_label_confidence": 90.2371538185235,
"heatmap_status": "ready",
"heatmap_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/uploads/00fee5ff-a55b-42fb-b7c7-d14f05ae0769",
"analysis_results_status": "ready",
"analysis_results": null
},
"preview_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/previews/00fee5ff-a55b-42fb-b7c7-d14f05ae0769"
}Example Response when analysis results are ready
{
"id": "00fee5ff-a55b-42fb-b7c7-d14f05ae0769",
"status": "done",
"result": 90.2371538185235,
"result_details": {
"heatmap_status": "ready",
"heatmap_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/uploads/....",
"analysis_results_status": "ready",
"analysis_results": {
"imageTags": ["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: Stage at which detection completed: 1 = only metadata; 2 = metadata and ocr; 3 = metadata, ocr, and ml_model.final_result: Overall determination (e.g. "AI Generated", "Real", "Digitally Edited", "AI Edited").confidence: Confidence score of the detection.final_label_confidence: How sure the model is of `final_result`, from 0 to 100. Read it as โthis image is N% [label]โ. For example, `final_result`: `"AI Generated"` with `final_label_confidence`: `90` means the model is 90% confident the image is AI generated; `final_result`: `"Real"` with `final_label_confidence`: `80` means the model is 80% confident the image is real.metadata: Information extracted from image metadata using ExifTool and Pillow.metadata_basic_source: May indicate whether the image was captured with a specific mobile camera model, generated by an AI tool, or modified with photo-editing software.ocr: Watermark-detection result under the historical field name ocr. Two-element array [label, score]: label is a detected watermark class (e.g. "Gemini") or "OCR did not detect AI"; score is on a 0โ100 scale (or 0 when unsure). Summarized in warnings when a label is present.ml_model: Results from the machine learning model.warnings: Optional array of heterogeneous warning objects (type blur_dark, watermark, screen_recapture, etc.). May be empty or omitted.preview_url: Preview image URL if generate_preview was true. May be direct storage or, when secure URLs are enabled, an API path such as https://<api-host>/preview/<document_id>.heatmap_status: pending, ready, or failed. Omitted when the image is not AI-generated or when generate_heatmap was false on submit. Heatmap generation is asynchronous and only runs for AI-classified images when generate_heatmap is true.heatmap_url: Present when heatmap_status is ready, the image was AI-classified, and generate_heatmap was enabled at submit time. Appearance depends on generate_heatmap_overlayed. May be direct storage or API path https://<api-host>/heatmap/<document_id> (use POST /heatmap/{id} with key when secure).analysis_results_status: pending, ready, skipped, failed, or analyzing. Omitted or null when generate_analysis_details was false.analysis_results: Detailed narrative analysis when enabled; see Analysis Result Explanation below.Analysis Result Explanation
When analysis_results is ready, it typically includes: agreement (strong | moderate | weak | disagreement), imageTags (up to five short tags), confidence (0โ100), keyIndicators, detailedReasoning, visualPatterns, and recommendations.
Notes
Heatmap and overlay behavior
The file at heatmap_url reflects generate_heatmap_overlayed and generate_heatmap_normalized from your /detect (or /bulk-upload) request when generate_heatmap was true: default overlay (true) is a normal image with the heatmap overlaid; false is typically a PNG with transparency for compositing. Real images and requests with generate_heatmap: false omit heatmap_status and heatmap_url.
Example Response (AI image, heatmap disabled at submit)
{
"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,
"final_label_confidence": 90.2371538185235
}
}Example Response (AI image, heatmap pending)
{
"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,
"final_label_confidence": 90.2371538185235,
"heatmap_status": "pending",
"heatmap_url": null
}
}Example: result ~90.24 with final_result AI Generated and detection_step 3 means full pipeline metadata, OCR, and ML model completed.
When generate_analysis_details is true in /detect, detailed analysis may complete after the main score. Poll /query until analysis_results_status is ready (or skipped/failed).
Core detection (result, final_result, confidence) can be done while analysis_results_status is still pending.
{
"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,
"final_label_confidence": 90.2371538185235,
"analysis_results_status": "pending",
"analysis_results": null
}
}What to do
Use core fields immediately; keep polling if you need analysis_results.
Call /query with the same id until analysis_results_status changes from pending.
curl -X 'POST' \
'https://detect-image.truthscan.com/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": "00fee5ff-a55b-42fb-b7c7-d14f05ae0769"
}'When analysis_results_status is ready, analysis_results includes agreement, imageTags, confidence, keyIndicators, detailedReasoning, visualPatterns, and recommendations.
{
"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,
"final_label_confidence": 90.2371538185235,
"heatmap_status": "ready",
"heatmap_url": "https://ai-image-detector-prod.nyc3.digitaloceanspaces.com/uploads/....",
"analysis_results_status": "done",
"analysis_results": {
"imageTags": [
"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/..."
}If analysis_results_status is skipped, failed, or absent, or generate_analysis_details was false, treat core detection as final.
{
"status": "done",
"result": 12.5,
"result_details": {
"analysis_results_status": "skipped",
"analysis_results": null
}
}Analysis Results Fields
Submit multiple images in one request by uploading a ZIP. Workflow mirrors single-image: presign (ZIP name) โ PUT ZIP โ POST /bulk-upload โ poll /query.
Use get-presigned-url with a .zip filename (e.g. images.zip).
GET https://detect-image.truthscan.com/get-presigned-url?file_name=images.zipExample Request
curl -X GET 'https://detect-image.truthscan.com/get-presigned-url?file_name=images.zip' \
--header 'apikey: YOUR API KEY GOES HERE'PUT the ZIP to the presigned URL with Content-Type: application/zip.
curl -X PUT '<PRESIGNED_URL_FOR_images.zip>' \
--header 'Content-Type: application/zip' \
--header 'x-amz-acl: private' \
--data-binary '@images.zip'ZIP Limits
Supported formats inside ZIP
JPG, JPEG, PNG, WebP, JFIF, HEIC, HEIF, AVIF, BMP, TIFF, TIF, GIF, SVG
PDF files inside the ZIP are not supported and will be skipped.
SVG files are converted to PNG before detection.
POST /bulk-upload with key and url pointing to the uploaded ZIP path.
Optional Parameters
generate_preview: Set to true to generate preview URLs for images (default: false).generate_analysis_details: Set to true to generate detailed analysis (default: false).generate_heatmap: When false, skip heatmap generation entirely (default: true). Heatmaps are only produced for AI-classified images when this is true. Real images never receive a heatmap.generate_heatmap_overlayed: Same behavior as /detect (overlay vs transparent RGBA heatmap). Only applies when generate_heatmap is true and the image is classified as AI-generated.generate_heatmap_normalized: Same behavior as /detect (default: true). Only applies when generate_heatmap is true and the image is classified as AI-generated.model: Model domain: generic or instance_id/model format.Heatmap flag validation
If generate_heatmap is false, do not explicitly set generate_heatmap_overlayed or generate_heatmap_normalized to true. The API returns 422 Unprocessable Entity with messages such as "generate_heatmap_overlayed cannot be true when generate_heatmap is false." or "generate_heatmap_normalized cannot be true when generate_heatmap is false."
Example Request
curl -X 'POST' \
'https://detect-image.truthscan.com/bulk-upload' \
-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,
"generate_analysis_details": false,
"model": "generic"
}'Example Response
{
"id": "77565038-9e3d-4e6a-8c80-e20785be5ee9",
"status": "pending",
"expected_count": 12
}Returns id, status pending, and expected_count (how many images from the ZIP will be analyzed).
HTTP responses
| Status | Body | When |
|---|---|---|
| 200 | JSON: id, status, expected_count | Bulk job accepted |
| 400 | {"error": "..."} (may include skipped) | ZIP validation failures |
| 403 | {"error": "..."} | Auth / credits |
| 500 | {"error": "..."} | Server error |
Same rule as /detect: any 2xx with id, status, and expected_count (when present) is success.
How bulk ZIP results update
Use POST /query with the id from /bulk-upload. Same endpoint as single-image; response shape depends on whether the id is a single image or a ZIP batch.
curl -X 'POST' \
'https://detect-image.truthscan.com/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": "77565038-9e3d-4e6a-8c80-e20785be5ee9"
}'Example Response (still processing)
{
"id": "3b81fb24-dd23-40e7-ae95-82f823f44098",
"status": "analyzing",
"results": [
{
"id": "4600c7e5-00ec-469d-9117-ff20e0f1c1fa",
"status": "done",
"result": 44.0006,
"result_details": {},
"filename": "photo1.jpg",
"preview_url": null
},
{
"id": "2f770c89-352a-4d53-b6a3-a2147ca2c0ae",
"status": "pending",
"result": null,
"result_details": null,
"filename": "photo2.jpg",
"preview_url": null
}
],
"skipped": []
}Response fields (bulk ZIP)
Billing: Credits are used only for images successfully analyzed. Failed SVG conversions and skipped files are not billed.
When heatmap_url or preview_url in /query point to API host (not direct object storage), download the bytes with POST and your key.
POST /heatmap/{id}
POST /preview/{id}
Request body JSON: { "key": "YOUR-API-KEY-GOES-HERE" }
Heatmap responses (check HTTP status and Content-Type)
Preview: POST /preview/{id} returns raw preview bytes. 404 with JSON if no preview was generated (generate_preview was false).
Examples
curl -X POST 'https://detect-image.truthscan.com/heatmap/00fee5ff-a55b-42fb-b7c7-d14f05ae0769' \
-H 'Content-Type: application/json' \
-d '{"key":"YOUR-API-KEY-GOES-HERE"}' \
--output heatmap.pngcurl -X POST 'https://detect-image.truthscan.com/preview/00fee5ff-a55b-42fb-b7c7-d14f05ae0769' \
-H 'Content-Type: application/json' \
-d '{"key":"YOUR-API-KEY-GOES-HERE"}' \
--output preview.pngThis endpoint accepts the user's apikey via the header and returns credit details.
GET https://detect-image.truthscan.com/check-user-creditsExample Request
curl -X 'GET' \
'https://detect-image.truthscan.com/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
}For external integrations, only the credits field will be populated.
Check the health status of the API server.
GET https://detect-image.truthscan.com/healthExample Request
curl -X 'GET' \
'https://detect-image.truthscan.com/health' \
-H 'accept: application/json'Example Response
{
"status": "healthy"
}A "healthy" response indicates the service is operating normally.
Most errors will be from incorrect parameters being sent to the API. Double-check each call and try the provided examples.
The generic error codes we use conform to the REST standard:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request is invalid. |
| 401 | Unauthorized -- Invalid job secret (internal usage endpoints) or similar auth failure. |
| 403 | Forbidden -- The API key is invalid, access denied, or there aren't sufficient credits for the operation. |
| 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, invalid, or has missing parameters. |
| 429 | Too Many Requests -- You exceeded your per-API-key rate limit (see Rate Limits). The body is {"error":"Too many requests"}; the X-RateLimit-Retry-After header tells you how many seconds to wait before retrying. |
| 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. |
Cause: Invalid or expired API key
Solution:
Cause: Insufficient credits for image processing
Solution:
Cause: Empty or invalid URL submitted
Solution:
Cause: Missing email for URL processing
Solution:
Cause: File format not supported
Solution:
Cause: Image file is below minimum size requirement
Solution:
Cause: Image file is too large
Solution:
Cause: File type validation failed
Solution:
Cause: Processing failed for various reasons
Solution:
Cause: Invalid user ID
Solution:
Cause: Unable to access uploaded file
Solution:
Cause: Invalid or expired pre-signed URL, or issues with the storage server
Solution:
Cause: Filename with spaces or expired/corrupted pre-signed URL
Solution:
Cause: The URL provided to /bulk-upload does not point to a ZIP file
Solution:
Cause: ZIP exceeds maximum size (100MB)
Solution:
Cause: ZIP contains more than 50 valid images
Solution:
Cause: All files in the ZIP were skipped (unsupported format, too small, invalid path, etc.)
Solution:
Cause: The id does not match that upload type (single image vs ZIP batch)
Solution:
Get full forensic reports - heat maps, key indicators, and detailed descriptions.
Free
Try the full engine
Starter
$0.03 / result - $290/yr
For individuals and small teams
Professional
$0.02 / result - $990/yr
For teams in production
Business
$0.01 / result - $3,990/yr
For high-volume operations
Find answers to the most common questions about our AI image detection API.