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(defaultall)?activeOnly=true|false(defaulttrue)
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.