> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tic.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Company and person screening

> Screen a company together with its board, management and beneficial owners, or a single person, in one call - who is included, how each person is matched, billing, reuse within 24 hours, and the response.

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](/api-lens/screening/screen-a-company-with-its-board-and-beneficial-owners) does all of it in one call from the company's ID, and [Screen a person](/api-lens/screening/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 | <Badge color="green" size="sm">Pro+ tier</Badge> | <Badge color="yellow" size="sm">Enterprise+ tier</Badge> |
| 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](/api-lens/screening/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](/api-lens/companies/get-company-representatives). To screen only some groups, list them:

```bash theme={null}
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"] }'
```

**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`. 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](/api-lens/screening/introduction#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. Entries without a birth date match any query on their name, so a hit found on the family name alone, without an identity number or birth date behind it (`hitRating` below 4), is kept only when the entry shares a given name with the person.

`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](/api-lens/screening/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 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](/api-lens/screening/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](/api-lens/screening/get-a-screening-hit).

```json theme={null}
{
  "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](#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. Check `errors` before treating a subject without hits as clear. |

### 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. |
| `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](/api-lens/screening/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](/api-lens/screening/introduction#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](/api-lens/screening/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), `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` | Person screening: code `not_screenable`, the person has a protected identity or nothing to screen on. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.