---
title: "Retrieve a screening"
method: GET
path: "/screenings/{screening_id}"
tags: ["Screenings"]
---

# Retrieve a screening

`GET /screenings/{screening_id}`

## Request

- Base URL: `https://developers.ozav.io/v2`
- URL: `https://developers.ozav.io/v2/screenings/{screening_id}`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Retrieves a single screening by its `ozav_scr_` id, including its
`result` and any `matches`. Retain the id as evidence of the check.

## Path parameters

- `screening_id` string, required

## Response `200`

The screening.

- Screening: A point-in-time designated-list screening of a subject.
  - `id` string, required: Opaque screening identifier, prefixed `ozav_scr_`.
  - `object` 'screening', required: Resource type discriminator; always the literal `screening`.
  - `subject` union, required: The screened subject. Provide exactly one of `customer_id`, `person`, `business`, or `wallet_address`. Inline subjects (`person` / `business`) enable standalone screening with no customer record.
    - object: Screen an existing customer by id.
      - `customer_id` string, required: The `ozav_cus_` id of an existing customer to screen.
    - object: Screen a person inline (no customer record required).
      - `person` object, required: The natural person to screen. Screened as given - no customer record is created and nothing is stored against a customer.
        - `name` string, required: Full name of the person to screen.
        - `date_of_birth` string, date: Date of birth (ISO 8601 date) - helps disambiguate matches.
        - `country` string: Country of the person as an ISO 3166-1 alpha-2 code.
        - `email` string: Optional contact email. Evaluated for contact signals (disposable mailbox; for businesses also non-existent domain, no mail server, domain age) when contact signals are enabled on the OZAV platform - a platform-wide setting, see `contact_evaluated`. Never stored or echoed back - only the resulting signal is kept, and for a person the email domain is quoted only when it is a public disposable-mail domain.
        - `phone` string: Optional contact phone (E.164 preferred; without `+`, send `country` so the number can be read - otherwise it is not evaluated). Evaluated for contact signals (invalid number, virtual line, country mismatch) when contact signals are enabled on the OZAV platform - a platform-wide setting. Never stored or echoed back.
    - object: Screen a business inline (no customer record required).
      - `business` object, required: The legal entity to screen. Screened as given - no customer record is created and nothing is stored against a customer.
        - `legal_name` string, required: Registered legal name of the business to screen.
        - `country` string: Country of registration as an ISO 3166-1 alpha-2 code.
        - `email` string: Optional contact email. Evaluated for contact signals (disposable mailbox; for businesses also non-existent domain, no mail server, domain age) when contact signals are enabled on the OZAV platform - a platform-wide setting, see `contact_evaluated`. Never stored or echoed back - only the resulting signal is kept, and for a person the email domain is quoted only when it is a public disposable-mail domain.
        - `phone` string: Optional contact phone (E.164 preferred; without `+`, send `country` so the number can be read - otherwise it is not evaluated). Evaluated for contact signals (invalid number, virtual line, country mismatch) when contact signals are enabled on the OZAV platform - a platform-wide setting. Never stored or echoed back.
    - object: Wallet-address screening is not available: this variant returns 422 FEATURE_NOT_AVAILABLE.
      - `wallet_address` object, required: The blockchain address to screen. Not available - sending this variant returns 422 `FEATURE_NOT_AVAILABLE`, it does not screen and return `clear`.
        - `address` string, required: The blockchain address to screen.
        - `network` 'ethereum' | 'base' | 'optimism' | 'polygon' | 'avalanche_c_chain' | 'worldchain' | 'unichain' | 'linea' | 'sonic' | 'sei' | 'celo' | 'zksync_era' | 'solana' | 'tron' | 'stellar', required: Public v2 blockchain network vocabulary for wallet balances and crypto transfer legs. This enum is the wire contract today and lists only networks accepted by public v2 fields now. The custody stack can have additional active networks before those networks are accepted by every public API flow; see `x-ozav-network-matrix` for that explicit split.
  - `lists` string[]: The designated lists that were requested / screened against. Each item is one of: - `sanctions` - consolidated sanctions / designated-persons lists. - `pep` - politically exposed persons. - `adverse_media` - negative-news screening.
  - `status` 'pending' | 'completed', required: Processing state of the screening: - `pending` - the screening is still running. - `completed` - the screening finished; read the outcome from `result`.
  - `result` 'clear' | 'match_found' | 'review', required: Conservative, fail-closed outcome: - `clear` - every requested list was fully consulted with zero matches. - `match_found` - a strong (exact/alias) designated-list match. - `review` - a weaker match, or a requested list that could not be fully consulted; never silently cleared. Telling the two `review` causes apart, because they call for opposite actions and the answer is already in this response - read `matches`: - `review` with a non-empty `matches` - a weak (token-level) hit. A human decides. Retrying changes nothing; the same subject screens the same way. - `review` with an empty `matches` - every list you requested came back without a hit, and at least one of them could not be fully consulted. Nobody matched anything. This is transient on our side: retry later rather than queueing the subject for review. One exception, flagged in `signals`: `pep_exact_name_only` means the name is too common on the PEP register for a word-by-word comparison, so only exact name and aliases were compared. That is not transient - retrying returns the same; queue the subject for human review. The two are exhaustive for `review`, by construction: a weak hit is counted from the same array that `matches` is serialized from, so an empty `matches` leaves an unconsultable source as the only remaining cause. Which source degraded is not published. It is an operational fact about OZAV's ingestion, not about your subject, and the action it implies (retry) is the same whichever one it was.
  - `matches` ScreeningMatch[]: The matches found. Empty when the outcome is `clear` - and also empty on the `review` that means a list could not be consulted, which is why `result` and this field have to be read together. See `ScreeningMatch`.
    - `list_source` 'un' | 'ofac' | 'eu' | 'uk' | 'national', required: Which designated-list source produced the match: - `un` - United Nations Security Council consolidated list. - `ofac` - US OFAC (SDN and related lists). - `eu` - European Union consolidated sanctions list. - `uk` - UK OFSI consolidated list. - `national` - a national designation list.
    - `matched_name` string, required: The name on the list that matched the screened subject.
    - `strength` 'exact' | 'alias' | 'fuzzy', required: How strong the name match is: - `exact` - the names match exactly. - `alias` - the subject matched a known alias of a listed entity. - `fuzzy` - a weaker, token-level match (surfaced for review, never auto-cleared).
    - `list_entry_ref` string: The list's own reference id for the matched entry (e.g. an OFAC SDN number), for audit.
    - `id` string: The hit id (`hit_...`). It is the hit's fingerprint - list, entry, strength and listed name - so the same subject hitting the same entry again carries the same id. Use it with `PATCH /screenings/{screening_id}/hits/{hit_id}`.
    - `status` 'open' | 'false_positive' | 'confirmed': The decision on this hit. Reused by later screenings of the same subject when it is identifiable (`customer_id`, or a person with `date_of_birth`): - `open` - not decided. - `false_positive` - decided as not being the subject; no longer escalates. - `confirmed` - decided as the subject. A confirmed sanctions hit makes `suggested_decision` `decline`. A changed list entry (other strength or listed name) is a new hit and starts `open`.
    - `decided_by` 'you' | 'ozav' | 'null', nullable: Who decided: `you` (your organization, via the API) or `ozav` (OZAV compliance, shown until you decide; your decision prevails). `null` while `open`.
  - `suggested_decision` 'clear' | 'review' | 'decline': OZAV's suggested decision for this subject, computed and stored when the screening ran (reading it later returns that decision, not a recomputation). It only escalates: - `decline` - a strong (exact/alias) sanctions match corroborated by a second attribute: the `date_of_birth` you sent matches the date on the list entry. A name-only match - no date on either side, or a different date - is `review`, never `decline`, because a homonym must not be declined automatically. Consequences: a `business` subject cannot reach `decline` (businesses carry no date of birth), and a `customer_id` subject is screened by name only today (the customer's stored date of birth is not used) - both stop at `review`. - `review` - any list signal (every sanctions or PEP signal escalates), a `high` contact signal, or a `review` result (see `result`). - `clear` - no list match, every requested list consulted, and any contact signals below the escalation threshold (`medium`/`low` contact signals may be present). `result` keeps its list-only meaning; `suggested_decision` also weighs contact signals.
  - `signals` ScreeningSignal[]: Every finding behind `suggested_decision`, explained: what was seen and why it matters. List matches appear here too (with `category` `sanctions_list` or `pep_list`), next to contact signals (`contact`) when email/phone were sent and contact signals are enabled. An empty array is only "nothing found" together with `contact_evaluated` (see below).
    - `code` string, required: Stable machine code of the finding. A plain string, not a closed enum: new codes are added over time, so treat an unknown code by its `category` and `severity`. Known values: - `sanctions_match` / `sanctions_possible_match` - strong / partial sanctions-list name match. - `pep_match` / `pep_possible_match` - strong / partial PEP-register name match. - `disposable_email` - disposable (temporary) mailbox service. - `email_domain_not_found` - the email domain does not exist (businesses). - `email_domain_no_mx` - the email domain has no mail server (businesses). - `email_domain_dns_unresolved` - the email domain's DNS did not answer; not evaluated. - `invalid_email_syntax` - not a name@domain address. - `recently_registered_domain` - company domain registered less than 90 days ago. - `free_email_for_business` - a company using a free email provider. - `domain_without_spf_dmarc` - company domain publishes neither SPF nor DMARC. - `domain_unrelated_to_name` - company domain contains no word of the company name. - `invalid_phone` - not a valid number for the given country. - `non_personal_phone` - virtual, toll-free or premium-rate line. - `phone_country_mismatch` - calling code differs from the declared country. - `org_blocklist_match` - the subject is on your organization's block list. - `org_allowlist_match` - the subject is on your organization's allow list; contact signals were suppressed (block-list, sanctions and PEP matches never are). - `org_lists_unavailable` - your own lists could not be checked; screen again shortly. - `pep_exact_name_only` - the name is too common on the PEP register to be compared word by word, so it was compared by exact name and aliases only. `result` is `review`, and this is not transient: retrying returns the same. Have a person review the subject.
    - `category` 'sanctions_list' | 'pep_list' | 'contact' | 'org_list', required: Where the finding comes from: - `sanctions_list` - a sanctions / designated-persons list. - `pep_list` - a politically-exposed-persons register. - `contact` - the email or phone sent with the subject. - `org_list` - your organization's own block/allow lists (`/lists/entries`).
    - `severity` 'high' | 'medium' | 'low', required: How much the finding weighs. Every list signal (`sanctions_list`, `pep_list`) is `high`. - `high` - escalates the decision on its own. - `medium` - below the escalation threshold; a human weighs it with the rest. - `low` - informational.
    - `evidence` string, required: What was seen, in plain language.
    - `why_it_matters` string, required: Why this finding matters for due diligence.
  - `contact_evaluated` boolean: `true` when the email/phone you sent were fully evaluated. `false` when no email or phone was sent, contact signals are disabled on the OZAV platform (a platform-wide setting, not per account), the evaluation failed, or the email domain's DNS did not answer in time (then `email_domain_dns_unresolved` appears in `signals`). With `false`, the absence of contact signals says nothing about the contact data.
  - `created_at` string, date-time: When the screening was created (RFC 3339 / ISO 8601, UTC).

## Other responses

- `401`: Missing or invalid API key.
- `404`: The resource does not exist, is not visible to the caller, or the id was malformed for this position (see "Resource ids" under Errors). These share one status; `code` and `message` tell them apart.

---

[API](https://skmtc.dev/ozav/apis/ozav-api.md) - [All operations](https://skmtc.dev/ozav/apis/ozav-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ozav/apis/ozav-api/revisions/4133dc2109d7?raw)
