🛡️Compliance Screening

Purpose

The Compliance screening API allows you to query the Company.info compliance datasets using a set of parameters. Screen for persons and businesses and get their compliance profile. It is delivered over HTTPs, conforms to RESTful principles, and returns JSON objects.


Compliance Screening

❗ These endpoints incur usage-based charges.

This API follows a two-step process:

  1. Search
    Use GET /persons or GET /businesses to search for a person or company. The response will return a list of candidates that best match your query.
  2. Select & Retrieve Details
    Once you’ve identified the correct person or business from the search results, use their id to request the full profile via GET /persons/{id} or GET /businesses/{id}.

Compliance Screening Flow

Base Path

All endpoints for this API are available under:

/compliance/screening

Append this to the base API URL to form the full endpoint path.


GET /persons

This endpoint allows you to search for a person using various search parameters. It returns a list of potential matches based on how closely the input aligns with available data.

Each result includes a score field that indicates the confidence level of the match, with 100 representing the highest possible score.

Note: The results contain only a basic profile. To retrieve the complete profile of a specific individual, use the GET /persons/{id} endpoint (see below for details).

Request parameters

  • provider - The source of the compliance data.
    Currently supported value: kyc_aml
  • name - The full name of the person to search for. For best results, use one of the following formats:
    • "lastnames, firstnames middlenames" – recommended if you know the exact last name.
    • "firstnames middlenames lastnames" – use this if you want the system to infer the last name automatically.
  • datasets - Specifies which datasets to search. You can provide multiple datasets separated by commas. A full list of available datasets and their definitions is provided below.
  • threshold - The minimum match score (between 75 and 100) required for a result to be returned. Defaults to 85.
  • countries - Filters results by country. Accepts one or more two-letter country codes (ISO 3166-1 alpha-2). Returns profiles matching at least one of the specified countries.
  • countryRequired - If set to true, profiles without a known country or nationality will be excluded from the results.
  • dateOfBirth - The full date of birth of the person you are searching for.
  • dateOfBirthMatching - Defines how strictly the provided date of birth must match (e.g., exact or approximate).
  • dateOfBirthRequired - If set to true, profiles with an unknown date of birth will be excluded from the results.
  • gender - Specifies the gender of the person being searched.
  • matching - Determines the name-matching algorithm used for the search.
    • Fuzzy (default): Applies advanced fuzzy matching to return the most relevant results, even if the name is not an exact match.
    • Strict: Uses limited fuzzy logic, better suited when the exact name is known. This mode reduces false positives but may miss valid matches.
      Recommendation: Use Fuzzy for most use cases.
  • pepTiers - When searching within the PEP dataset, this defines which tiers of politically exposed persons to include:
    • Tier 1 – Senior roles
    • Tier 2 – Middle-ranking officials
    • Tier 3 – Junior officials
      If the PEP dataset is not part of the selected datasets, this filter is ignored.
      Notes:
    • This filter does not apply to PEP-Linked profiles.
    • When a parameter such as dateOfBirthRequired or countryRequired is set to false, profiles missing that specific value will still be included in the results. However, a minor score penalty will be applied to reflect the reduced confidence.

Available Datasets for Person Screening

Dataset KeyDescription
PEPSearch all Politically Exposed Persons: current, former, and linked
PEP-CURRENTSearch only the current Politically Exposed Persons
PEP-FORMERSearch only the former Politically Exposed Persons
PEP-LINKEDSearch only the Politically Exposed Persons by association
SANSearch all Sanctions: current and former
SAN-CURRENTSearch only current Sanctions
SAN-FORMERSearch only former Sanctions
RRESearch the Reputational Risk Exposure dataset
RELSearch the Regulatory Enforcement Lists
POISearch the Profiles of Interest dataset
DDSearch the Disqualified Directors dataset
INSSearch the Insolvency Register

📘

Datasets with CURRENT and FORMER cannot be specified with the full versions of datasets. For example: PEP-CURRENT,PEP is an invalid combination, while PEP-CURRENT,PEP-FORMER is okay


Example request

📘

