TIC

Screening a company for KYC means screening more than the company: also the people who run it and the people who own it. Screen a company does all of it in one call from the company’s ID, and Screen a person screens one person the same way. You do not supply names or identity numbers; they come from the registers.

Company Person
Endpoint POST /screening/companies/{companyId} POST /screening/persons/{personId}
Tier Pro+ tier Enterprise+ tier
Access The pep scope on the API key The pep scope on the API key
Billing Your screening price per screened person or company Your screening price
The same screening again within 24 hours The earlier result, free of charge The earlier result, free of charge

Every screening is stored. Hits are marked as new or already seen, and decisions you record on hits follow the person into later screenings. See Reviewing hits.

Who is screened

A company screening always includes the company itself. Besides the company it includes these role groups, set with roles:

roles value Included by default Who
board Yes Chair, vice chair, board members and deputy board members
management Yes CEO, deputy CEO and external (deputy) CEO
signatory Yes External signatories and procurators (prokurist)
liquidator Yes Liquidators and deputy liquidators
partner Yes Sole trader, partners, general partners, limited partners and the manager of a branch
beneficialOwner Yes The owners in the company’s latest registration in the register of beneficial owners
beneficialOwnerRepresentative Yes Representatives listed in that registration
ownershipChain Yes Companies an owner controls the company through
auditor No Auditors, deputy auditors and lay auditors

Positions are the current ones, the same as in representatives. To screen only some groups, list them:

curl -X POST "https://lens-api.tic.io/screening/companies/3508351" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "roles": ["board", "management", "beneficialOwner"] }'

Choosing who to screen

Plan a company screening lists everyone a screening can include, with their positions and, for beneficial owners, the extent and kind of control, and what it costs, without screening anyone. Send the subjectKey of the people and companies you want in subjects; the company itself is always screened:

curl -X POST "https://lens-api.tic.io/screening/companies/3508351" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "subjects": ["P1234567", "P2345678"] }'

subjects picks from every role group, auditors included; roles narrows the groups first. A subjectKey the company no longer has (the board or the owners changed after the plan was fetched) returns 400 with code unknown_subjects: fetch the plan again.

Everyone is screened once. A chair who is also a beneficial owner is one subject with both roles, and is billed once. A person registered twice without a personal identity number, with the same name and birth date, is also one subject.

When there are no owners, beneficialOwnerStatus says why:

beneficialOwnerStatus Meaning
FINNS Beneficial owners are registered.
FINNS_EJ The company has registered that it has no beneficial owner.
EJFASTSTALLD The company cannot determine whether there is a beneficial owner, or who it is.
GALLRAD The company has been removed from the register of beneficial owners.
absent The company has never registered.

A company screening can include at most 250 people and companies. Above that the call returns 400 with code too_many_subjects; narrow roles or pick subjects. Limited partnerships with hundreds of limited partners can be screened without partner.

How each person is matched

Two rules of the lists shape how a person has to be screened (see How matching works):

  • Every word of the name must be on the list entry. A full legal name with all given names misses an entry listed under fewer names.
  • A list entry whose identity number differs from the one in the query is left out, also from name matching. A person whose personal identity number has changed is only found under the old number by a query with the old number.

So the API sends one or more queries per person, depending on what is registered:

What is registered Queries
Personal identity number One per identity number the person has had, each with the family name and the birth date in that number. One more per further part of the family name (middle name, double surname) and per previous family name.
Birth date only, e.g. a foreign board member The family name with the birth date. When the birth date is registered with six digits, one query per possible century.
Name only The given name with the family name, one query per given name.
Protected identity (skyddad identitet) Not screened. The subject is listed with notScreenedReason protectedIdentity, without name or identity number.

The family name with the birth date finds an entry however many given names it lists. But it also finds entries with the same family name that have only a birth year, or no birth date at all, so a hit that did not match on the identity number (hitRating below 5) is kept only when the entry or one of its aliases shares a given name with the person. The family name searched on does not count as a given name, also when the person has it among the given names.

screenedOn on each subject says what its strongest query used: identityNumber, nameAndBirthDate or name. A subject screened on name gets more false positives; review those hits against the birth date and countries on the entry. With includeQueries=true every query is listed with its reason:

reason Why the query was sent
primary The current identity number and name.
otherIdentityNumber Another personal identity number the person has had.
otherFamilyName Another part of the family name.
previousName A previous family name, or a previous company name.
givenNameVariant A name-only subject: one query per given name.
alternativeBirthDate A six-digit birth date: the other possible century.
otherCompanyName The company’s name in a foreign language.
supplied Exactly as supplied (search only).

