A manual for a client application to interpret the response of the public endpoint POST /v1/screening, including when an advanced query expands the ownership network through ownership_network.
Text shown to end users can be localized by the client layer. The interactive documentation (/docs) is the reference for types and fields; this manual explains the semantics and the reading order.
The API's recommendation supports the compliance decision. It does not replace the policy, approvals, or human analysis required by the client.
Safe reading order
A long response should not be read as a single list of matches. The consumer should follow this sequence:
- Confirm whether the response is conclusive (
status). - Read the decision on the directly queried subject.
- Evaluate the matches and the source coverage.
- Separately evaluate the ownership network, when requested.
- Use the dossier and billing as evidence and traceability.
1. Is the response conclusive?
{
"status": "COMPLETE",
"billable": true,
"warnings": [],
"notices": []
}
| Field | Interpretation |
|---|---|
status: COMPLETE | The requested steps were completed. |
status: PARTIAL | At least one source or step did not complete. The response is inconclusive. Do not treat CLEAR as an automatic approval. |
status: ERROR | The query did not produce a reliable classification. Do not make a risk decision. |
billable | States whether a charge occurred; it does not state whether the result is favorable. |
warnings | Human-readable messages. |
notices | The same alerts in structured form, with code, severity and message. |
Example of a response that calls for a retry or review, not an approval:
{
"status": "PARTIAL",
"billable": false,
"notices": [
{
"code": "PARTIAL_SOURCE_FAILURE",
"severity": "WARNING",
"message": "Partial screening: at least one selected live source was unavailable. The result is not conclusive and was not charged. Run the screening again."
}
]
}
2. Decision on the directly queried subject
{
"risk_level": "HIGH",
"identity_class": "TRUE_MATCH",
"recommendation": "REJECT",
"summary": "One or more high-risk matches have confirmed identity. Blocking is recommended subject to your compliance policy."
}
These four fields describe only the person or company sent in the request. They should not be assumed to be an automatic summary of the QSA network.
| Field | Question answered |
|---|---|
risk_level | How severe is the effective risk found? |
identity_class | How certain is the identity match between the record and the queried subject? |
recommendation | What action does the API suggest to the client? |
summary | Short explanation for a human interface. |
Identity classes
| Value | Practical use |
|---|---|
TRUE_MATCH | Identity confirmed by document or strong evidence. |
POTENTIAL_MATCH | Relevant evidence, but human review is required. |
WEAK_MATCH | Insufficient evidence for an actionable match. |
NO_MATCH | No relevant match found. |
Risk levels
| Value | Practical use |
|---|---|
CLEAR | No actionable risk within the effectively queried scope. |
MEDIUM | Requires review; for example, a confirmed PEP or a potential match from a severe source. |
HIGH | Severe match with identity sufficiently confirmed. |
ERROR | No reliable classification. |
A typical integration policy is:
COMPLETE + CLEAR + NO_MATCH -> proceed, respecting the queried scope
COMPLETE + MEDIUM or POTENTIAL_MATCH -> human review
COMPLETE + HIGH + TRUE_MATCH -> block or escalate per policy
PARTIAL or ERROR -> do not approve automatically
PEP is a special case: requires_edd: true requires enhanced due diligence, but PEP status alone is not grounds for an automatic block.
3. Direct matches: hits
{
"total_hits": 2,
"actionable_hits_count": 2,
"informational_hits_count": 3,
"returned_hits_count": 2,
"hits_truncated": false,
"hits": [
{
"source": "OFAC_SDN",
"category": "Financial Sanction",
"name_similarity": 0.98,
"identity_confidence": 1.0,
"document_evidence": "EXACT_MATCH",
"identity_class": "TRUE_MATCH",
"risk_level": "HIGH",
"requires_edd": true,
"downgraded": false
}
]
}
| Field | How to use it |
|---|---|
hits | Actionable matches that support the main subject's decision. |
total_hits / actionable_hits_count | Actionable matches found before the response size limit. |
returned_hits_count | Always equal to hits.length. |
informational_hits | Discarded or weak candidates; useful for audit, not for automatic blocking. |
hits_truncated | If true, hits does not contain every match. |
truncated_hits_by_source | Count omitted per source. |
category | Regulatory nature of the record, e.g. sanction, PEP, or insolvency. |
source_risk_level | Original severity from the source. |
risk_level on the hit | Effective severity after considering identity. |
name_similarity | Name similarity; not standalone proof of identity. |
identity_confidence | Final identity confidence. |
document_evidence | How the document contributed to identification. |
downgraded | Confidence or risk was reduced by the available evidence. |
requires_edd | The case calls for enhanced due diligence. |
Never make a decision based on name_similarity alone. Use identity_class, risk_level, document_evidence, and the source's context.
4. Source coverage: sources_checked
sources_checked is the proof of which sources were actually queried and what happened at each one.
{
"sources_checked": {
"OFAC_SDN": {
"list_status": "AVAILABLE",
"query_result": "MATCH",
"risk_level": "HIGH",
"hits": 1,
"confirmed_hits": 1,
"potential_hits": 0,
"skip_reason": null
},
"PY_DNIT_RUC": {
"list_status": "NOT_APPLICABLE",
"query_result": "NOT_QUERIED",
"hits": 0,
"skip_reason": "COMPATIBLE_DOCUMENT_REQUIRED"
}
}
}
- A source with
NO_MATCHonly supports a conclusion if it was actually queried. skip_reason: COMPATIBLE_DOCUMENT_REQUIREDis not a failure: that source requires a compatible document and cannot be searched by name alone.- A populated
error, an unavailable source, or a partial-scope warning prevents treating the response as full coverage. confirmed_hits,potential_hits,weak_hits, andbest_match_classhelp explain the quality of evidence per source.
5. Requesting QSA
QSA is an internal enrichment returned by the same Screening call. To request it, the consumer adds these fields to the POST /v1/screening body:
{
"name": "EMPRESA ALFA LTDA",
"cnpj": "12345678000190",
"groups": ["national", "sanctions"],
"advanced": true,
"ownership_depth": 3
}
ownership_depth can range from 1 to 8 and requires advanced: true plus a CPF or CNPJ. QSA does not run at depth 0.
6. What a QSA level represents
A level is a full round of ownership expansion, not a fixed alternation between companies and partners.
| Depth | Expected result |
|---|---|
0 | QSA not requested. |
1 | Direct links of the queried subject. |
2 | Expansion of all new individuals and companies found at level 1. |
3 | Expansion of all new entities from level 2. |
4 to 8 | Repetition of the same rule for the previous round. |
CPF root
Queried individual
└── level 1: companies where the individual is a partner
└── level 2: partners of those companies and companies they hold
└── level 3: expansion of the new entities from level 2
CNPJ root
Queried company (level 0)
├── level 1: its partners
├── level 1: companies it also holds a stake in
└── level 2: expansion of the new individuals and companies from level 1
└── level 3: expansion of the new entities from level 2
Level measures expansion distance, not risk, ownership share, or control. A level-3 entity can be more severe than a level-1 one, and vice versa.
7. How to read a multi-level response
{
"ownership_network": {
"status": "FOUND",
"queried_cnpj_root": "12345678",
"requested_depth": 3,
"reached_depth": 3,
"billable_depth": 3,
"total_companies": 4,
"companies": [
{
"cnpj_root": "12345678",
"legal_name": "EMPRESA CONSULTADA LTDA",
"level": 0,
"partners": [
{
"level": 1,
"name": "ANA EXEMPLO",
"party_type": "PF",
"role": "SOCIO-ADMINISTRADOR"
}
]
},
{
"cnpj_root": "87654321",
"legal_name": "HOLDING ALFA LTDA",
"level": 1,
"originating_partner_name": "EMPRESA CONSULTADA LTDA",
"screening": {
"risk_level": "CLEAR",
"identity_class": "NO_MATCH",
"recommendation": "APPROVE"
}
},
{
"cnpj_root": "11223344",
"legal_name": "BETA PARTICIPACOES LTDA",
"level": 2,
"originating_partner_name": "ANA EXEMPLO",
"screening": {
"risk_level": "MEDIUM",
"identity_class": "TRUE_MATCH",
"recommendation": "REVIEW",
"actionable_hits_count": 1
}
},
{
"cnpj_root": "55667788",
"legal_name": "GAMMA INVESTIMENTOS LTDA",
"level": 3,
"originating_partner_name": "BETA PARTICIPACOES LTDA",
"screening": {
"risk_level": "HIGH",
"identity_class": "TRUE_MATCH",
"recommendation": "REJECT",
"actionable_hits_count": 1
}
}
]
}
}
The client should analyze each company.screening and each company.partners[].screening as a conclusion about that related entity.
| Result on a related entity | Recommended handling |
|---|---|
CLEAR + NO_MATCH | No actionable match on that entity, within the derived scope queried. |
MEDIUM, POTENTIAL_MATCH, or requires_edd: true | Flag the network for human review. |
HIGH + TRUE_MATCH | Flag high risk in the network; block, escalate, or require approval per the client's policy. |
PARTIAL, ERROR, hits_truncated, or a limit warning | Do not consider that entity's or the network's analysis complete. |
In the example above, the main result can remain CLEAR, but the client should display something like:
Main subject: no actionable match.
Ownership network: high risk found at level 3 in GAMMA INVESTIMENTOS LTDA.
Next action: compliance review of the ownership network.
This preserves the truth of the contract: direct risk and relationship risk are not the same statement.
Recommended presentation
Grouping the list by level is safer than trying to draw an exact legal tree:
Ownership network — 3 of 3 levels completed
Level 0
• EMPRESA CONSULTADA LTDA
Level 1 — direct links
• ANA EXEMPLO — managing partner
• HOLDING ALFA LTDA — no actionable match
Level 2 — links of the related entities
• BETA PARTICIPAÇÕES LTDA — review required
Level 3 — additional expansion
• GAMMA INVESTIMENTOS LTDA — confirmed high risk
companies is a flat list. originating_partner_name indicates through which partner the company was found, but the contract does not include a parent-company or edge identifier. So matching names can make a graphical tree ambiguous. The interface should prefer the phrasing "found at level X via Y."
8. Completeness, limits and QSA cost
{
"ownership_network": {
"requested_depth": 3,
"reached_depth": 2,
"warnings": ["The ownership entity limit was reached."],
"derived_screening": {
"entities_processed": 100,
"unique_entities": 98,
"relationships_found": 156,
"entity_limit": 100,
"interpol_excluded": true
},
"billing": {
"base_groups": ["national", "sanctions"],
"base_group_cost": 2,
"billable_depth": 2,
"ownership_tokens": 4,
"interpol_excluded": true
}
}
}
| Field | Interpretation |
|---|---|
requested_depth | Depth requested in the request. |
reached_depth | Highest round actually reached. Can be lower than requested if there were no new links. |
warnings | If there is a limit or unavailability warning, the network should not be treated as complete. |
billable_depth | Depth actually used for billing. |
derived_screening | Risk-analysis metrics for the related entities. |
entities_processed / unique_entities | Processed volume and volume after deduplication. |
relationships_found | Ownership links found. |
entity_limit | Operational limit that protects against excessively large networks. |
interpol_excluded | INTERPOL does not take part in the QSA-derived analysis. |
billing.ownership_tokens | Token component for the ownership expansion. |
When QSA runs, the minimum billable depth is 1, even with no links found. Expansion cost is based on the source group cost and the effectively billable depth. If QSA is unavailable, the main query can still proceed; in that case, treat the ownership block as unavailable and follow the returned warnings and billing.
9. Dossier and audit trail
dossier organizes the main subject's evidence for audit purposes:
{
"dossier": {
"audit_trail": {
"api_version": "v1",
"timestamp_utc": "2026-08-04T12:15:18Z",
"groups_checked": ["national", "sanctions"],
"tokens_charged": 6
},
"decision": {
"risk_level": "MEDIUM",
"identity_class": "POTENTIAL_MATCH",
"recommendation": "REVIEW"
},
"regulatory_taxonomy": {
"by_category": {
"Politically Exposed Person (PEP)": 1
},
"risk_by_category": {
"Politically Exposed Person (PEP)": "MEDIUM"
}
},
"proof_of_compliance": {
"status": "RECORDED",
"ledger_ref": "SCR-20260804-ABC123",
"hash": "..."
}
}
}
The dossier should not be used to recompute the decision: it is an auditable presentation of decision, detailed_hits, taxonomy, and billing evidence.
10. Summarized result for the client interface
An application can display its own summary, as long as it preserves the original response for audit purposes:
{
"screening_completeness": "COMPLETE",
"direct_subject": {
"risk": "CLEAR",
"identity": "NO_MATCH",
"recommendation": "APPROVE",
"actionable_hits": 0
},
"ownership_network": {
"status": "FOUND",
"requested_depth": 3,
"reached_depth": 3,
"related_entities_with_actionable_hits": 2,
"highest_related_risk": "HIGH"
},
"next_action": "MANUAL_REVIEW"
}
related_entities_with_actionable_hits, highest_related_risk, and next_action are examples of fields computed by the client application. They do not replace the official fields returned by the API.
11. Implementation checklist
- Validate
statusbefore consuming any recommendation. - Treat
risk_levelandidentity_classas independent axes. - Display
noticesand log the full response. - Do not confuse the direct result with the ownership network's risk.
- Evaluate every
company.screeningandpartners[].screeningin QSA. - Show
requested_depth,reached_depth, warnings, and network limits. - Flag that INTERPOL is excluded from the QSA-derived analysis.
- Use
tokens_charged,token_balance,billing, andproof_of_compliancefor traceability. - Never infer that a source was queried just because there are no hits; use
sources_checked.
See it working
The five most common calls — health, sources, balance, screening (with and without a hit), and statement — running live, side by side, on the See it working page.
Sign in