All the available parameters can also be found at our API reference page here

curl --request GET \
     --url 'https://api.company.info/compliance/screening/persons?provider=kyc_aml&match[threshold]=85&match[countryRequired]=false&match[dateOfBirthMatching]=sameYear&match[dateOfBirthRequired]=false&match[matching]=fuzzy&match[name]=Mark%2C%20Rutte&match[datasets]=PEP&page[size]=10&page[number]=1' \
     --header 'X-API-KEY: ***********************' \
     --header 'accept: application/vnd.api+json'

Example response

{
  "data": [
    {
      "type": "persons",
      "id": "123456789",
      "attributes": {
        "countries": [
          "NL"
        ],
        "datasets": [
          "PEP-FORMER"
        ],
        "datesOfBirth": [
          "1967-02-14"
        ],
        "gender": "Male",
        "match": "Mark Rutte",
        "monitoringID": "123456789",
        "name": "Mark Rutte",
        "pepTier": "PEP Tier 1",
        "profileImage": "https://example.com/image.png",
        "score": 100,
        "version": 1720112978087
      },
      "links": {
        "self": "/persons/123456789"
      }
    }
  ],
  "links": {
    "self": "/persons?match[countryRequired]=false&match[datasets]=PEP&match[dateOfBirthMatching]=sameYear&match[dateOfBirthRequired]=false&match[matching]=fuzzy&match[name]=Mark, Rutte&match[threshold]=85&provider=kyc_aml&page[size]=10&page[number]=1"
  },
  "meta": {
    "totalPages": 1,
    "totalResults": 1
  }
}

GET /businesses

This endpoint is used to search a business on some search parameters and see if they are being mentioned in some or all datasets. This will return a list of potential hits. The certainty of the hit will be marked with a score in the result where 100 is the highest score. This endpoint returns just a basic profile of the returned hits. For a more detailed profile, the GET /businesses/{id} will give a detailed profile of a business (more information about this endpoint down below).


⁉️ Request parameters

  • provider - The provided of the compliance data (available: kyc_aml)
  • name - The full name of the person you are searching for. For best results use the format of "lastnames, firstnames middlenames", or "firstnames middlenames lastnames". The former should be used if you know the explicit last name of the person as the latter will determine the last name automatically.
  • datasets - The datasets you want to search through. All of the available datasets and what they mean are down below. Can search through multiple datasets if you provide them with comma separation.
  • threshold - The minimum score you want the match to be before it returns a result. (min 75 to max 100. Defaults to 85)
  • countries - Searches if the person is from a certain country. It is possible to search for multiple countries and returns if it matches one of them. Two-letter country code ISO-3166-2.
  • countryRequired - Tells if profiles with unknown country and no nationality should be filtered out of the search results when searching for a person or a business from a specified country. If set to false (default value), and the country is specified, profiles with no country and no nationality will appear in the results with a small penalty applied due to the lack of a country match. If set to true, and country is specified, profiles with no country and no nationality will NOT appear in the results. If the country is not specified in the search, the attribute is ignored (profiles with no country and no nationality will appear in search results with no penalty).
  • matching - Defines what name-matching algorithm is used for profile search. The Fuzzy algorithm is the default and applies all of our fuzzy matching techniques to ensure the most accurate results. The Strict algorithm uses some fuzzy matching, but is more restrictive in its approach and may miss some matches if the exact name is not known. We strongly recommend using the Fuzzy algorithm for the best results and only using the Strict algorithm to reduce the number of matches to the bare minimum, when the exact name is known.

📘

When a parameter is set to false, profiles without that value will appear in the results with a small penalty applied to the score. This applies to for example the countryRequired field.


📚 Datasets for Businesses profile

Dataset KeyDescription
PEPSearch all Politically Exposed Persons: current, former, and linked
PEP-LINKEDSearch only the Politically Exposed Persons by association
SANSearch all Sanctions: current and former
SAN-CURRENTSearch only current Sanctions
SAN-FORMERSearch only former Sanctions
RRESearch the Reputational Risk Exposure dataset
RELSearch the Regulatory Enforcement Lists
POISearch the Profiles of Interest dataset
INSSearch the Insolvency Register
SOESearch all State-Owned Enterprises: current and former
SOE-CURRENTSearch only current State-Owned Enterprises
SOE-FORMERSearch only former State-Owned Enterprises

