It submits the values you send to the sanctions provider, saves the normalized
answer to the exposure, and returns it. It requires
exposure.edit — running
a screening writes to the exposure, and needs no separate authority.
Screening is advisory
A screening blocks nothing: not a save, a quote, a bind, an issue, or an import. What comes back is a list of potential matches — similarity hits against sanctions entries, for a person to review. A hit is never a determination that the party you screened is the party on the list.The carrier turns screening on
Screening runs through a placed screening field, and placing that field is the only on-switch. The carrier’s configuration needs an exposure field of typeObject: OfacScreening, single-cardinality, placed on a card with the OFAC
Screening input modality. The fieldReferenceId you send names that field.
A company with no such field has no screening: the endpoint returns 400
(ofac-screening-field-not-placed) and nothing is submitted to the provider.
Read GET /entities/{entityType}/configuration to discover the field and the
screening sub-fields the carrier has configured.
What you can and cannot send
The values to screen — name, subject type, date of birth, address, identity documents and the rest — are yours. The server copies nothing from other exposure fields: it screens exactly what you send, or exactly what the exposure already holds when you omitrequestValues.
The carrier’s own users see one convenience this API does not have: an empty
name box on the screening card starts out holding the exposure’s name, which
they can overwrite before running. That is a form affordance in their browser,
not a server rule — this endpoint screens when you call it and at no other
time, and nothing about your writes triggers a screening. An exposure you
create or update through the API is not screened until somebody asks.
The sanctions lists, the match threshold and the provider are not yours to
choose. They are fixed platform settings, recorded on every result so a
reader knows what a saved screening covered. Sending sources or minScore is
rejected with 400 rather than quietly ignored, so a caller can never believe
it selected its own lists.
requestValues replaces the stored request values rather than patching
them: send the whole set you want screened, because the saved record has to say
what was actually submitted. Omit it entirely to re-screen what the exposure
already holds.
Reading a result
A result keeps three questions separate, because collapsing them into a single verdict loses information that matters:
“The provider found nothing” and “a reviewer decided the hits were not this
party” are different facts, so
screeningOutcome and reviewOutcome never
merge. A failed call is neither noMatches nor matches.
A provider failure comes back as 200 with status: failed, not as an HTTP
error. The failure is recorded on the exposure, where it stays visible; HTTP
errors are reserved for requests that were refused.
Review decisions are written through an ordinary entity update: set
reviewDecision (and optionally reviewNote) on a match. The platform stamps
reviewedBy and reviewedAt itself and recomputes reviewOutcome, so those
are read-only.
A screening or review made with an API key is attributed to External API in
screenedBy / reviewedBy and in the app, not to the person who owns the key.
Staleness is a comparison, not a flag
Every result carriesscreenedRequest — a snapshot of the values actually
submitted. A saved result describes those values, as of screenedAt, against
the sanctions lists as they stood then.
So there are two reasons a stored result may no longer be current, and you
decide both:
- The party changed. Compare the exposure’s current screening values
against
screenedRequest. If they differ, the result describes someone else. - The lists changed. Sanctions lists are updated frequently. A party cleared last month is not cleared today.
