Jobs API Reference
A job is one analysis of your media by one detection model. You create a job, upload the media straight to storage, finalize the job, and read the result once processing completes.
| Endpoint | Method | Permission | Description |
|---|---|---|---|
/jobs | POST | Write | Create a job and get an upload URL per input |
/jobs/{id}/finalize | POST | Write | Queue the job for processing once its files are uploaded |
/jobs | GET | Read | List your jobs |
/jobs/{id} | GET | Read | Get a job with its status, result and files |
/jobs/{id}/cancel | POST | Delete | Cancel a job that has not started processing |
/jobs/{id} | DELETE | Delete | Delete a job and its files |
All paths are relative to the base URL https://platform.authenta.ai/api/v1, and every request needs your API key:
Authorization: Bearer api_xxxxxxxx...See Authentication and Managing API Keys for permissions.
Task types
A task type is a detection model. Pass its ID as taskTypeId when creating a job, with one input per slot; every task type has a single input slot named original. Each task type accepts its own file formats and returns its own result fields.
See Task Types for the catalog of IDs, slugs and accepted formats, and a page per task type with its limits, result and artifacts. Which task types you can use depends on your plan. On-prem deployments may use different IDs, so keep the slug (e.g. ai-image-detection) as the identifier in your code.
Job lifecycle
initiated ──finalize──► queued ──► processing ──► completed
│ │ └──► failed
└──────cancel─────────┴──► cancelled| Status | Meaning |
|---|---|
initiated | Created; waiting for the file upload and finalize |
queued | Finalized; waiting for a detection worker |
processing | A worker is analyzing the media |
completed | Done — result holds the verdict |
failed | Processing failed — result describes the error |
cancelled | Cancelled before processing started |
Running a job
1. Create a job
POST /jobs
Send the task type and, for each input file, its name, MIME type and exact size in bytes.
Request body
interface CreateJobRequest {
taskTypeId: string; // e.g. "1" for AI image detection
inputs: {
slotName: string; // input slot: "original"
fileName: string; // e.g. "test.jpg"
contentType: string; // MIME type accepted by the task type
sizeBytes: number; // exact file size in bytes
pageCount?: number; // PDFs only: required for pdf-tampering-detection
}[];
parameters?: { // face-intelligence only
isFaceswapCheck?: boolean;
isLivenessCheck?: boolean;
isSimilarityCheck?: boolean;
};
}Example
curl -X POST "https://platform.authenta.ai/api/v1/jobs" \
-H "Authorization: Bearer api_xxxxxxxx..." \
-H "Content-Type: application/json" \
-d '{
"taskTypeId": "1",
"inputs": [
{ "slotName": "original", "fileName": "test.jpg", "contentType": "image/jpeg", "sizeBytes": 414241 }
]
}'Response — 201 Created
{
"job": {
"id": "1",
"tenantId": "6f1c2a4e-1d2b-4c3d-9e8f-0a1b2c3d4e5f",
"taskTypeId": "1",
"status": "initiated",
"cost": 1,
"createdAt": "2026-10-14T16:10:21.040Z",
"updatedAt": "2026-10-14T16:10:21.040Z",
"result": null
},
"inputs": [
{
"slotName": "original",
"uploadUrl": "https://<bucket>.s3.us-east-1.amazonaws.com/jobs/1/input/original.media?X-Amz-Algorithm=...",
"uploadUrlExpiresAt": "2026-10-14T16:10:51.040Z"
}
]
}The job's cost in credits is charged when the job is created, and refunded in full if the job is cancelled, deleted before processing, or fails. See Quotas & Credits.
Errors
| Status | name | Cause |
|---|---|---|
401 | INVALID_API_KEY | Missing, revoked or expired API key |
402 | INSUFFICIENT_BALANCE / PAYG_LIMIT_REACHED | Not enough credits, or the monthly pay-as-you-go limit is reached |
404 | TASK_TYPE_NOT_FOUND | Unknown task type, or not available to your account |
422 | VALIDATION_ERROR | Invalid body — wrong slot name, MIME type not accepted by the task type, missing pageCount; see fields |
422 | FILE_TOO_LARGE | sizeBytes is above the upload limit (10 MB by default) |
2. Upload the file
PUT the file's bytes to its uploadUrl. This request goes straight to storage, not to the Authenta API, so do not send your Authorization header.
curl -X PUT "<uploadUrl>" \
-H "Content-Type: image/jpeg" \
--upload-file test.jpgIf the upload URL expires before you upload, cancel the job (its credits are refunded) and create a new one. Jobs left in initiated are cleaned up after about 20 minutes: if every file was uploaded, the job is finalized for you; otherwise it is deleted and its credits are refunded.
3. Finalize the job
POST /jobs/{id}/finalize
Call once every input is uploaded. The job moves to queued.
curl -X POST "https://platform.authenta.ai/api/v1/jobs/1/finalize" \
-H "Authorization: Bearer api_xxxxxxxx..."Response — 200 OK
The job object with "status": "queued".
Errors
| Status | name | Cause |
|---|---|---|
404 | JOB_NOT_FOUND | No such job in your account |
404 | UPLOAD_NOT_FOUND | A file was not uploaded to its uploadUrl (or the upload was rejected) |
409 | UPLOAD_ALREADY_FINALIZED | The job was already finalized |
4. Get the result
Poll GET /jobs/{id} every few seconds until status is completed or failed, then read result:
import os, time, requests
API = "https://platform.authenta.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['AUTHENTA_API_KEY']}"}
def wait_for_job(job_id: str, interval: float = 3.0, timeout: float = 600.0) -> dict:
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
res = requests.get(f"{API}/jobs/{job_id}", headers=HEADERS)
res.raise_for_status()
job = res.json()
if job["status"] in ("completed", "failed", "cancelled"):
return job
time.sleep(interval)
raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")Reading jobs
List jobs
GET /jobs
Returns your jobs, newest first.
| Query parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Items per page (1–100) |
offset | integer | 0 | Items to skip |
status | string | — | Filter by status |
taskTypeSlug | string | — | Filter by task type slug, e.g. ai-image-detection |
createdAfter | ISO 8601 date | — | Jobs created on or after this time |
createdBefore | ISO 8601 date | — | Jobs created on or before this time |
curl "https://platform.authenta.ai/api/v1/jobs?limit=10&status=completed" \
-H "Authorization: Bearer api_xxxxxxxx..."Response — 200 OK
{
"data": [
{
"id": "1",
"tenantId": "6f1c2a4e-1d2b-4c3d-9e8f-0a1b2c3d4e5f",
"taskTypeId": "1",
"status": "completed",
"cost": 1,
"createdAt": "2026-10-14T16:10:21.040Z",
"updatedAt": "2026-10-14T16:11:02.511Z",
"result": { "isFake": false, "confidencePercent": 85.93, "fakeConfidencePercent": 14.07, "realConfidencePercent": 85.93, "tag": "real", "tagBoundaries": { "real": 30, "likelyReal": 50, "likelyFake": 75 }, "modelVersion": "v2.1.0" }
}
],
"total": 42,
"limit": 10,
"offset": 0
}Get a job
GET /jobs/{id}
Returns the job object plus its artifacts: the media you uploaded and any files the model produced.
curl "https://platform.authenta.ai/api/v1/jobs/1" \
-H "Authorization: Bearer api_xxxxxxxx..."Response — 200 OK
{
"id": "1",
"tenantId": "6f1c2a4e-1d2b-4c3d-9e8f-0a1b2c3d4e5f",
"taskTypeId": "1",
"status": "completed",
"cost": 1,
"createdAt": "2026-10-14T16:10:21.040Z",
"updatedAt": "2026-10-14T16:11:02.511Z",
"result": { "isFake": false, "confidencePercent": 85.93, "fakeConfidencePercent": 14.07, "realConfidencePercent": 85.93, "tag": "real", "tagBoundaries": { "real": 30, "likelyReal": 50, "likelyFake": 75 }, "modelVersion": "v2.1.0" },
"artifacts": [
{
"id": "1",
"kind": "input",
"slotName": "original",
"status": "completed",
"contentType": "image/jpeg",
"metadata": { "fileName": "test.jpg", "sizeBytes": 414241 },
"downloadUrl": "https://<bucket>.s3.us-east-1.amazonaws.com/jobs/1/input/original.media?X-Amz-...",
"createdAt": "2026-10-14T16:10:21.040Z"
}
]
}Errors
| Status | name | Cause |
|---|---|---|
404 | JOB_NOT_FOUND | No such job in your account, or it was deleted |
Downloading files
Each entry in artifacts is one file of the job:
| Field | Type | Description |
|---|---|---|
id | string | Artifact ID |
kind | string | input (your upload) or a model output: result, heatmap, image, report, mask, audio |
slotName | string | null | Input slot for input artifacts, otherwise null |
status | string | pending (not uploaded/finalized yet) or completed |
contentType | string | MIME type of the file |
metadata | object | null | For inputs: fileName, sizeBytes (and pageCount for PDFs) |
downloadUrl | string | null | Signed URL, valid for about 15 minutes; null while pending |
createdAt | ISO 8601 date | When the artifact was recorded |
Download a file with a plain GET to its downloadUrl — without your Authorization header, since the URL points at storage:
curl -o heatmap.png "<downloadUrl>"If a downloadUrl has expired, call GET /jobs/{id} again for fresh URLs.
Result shapes
result is null until the job finishes. Branch on status before reading it, and ignore fields you don't recognize: new fields can be added at any time.
Scored detection results share the same fields: isFake, fakeConfidencePercent, realConfidencePercent, confidencePercent, tag, tagBoundaries and modelVersion. See Reading results for what each means and how to act on the tags.
{
"isFake": false,
"confidencePercent": 89.6,
"fakeConfidencePercent": 10.4,
"realConfidencePercent": 89.6,
"tag": "real",
"tagBoundaries": { "real": 30, "likelyReal": 50, "likelyFake": 75 },
"modelVersion": "v2.1.0"
}Some task types add their own fields, such as per-window scores for audio or page counts for PDFs, and the utilities return no verdict at all. Each task type's page shows its full result with an example.
Failed jobs: result stays null. A job is retried automatically before it is marked failed, and its credits are refunded. Create a new job to try again; if it keeps failing, contact support with the job ID.
Managing jobs
Cancel a job
POST /jobs/{id}/cancel
Cancels a job in initiated or queued status and refunds its credits. Jobs that are already processing cannot be cancelled. Requires the Delete permission.
curl -X POST "https://platform.authenta.ai/api/v1/jobs/1/cancel" \
-H "Authorization: Bearer api_xxxxxxxx..."Response — 200 OK
The job object with "status": "cancelled".
Errors
| Status | name | Cause |
|---|---|---|
404 | JOB_NOT_FOUND | No such job in your account |
422 | CANCEL_NOT_ALLOWED | The job is processing or already finished |
Delete a job
DELETE /jobs/{id}
Deletes the job's stored files. Jobs that are currently processing cannot be deleted. A job deleted while still initiated or queued is cancelled first, so its credits are refunded.
curl -X DELETE "https://platform.authenta.ai/api/v1/jobs/1" \
-H "Authorization: Bearer api_xxxxxxxx..."Response — 204 No Content
Errors
| Status | name | Cause |
|---|---|---|
404 | JOB_NOT_FOUND | No such job in your account, or it was already deleted |
422 | JOB_DELETE_NOT_ALLOWED | The job is processing |
The job object
| Field | Type | Description |
|---|---|---|
id | string | Job ID |
tenantId | string (UUID) | Your account ID |
taskTypeId | string | Task type used |
status | string | See Job lifecycle |
cost | integer | Credits charged for the job |
createdAt / updatedAt | ISO 8601 date | Timestamps |
result | object | null | The verdict: isFake, confidence fields, tag, tagBoundaries and modelVersion, plus task-specific fields. See Result shapes and Reading results |
Errors
Every error response has the same shape:
{
"rid": "9b6f1d2e-5c1a-4b7e-8f3d-2a1c0e9d8b7a",
"name": "VALIDATION_ERROR",
"message": "Some fields contain invalid data. Please check and try again",
"fields": [
{ "field": "inputs", "msg": "Content type \"video/mp4\" is not accepted for slot \"original\"" }
]
}| Field | Description |
|---|---|
rid | Request ID — include it when contacting support |
name | Machine-readable error code; branch on this, not on message |
message | Human-readable description |
fields | Present on VALIDATION_ERROR: which fields are invalid and why |
Errors common to every endpoint:
| Status | name | Cause |
|---|---|---|
401 | UNAUTHENTICATED | No Authorization header, or it isn't Bearer api_... |
401 | INVALID_API_KEY | Revoked, expired or unknown API key |
403 | FORBIDDEN | The key lacks the permission the endpoint needs (see the endpoint table) |
500 | INTERNAL_ERROR | Unexpected server error; safe to retry with backoff |
