---
title: "Start a media analysis job"
method: POST
path: "/api/analyse/job"
tags: ["Analyse"]
---

# Start a media analysis job

`POST /api/analyse/job`

## Request

- Base URL: `https://snapwonders.com`
- URL: `https://snapwonders.com/api/analyse/job`
- Auth: API key in header `X-Api-Key`

Submits analysis options and dispatches the job to the worker queue. All files must be fully uploaded via TUS and show `"status":"completed"` (verify with `GET /api/analyse/session/{uid}/files`) before calling this endpoint.

The call is **idempotent**: calling it again for a session that already has a job returns the existing job without creating a duplicate.

**Authentication:** `X-Api-Key` header required.

## Request body

- object
  - `upload_uid` string, uuid, required: The `upload_uid` returned by `POST /api/analyse/session`
  - `face_detection` boolean: Enable face detection (YuNet). Default: `true`.
  - `text_detection` boolean: Enable OCR / text region detection. Default: `true`.
  - `face_sensitivity` 'standard' | 'thorough': `standard` — confidence threshold 0.5 (fewer false positives). `thorough` — threshold 0.2 (catches more faces, more false positives). Default: `standard`.
  - `forensic_depth` 'standard' | 'deep': `standard` — core forensic checks (ELA, clone detection, noise analysis, etc.). `deep` — extended checks with higher sensitivity; reserved for future use (currently identical to `standard`). Default: `standard`.
  - `expiry` '1h' | '12h' | '1d' | '2d' | '1w' | '1m': How long the result data remains accessible after the job completes. `1h` = 1 hour, `12h` = 12 hours, `1d` = 1 day (default), `2d` = 2 days, `1w` = 1 week, `1m` = 1 month. **Free-tier keys are silently clamped** to `upload.free_max_expiry` (default `1d`): the job still succeeds, but anything longer is reduced. Pro accounts get the requested value. No response currently returns the granted expiry, so assume the free maximum unless the owning account is Pro.
  - `archive_passwords` object: Optional. Passwords for encrypted archives, keyed by the archive's original filename (e.g. `{"secret.zip":"hunter2"}`). Used transiently to extract password-protected archives before analysis — **never stored**. Non-encrypted archives ignore it. Check `needs_password` in `GET /api/analyse/session/{uid}/files` to see which archives require one.

## Response `200`

Job already exists (idempotent repeat call) — returns existing job

## Other responses

- `201`: Job queued
- `400`: Validation error — no files uploaded, invalid option value, etc.
- `401`: Not authenticated. `error` names the exact cause: `missing_api_key`, `malformed_api_key`, `invalid_api_key` (key unknown/revoked/expired), or — when the key itself is valid — `account_not_verified` / `account_inactive`.
- `403`: Two distinct causes, named by `error`. `forbidden` — the session does not belong to your API key. `account_blocked` — an administrator has blocked this account from submitting jobs; permanent until reversed by support, so do not retry. `account_blocked` is a different axis from the 401 account-status codes: the account may be fully active and verified and still be job-blocked.
- `404`: Session not found
- `410`: Session expired — sessions are valid for 24 hours from creation
- `429`: Too many active jobs for this API key. Wait for queued/processing jobs to finish, then retry. Response includes `active_jobs` and `limit`.

---

[API](https://skmtc.dev/snapwonders/apis/snapwonders-api-mcp.md) · [All operations](https://skmtc.dev/snapwonders/apis/snapwonders-api-mcp/llms.txt) · [OpenAPI document](https://skmtc.dev/snapwonders/apis/snapwonders-api-mcp/revisions/645bbccc9550?raw)
