Skip to content

Downloading documents, images & videos

Every byte attached to an applicant — ID document front + back, selfies, liveness video clips, company-document PDFs — lives behind one discovery endpoint + one bytes endpoint.

Endpoint Returns
GET /v1/applicants/{externalUserId}/resources Metadata list
GET /v1/applicants/{externalUserId}/resources/{resourceId} Raw bytes
GET /v1/applicants/{externalUserId}/uploads/history Superseded uploads (older versions)

Discover first

curl -X GET 'https://api.compliance.example/v1/applicants/user-12345/resources' \
  -H 'X-Api-Key: pk_live_...' \
  -H 'X-Api-Secret: ...' \
  -H 'X-Environment: production'
{
  "items": [
    {
      "id": "0a1b2c3d4e5f6789abc...db.7fa3c91b88de",
      "enrollmentId": "0a1b2c3d-4e5f-...",
      "kind": "image",
      "slot": "document_front",
      "documentType": "passport",
      "side": "front",
      "mime": "image/jpeg",
      "addedAtUtc": "2026-06-07T10:15:11Z",
      "source": "docapture",
      "active": true
    },
    {
      "id": "0a1b2c3d4e5f6789abc...lv.f0aa1cbb31df",
      "enrollmentId": "0a1b2c3d-4e5f-...",
      "kind": "video",
      "slot": "liveness_video",
      "mime": "video/webm",
      "addedAtUtc": "2026-06-07T10:15:42Z",
      "source": "liveness",
      "active": true
    }
  ],
  "totalItems": 2
}

kind discriminator

image (jpeg/png/heic/webp), pdf (company docs), video (webm/mp4 liveness clips). Tells you what Content-Type the bytes endpoint will return before you fetch.

slot

document_front · document_back · selfie · liveness_video · company_doc · additional.

Query filters

  • ?enrollmentId={guid} — only resources from one enrollment
  • ?kind=image|video|pdf|all (default all)
  • ?activeOnly=true|false (default true)

Then fetch the bytes

curl -X GET 'https://api.compliance.example/v1/applicants/user-12345/resources/0a1b2c3d4e5f6789abc...db.7fa3c91b88de' \
  -H 'X-Api-Key: pk_live_...' \
  -H 'X-Api-Secret: ...' \
  -H 'X-Environment: production' \
  -o doc-front.jpg

The Content-Type header reflects the resource's actual MIME — you should NOT assume from the URL or slot. Supports HEAD for size/mime probing before download. Supports Range for video.

Resource id format

{enrollmentIdHex32}.{slotCode}.{hmac16} — opaque. The HMAC fragment is generated server-side using a private key and verified on every bytes request, so a forged id returns 404. Cross-product probes also return 404 (no existence leak).

Historical (superseded) uploads

When an applicant re-uploads over a slot (e.g. they retook a bad selfie), the older capture stays in storage marked inactive. List them:

curl -X GET 'https://api.compliance.example/v1/applicants/user-12345/uploads/history' \
  -H 'X-Api-Key: pk_live_...' \
  -H 'X-Api-Secret: ...' \
  -H 'X-Environment: production'

Each row carries a resourceId you pass to the bytes endpoint just like an active row — the resolver matches both active and historical uploads.