Lists: every sanctions list (including the financial supervisors’ warning lists) and PEP list; serviceScope narrows that. Adverse media is not screened.

Companies are screened on their organisation number and their name without the legal form (AB, Aktiebolag, (publ), HB, …) when at least two words remain, plus previous names and names in foreign languages.

Billing and reuse

  • Each call places one order. A company screening costs your screening price times the number of people and companies screened (summary.screenedSubjectCount); those not screened are not billed. A company screened with anyone else is its own order type, priced per screened subject; the company alone is priced as a single screening. A person screening costs your screening price.
  • The same screening within 24 hours is free. It returns the earlier result with reused true and places no order. The same means the same company or person, the same people, roles and queries, the same options and the same test mode. A change in the board or the owners gives new queries and therefore a new screening.
  • Add refresh=true to screen again within the 24 hours. That screening is billed.
  • Test mode screenings are free.

The response

The response is compact: every subject with its roles and one short line per hit. onlyWithHits=true leaves out subjects without hits (they are still counted in summary), and includeQueries=true adds the queries sent. The full list entry behind a hit is fetched with Get a screening hit. A screening of many people can have thousands of hits: includeHits=false returns the subjects with their hit counts only, and List a subject’s hits pages the hits of one subject.

{
  "screeningId": "243446ba-09c1-4ceb-b49f-d11806214a74",
  "type": "company",
  "companyId": 3508351,
  "screenedAtUtc": "2026-10-07T14:10:05",
  "testMode": false,
  "reused": false,
  "order": { "documentOrderGuid": "59e84a7a-7e13-4986-8d0b-af224bd5b8be", "orderedAtUtc": "2026-10-07T14:10:05", "price": 15.00, "currency": "SEK" },
  "summary": {
    "subjectCount": 4, "screenedSubjectCount": 3, "notScreenedCount": 1, "queryCount": 4,
    "subjectsWithHits": 1, "hitCount": 1, "newHitCount": 1, "pendingHitCount": 1,
    "hitCountByCategory": { "pep": 1 }
  },
  "beneficialOwnerStatus": "FINNS",
  "subjects": [
    {
      "subjectId": 101, "type": "company", "companyId": 3508351, "name": "Exempel AB", "identityNumber": "5560000000",
      "screenedOn": "identityNumber", "roles": [{ "group": "target" }], "queryCount": 1, "hitCount": 0, "newHitCount": 0, "hits": []
    },
    {
      "subjectId": 102, "type": "person", "personId": 2954253, "name": "Anna Maria Exempelsson",
      "screenedOn": "identityNumber",
      "roles": [
        { "group": "board", "code": "OF", "description": "ORDFÖRANDE" },
        { "group": "beneficialOwner", "code": "ART10", "description": "Personen har kontroll genom aktier, andelar, medlemskap, avtal eller bestämmelse i exempelvis bolagsordning eller stadgar.", "extentCode": "INTERVALL5", "extentDescription": "100 %" }
      ],
      "queryCount": 2, "hitCount": 1, "newHitCount": 1, "maxHitRating": 5,
      "hits": [
        {
          "hitId": 9001, "category": "pep", "name": "Anna Exempelsson", "birthDate": "1975-04-12", "isEntity": false,
          "sourceName": "PEP_Edge", "listType": "PEP", "externalId": "SE-113942", "hitRating": 5, "tier": 2,
          "matchedVia": "otherIdentityNumber", "isNew": true, "resolution": "pending", "listEntryUpdatedAtUtc": "2026-08-30T02:15:07"
        }
      ]
    },
    {
      "subjectId": 103, "type": "person", "personId": 2954254, "name": "Erik Exempelsson", "screenedOn": "identityNumber",
      "roles": [{ "group": "board", "code": "SU", "description": "STYRELSESUPPLEANT" }], "queryCount": 1, "hitCount": 0, "newHitCount": 0, "hits": []
    },
    {
      "subjectId": 104, "type": "person", "notScreenedReason": "protectedIdentity",
      "roles": [{ "group": "board", "code": "LE", "description": "STYRELSELEDAMOT" }], "queryCount": 0, "hitCount": 0, "newHitCount": 0, "hits": []
    }
  ]
}

Screening

