> ## Documentation Index
> Fetch the complete documentation index at: https://docs.samsa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Check an image or video

> Upload one asset and get a per-technique detection result, with the C2PA verdict as the authoritative answer.

```
POST https://detect.samsa.ai/v1/public/detect
```

Upload a single image or video as `multipart/form-data`. The response carries one
top-level `detected` verdict plus a per-technique breakdown. No authentication, no
credits. The upload is processed **in memory and never retained**.

## Request

Send exactly **one** file part named `file`. The part must carry a `filename` in its
`Content-Disposition` header — a plain form field without one is not a file part.

|                   |                                      |
| ----------------- | ------------------------------------ |
| **Content-Type**  | `multipart/form-data`                |
| **Field**         | `file` — the image or video to check |
| **Max size**      | 50 MB                                |
| **Image formats** | JPEG, PNG, WebP, GIF                 |
| **Video formats** | MP4, QuickTime, WebM                 |

<Note>
  JPEG/PNG/WebP/GIF and MP4/QuickTime are recognised by magic bytes, so a wrong or
  generic part `Content-Type` (for example `application/octet-stream`) does not break
  detection for those formats. **WebM has no magic-byte branch** and is accepted only
  when the part declares `Content-Type: video/webm`.
</Note>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://detect.samsa.ai/v1/public/detect \
    -F "file=@photo.jpg"
  ```

  ```python Python theme={null}
  import requests

  with open("photo.jpg", "rb") as fh:
      response = requests.post(
          "https://detect.samsa.ai/v1/public/detect",
          files={"file": ("photo.jpg", fh, "image/jpeg")},
          timeout=120,
      )

  response.raise_for_status()
  result = response.json()
  print(result["detected"])
  ```

  ```typescript TypeScript theme={null}
  import { readFile } from "node:fs/promises";

  const form = new FormData();
  // The third argument sets the part filename — required for it to count as a file part.
  form.append("file", new Blob([await readFile("photo.jpg")]), "photo.jpg");

  const response = await fetch("https://detect.samsa.ai/v1/public/detect", {
    method: "POST",
    body: form,
  });

  if (!response.ok) {
    const { detail } = await response.json();
    throw new Error(`Detection failed (${response.status}): ${detail}`);
  }

  const result = await response.json();
  console.log(result.detected);
  ```
</CodeGroup>

## Response

`200 OK`. An image or video that carries a valid, trusted Samsa C2PA manifest:

```json Response theme={null}
{
  "request_id": "c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "detected": "samsa",
  "techniques": [
    {
      "type": "metadata",
      "result": "samsa",
      "confidence": "high",
      "manifest": {
        "claim_generator": "Samsa/1.0",
        "digital_source_type": "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia",
        "upstream_provider": "fal",
        "upstream_model": "flux-pro",
        "timestamp": "2026-07-02T14:21:07+00:00",
        "assertions": ["c2pa.actions", "c2pa.hash.data"]
      }
    },
    {
      "type": "watermark",
      "result": "not_checked",
      "confidence": null,
      "vendor_id": null
    },
    {
      "type": "watermark",
      "result": "not_checked",
      "confidence": null,
      "vendor_id": null
    }
  ],
  "external_verification": {
    "c2pa": "https://verify.contentauthenticity.org"
  },
  "result_pdf_url": "https://detect.samsa.ai/v1/public/detect/result/c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/pdf",
  "responded_at": "2026-07-02T14:21:09.412093Z"
}
```

| Field                   | Type              | Description                                                                                                 |
| ----------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------- |
| `request_id`            | string (UUID)     | Server-generated id for this check. Use it to fetch the [signed result PDF](/content-verification/results). |
| `detected`              | enum              | The top-level verdict: `samsa`, `non_samsa`, or `unknown`.                                                  |
| `techniques[]`          | array             | One entry per technique that was applied — see [below](#reading-the-techniques-breakdown).                  |
| `external_verification` | object            | Links for verifying the result independently of Samsa. Currently `c2pa`.                                    |
| `result_pdf_url`        | string \| null    | Link to the signed PDF of this result, or `null` when result persistence is unavailable.                    |
| `responded_at`          | string (ISO 8601) | When the check completed, in UTC.                                                                           |

<Note>
  `result_pdf_url` may be `null`. When it is present, follow it exactly as returned
  rather than assembling the URL yourself — the returned URL and the
  [documented result endpoint](/content-verification/results) serve the identical
  signed PDF.
</Note>

### The `detected` verdict

The verdict comes from C2PA manifest verification, which is authoritative. Watermark
techniques are corroboration: they can supply attribution when no manifest is present,
but they never override a manifest verdict.

| `detected`  | Reached when                                                                                                                       |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `samsa`     | A valid, trusted, allowlisted Samsa manifest was verified — or, with no manifest present, a watermark decode returned a Samsa hit. |
| `non_samsa` | A manifest is present but is not attributable to Samsa (another issuer, untrusted, or tampered).                                   |
| `unknown`   | No manifest is present and no watermark hit was returned.                                                                          |

<Warning>
  `unknown` means **this check found no evidence**, not that the asset is
  authentic or human-made. Provenance metadata is easily stripped, and hosted watermark
  decode is [not yet available](#reading-the-techniques-breakdown).
</Warning>

## Reading the techniques breakdown

`techniques[]` always starts with the single `metadata` entry (the authoritative C2PA
layer), followed by the watermark techniques applicable to the asset's modality.

### The `metadata` technique

```json theme={null}
{
  "type": "metadata",
  "result": "absent",
  "confidence": "low",
  "manifest": null
}
```

| Field        | Description                                                                                                                                                                                                                                          |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `result`     | `samsa` (valid, trusted, allowlisted Samsa manifest), `non_samsa` (a manifest from another issuer, or one that is valid but untrusted), `tampered` (a manifest that fails validation), or `absent` (no manifest — commonly because it was stripped). |
| `confidence` | `high`, `medium`, or `low`. Always present for this technique.                                                                                                                                                                                       |
| `manifest`   | A layperson-readable summary of the verified manifest (`claim_generator`, `digital_source_type`, `upstream_provider`, `upstream_model`, `timestamp`, `assertions`), or `null` when there is nothing to summarize.                                    |

<Info>
  C2PA manifest verification is **live**: it is served by the Samsa public API and by any
  independent C2PA validator. Attribution of a manifest to Samsa becomes available once
  production signing is enabled.
</Info>

### Watermark techniques

```json theme={null}
{
  "type": "watermark",
  "result": "not_checked",
  "confidence": null,
  "vendor_id": null
}
```

| Field        | Description                                                                                                     |
| ------------ | --------------------------------------------------------------------------------------------------------------- |
| `result`     | `samsa`, `absent`, `low_confidence`, or `not_checked` — see the table below.                                    |
| `confidence` | `high`, `medium`, or `low`, and `null` **if and only if** `result` is `not_checked`. The key is always present. |
| `vendor_id`  | Identifies the decoder that produced a hit; `null` unless `result` is `samsa`.                                  |

| `result`         | Meaning                                                                           |
| ---------------- | --------------------------------------------------------------------------------- |
| `samsa`          | A decoder ran and found a Samsa watermark.                                        |
| `absent`         | A decoder ran and found no Samsa watermark.                                       |
| `low_confidence` | A decoder ran and returned a weak hit.                                            |
| `not_checked`    | The decoder backend is not provisioned, so **the technique was never evaluated**. |

<Warning>
  `not_checked` is **not** a statement that no watermark is present — that is what
  `absent` means. Hosted watermark decode is not yet available; it is scheduled before
  2 February 2027. Until then the API reports these techniques as `not_checked`, never
  as a false “no watermark”. Never render a `not_checked` technique as an absent
  watermark.
</Warning>

Because hosted watermark decode is not yet live, every watermark entry currently comes
back as `not_checked` with `confidence: null`. Watermark entries carry no technique
name of their own — for the algorithm IDs, pinned model artifact hashes, per-lane
soft-binding labels, and open-source decoders behind each technique, read
[How detection works](https://detect.samsa.ai/how-detection-works) or
[`GET /v1/public/detect/info`](/content-verification/info).

## Errors

Errors return `{"detail": "…"}` — not the Samsa REST API
[error envelope](/guides/errors).

| Status | When                                                                                                             |
| ------ | ---------------------------------------------------------------------------------------------------------------- |
| `400`  | Malformed multipart body, a missing boundary, an empty upload, or a file-part count other than exactly one.      |
| `413`  | The upload exceeds the 50 MB limit.                                                                              |
| `415`  | The request is not `multipart/form-data`, or the uploaded bytes are not a supported image or video.              |
| `503`  | An available decoder or the C2PA verifier failed at inference time. The response carries a `Retry-After` header. |

<Tip>
  Treat `503` as transient and retry after the `Retry-After` interval. A decoder that is
  simply not provisioned never produces a `503` — it degrades to `not_checked` in a
  normal `200` response.
</Tip>