📘

Datasets with CURRENT and FORMER cannot be specified with the full versions of datasets. For example: SAN-CURRENT,SAN is an invalid combination, while SAN-CURRENT,SAN-FORMER is okay


Example request

📘

All the available parameters can also be found at our API reference page here

curl --request GET \
     --url 'https://api.company.info/compliance/screening/businesses?provider=kyc_aml&match[threshold]=85&match[countryRequired]=false&match[matching]=fuzzy&match[name]=wagner&match[datasets]=REL&page[size]=10&page[number]=1' \
     --header 'X-API-KEY: ***********************' \
     --header 'accept: application/vnd.api+json'

Example response

{
  "data": [
    {
      "type": "businesses",
      "id": "123456789",
      "attributes": {
        "countries": [
          "RU"
        ],
        "datasets": [
          "PEP-LINKED",
          "REL",
          "SAN-CURRENT"
        ],
        "match": "Wagner",
        "monitoringID": "123456789",
        "name": "The Wagner Group",
        "score": 100,
        "version": 1724761185610
      },
      "links": {
        "self": "/businesses/123456789"
      }
    }
  ],
  "links": {
    "self": "/businesses?match[countryRequired]=false&match[datasets]=REL&match[matching]=fuzzy&match[name]=wagner&match[threshold]=85&provider=kyc_aml&page[size]=10&page[number]=1"
  },
  "meta": {
    "totalPages": 1,
    "totalResults": 1
  }
}

GET /persons/{id}

This endpoint is used to fetch the full compliance profile of a person.

⁉️ Request parameters

  • id - The ID of the person you want to get the profile for. This ID can be fetched from the GET /persons search endpoint.

Example request

curl --request GET \
     --url https://api.company.info/compliance/screening/persons/123456789 \
     --header 'X-API-KEY: *********************' \
     --header 'accept: application/vnd.api+json'

Example response

{
  "data": {
    "type": "persons",
    "id": "123456789",
    "attributes": {
      "addresses": [
        {
          "addressType": "Place of birth",
          "city": "Cityname",
          "countryISOCode": "NL",
          "county": "Province",
          "countyAbbreviation": "PV",
          "line1": "",
          "line2": "",
          "postcode": ""
        },
        {
          "addressType": "Business",
          "city": "Cityname",
          "countryISOCode": "NL",
          "county": "Province",
          "countyAbbreviation": "PV",
          "line1": "Streetname 1",
          "postcode": "1111"
        }
      ],
      "aliases": [
        {
          "firstName": "M.",
          "lastName": "Rutte",
          "type": "Shortened Name"
        }
      ],
      "businessLinks": [
        {
          "datasets": [
            "PEP-LINKED"
          ],
          "id": "123456789",
          "individualLinks": [],
          "monitoringID": "123456789",
          "name": "name",
          "ownershipPercentage": 0,
          "relationship": "Relationship to the business"
        }
      ],
      "firstName": "Mark",
      "gender": "Male",
      "griEntries": [],
      "identifiers": [],
      "insEntries": [],
      "isDeceased": false,
      "isDeleted": false,
      "lastName": "Rutte",
      "middleName": "",
      "monitoringID": "123456789",
      "nationalitiesISOCodes": [
        "NL"
      ],
      "notes": [],
      "pepByAssociationEntries": [],
      "pepEntries": {
        "pepTier": "PEP Tier 1",
        "former": [
          {
            "countryISOCode": "NL",
            "dateFromISO": "2022-01-10",
            "dateToISO": "2024-07-02",
            "evidenceIDs": [
              "1234",
              "5678",
              "9012"
            ],
            "position": "Prime Minister (Minister-President) | Government (Regering)",
            "segment": "Executive Branch - Head and Members of Government and Deputies"
          }
        ]
      },
      "poiEntries": [],
      "profileImages": [
        "https://example.com/image.png"
      ],
      "relEntries": [],
      "rreEntries": [],
      "sanEntries": {},
      "version": 1720112978087
    },
    "links": {
      "self": "/persons/123456789"
    }
  }
}

