API documentation

Sanctions screening API requests and responses

Send one subject, choose its source coverage, and handle a possible match, no-match, or error. See the complete request and result fields.

Updated

250 free live screenings. One lifetime allowance. No credit card required.
Create
POST /screenings

Submit a subject and selected coverage.

JSON body
Subject + coverage

Required fields are separate from HTTP headers.

Success
201 · data object

Completed outcome; preserve coverage and versions.

1. Send one complete screening request

Create a sandbox key with screenings:write and results:read using the quickstart. Set SANCTIONSKIT_API_KEY and set REQUEST_KEY to a newly generated UUID before the first attempt. Persist that key with your intended operation and reuse it unchanged after a timeout. The example subject and reference below are invented.

POST /api/v1/screenings completes synchronously and returns HTTP 201 with {data: ScreeningResult}. Required input is subject with a name, plus exactly one of package or sources. The smallest sandbox body is {"subject":{"name":"Alex Morgan"},"package":"sandbox@1"}. entityType defaults to person, identifiers to an empty array, and retention to standard.

reference is your optional business correlation string, not the retry key. Optional counterpartyId must identify a saved record in this environment whose identity agrees with the request. Optional policy is an actual published {id, version}; discover it through /policies. No match threshold or arbitrary metadata field is accepted. Unknown fields are rejected.

Terminal · curl
curl --fail-with-body "https://www.sanctionskit.com/api/v1/screenings" \
  -H "Authorization: Bearer $SANCTIONSKIT_API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $REQUEST_KEY" \
  --data '{
  "subject": {
    "name": "Alex Morgan",
    "entityType": "person",
    "birthDate": "1984"
  },
  "package": "sandbox@1",
  "reference": "demo-customer-001",
  "retention": "standard"
}'

2. Read the success contract before making a decision

Every successful create response has a top-level data object. Its required keys are id, environment, status, createdAt, matches, coverage, versions and disclaimer. status is potential_match or no_match; error is not a ScreeningResult status. The linked endpoint reference includes all nested record, evidence, coverage and version properties, their types, required markers and complete synthetic response examples.

matches is an array, including an empty array for no_match. Every match contains record, score, evidence and conflicts. Preserve record.sourceId and record.id together; compare the source facts with your submitted identity. coverage records the actual source versions and freshness used. versions always contains dataset, matchingEngine and policy; package is conditional on package selection. policySnapshot is conditional on an organization policy.

POST /screenings does not guarantee echoed subject or reference properties. Save your own correlation at submission. GET /results/{id} adds subject and reference to its data object; those values can be null under minimal retention. Do not infer the create response shape from a later detail read. A no_match is limited to the selected coverage, known inputs, time and matching rules; it is not legal clearance.

Complete synthetic no-match response

This full response illustrates a separate invented no-match scenario, Juniper Example Cooperative, using sandbox@1. It is not the predicted response for the Alex Morgan request above. UUIDs and timestamps are fixed examples, not a claim that a hosted request was made. The linked endpoint reference also provides a full potential-match response with nested source records, match evidence and conflicts.

Notice that matches remains an array when empty, coverage and versions are still present, and there is no error object or success requestId property. Check the X-Request-Id header for transport diagnostics. Missing optional properties such as policySnapshot must be handled without rejecting an otherwise valid result.

JSON · synthetic HTTP 201
{
  "data": {
    "id": "01234567-89ab-4cde-8f01-23456789abce",
    "environment": "sandbox",
    "status": "no_match",
    "createdAt": "2026-09-17T12:00:00.000Z",
    "matches": [],
    "matching": {
      "version": "review-1.3.0",
      "profile": "standard",
      "nameThreshold": 78,
      "corroboratedNameThreshold": 75,
      "retrievalVersion": "indexed-1.2.0",
      "partialNames": "exclude"
    },
    "coverage": [
      {
        "sourceId": "sandbox-synthetic",
        "version": "synthetic-v1",
        "retrievedAt": "2026-09-16T00:00:00.000Z",
        "fresh": true
      }
    ],
    "versions": {
      "dataset": "synthetic-v1",
      "matchingEngine": "deterministic-1.3.0",
      "policy": "review-1.3.0",
      "package": "sandbox@1"
    },
    "disclaimer": "This demonstration uses invented records. It does not search government lists, screen a real person, or provide legal clearance. Scores describe similarity, not wrongdoing."
  }
}

3. Implement separate success and failure paths

Save the request helper as sk-api.mjs and this example as screen.mjs, then run node screen.mjs. Use the same REQUEST_KEY and body when recovering an uncertain attempt. The comments mark the points where your application must save evidence and create review work; console output deliberately contains only an ID and status.

A failed HTTP request throws before the status switch. On potential_match, send evidence to an authorized reviewer. On no_match, apply your own documented policy to the result and its coverage. Unsupported statuses or invalid response shapes stop processing rather than treating the screening as successful.

JavaScript · screen.mjs
import { api } from './sk-api.mjs';

const key = process.env.REQUEST_KEY;
if (!key) throw new Error('Set REQUEST_KEY once for this screening operation.');
const result = await api('/screenings', {
  method: 'POST',
  key,
  body: {
  "subject": {
    "name": "Alex Morgan",
    "entityType": "person",
    "birthDate": "1984"
  },
  "package": "sandbox@1",
  "reference": "demo-customer-001",
  "retention": "standard"
},
});
if (typeof result.id !== 'string' || !Array.isArray(result.matches) ||
    !Array.isArray(result.coverage) || !result.versions) {
  throw new Error('Unexpected screening response.');
}
switch (result.status) {
  case 'potential_match':
    // Save the full result in authorized storage and queue a human review.
    break;
  case 'no_match':
    // Save the result with its coverage and versions; apply your business policy.
    break;
  default:
    throw new Error('Unrecognized screening status.');
}
// These opaque identifiers are sufficient for operational logs.
console.log({ id: result.id, status: result.status });

