The deeptrack team recommends using the SDK for most integrations. The SDK handles authentication, file uploads, job polling, and error handling automatically. Consider checking if your preferred language is supported before using the raw API directly.View SDK Documentation →
Authentication
The deeptrack API authenticates via theX-API-Key header. Every request must include your API key.
X-API-Key: dt_your_key_here
Keep your API key secure. Do not commit it to version control or expose it in client-side code.
Base URL
https://api.deeptrack.io
Size Limits
| Media Type | Maximum Size |
|---|---|
| Image | 15 MB |
| Video | 500 MB |
| Audio | 50 MB |
Supported File Types
| Type | Extensions |
|---|---|
| Image | .jpg, .jpeg, .png, .webp, .gif |
| Video | .mp4, .mov, .avi, .mkv |
| Audio | .mp3, .wav, .m4a, .aac, .ogg, .flac |
Analyze an Image
Upload an image file and receive an authenticity verdict instantly. EndpointPOST /v1/image/predict
| Header | Value |
|---|---|
X-API-Key | Your API key |
Content-Type | multipart/form-data |
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | Image file to analyze |
import requests
BASE_URL = "https://api.deeptrack.io"
HEADERS = {"X-API-Key": "dt_your_key_here"}
with open("photo.jpg", "rb") as f:
resp = requests.post(
f"{BASE_URL}/v1/image/predict",
headers=HEADERS,
files={"file": ("photo.jpg", f, "image/jpeg")},
)
print(resp.json())
import fs from "fs";
import FormData from "form-data";
const BASE_URL = "https://api.deeptrack.io";
const HEADERS = { "X-API-Key": "dt_your_key_here" };
const form = new FormData();
form.append("file", fs.createReadStream("photo.jpg"));
const resp = await fetch(`${BASE_URL}/v1/image/predict`, {
method: "POST",
headers: { ...HEADERS, ...form.getHeaders() },
body: form,
});
console.log(await resp.json());
import fs from "fs";
import FormData from "form-data";
const BASE_URL = "https://api.deeptrack.io";
const HEADERS = { "X-API-Key": "dt_your_key_here" };
interface ImageResult {
filename: string;
prediction: "Real" | "Fake" | "UNCERTAIN";
confidence_percentage: number;
raw_scores: { Real: number; Fake: number };
}
const form = new FormData();
form.append("file", fs.createReadStream("photo.jpg"));
const resp = await fetch(`${BASE_URL}/v1/image/predict`, {
method: "POST",
headers: { ...HEADERS, ...form.getHeaders() },
body: form as any,
});
const result = await resp.json() as ImageResult;
console.log(result);
curl -X POST https://api.deeptrack.io/v1/image/predict \
-H "X-API-Key: dt_your_key_here" \
-F "file=@photo.jpg"
Response
{
"filename": "photo.jpg",
"prediction": "FAKE",
"confidence_percentage": 87.3,
"raw_scores": {
"Real": 12.7,
"Fake": 87.3
}
}
| Field | Type | Description |
|---|---|---|
filename | string | Name of the uploaded file |
prediction | string | Real, Fake, or UNCERTAIN |
confidence_percentage | float | Confidence of the verdict (0–100) |
raw_scores.Real | float | Raw probability score for Real |
raw_scores.Fake | float | Raw probability score for Fake |
Analyze a Video
Video analysis is asynchronous. Upload the file, receive ajob_id, then poll for the result.
Step 1 — Upload the video
EndpointPOST /v1/video/predict/video
| Header | Value |
|---|---|
X-API-Key | Your API key |
Content-Type | multipart/form-data |
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | Video file to analyze |
import requests
import time
BASE_URL = "https://api.deeptrack.io"
HEADERS = {"X-API-Key": "dt_your_key_here"}
# step 1 — upload
with open("clip.mp4", "rb") as f:
resp = requests.post(
f"{BASE_URL}/v1/video/predict/video",
headers=HEADERS,
files={"file": ("clip.mp4", f, "video/mp4")},
)
job_id = resp.json()["job_id"]
print(f"Job queued: {job_id}")
# step 2 — poll until done
while True:
resp = requests.get(f"{BASE_URL}/v1/video/jobs/{job_id}", headers=HEADERS)
status = resp.json()["status"]
print(f"Status: {status}")
if status == "done":
print(resp.json()["result"])
break
elif status == "error":
print("Error:", resp.json()["error"])
break
time.sleep(3)
import fs from "fs";
import FormData from "form-data";
const BASE_URL = "https://api.deeptrack.io";
const HEADERS = { "X-API-Key": "dt_your_key_here" };
// step 1 — upload
const form = new FormData();
form.append("file", fs.createReadStream("clip.mp4"));
const uploadResp = await fetch(`${BASE_URL}/v1/video/predict/video`, {
method: "POST",
headers: { ...HEADERS, ...form.getHeaders() },
body: form,
});
const { job_id } = await uploadResp.json();
console.log("Job queued:", job_id);
// step 2 — poll until done
while (true) {
await new Promise(r => setTimeout(r, 3000));
const pollResp = await fetch(`${BASE_URL}/v1/video/jobs/${job_id}`, {
headers: HEADERS,
});
const job = await pollResp.json();
console.log("Status:", job.status);
if (job.status === "done") { console.log(job.result); break; }
if (job.status === "error") { console.error(job.error); break; }
}
import fs from "fs";
import FormData from "form-data";
const BASE_URL = "https://api.deeptrack.io";
const HEADERS = { "X-API-Key": "dt_your_key_here" };
interface VideoResult {
label: "REAL" | "FAKE" | "UNCERTAIN";
confidence: number;
fake_prob: number;
face_pct: number;
total_frames: number;
n_segments: number;
segments: Array<{
segment: number;
start_sec: number;
end_sec: number;
label: string;
confidence: number;
fake_prob: number;
}>;
}
// step 1 — upload
const form = new FormData();
form.append("file", fs.createReadStream("clip.mp4"));
const uploadResp = await fetch(`${BASE_URL}/v1/video/predict/video`, {
method: "POST",
headers: { ...HEADERS, ...form.getHeaders() },
body: form as any,
});
const { job_id } = await uploadResp.json() as { job_id: string };
console.log("Job queued:", job_id);
// step 2 — poll until done
while (true) {
await new Promise(r => setTimeout(r, 3000));
const pollResp = await fetch(`${BASE_URL}/v1/video/jobs/${job_id}`, {
headers: HEADERS,
});
const job = await pollResp.json() as {
status: string;
result: VideoResult;
error: string;
};
console.log("Status:", job.status);
if (job.status === "done") { console.log(job.result); break; }
if (job.status === "error") { throw new Error(job.error); }
}
# step 1 — upload
curl -X POST https://api.deeptrack.io/v1/video/predict/video \
-H "X-API-Key: dt_your_key_here" \
-F "file=@clip.mp4"
# step 2 — poll (replace JOB_ID with the returned job_id)
curl https://api.deeptrack.io/v1/video/jobs/JOB_ID \
-H "X-API-Key: dt_your_key_here"
Upload Response
{
"job_id": "3f8a2c1d-...",
"status": "queued",
"filename": "clip.mp4",
"size_mb": 12.4,
"poll_url": "/v1/video/jobs/3f8a2c1d-..."
}
Step 2 — Poll for Result
EndpointGET /v1/video/jobs/{job_id}
status is done or error. Larger files may take longer to analyze.
Poll Response
{
"job_id": "3f8a2c1d-...",
"status": "done",
"filename": "clip.mp4",
"result": {
"label": "FAKE",
"confidence": 91.2,
"fake_prob": 0.912,
"face_pct": 98.0,
"total_frames": 240,
"n_segments": 4,
"segments": [
{
"segment": 1,
"start_sec": 0.0,
"end_sec": 4.3,
"label": "FAKE",
"confidence": 91.2,
"fake_prob": 0.912
}
]
}
}
| Field | Type | Description |
|---|---|---|
job_id | string | Unique job identifier |
status | string | queued, processing, done, or error |
result.label | string | REAL, FAKE, or UNCERTAIN |
result.confidence | float | Confidence percentage (0–100) |
result.fake_prob | float | Raw fake probability (0.0–1.0) |
result.face_pct | float | % of frames with a detected face |
result.total_frames | int | Total frames processed |
result.n_segments | int | Number of rPPG segments |
result.segments | array | Per-segment breakdown |
Check Usage
Returns your monthly usage stats for the authenticated API key. EndpointGET /v1/client/usage/me
resp = requests.get(f"{BASE_URL}/v1/client/usage/me", headers=HEADERS)
print(resp.json())
const resp = await fetch(`${BASE_URL}/v1/client/usage/me`, { headers: HEADERS });
console.log(await resp.json());
const resp = await fetch(`${BASE_URL}/v1/client/usage/me`, { headers: HEADERS });
console.log(await resp.json());
curl https://api.deeptrack.io/v1/client/usage/me \
-H "X-API-Key: dt_your_key_here"
Response
{
"owner": "Gotham Media",
"track": "api",
"plan": "starter",
"rate_per_scan": 0.39,
"monthly_limit": 5000,
"used_this_month": 23,
"remaining": 4977,
"resets_at": "2026-03-31"
}
Error Reference
All errors return a JSON body with adetail field.
| Status | Meaning | Example detail |
|---|---|---|
401 | Missing or invalid API key | "Missing X-API-Key header." |
400 | Bad request | "Unsupported format '.wmv'." |
413 | File too large | "File too large (520MB). Max is 500MB." |
422 | Missing required field | "field required: file" |
429 | Monthly limit exceeded | "Monthly limit of 5000 scans exceeded." |
503 | Model not loaded | "Video model not loaded." |
{
"detail": "Monthly limit of 5000 scans exceeded. Upgrade your plan at deeptrack.io/pricing"
}