GET /businesses/{id}

This endpoint is used to fetch the full compliance profile of a business.

⁉️ Request parameters

  • id - The ID of the business you want to get the profile for. This ID can be fetched from the GET /businesses search endpoint.

Example request

curl --request GET \
     --url https://api.company.info/compliance/screening/businesses/123456789 \
     --header 'X-API-KEY: *************************' \
     --header 'accept: application/vnd.api+json'

Example response

{
  "data": {
    "type": "businesses",
    "id": "123456789",
    "attributes": {
      "activities": [
        "Private military company"
      ],
      "addresses": [
        {
          "addressType": "Operating",
          "city": "",
          "countryISOCode": "RU",
          "county": "",
          "countyAbbreviation": "",
          "line1": "",
          "line2": "",
          "postcode": ""
        }
      ],
      "aliases": [
        {
          "alias": "alias",
          "type": "Name Spelling Variation"
        }
      ],
      "businessLinks": [
        {
          "datasets": [
            "SAN-CURRENT"
          ],
          "id": "123456789",
          "monitoringID": "123456789",
          "name": "Sanad Protection and Security Services",
          "ownershipPercentage": 0,
          "relationship": "relationship to business"
        }
      ],
      "businessTypes": [],
      "contactEntries": [],
      "datasets": [
        "PEP-LINKED",
        "REL",
        "SAN-CURRENT"
      ],
      "deletionReason": {},
      "description": "description of business",
      "evidences": [
        {
          "assetURL": "file.pdf",
          "captureDateISO": "2000-01-01",
          "credibility": "High",
          "datasets": [
            "SAN-CURRENT",
            "CORP"
          ],
          "evidenceID": "24322945",
          "isCopyrighted": false,
          "keywords": "",
          "language": "eng",
          "originalURL": "https://website.com",
          "publicationDateISO": "2000-01-01",
          "summary": "",
          "title": ""
        }
      ],
      "individualLinks": [
        {
          "datasets": [
            "SAN-CURRENT"
          ],
          "firstName": "firstname",
          "id": "123456789",
          "lastName": "lastname",
          "middleName": "middlename",
          "monitoringID": "123456789",
          "ownershipPercentage": 0,
          "relationship": "relationship"
        }
      ],
      "insEntries": [],
      "isDeleted": false,
      "monitoringID": "123456789",
      "name": "The Wagner Group",
      "notes": [
        {
          "value": "notes"
        }
      ],
      "poiEntries": [],
      "profileImages": [],
      "relEntries": [
        {
          "category": "category",
          "subcategory": "subcategory",
          "events": [
            {
              "amount": 0,
              "currencyCode": "",
              "dateISO": "2000-01-01",
              "evidenceIDs": [
                "23594463"
              ],
              "period": {},
              "type": "Economic Restrictive Measure"
            }
          ]
        }
      ],
      "rreEntries": [],
      "sanEntries": {
        "current": [
          {
            "events": [
              {
                "dateISO": "2024-07-03",
                "evidenceIDs": [
                  "24322945"
                ],
                "type": "Amended"
              }
            ],
            "measures": [
              "Asset Freeze"
            ],
            "regime": {
              "body": "body",
              "name": "name",
              "origin": "origin country"
            },
            "sanctionID": "22543"
          }
        ]
      },
      "soeEntry": null,
      "version": 1724761185610
    },
    "links": {
      "self": "/businesses/123456789"
    }
  }
}

🔢 Pagination

The results are being paginated. This means the returned result is delivered in batches (by default in 10). To get access to the rest of the results, you can either increase the size in the request to get more results in 1 response or send the same request with page set to 2 or higher. In the metadata of the response is visible how many results and pages the request has in total.

  • size - The amount of total results that will be returned (Default is 10, maximum is 20).
  • page - The page to retrieve (Default is 1).