4. Retrieve the saved result and find its review case

Set SCREENING_ID to the returned data.id. GET /results/{id} requires results:read and returns the current retained screening evidence. A missing or inaccessible ID returns 404; expired evidence returns 410 result_expired. Neither is a no-match result.

To connect the screening to human review, GET /cases?screeningId=ID&evidence=all returns data.items and nextCursor. Potential matches normally create a standard-retention case; some policies also require a case for no-match results. Treat an empty case list as the absence of a case, not as an approval. See review integration for the distinction between machine-readable evidence and human decisions.

Terminal · curl
curl --fail-with-body "https://www.sanctionskit.com/api/v1/results/$SCREENING_ID" \
  -H "Authorization: Bearer $SANCTIONSKIT_API_KEY"

5. Recover from a rejected or interrupted screening

400 invalid_request means the JSON or a field failed validation; inspect error.details paths such as subject.name. Missing or invalid Idempotency-Key returns idempotency_key_required. Fix rejected input, assign a new operation key for the changed request and keep the original failed attempt for your own operational trace.

409 idempotency_conflict means a key already belongs to another request. Investigate your stored operation before generating a new key. 422 can mean incompatible retention or a request whose coverage/candidate set cannot be safely processed. Unavailable source coverage and temporary capacity failures are errors, never a partial successful no-match. Preserve the requested coverage when retrying.

For 401/403, repair credentials or scopes. For 402 subscription_required, production entitlement needs attention. For 429, branch on rate_limited versus usage_cap_reached. Use errors for complete retry rules and idempotency for uncertain network outcomes.

Describe the subject with the facts you have

POST /api/v1/screenings accepts subject, one coverage selector, and optional retention. Standard retention saves subjects and evidence for review. Minimal retention is available only for individual API-key requests and does not create a review case. The subject requires a name of 2 to 300 characters. entityType supports person, organization, vessel, aircraft, and other. Supply optional identifiers as type, value, and issuer rather than guessing a universal document-number format.

birthDate accepts a real full date, a year and month, or a year. Omit unknown fields. Do not replace an unknown day with January 1 or split every name into Western first-name and last-name fields. Country and identifiers can help a review, but missing values are not evidence that a candidate is different.

JSON request
{
  "subject": {
    "name": "Alex Morgan",
    "entityType": "person",
    "birthDate": "1984"
  },
  "package": "sandbox@1"
}

Interpret the response in three paths

potential_match means at least one candidate met the matching policy. Read record, evidence, conflicts, and assessment for each match. no_match means the screen completed without such a candidate in the requested qualified coverage. An error means the request did not establish either result.

New results separate name similarity in assessment.name from identifier, birth-date, country, and subject-type comparisons. The legacy score remains a composite ranking value. Neither is a probability of identity, wrongdoing, or legal risk. The result’s matching snapshot records the applied profile and retrieval version, including for no-match results; older retained results may omit these additive fields.

Matching profiles belong to approved, versioned screening policies. Standard is the default; Focused applies stricter alert thresholds within the same candidate retrieval coverage and may miss relevant variants. Record the full result, ID, and versions with your business record. Do not reduce the response to a permanent isSanctioned boolean that loses its scope, date, and review context.

Partial-name review is a separate policy setting. Set matching.partialNames to review in an approved policy to consider name-word prefixes of at least three characters and missing name components. These results carry partial_name evidence with lower name similarity than complete agreement. Omission or exclude preserves complete-name behavior. Exact identifiers remain separate evidence. Very broad searches still fail instead of returning a truncated result.

A one-word person name is accepted, including legitimate single-word names, but produces a limited_name_information warning. Preserve warnings alongside the outcome. A no_match result does not establish that the submitted name contained enough information to find longer names.

Request and response reference

Base URL: https://www.sanctionskit.com/api/v1. Open an operation for its complete headers, body fields, response formats, examples and error codes.

Browse the complete API reference or download the OpenAPI contract.

Frequently asked questions

What is the smallest valid sandbox screening request?

Send subject with a name and package: sandbox@1. entityType defaults to person, identifiers to an empty array, and retention to standard. Use a sandbox key and a saved Idempotency-Key. Add only supported fields and identity facts you know.

Does the screening create response echo my customer reference?

POST /screenings does not guarantee echoed subject or reference fields. Save your own customer reference with the operation before sending it. GET /results/{id} adds subject and reference to the retained detail response, but those fields can be null under minimal retention.

Is a screening score the probability that two people are the same?

No. Name similarity and the legacy composite score describe matching behavior. They are not probabilities of identity, wrongdoing, or legal risk. Review the record, evidence, conflicts, and separate identity fields before making a decision.

Can I pass my own match threshold to the screening endpoint?

No arbitrary threshold field is accepted. Matching profiles belong to approved, versioned screening policies. Standard is the default. Focused uses stricter alert thresholds within the same retrieval coverage and can miss relevant variants. Keep the full result and its versions for review.

KEEP BUILDING

Where to go next