Skip to content
API

One request. One verdict.

Send an image, get a three-band verdict with the exact score, the provenance we found and the model version.

Anyone can request access, any time. Enabled within an hour.

POST /api/v1/scans · example
$ curl https://perspicax.io/api/v1/scans \    -H "Authorization: Bearer $PERSPICAX_KEY" \    -H "Prefer: wait=10" \    -F [email protected]# 200 OK{  "status": "completed",  "result": {    "label": "ai_generated",    "score": 0.97,    "provenance": { "c2pa": null }  },  "model": { "name": "TrueEye", "version": "2.1" }}

At a glance

Endpoint
POST /api/v1/scans
Authentication
Authorization: Bearer pcx_live_…
Wait
Prefer: wait=N, up to 30 seconds
Retries
Idempotency-Key header
Images
Up to 20 MB, by file or by URL

Sync: wait for the answer

Send Prefer: wait=N (N up to 30). If the scan finishes in time, you get 200 with the result in the same call.

curl https://perspicax.io/api/v1/scans \
  -H "Authorization: Bearer $PERSPICAX_KEY" \
  -H "Prefer: wait=10" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F [email protected]

# Or scan an image by URL:
curl https://perspicax.io/api/v1/scans \
  -H "Authorization: Bearer $PERSPICAX_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=10" \
  -d '{"url": "https://example.com/photo.jpg"}'

Async: take a 202 and poll

If the scan is still running, you get 202 with a Location header. Poll GET /api/v1/scans/:id until status is completed.

Credits

GET /api/v1/usage returns your remaining credits, the end of the period and what you used in it.

Enterprise

A credit allowance for your team that refreshes every month or year, with top-ups any time, a live usage dashboard, alerts before you run out, API keys and retention options. Contact us and we'll set it up.

Contact us
# 1. Send without waiting (or when your wait runs out): 202 Accepted
curl -i https://perspicax.io/api/v1/scans \
  -H "Authorization: Bearer $PERSPICAX_KEY" \
  -F [email protected]
# HTTP/1.1 202 Accepted
# Location: /api/v1/scans/<id>

# 2. Poll until status is "completed" (or "failed")
curl https://perspicax.io/api/v1/scans/<id> \
  -H "Authorization: Bearer $PERSPICAX_KEY"

# Credits left in this period
curl https://perspicax.io/api/v1/usage \
  -H "Authorization: Bearer $PERSPICAX_KEY"
# { "creditsRemaining": …, "periodEnd": "…", "usedThisPeriod": … }

Read the result

FieldMeaning
result.labelai_generated, inconclusive or not_ai_generated. Build your flow on this.
result.scoreThe detector score from 0 to 1. Only API keys see it. It is not a probability.
result.thresholdsThe two cut-offs of this model version.
result.inconclusiveReasonbetween_thresholds, or outside_scope for screenshots, documents and graphics.
result.provenanceContent Credentials (C2PA) and the IPTC digital source type, when present.
model.versionThe model name and version (TrueEye 2.1), recorded on every scan.
Provenance checks
  • Content Credentials (C2PA)Live
  • SynthID watermark checkSupported

Errors to handle

Errors follow RFC 9457 problem details with a code field.

StatusCodeWhat to do
401unauthorizedCheck the key in the Authorization header.
402insufficient_creditsYour credits are used up. Top up, or wait for the next period.
413file_too_largeSend an image of 20 MB or less.
415unsupported_media_typeSend JPEG, PNG, WebP, HEIC, AVIF or a still GIF.
422unprocessable_imageThe image could not be decoded. Check the file.
429rate_limitedSlow down and retry after the Retry-After header.
503detector_unavailableRetry with the same Idempotency-Key.

Request API access

Anyone can request access, any time. Enabled within an hour.

Request API access