# Credential reads

A credential read fetches an image, reads the C2PA manifest embedded in its
bytes, and returns a summary. It describes the image file only. To check the
product page, use [`POST /mc4p/page-checks`](/api/page-checks).

```bash
curl -X POST https://api.mintall.ai/api/v1/mc4p/credential-reads \
  -H "Content-Type: application/json" \
  -d '{ "image_url": "https://merchant.example/images/pendant.jpg" }'
```

Returns 200 with the summary, whatever the verdict.

```json
{
  "scope": "image_bytes",
  "verdict": "credential_present",
  "requested_url": "https://merchant.example/images/pendant.jpg",
  "final_url": "https://merchant.example/images/pendant.jpg",
  "media_type": "image/jpeg",
  "findings": [],
  "embedded_credential": {
    "present": true,
    "active_manifest": "...",
    "claim_generator": "...",
    "signing_time": "2026-09-16T12:00:00Z",
    "signer": { "issuer": "...", "common_name": "..." },
    "assertion_labels": ["c2pa.actions"],
    "assertions_truncated": false
  },
  "blockchain": null
}
```

## Verdicts

| Verdict              | Meaning                                                  |
| -------------------- | -------------------------------------------------------- |
| `credential_present` | A manifest was read and C2PA did not mark it invalid.    |
| `credential_invalid` | A manifest was read and C2PA marked it invalid.          |
| `no_credential`      | The image carries no C2PA manifest.                      |
| `image_fetch_failed` | Blocked, timed out, too large, or non-2xx. See findings. |
| `not_an_image`       | The bytes are not a supported image format.              |

**Storefront CDNs strip credentials:** An image served from a Shopify storefront (`cdn.shopify.com`) usually reads
  `no_credential`. Shopify's CDN re-encodes images and drops the C2PA data on
  the way. Read the original asset instead.

## Limits

Reads are rate limited per caller. Past that the endpoint returns 429. A 503
means too many reads are in flight; retry after the `Retry-After` header's
seconds. A 503 does not count against the rate limit. A 502 means the image was
fetched but its credential could not be extracted.

The request body takes `image_url` only. Any other field returns 422.