Skip to main content
This guide helps you migrate an existing integration from the legacy KYC screening endpoint to the current v2 API. The v2 API keeps the same screening engine and list coverage, but standardizes the request/response envelope, authentication, and identifier matching so integrations are simpler and more predictable.
The screening logic, watchlists, and matching quality are the same across both versions. Migration is almost entirely about how you authenticate and how you read the response — the request body is largely backward compatible.

Why migrate

Standard response envelope

Every endpoint now returns a consistent status + payload + execution_context structure, so error handling and parsing are uniform across the platform.

Unified authentication

A single Authorization: Bearer scheme (API key or JWT) replaces the legacy per-endpoint auth, with role-based permissions.

Value-first identifier matching

Document and ID matching now keys on the value, not the document-type label — you no longer need to send the exact document_type to get an exact ID hit.

Multi-list in one call

Screen against many lists in a single request with a consolidated summary and per-list results.

At a glance

Migration in 5 steps

1

Switch the base URL and endpoint

Point your client at https://stg.kyc.legaltalent.ai/kyc for integration testing, then https://kyc.legaltalent.ai/kyc for production. The method stays POST.
2

Switch to Bearer authentication

Replace the legacy credential with an Authorization: Bearer header using your API key (sk_...) or a JWT. See Authentication. You no longer pass tenant_id in the body — it is derived from the token.
3

Keep your request body (with minor tweaks)

The subject object is backward compatible. If you used match_type, send search_type instead. Accepted values: exact, fuzzy, token, composite, fast_precise_cascade (default). The legacy default was composite — send it explicitly if you want to preserve the previous matching behavior. Lists move from lists_to_check to lists.
4

Update your response parser

Read results from the new envelope: result (single list) or results keyed by list name plus summary (multi-list), and execution_context.request_id for the correlation id. There is no data or meta wrapper. See the field mapping below.
5

Re-point your risk/decision logic

The v2 response does not return an aggregate risk level or recommended action. Use matches[].confidence_score for per-match intensity and is_match / summary.match_count for the decision, deriving your own risk level from the score (see Risk and decisioning).

Authentication

The legacy integration used a dedicated credential on the legacy gateway. The v2 API uses a single Bearer scheme for both user (JWT) and machine-to-machine (API key) access.
POST /kyc requires the kyc:create permission. The token also scopes the request to your tenant, so remove any tenant_id you previously sent in the request body.

Request changes

The request body is largely unchanged. The main adjustments:

Identifier matching improvement

In v2, identifier matching is value-first: an exact ID/document number matches a list entry regardless of how the document-type label is named on either side (CI, DNI, National ID, document_id, numeric id, etc.). Values are normalized (non-alphanumeric characters stripped, case-insensitive) before comparison.
Country (nationality) and birth_date behave the same as before: they refine name-based matches (and can lower confidence on a mismatch). They never affect an exact identifier match, which always returns confidence_score: 1.0.

Response changes

The biggest change is the envelope. Below is the same multi-list screening in both formats, side by side.

Field mapping

Single-list responses (using list_name) return the result under a top-level result object and have no summary. Multi-list responses (using lists, or omitting both) return results keyed by list name plus an aggregate summary. In multi-list responses each match also carries a source_list field. There is no data or meta wrapper. See List Check for full schemas.

Risk and decisioning

The v2 API returns the raw matching signal and leaves the risk classification to you. There is no overall_risk_level, recommended_action, or per-match risk_level in the response.
  • Per match — confidence_score (0.0–1.0): the intensity of an individual hit. An exact identifier match is always 1.0. Name matches are scored by the search engine and refined by nationality / birth_date.
  • Aggregate — summary.is_match / summary.match_count / summary.lists_with_matches: whether anything matched, how many, and on which lists.
If your legacy integration read per-match risk_level or an aggregate overall_risk_level, derive your own level from confidence_score using thresholds that fit your risk appetite:
The thresholds above mirror the platform defaults, but you own the final decision policy (block / review / proceed). Tune the cutoffs to your compliance requirements.

Error handling

Errors also move into the standard envelope.
See List Check → Error Responses and Authentication → Error Responses for the full catalog.

Migration checklist

1

Update endpoint and base URL

POST /kyc on the staging host first.
2

Move to Bearer auth

Use an API key or JWT; drop the legacy credential and any body-level tenant_id.
3

Rename match_type → search_type and lists_to_check → lists

Send "search_type": "composite" to keep the legacy default behavior.
4

Re-map the response

Read result (single) or results + summary (multi); switch has_matches → is_match, matched_entity → match_data, job_id → execution_context.request_id. Drop any data / meta access.
5

Re-point risk logic

Derive your own risk level from matches[].confidence_score; the v2 response has no overall_risk_level / recommended_action.
6

Update error handling

Branch on status and read error.type / error.message; handle 401 / 403.
7

Validate on staging, then cut over

Run representative cases against staging, compare to legacy output, then switch the production base URL.

FAQ

Minimally. The subject object is backward compatible. The only common changes are renaming match_type to search_type and removing any tenant_id from the body.
Yes — the screening engine and lists are the same. Identifier matching is more forgiving (value-first), so you may see exact ID hits that previously required the correct document_type. Name-based scoring is unchanged.
The v2 response does not return a risk level — neither per match nor aggregate. Each match exposes confidence_score (0.0–1.0); derive your own level from it and apply your decision policy. Use summary.is_match / summary.match_count for the overall outcome.
Yes. Point a copy of your traffic at the v2 staging endpoint, compare outputs, and cut over once parity is confirmed. There is no forced switch on the request side.
You need a v2 API key (or JWT) for Bearer auth. Contact your account administrator to provision an API key with the kyc:create permission.

Next steps

List Check reference

Full v2 request/response schemas, lists, and examples.

Authentication

Bearer tokens, API keys, and the permission model.

API Overview

Environments, rate limits, and platform basics.

Validate a Person or Entity

End-to-end screening walkthrough on v2.