Quickstart
This walks through the smallest useful loop: create a key, screen an entity, and check whether it opened a case.
1. Create an API key
Admin → API Keys → Create Key. Grant at minimum entities:write, entities:read, screening:write, cases:read. Copy the plaintext key shown — it is not shown again.
2. Create and screen an entity
POST /api/v1/entities
Authorization: Bearer drsk_live_...
Content-Type: application/json
{
"external_id": "CUST-001",
"entity_type": "individual",
"name": "Vladimir Ivanovich Petrov",
"country": "RU",
"birth_year": 1975
}
Creating an entity screens it automatically — the 201 response is the entity detail, including its current entity_status and any matches found.
external_id is optional: if omitted, the API generates one (prefixed ENT-, e.g. ENT-7K2M9QX4TB) and returns it in the response. Supplying your own customer reference ID is recommended — it keeps screening records traceable to your system and is the key you use on every entity endpoint (GET /entities/{external_id}, etc.). Note that omitting it also weakens retry safety: use an Idempotency-Key header so a retried create doesn't produce a duplicate entity (see idempotency.md).
Alternatively, use POST /screenings with name + entity_type (or external_id alone to rescreen an entity you already created). This still creates and persists an entity — like POST /entities, it auto-generates an ENT- prefixed external_id if you don't supply one — it's just a single combined create-and-screen call rather than two.
3. Check for a case
If the screening produced a qualifying match, a case was opened. List it:
GET /api/v1/entities/CUST-001/blocking-cases
Authorization: Bearer drsk_live_...
This is the entity-scoped way to find a case (GET /cases itself filters by status/risk_level/created_reason/date range, not by entity — see pagination-and-rate-limits.md). Once you have a case_id, pull match detail with GET /cases/{case_id}/matches.
When recording a decision, choose decision_type from the pair allowed for that match's match_category (sanctions → True Match / False Positive; PEP/RCA → Confirmed / Not a Match). Details: Case decisions.
4. (Bulk alternative) Batch upload + poll
For many entities at once:
POST /api/v1/entities/batch
{
"review_confirmed": true,
"entities": [ { "external_id": "CUST-001", "entity_type": "individual", "name": "..." }, ... ]
}
returns a job_id and handshake_token (also mirrored under webhook.handshake_token). Validation is all-or-nothing: if any row fails validation (e.g. a missing name), the whole request is rejected with 422 VALIDATION_FAILURES_EXCEEDED and error.details.validation_errors listing the offending rows — no job is created, and no rows are screened, including the valid ones. Fix and resubmit the full batch. Poll it (respect the job's own rate limit — don't tight-loop):
GET /api/v1/jobs/{job_id}
until status is terminal, then list cases as in step 3.
failed_count being non-zero doesn't necessarily mean something broke — a row can be deliberately rejected
(e.g. a placeholder value like N/A) rather than genuinely failing. Check GET /api/v1/jobs/{job_id}/row-results
for which rows and why; see Webhooks for the
full breakdown.
Correlation IDs
Every /api/v1/** response includes a per-request correlation_id (UUID) in the body and echoes the same value as the X-Correlation-Id response header. Errors use the same field in the standard envelope.
You may send X-Correlation-Id or X-Request-Id (UUID) on the request to supply your own trace id; otherwise the server generates one. Include the value when contacting support — it joins API responses, usage logs, and (when applicable) webhook deliveries.
Next steps
- Authentication & scopes
- Case decisions — sanctions vs PEP/RCA
decision_typematrix - Idempotency
- Pagination & rate limits
- Webhooks — get pushed
case.openedinstead of polling - Error code catalog
- Full reference: every endpoint, parameter, and schema is in the API Reference tab, with try-it-out support