Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

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.

EndpointMethodPermissionDescription
/jobsPOSTWriteCreate a job and get an upload URL per input
/jobs/{id}/finalizePOSTWriteQueue the job for processing once its files are uploaded
/jobsGETReadList your jobs
/jobs/{id}GETReadGet a job with its status, result and files
/jobs/{id}/cancelPOSTDeleteCancel a job that has not started processing
/jobs/{id}DELETEDeleteDelete 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
StatusMeaning
initiatedCreated; waiting for the file upload and finalize
queuedFinalized; waiting for a detection worker
processingA worker is analyzing the media
completedDone — result holds the verdict
failedProcessing failed — result describes the error
cancelledCancelled 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

StatusnameCause
401INVALID_API_KEYMissing, revoked or expired API key
402INSUFFICIENT_BALANCE / PAYG_LIMIT_REACHEDNot enough credits, or the monthly pay-as-you-go limit is reached
404TASK_TYPE_NOT_FOUNDUnknown task type, or not available to your account
422VALIDATION_ERRORInvalid body — wrong slot name, MIME type not accepted by the task type, missing pageCount; see fields
422FILE_TOO_LARGEsizeBytes 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.jpg

If 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

StatusnameCause
404JOB_NOT_FOUNDNo such job in your account
404UPLOAD_NOT_FOUNDA file was not uploaded to its uploadUrl (or the upload was rejected)
409UPLOAD_ALREADY_FINALIZEDThe 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 parameterTypeDefaultDescription
limitinteger20Items per page (1–100)
offsetinteger0Items to skip
statusstring—Filter by status
taskTypeSlugstring—Filter by task type slug, e.g. ai-image-detection
createdAfterISO 8601 date—Jobs created on or after this time
createdBeforeISO 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

StatusnameCause
404JOB_NOT_FOUNDNo such job in your account, or it was deleted

Downloading files

Each entry in artifacts is one file of the job:

FieldTypeDescription
idstringArtifact ID
kindstringinput (your upload) or a model output: result, heatmap, image, report, mask, audio
slotNamestring | nullInput slot for input artifacts, otherwise null
statusstringpending (not uploaded/finalized yet) or completed
contentTypestringMIME type of the file
metadataobject | nullFor inputs: fileName, sizeBytes (and pageCount for PDFs)
downloadUrlstring | nullSigned URL, valid for about 15 minutes; null while pending
createdAtISO 8601 dateWhen 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

StatusnameCause
404JOB_NOT_FOUNDNo such job in your account
422CANCEL_NOT_ALLOWEDThe 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

StatusnameCause
404JOB_NOT_FOUNDNo such job in your account, or it was already deleted
422JOB_DELETE_NOT_ALLOWEDThe job is processing

The job object

FieldTypeDescription
idstringJob ID
tenantIdstring (UUID)Your account ID
taskTypeIdstringTask type used
statusstringSee Job lifecycle
costintegerCredits charged for the job
createdAt / updatedAtISO 8601 dateTimestamps
resultobject | nullThe 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\"" }
  ]
}
FieldDescription
ridRequest ID — include it when contacting support
nameMachine-readable error code; branch on this, not on message
messageHuman-readable description
fieldsPresent on VALIDATION_ERROR: which fields are invalid and why

Errors common to every endpoint:

StatusnameCause
401UNAUTHENTICATEDNo Authorization header, or it isn't Bearer api_...
401INVALID_API_KEYRevoked, expired or unknown API key
403FORBIDDENThe key lacks the permission the endpoint needs (see the endpoint table)
500INTERNAL_ERRORUnexpected server error; safe to retry with backoff

Next steps