Skip to content

ComplyAdvantage

The ComplyAdvantage adapter is implemented for name screening through the ComplyAdvantage Search API.

Field Value
Integration name complyadvantage
Display name ComplyAdvantage
Type sanctions
Required credentials apiKey
Optional settings region, fuzziness
Base URL Set by region
Endpoint paths POST /searches (screening), GET /users (connection test)
Authentication Authorization: Token <apiKey>
Timeout 10 seconds
Retries None: one attempt per request
region Base URL
eu (default) https://api.complyadvantage.com
us https://api.us.complyadvantage.com
apac https://api.ap.complyadvantage.com

The adapter screens names: wallet addresses and transaction hashes are not sent to ComplyAdvantage. It runs at a stage only when an active rule that applies to the transfer at that stage reads ComplyAdvantage; enabling it alone screens nothing.

Stage Names screened
precheck Outgoing transfers, before wallet discovery or any Travel Rule exchange: the first originator person and the first beneficiary person in the IVMS101 data sent with the transfer.
postcheck Once the counterparty's IVMS101 data arrives: its first person's name, with your party's stored name.

Sygna Bridge instead screens each person the counterparty lists alone, in a postcheck evaluation of its own; Global Travel Rule and incoming CodeVASP transfers screen each further person the counterparty lists that way. Each evaluation records its own ComplyAdvantage check on the transfer, with its stage.

A natural person's name is its first name identifier, secondary then primary identifier (Jane Doe); a legal person's is its first legal name. Each name is one search:

  • search_term: the name, trimmed. A name over 255 characters fails its screening without a request.
  • fuzziness: your setting, default 0.6.
  • filters.entity_type: person for every name, a legal person's included.
  • limit: 100, and share_url: 0.

After five failed ComplyAdvantage checks in a row, each within a minute of the one before, a circuit breaker skips ComplyAdvantage in that environment for a minute: its checks are skipped, without a request. Two successful checks then close the breaker, and a failure opens it again.

The adapter uses the settings saved for the transfer's environment; test and live call the same base URLs. Without an API key for the environment, the check fails (error, with response: null) without calling ComplyAdvantage. There is no sandbox fallback: save test credentials to screen test transfers.

Field Dashboard label Value
apiKey Search API Key Your ComplyAdvantage API key. A secret: never returned.
region Account Region (default: EU) eu, us or apac: your account's region.
fuzziness Name Fuzziness (0–1, default: 0.6) A number from 0 to 1, as text.
Terminal window
curl -X PUT "$COVALENT_URL/api/v2/integrations/complyadvantage" \
-H "x-api-key: $COVALENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "credentials": { "apiKey": "...", "region": "us", "fuzziness": "0.6" } }'

region and fuzziness are checked when used, not when saved. A region other than eu, us or apac fails every screening and the connection test, without a request. A fuzziness that is not a number from 0 to 1 fails each name's screening, without a request; the connection test does not check it. See Providers and Integrations.

POST /api/v2/integrations/complyadvantage/test sends GET /users with the environment's API key and region: a read-only call that creates no search. An answer with status: success and a content.data list passes, with the message Successfully connected to ComplyAdvantage Search API. Anything else fails the test, and error says why, such as ComplyAdvantage API returned HTTP 401, ComplyAdvantage request timed out or Invalid ComplyAdvantage connection response. Without saved credentials for the environment, the test is 409 NOT_CONFIGURED.

The check's response holds one entry per screened name, with ComplyAdvantage's search response as received (shortened here):

{
"screenings": [
{
"party": "originator",
"kind": "name",
"status": "success",
"response": {
"status": "success",
"content": { "data": { "total_hits": 0, "hits": [] } }
}
}
]
}

A name's screening succeeds when ComplyAdvantage answers status: success with content.data.total_hits and content.data.hits, each hit with a doc.name, doc.types and a score. An answer whose hit count differs from total_hits (the search asks for up to 100 hits) fails it with ComplyAdvantage returned incomplete search results; review the search; the response is kept, so a partial list is never read as clean. Any other answer, an HTTP error or a timeout fails it, with an error. The check is success when every name's screening succeeded, else error. No score or verdict is derived from the hits. A role without pii:view gets response: null.

A hit changes nothing by itself: your compliance rules decide whether it flags the transfer, holds it for review or blocks it. Read ComplyAdvantage with a query branch, which runs on each name's response: content.data.total_hits counts its hits, and content.data.hits[].doc.types[] (the rule editor's example) lists every hit's types, empty when there are none. The branch matches when any name's value meets the comparison, or, with subjectMatch: "all", when every name's does. The rule requires review when the query finds no value (such as content.data.hits[0] without hits), when a dotted field reads a check that screened more than one name, or when the check failed or was skipped.