Property Type Description
screeningId guid The screening’s ID: fetch it again, its hits, and record decisions.
type string company, person or search.
companyId / personId integer The screened company or person.
screenedAtUtc date-time When the screening ran. For a reused screening, when it first ran.
testMode boolean true for a test screening.
reused boolean true when the same screening ran within the last 24 hours and that result is returned, without a new order.
order Order The order the screening was billed as: documentOrderGuid, orderedAtUtc, price, currency.
summary Summary Counts, see below.
beneficialOwnerStatus string Company screening: the status of the latest beneficial-owner registration, see Who is screened.
beneficialOwnerStatusDescription string The status in words.
subjects array of Subject Everyone screened, the screened company or person first.
warnings / errors array of string Warnings and errors about individual queries, on the call that ran the screening. A subject an error concerns has notScreenedReason screeningError.

Summary

Property Type Description
subjectCount integer People and companies found, including those not screened.
screenedSubjectCount integer People and companies screened. A company screening is billed per screened subject.
notScreenedCount integer Subjects not screened: protected identity, or nothing to screen on.
queryCount integer Queries sent to the lists.
subjectsWithHits integer Subjects with at least one hit.
hitCount integer All hits.
newHitCount integer Hits the team had not seen before for the same person or company.
pendingHitCount integer Hits without a decision.
hitCountByCategory object Hits per category: pep, sanction, regulatoryWarning (financial supervisors’ warning lists), other.

Subject

Property Type Description
subjectId integer The subject in this screening.
type string person or company.
personId / companyId integer The person or company, when it exists as a record.
name string The name as registered. Absent for a protected identity.
identityNumber string The current personal identity number or organisation number. On the Pro tier a personal identity number keeps only its birth date.
birthDate string The birth date, when only a birth date is registered.
citizenshipCountryCode string Citizenship, when registered.
screenedOn string What the strongest query used: identityNumber, nameAndBirthDate or name. Absent when not screened.
notScreenedReason string protectedIdentity or notIdentifiable when the subject was not screened. screeningError when the lists could not be searched for it: not billed, screen again. Hits its other queries found are still listed.
roles array of Role Why the subject is in the screening.
queryCount integer Queries sent for the subject.
queries array of Query The queries, with includeQueries=true: reason, name, itemNumber, itemDate and rawHitCount (entries returned before the given-name check).
hitCount / newHitCount integer Hits, and hits not seen before.
maxHitRating integer The strongest hit rating.
hits array of Hit The hits, strongest first.

Role

Property Type Description
group string target (the screened company or person), board, management, signatory, liquidator, partner, beneficialOwner, beneficialOwnerRepresentative, ownershipChain, auditor or supplied.
code string The registered position (OF, LE, SU, VD, …), or for a beneficial owner how control is exercised (ART10 through shares, ART20 appoints the board, ART30 together with relatives, ART40 through other companies, …).
description string The position or way of control in words.
extentCode / extentDescription string Beneficial owner: the extent of ownership, INTERVALL1 (up to 25 %) to INTERVALL5 (100 %).
positionStart date When the position was registered.

Hit

Property Type Description
hitId integer The hit’s ID: full details and decisions.
category string pep, sanction, regulatoryWarning or other.
name string The list entry’s name.
birthDate string The list entry’s birth date.
isEntity boolean true for an organisation entry.
sourceName string The list, for example EU_GLOBAL or PEP_Edge. See Lists.
listType string The group the list belongs to.
externalId string The list’s own ID for the entry.
hitRating integer What the entry matched on, 1 to 5. See Hit rating.
nameMatchScore number Name similarity, with phonetic matching.
tier integer PEP seniority, 1 the most senior.
matchedVia string The reason of the query that found the entry, e.g. otherIdentityNumber when it carries a previous personal identity number.
isNew boolean The team had not seen this entry for this person or company before.
resolution string The team’s decision. See Reviewing hits.
resolvedAtUtc / resolutionComment When the decision was made, and why.
listEntryUpdatedAtUtc date-time When the list last updated the entry.

HTTP status codes

Status Meaning
200 OK The screening ran, or an earlier one was reused (reused).
400 Bad Request Code invalid_roles (a roles value that cannot be requested), unknown_subjects (a subjects key the company does not have), too_many_subjects, or invalid_service_scope (a serviceScope naming only lists that are not screened).
404 Not Found The company or person does not exist or is not accessible.
422 Unprocessable Entity Code not_screenable: the person has a protected identity or nothing to screen on, or the company has no name or organisation number to screen on.
502 Bad Gateway Code screening_failed: the lists could not be searched for any subject. Nothing was stored or billed; try again.