Address Screening¶
Address screening is served by a separate Public API. Use the screening service base URL provided for your environment; do not assume these paths share the trading API host. Public queries do not require a trading API key. Availability of each version depends on the deployment.
“Public query” describes a contract for external integrations, not anonymous internet availability in every deployment. Use the ingress supplied by the service operator and follow its access and rate limits. Query results do not replace transaction admission or provide internal-service credentials.
Endpoints and Versions¶
All current-check endpoints use POST with a JSON body. Select a version deliberately: their decisions and response shapes differ.
| Version | Single / batch paths | Response contract |
|---|---|---|
| v1 | /api/v1/address-screenings, /api/v1/address-screenings/batch | Official-list MATCH / NO_MATCH; batch uses parallel decisions and is_sanctions_matches arrays |
| v2 | /api/v2/address-screenings, /api/v2/address-screenings/batch | Official current result plus historical summary; single result, batch results |
| v3 | /api/v3/address-screenings, /api/v3/address-screenings/batch | Local-snapshot MATCH / NO_MATCH with independent coverage/evidence fields; batch uses parallel arrays |
| v4 | /api/v4/address-screenings, /api/v4/address-screenings/batch | Official/manual/one-hop decisions; single result at top level, batch results |
| v5 | /api/v5/address-screenings, /api/v5/address-screenings/batch | Adds per-source state and completeness of negative evidence; batch results |
| v6 | /api/v6/address-screenings, /api/v6/address-screenings/batch | Adds confirmed membership and detail-availability semantics; batch results |
Single Request¶
Batch Request¶
{
"chain_family": "evm",
"addresses": [
"0x1111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222"
]
}
chain_family must be evm. Each address must be a 20-byte 0x EVM address and is normalized to lowercase. Batches contain 1–50 unique addresses after normalization; results preserve input order. Extra fields and query parameters are rejected. Single/history bodies are limited to 2 KiB and batch bodies to 16 KiB. Interpret Current Results¶
v1 and v3¶
v1 returns schema_version, request_id, decision, is_sanctions_match, provider_id, policy_id, capability, dataset_revision, checked_at and authority_checked_at. Its batch form adds decision_count and replaces the single decision/boolean with parallel arrays.
v3 returns the decision and boolean plus coverage_status (COMPLETE / PARTIAL), coverage_incomplete, evidence_mode (LOCAL_SNAPSHOT_MATCH / LOCAL_SNAPSHOT_NO_MATCH), nullable reason_code, policy_revision, serving_policy_id, serving_policy_revision and dataset_published_at. A partial result uses reason_code="SOURCE_COVERAGE_INCOMPLETE". Batch evidence uses an evidence_modes array; reason_code remains a single envelope-level field.
A NO_MATCH is only a statement about the queried dataset. It must not be relabeled as a general guarantee that a wallet is safe. With partial coverage, the local absence of a match is not complete negative evidence.
v4–v6¶
decision | Meaning |
|---|---|
BLOCK | Positive blocking evidence exists |
NO_BLOCK | The selected policy has sufficient evidence for a non-blocking result |
STALE | Evidence is stale; do not treat it as NO_BLOCK |
UNKNOWN | Evidence does not establish a decision; do not treat it as NO_BLOCK |
v4 includes address, nullable match_type, official_dataset_revision, official_coverage_mode (COMPLETE / POSITIVE_ONLY), nullable composite_generation, composite_revision, composite_policy_digest, and checked_at.
v5/v6 additionally report official_state and composite_state (MATCH, NO_MATCH, STALE, UNKNOWN, UNAVAILABLE), nullable official_membership_digest, composite_membership_digest, combined_membership_revision, and negative_evidence_complete. Unavailable official identity fields can be null. A positive result from one available source can still establish BLOCK; missing source evidence must not be converted to a clean negative result.
match_type | Meaning |
|---|---|
DIRECT_OFFICIAL | Direct official-list match |
DIRECT_MANUAL | Direct manual-policy match |
ASSOCIATED_ONE_HOP | Match through the configured one-hop policy |
COMPOSITE_CONFIRMED | v6 only: membership is confirmed while attribution details are unavailable or inconsistent |
null | No positive match classification |
v6 adds details_status: AVAILABLE, UNAVAILABLE, INCONSISTENT, or NOT_REQUESTED. For COMPOSITE_CONFIRMED, keep the BLOCK decision even when details are unavailable/inconsistent. v4–v6 batch envelopes contain schema_version, request_id, decision_count, and ordered results with the corresponding single-result fields.
v2 Historical Summary¶
Single queries return a result object; batch queries return results. Each summary has:
| Fields | Description |
|---|---|
address, decision, currently_listed | Current official-list result |
ever_listed | Historical presence; null means unknown, not false |
advisory | HISTORICAL_OFFICIAL_MATCH for a known historical-only match, otherwise null |
current_origins | Current source records |
first_listed_at, last_delisted_at, period_count, source_count | Available historical summary |
The envelope includes coverage_status, coverage_incomplete, history_coverage, policy_id, policy_revision, dataset_revision, checked_at, dataset_published_at, and valid_until. Single responses also include history_status (SUMMARY_ONLY / UNAVAILABLE). history_coverage has status (COMPLETE, PARTIAL, CURRENT_ONLY), complete, available_from, and basis. A missing historical record does not prove the address was never listed.
Paginated History¶
Authentication: None.
Request Body¶
{
"chain_family": "evm",
"address": "0x1111111111111111111111111111111111111111",
"page_size": 25,
"cursor": null
}
page_size defaults to 25 and accepts 1–50. Send the returned opaque next_cursor on subsequent requests; do not construct it yourself. The response contains result, history_coverage, history_status="AVAILABLE", periods, has_more, next_cursor, policy_id, policy_revision, dataset_revision, published_at, queried_at, schema_version, request_id, coverage_status and coverage_incomplete. Each period identifies period_id, source_id, authority, jurisdiction, measure_type, optional subject_name / legal_reference, official and system validity intervals, opening/closing event identifiers, types and reasons, superseded-event references, and policy_applications. Official validity dates and system observation dates are different facts. next_cursor is null when has_more is false. Invalid or stale cursors may be rejected; restart from the first page instead of guessing a cursor.
Source and History Entry Fields¶
Each current_origins entry contains source_id, authority, jurisdiction, nullable subject_name, legal_reference, measure_type, current_state (ACTIVE / REMOVAL_PENDING), and nullable official_effective_from / official_effective_to.
Fields in each periods entry | Meaning |
|---|---|
period_id, source_id, authority, jurisdiction, measure_type | Period identity and source attribution |
subject_name, legal_reference | Optional source details |
official_valid_from, official_valid_to | Official validity interval; either endpoint can be null |
system_valid_from, system_valid_to | System observation interval; null end means not closed |
opening_event_id, opening_event_type, opening_reason_code | Event that opened the period |
closing_event_id, closing_event_type, closing_reason_code | Nullable closing event details |
opening_supersedes_event_id, closing_supersedes_event_id | Nullable references to corrected/superseded events |
policy_applications | 1–100 policy application records |
Each policy application contains policy_id, policy_revision, participation_mode (required / optional), applicable_from and nullable applicable_to. history_coverage.basis is OFFICIAL_ARCHIVE, CURATED_BACKFILL, FIRST_VERIFIED_SNAPSHOT or MIXED. Dates/times are serialized as ISO-formatted strings. A cursor is 16–256 URL-safe characters; preserve it exactly as returned.
Errors¶
Protocol errors and rate limits use this minimal shape; neither schema_version nor error.retryable is guaranteed:
| HTTP | error.code | Meaning |
|---|---|---|
| 400 | INVALID_REQUEST | Empty/malformed JSON, duplicate keys or invalid Content-Length |
| 408 | REQUEST_TIMEOUT | Request body read timed out (current budget: 5 seconds) |
| 413 | REQUEST_TOO_LARGE | Body exceeds the endpoint limit |
| 415 | UNSUPPORTED_MEDIA_TYPE | Use application/json; Content-Encoding is not accepted |
| 422 | INVALID_REQUEST | Invalid fields, query parameters or cursor |
| 429 | RATE_LIMITED | Admission/rate limit; honor Retry-After |
Screening unavailability returns HTTP 503, Retry-After: 5 and:
{
"schema_version": "sanctions-screening.error.v1",
"request_id": "00000000000000000000000000000001",
"error": {
"code": "SCREENING_UNAVAILABLE",
"retryable": true
}
}
History unavailability also returns 503 with Retry-After: 5, but uses a separate envelope:
{
"schema_version": "sanctions-screening.history-error.v2",
"request_id": "00000000000000000000000000000001",
"history_status": "UNAVAILABLE",
"error": {
"code": "HISTORY_UNAVAILABLE",
"retryable": true
}
}
Branch on HTTP status and error.code, honoring Retry-After when present. A missing retryable field is not an explicit false. Fix invalid input before resubmitting; a technical failure is never a NO_MATCH or NO_BLOCK decision. These envelopes differ from the trading API's detail responses.
Operational Probes¶
These endpoints support deployment, load balancing and monitoring and should be accessed through restricted operational ingress. Customer integrations do not need to poll them. Some probes query downstream dependencies and return runtime status; listing them here does not recommend direct public exposure.
| Method | Path | Meaning |
|---|---|---|
| GET | /live | Process liveness |
| GET | /ready | Configured public-service readiness |
| GET | /serving-ready | Ability to serve the current query surface |
| GET | /policy-ready | Policy/source coverage readiness |
| GET | /v2-ready | Readiness of the v2 summary/history dependencies |
A 200 from a liveness probe does not establish complete policy coverage. Public query results do not authorize a later transaction; transaction endpoints perform their own admission checks.