curl --request POST \
--url https://api-sandbox.finogates.com/v1/platform/screening/checks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"dateOfBirth": "<string>",
"gender": "<string>",
"incorporationDate": "<string>",
"website": "<string>",
"altNames": [
"<string>"
],
"address": {
"line1": "<string>",
"line2": "<string>",
"city": "<string>",
"state": "<string>",
"postalCode": "<string>",
"country": "<string>"
},
"email": "<string>",
"phone": "<string>",
"governmentIds": [
"<string>"
],
"externalRef": "<string>"
}
'import requests
url = "https://api-sandbox.finogates.com/v1/platform/screening/checks"
payload = {
"name": "<string>",
"dateOfBirth": "<string>",
"gender": "<string>",
"incorporationDate": "<string>",
"website": "<string>",
"altNames": ["<string>"],
"address": {
"line1": "<string>",
"line2": "<string>",
"city": "<string>",
"state": "<string>",
"postalCode": "<string>",
"country": "<string>"
},
"email": "<string>",
"phone": "<string>",
"governmentIds": ["<string>"],
"externalRef": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
dateOfBirth: '<string>',
gender: '<string>',
incorporationDate: '<string>',
website: '<string>',
altNames: ['<string>'],
address: {
line1: '<string>',
line2: '<string>',
city: '<string>',
state: '<string>',
postalCode: '<string>',
country: '<string>'
},
email: '<string>',
phone: '<string>',
governmentIds: ['<string>'],
externalRef: '<string>'
})
};
fetch('https://api-sandbox.finogates.com/v1/platform/screening/checks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.finogates.com/v1/platform/screening/checks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'dateOfBirth' => '<string>',
'gender' => '<string>',
'incorporationDate' => '<string>',
'website' => '<string>',
'altNames' => [
'<string>'
],
'address' => [
'line1' => '<string>',
'line2' => '<string>',
'city' => '<string>',
'state' => '<string>',
'postalCode' => '<string>',
'country' => '<string>'
],
'email' => '<string>',
'phone' => '<string>',
'governmentIds' => [
'<string>'
],
'externalRef' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.finogates.com/v1/platform/screening/checks"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"dateOfBirth\": \"<string>\",\n \"gender\": \"<string>\",\n \"incorporationDate\": \"<string>\",\n \"website\": \"<string>\",\n \"altNames\": [\n \"<string>\"\n ],\n \"address\": {\n \"line1\": \"<string>\",\n \"line2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"postalCode\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"governmentIds\": [\n \"<string>\"\n ],\n \"externalRef\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sandbox.finogates.com/v1/platform/screening/checks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"dateOfBirth\": \"<string>\",\n \"gender\": \"<string>\",\n \"incorporationDate\": \"<string>\",\n \"website\": \"<string>\",\n \"altNames\": [\n \"<string>\"\n ],\n \"address\": {\n \"line1\": \"<string>\",\n \"line2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"postalCode\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"governmentIds\": [\n \"<string>\"\n ],\n \"externalRef\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.finogates.com/v1/platform/screening/checks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"dateOfBirth\": \"<string>\",\n \"gender\": \"<string>\",\n \"incorporationDate\": \"<string>\",\n \"website\": \"<string>\",\n \"altNames\": [\n \"<string>\"\n ],\n \"address\": {\n \"line1\": \"<string>\",\n \"line2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"postalCode\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"governmentIds\": [\n \"<string>\"\n ],\n \"externalRef\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status_code": 200,
"data": {
"id": "3f8a1c2e-9b47-4d51-8e06-1a2b3c4d5e6f",
"entityType": "person",
"decision": "review",
"topScore": 0.8762,
"dataCompleteness": "full",
"hits": [
{
"sourceList": "us_ofac",
"sourceId": "22790",
"entityName": "Nicolas MADURO MOROS",
"matchScore": 0.8762,
"category": "sanctions_blocking",
"programs": [
"VENEZUELA"
]
}
],
"confirmWith": [
{
"key": "governmentIds",
"label": "Government ID number"
}
],
"externalRef": "order-1043",
"createdAt": "2026-07-16T10:12:04Z"
},
"query_generated_time": 1784282324000
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Screen a Subject
Screen a person or business against global sanctions and denied-party watchlists.
Act on decision, not on topScore
decision is the integration contract. Branch on it and nothing else:
decision | Meaning | What you should do |
|---|---|---|
clear | Nothing matched | Proceed |
review | A possible match a human must adjudicate | Hold the subject |
blocked | A confident match to an asset-freeze list | Hold and escalate |
unavailable | Screening could not complete | Not screened. Retry or hold — never treat as clear |
Why not the score
topScore is a name-similarity score, not a risk score, and it is returned for
diagnostics only — show it to your reviewers to help them triage, but do not build
thresholds on it. Four reasons, all measured against live watchlist data:
- It does not separate real from innocent. A true OFAC SDN entry scores
0.8122on name alone; an innocent person with a common name scores0.7513. Six points apart — no threshold sits safely between them. - It is not comparable across subjects. The score carries a coverage penalty — a
name-only query is structurally capped however perfect the name, while a query with a
date of birth is not. The same SDN entry scores
0.8122on name alone and0.9025with a date of birth. Same person, same list entry, different number. A threshold applied across a mixed population applies different standards to different customers. - It is not stable over time. That same entry scored
0.8762on 2026-07-14 and0.9025on 2026-07-16 — same subject, same query, same software. The watchlists themselves refresh (OFAC gained 61 entries in those two days) and scores move with the data. Lists reload every 12 hours. A hard-coded>= 0.90can change behaviour twice a day, with no release on your side. - Legal effect follows the list, not the number. A
0.95match on a sectoral list is a transaction restriction; a0.82match on a freeze list is an asset freeze. Ranking those by score is backwards.
decision absorbs all four. It is the only part of this response we treat as a stable
contract.
decision already folds in the score, the list’s legal effect, how much identity data was
available, and exact government-ID matches — so you do not have to.
Send more than a name
A dateOfBirth (people) or address (businesses) is what makes the answer trustworthy.
dataCompleteness in the response tells you what you gave us: full, partial, or
name_only. A name_only check is deliberately never auto-blocked, because at that
coverage the score cannot carry the weight. If you see name_only, your integration is
leaving accuracy on the table.
confirmWith — the one thing to send next
When a check comes back review or blocked, confirmWith asks for exactly one field:
the strongest piece of identity data you have not already sent. key is the request field
to send it in, so the ask is directly actionable — populate it, POST a new check, and if
that still hits you are asked for the next one. Anything already in hand is never asked for
twice, whatever order it arrived in.
For a person the ladder is dateOfBirth → governmentIds → altNames → address; for
a business, address → governmentIds → altNames → incorporationDate. So a check
carrying only a name is asked for a date of birth, while one that already carried a
government ID skips straight past it:
| Your check carries | confirmWith asks for |
|---|---|
| name | dateOfBirth |
name + governmentIds | dateOfBirth |
name + governmentIds + dateOfBirth | altNames |
| the whole ladder | (empty — nothing left to send) |
label is the same wording our compliance desk would use for that field, so it is safe to
show verbatim to whoever supplies the data.
Two things the ordering is honest about. A government ID is the strongest confirmation available — an exact match to a listed party’s identifier is not a coincidence — but the effect is one-way: an ID that doesn’t match does not clear anything by itself, it gives a reviewer the grounds to. That is why a date of birth outranks it for a person: it changes what the search returns rather than only how a returned match is judged.
confirmWith is empty on clear, and empty on unavailable — that check never ran, so more
identity data does not help; retry it instead. An empty array on a hit means the check is
already as strong as this API can make it and the remaining question needs a human.
Each successful check is billed once on your monthly invoice. unavailable checks are not
billed.
curl --request POST \
--url https://api-sandbox.finogates.com/v1/platform/screening/checks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"dateOfBirth": "<string>",
"gender": "<string>",
"incorporationDate": "<string>",
"website": "<string>",
"altNames": [
"<string>"
],
"address": {
"line1": "<string>",
"line2": "<string>",
"city": "<string>",
"state": "<string>",
"postalCode": "<string>",
"country": "<string>"
},
"email": "<string>",
"phone": "<string>",
"governmentIds": [
"<string>"
],
"externalRef": "<string>"
}
'import requests
url = "https://api-sandbox.finogates.com/v1/platform/screening/checks"
payload = {
"name": "<string>",
"dateOfBirth": "<string>",
"gender": "<string>",
"incorporationDate": "<string>",
"website": "<string>",
"altNames": ["<string>"],
"address": {
"line1": "<string>",
"line2": "<string>",
"city": "<string>",
"state": "<string>",
"postalCode": "<string>",
"country": "<string>"
},
"email": "<string>",
"phone": "<string>",
"governmentIds": ["<string>"],
"externalRef": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
dateOfBirth: '<string>',
gender: '<string>',
incorporationDate: '<string>',
website: '<string>',
altNames: ['<string>'],
address: {
line1: '<string>',
line2: '<string>',
city: '<string>',
state: '<string>',
postalCode: '<string>',
country: '<string>'
},
email: '<string>',
phone: '<string>',
governmentIds: ['<string>'],
externalRef: '<string>'
})
};
fetch('https://api-sandbox.finogates.com/v1/platform/screening/checks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.finogates.com/v1/platform/screening/checks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'dateOfBirth' => '<string>',
'gender' => '<string>',
'incorporationDate' => '<string>',
'website' => '<string>',
'altNames' => [
'<string>'
],
'address' => [
'line1' => '<string>',
'line2' => '<string>',
'city' => '<string>',
'state' => '<string>',
'postalCode' => '<string>',
'country' => '<string>'
],
'email' => '<string>',
'phone' => '<string>',
'governmentIds' => [
'<string>'
],
'externalRef' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.finogates.com/v1/platform/screening/checks"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"dateOfBirth\": \"<string>\",\n \"gender\": \"<string>\",\n \"incorporationDate\": \"<string>\",\n \"website\": \"<string>\",\n \"altNames\": [\n \"<string>\"\n ],\n \"address\": {\n \"line1\": \"<string>\",\n \"line2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"postalCode\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"governmentIds\": [\n \"<string>\"\n ],\n \"externalRef\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sandbox.finogates.com/v1/platform/screening/checks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"dateOfBirth\": \"<string>\",\n \"gender\": \"<string>\",\n \"incorporationDate\": \"<string>\",\n \"website\": \"<string>\",\n \"altNames\": [\n \"<string>\"\n ],\n \"address\": {\n \"line1\": \"<string>\",\n \"line2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"postalCode\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"governmentIds\": [\n \"<string>\"\n ],\n \"externalRef\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.finogates.com/v1/platform/screening/checks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"dateOfBirth\": \"<string>\",\n \"gender\": \"<string>\",\n \"incorporationDate\": \"<string>\",\n \"website\": \"<string>\",\n \"altNames\": [\n \"<string>\"\n ],\n \"address\": {\n \"line1\": \"<string>\",\n \"line2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"postalCode\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"governmentIds\": [\n \"<string>\"\n ],\n \"externalRef\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status_code": 200,
"data": {
"id": "3f8a1c2e-9b47-4d51-8e06-1a2b3c4d5e6f",
"entityType": "person",
"decision": "review",
"topScore": 0.8762,
"dataCompleteness": "full",
"hits": [
{
"sourceList": "us_ofac",
"sourceId": "22790",
"entityName": "Nicolas MADURO MOROS",
"matchScore": 0.8762,
"category": "sanctions_blocking",
"programs": [
"VENEZUELA"
]
}
],
"confirmWith": [
{
"key": "governmentIds",
"label": "Government ID number"
}
],
"externalRef": "order-1043",
"createdAt": "2026-07-16T10:12:04Z"
},
"query_generated_time": 1784282324000
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
The access token received from the authorization server in the OAuth 2.0 flow.
Body
Screen one subject on demand. Each successful call is billed once.
Whether the subject is a person or a business.
person, business Full name / legal name.
1 - 500Date of birth (any common format; normalised to YYYY-MM-DD). Supplying it dramatically reduces false positives for people.
A structured address; flattened to one line before screening.
Show child attributes
Show child attributes
255Response
The screening result. This example shows a review — a real match that a human must confirm, and the shape most genuine hits arrive in. The topScore shown is illustrative: do not assert on it, and do not infer a threshold from it (see the endpoint description).