❗️

This API has rate limit of 20 requests per second


⚠️ Possible errors/ unexpected behavior

This list does not contain the error messages associated with API key errors. Please also check the following page to see if the error is listed here when it is not listed in the table below.

Error CodeError MessageSolution
400failed to process provider request: Invalid {search parameter}Please make sure your request contains all the required search parameters
400failed to process request: invalid id formatThe ID in the request is invalid. Please make sure you copy the ID correctly. For example, the ID contains an equal character which could be skipped if you copy it.
400failed to process request: provider not foundThe provider is missing from the request. Please make sure you add &provider=kyc_aml to the request
500failed to process responseThis could happen if the requested pagenumber is higher than the total pages the search produces

Example error response

{
    "errors": [
        {
            "title": "Bad Request",
            "detail": "failed to process provider request: Invalid name",
            "status": "400",
            "code": "400"
        }
    ]
}

🛠️ Try it yourself!

Ready to test it for yourself?! Please also check our API reference page where you can easily test the API yourself!


🔎 Compliance Monitoring

👀

Do you want to automate the screening process? You will get notified if a person or business profile changed. For this feature and more, check our Monitoring API here


🔤 Glossary

A person or business profile - Full profile of the person or a business, part of the Screening API (e.g., a complete profile of John Doe with all the documents and details).


❓ FAQ

Are all input parameters case-sensitive?

Yes, both monitoring- and screening APIs are case-sensitive

I get an empty response, what’s going wrong?

The empty response doesn't mean that an error happened. It means the person you're looking for is not present in a given dataset. In the example provided, Willem Holleeder is not a politician (PEP) nor sanctioned (SAN). That's why it makes sense why they don't get any results. You can try adding, for example, RRE (reputational risk exposure) dataset to the request and then they will get a response.

We can’t find the Mayor of Amsterdam / Cologne in the PEP dataset, why?

Mayors are considered PEPs only in the jurisdictions in which the national AML legislation has specifically mentioned them as being in scope.

Generally speaking, only prominent public figures/roles, i.e. senior government members are regarded as PEPs but there are countries in which lower-level government officials are included in the national PEP definitions as well.

Include the POI and RRE datasets and the Mayor’s will be found.

What’s the difference between Fuzzy Matching and Strict matching?

Fuzzy Matching

Description: Fuzzy matching is an advanced technique that can handle small variations and errors in the entered name. It accounts for variations in spelling, typos, etc.

Advantages:

Higher Accuracy: It can find variants of a name even if they do not exactly match the entered name.

Flexibility: Useful if you are unsure of the exact spelling or form of the name you are searching for.

Use Cases: Recommended when you want the most accurate and comprehensive search results. This is particularly useful in situations where there is uncertainty about the exact name, such as compliance checks where different spellings of a name need to be considered.

Strict Matching
Description: Strict matching uses a more restrictive approach that is less tolerant of variations and errors. While this API still applies some degree of fuzzy matching, it is much less forgiving, so to speak.

Advantages:

Fewer Results: Reduces the number of search results by returning only highly accurate matches.

Precise Matches: Suitable when you are certain of the exact name and do not want to consider variations.

Use Cases: Recommended when you want to minimize the number of matches and are confident that you have the exact name. This can be useful in situations where you prefer not to have excessive data and need only the most accurate matches.

Recommendation
Fuzzy Matching: Use this algorithm for the most accurate and comprehensive results. This is particularly useful in compliance screening where names can be written in various ways or may contain small errors.

Strict Matching: Use this algorithm only if you want to minimize the number of matches and are certain of the exact name. This can help prevent too many irrelevant results from being returned.

Example
Suppose you are searching for the name "John Smith":

Fuzzy Matching: Will also return results for "Jon Smith," "J. Smith," "John Smyth," etc.

Strict Matching: Will primarily return results for "John Smith" and possibly some very close variants, but will likely exclude "Jon Smith" or "J. Smith."

By choosing between these algorithms, you can tailor the search results to your specific needs and accuracy requirements in compliance screening processes.