Sanctions Screening (UN, OFAC, EU)
kycScreen a person or company name against the UN Security Council Consolidated List, the US OFAC SDN list and the EU Consolidated Financial Sanctions List in one call. Lists are refreshed from the official sources every 6 hours. Matching understands spelling variants, initials, word order and aliases. Pass dob to rank hits with the same birth year first and to set aside same-name hits with a different birth year. result is possible_match when at least one hit is not ruled out by date of birth: send those for manual review. A hit is never proof on its own.
Authentication
Pass your key in the X-API-Key header. Use a test_ key against the sandbox and a live_ key in production. Send an optional Idempotency-Key header to safely retry — the same key returns the same response for 24h.
Request
Endpoint: POST https://apisathi.in/gw/v1/sanctions-screening-v1/
The trailing slash is required. /v1/sanctions-screening-v1/ works; /v1/sanctions-screening-v1 returns 404 Not Found. This applies to every product.
| Field | Type | Required | Constraints |
|---|---|---|---|
| name | string | required | minLength: 3 · maxLength: 200 |
| type | string | optional | Optional. Default both. |
| dob | string | optional | Optional. Date of birth or year, e.g. 1975-05-12. |
| threshold | number | optional | Optional. Minimum name-match score, default 85. |
Code snippets
curl -X POST https://apisathi.in/gw/v1/sanctions-screening-v1/ \
-H "X-API-Key: $API_SATHI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Hafiz Muhammad Saeed","dob":"1950-06-05"}'Response
| Field | Type | Required | Constraints |
|---|---|---|---|
| name | string | optional | — |
| result | string | optional | — |
| hit_count | integer | optional | — |
| hits | array | optional | — |
| threshold | number | optional | — |
| lists | object | optional | — |
| lists_as_of | string | optional | — |
Sample response
{
"name": "Hafiz Muhammad Saeed",
"result": "possible_match",
"hit_count": 2,
"hits": [
{
"source": "UN",
"reference": "QDi.263",
"type": "individual",
"listed_name": "HAFIZ MUHAMMAD SAEED",
"matched_name": "HAFIZ MUHAMMAD SAEED",
"score": 100,
"dob_match": true,
"dob": [
"1950-06-05"
],
"nationality": [
"Pakistan"
],
"programme": "Al-Qaida",
"listed_on": "2008-12-10"
},
{
"source": "EU",
"reference": "5419",
"type": "individual",
"listed_name": "Hafiz Muhammad Saeed",
"matched_name": "Hafiz Muhammad Saeed",
"score": 100,
"dob_match": true,
"dob": [
"1950-06-05"
],
"nationality": [],
"programme": "TAQA",
"listed_on": "2008-12-10"
}
],
"threshold": 85,
"lists": {
"UN": {
"generated": "2026-10-17T23:00:01.054Z",
"count": 1010
},
"OFAC": {
"generated": null,
"count": 17556
},
"EU": {
"generated": "15/10/2026",
"count": 6234
}
},
"lists_as_of": "2026-10-18T03:00:00.000Z"
}Reading a 400
A schema rejection returns INVALID_REQUEST with a details array naming the exact field. Read it before guessing — it gives you the JSON path and what was wrong with it.
{
"error": {
"code": "INVALID_REQUEST",
"message": "Request body failed schema validation",
"details": [
{ "path": "/callback_url",
"message": "unexpected property 'callback_url' — this endpoint does not accept unknown fields" }
]
}
}Most endpoints reject unknown top-level fields outright, so an extra key you added for your own bookkeeping will fail the call. Enum errors list the accepted values, and a missing required field is named with its full path.
Error codes
| Code | HTTP | When |
|---|---|---|
| INVALID_INPUT | 422 | The request was rejected as invalid — either it failed OUR schema validation (malformed input; not charged), or the upstream source rejected the value you sent. NOTE: an identifier that is well-formed but simply has NO RECORD is no longer an error — it returns 200 with `verified: false` and is charged (see the result-code table below). FIX the input before retrying; retrying the same value will fail again. |
| INVALID_API_KEY | 401 | Missing, malformed, or revoked X-API-Key. |
| OUT_OF_SCOPE | 403 | API key is not scoped for this product. |
| INSUFFICIENT_BALANCE | 402 | Wallet balance is below the per-call sale price. Recharge and retry. |
| RATE_LIMITED | 429 | Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header. |
| PRODUCT_DEPRECATED | 410 | This API has been retired and is no longer available. Stop calling it — it will not return. Check the catalog for the current equivalent. |
| ROUTER_NO_VENDOR | 503 | No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged. |
| VENDOR_AUTH_FAILED | 502 | Upstream vendor rejected our credentials (our config issue). Not charged. |
| VENDOR_ERROR | 502 | A genuine transient upstream error (the source was briefly unavailable). Safe to RETRY after a short backoff. Not charged. NOTE: this is NOT for bad input — invalid values return 422 INVALID_INPUT, not 502. |
| TIMEOUT | 504 | Upstream vendor did not respond within the SLA window. Safe to retry after a short backoff. Not charged. |
| SERVICE_UNAVAILABLE | 503 | The sanctions lists are being refreshed. Not charged; retry in a few minutes. |
OpenAPI 3.1
Generated from this product's request/response JSON Schemas.
{
"openapi": "3.1.0",
"info": {
"title": "API Sathi — Sanctions Screening (UN, OFAC, EU)",
"version": "1.0.0",
"description": "Screen a person or company name against the UN Security Council Consolidated List, the US OFAC SDN list and the EU Consolidated Financial Sanctions List in one call. Lists are refreshed from the official sources every 6 hours. Matching understands spelling variants, initials, word order and aliases. Pass dob to rank hits with the same birth year first and to set aside same-name hits with a different birth year. result is possible_match when at least one hit is not ruled out by date of birth: send those for manual review. A hit is never proof on its own."
},
"servers": [
{
"url": "https://apisathi.in/gw/v1"
}
],
"components": {
"securitySchemes": {
"ApiKeyAuth": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key",
"description": "Your live or test key, e.g. `live_xxxxxxxxxxxx`."
}
}
},
"paths": {
"/sanctions-screening-v1": {
"post": {
"operationId": "sanctionsScreeningV1",
"tags": [
"kyc"
],
"summary": "Sanctions Screening (UN, OFAC, EU)",
"description": "Screen a person or company name against the UN Security Council Consolidated List, the US OFAC SDN list and the EU Consolidated Financial Sanctions List in one call. Lists are refreshed from the official sources every 6 hours. Matching understands spelling variants, initials, word order and aliases. Pass dob to rank hits with the same birth year first and to set aside same-name hits with a different birth year. result is possible_match when at least one hit is not ruled out by date of birth: send those for manual review. A hit is never proof on its own.",
"security": [
{
"ApiKeyAuth": []
}
],
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": false,
"schema": {
"type": "string"
},
"description": "Optional. Same key returns the same response for 24h."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 3,
"maxLength": 200
},
"type": {
"type": "string",
"enum": [
"individual",
"entity"
],
"description": "Optional. Default both."
},
"dob": {
"type": "string",
"description": "Optional. Date of birth or year, e.g. 1975-05-12."
},
"threshold": {
"type": "number",
"minimum": 50,
"maximum": 100,
"description": "Optional. Minimum name-match score, default 85."
}
},
"additionalProperties": false
},
"example": {
"name": "Hafiz Muhammad Saeed",
"dob": "1950-06-05"
}
}
}
},
"responses": {
"200": {
"description": "Successful, normalized response.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"result": {
"type": "string",
"enum": [
"clear",
"possible_match"
]
},
"hit_count": {
"type": "integer"
},
"hits": {
"type": "array"
},
"threshold": {
"type": "number"
},
"lists": {
"type": "object"
},
"lists_as_of": {
"type": "string"
}
}
},
"example": {
"name": "Hafiz Muhammad Saeed",
"result": "possible_match",
"hit_count": 2,
"hits": [
{
"source": "UN",
"reference": "QDi.263",
"type": "individual",
"listed_name": "HAFIZ MUHAMMAD SAEED",
"matched_name": "HAFIZ MUHAMMAD SAEED",
"score": 100,
"dob_match": true,
"dob": [
"1950-06-05"
],
"nationality": [
"Pakistan"
],
"programme": "Al-Qaida",
"listed_on": "2008-12-10"
},
{
"source": "EU",
"reference": "5419",
"type": "individual",
"listed_name": "Hafiz Muhammad Saeed",
"matched_name": "Hafiz Muhammad Saeed",
"score": 100,
"dob_match": true,
"dob": [
"1950-06-05"
],
"nationality": [],
"programme": "TAQA",
"listed_on": "2008-12-10"
}
],
"threshold": 85,
"lists": {
"UN": {
"generated": "2026-10-17T23:00:01.054Z",
"count": 1010
},
"OFAC": {
"generated": null,
"count": 17556
},
"EU": {
"generated": "15/10/2026",
"count": 6234
}
},
"lists_as_of": "2026-10-18T03:00:00.000Z"
}
}
}
},
"401": {
"description": "Missing, malformed, or revoked X-API-Key.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"402": {
"description": "Wallet balance is below the per-call sale price. Recharge and retry.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"403": {
"description": "API key is not scoped for this product.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"410": {
"description": "This API has been retired and is no longer available. Stop calling it — it will not return. Check the catalog for the current equivalent.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"422": {
"description": "The request was rejected as invalid — either it failed OUR schema validation (malformed input; not charged), or the upstream source rejected the value you sent. NOTE: an identifier that is well-formed but simply has NO RECORD is no longer an error — it returns 200 with `verified: false` and is charged (see the result-code table below). FIX the input before retrying; retrying the same value will fail again.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"429": {
"description": "Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"502": {
"description": "Upstream vendor rejected our credentials (our config issue). Not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"503": {
"description": "No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"504": {
"description": "Upstream vendor did not respond within the SLA window. Safe to retry after a short backoff. Not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
}
}