curl --request POST \
--url https://app.sahlfinancial.com/api/v1/kyc/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reference": "client-0001",
"environment": "sandbox",
"subject": "Test Client",
"kind": "individual",
"values": {
"first_name": "Test",
"last_name": "Client"
},
"documents": [],
"require_documents": false
}
'{
"passed": true,
"checks": [
{
"id": "legible:national_id",
"label": "national_id — key fields readable",
"severity": "warning",
"passed": true,
"detail": ""
},
{
"id": "expiry:national_id",
"label": "national_id — not expired",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "format:cin:national_id",
"label": "national_id — CIN number is well-formed",
"severity": "warning",
"passed": true,
"detail": ""
},
{
"id": "adult:national_id",
"label": "national_id — holder is 18+",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "required:photo_id",
"label": "Document establishing the account holder provided",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "expiry:recorded:id_expiry",
"label": "The identity document on file is not expired",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "screening",
"label": "Sanctions screening — no matches; PEP not list-screened",
"severity": "info",
"passed": true,
"detail": "screened against 23000 sanctions entries. The bundle carries no PEP list, so politically-exposed status rests on the client's declaration, not on a list check."
},
{
"id": "completeness",
"label": "KYC/KYB data completeness (61%)",
"severity": "warning",
"passed": false,
"detail": "missing 11 required data point(s): street1, city, province, postal_code, phone, email, source_of_funds, account_type"
}
],
"critical_failures": [],
"flags": [
{
"id": "completeness",
"label": "KYC/KYB data completeness (61%)",
"severity": "warning",
"passed": false,
"detail": "missing 11 required data point(s): street1, city, province, postal_code, phone, email, source_of_funds, account_type"
}
],
"completeness": {
"required": 28,
"present": 17,
"missing": [
"street1",
"city",
"province",
"postal_code",
"phone",
"email",
"source_of_funds",
"account_type",
"third_party",
"sin/ssn",
"pep_foreign/pep_domestic/pep_hio/pep"
],
"percent": 61
},
"policy": {
"id": null,
"version": 0,
"source": "legacy",
"regime": "none",
"regulator": null,
"purpose": "onboarding",
"overrides_refused": []
},
"registry": null,
"case_id": "00000000-0000-4000-8000-000000000001"
}{
"detail": "Invalid or revoked API key"
}{
"detail": {
"code": "kyc_scope_not_allowed",
"message": "This workspace is not enabled for the partner KYC API."
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"code": "rate_limit_exceeded",
"message": "Too many requests. Please slow down."
}{
"code": "internal_error",
"message": "An unexpected error occurred",
"details": null
}Verify a profile
Required scope: kyc:verify.
The full verification verdict for a profile and its documents.
Guide: Verify a profile.
curl --request POST \
--url https://app.sahlfinancial.com/api/v1/kyc/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reference": "client-0001",
"environment": "sandbox",
"subject": "Test Client",
"kind": "individual",
"values": {
"first_name": "Test",
"last_name": "Client"
},
"documents": [],
"require_documents": false
}
'{
"passed": true,
"checks": [
{
"id": "legible:national_id",
"label": "national_id — key fields readable",
"severity": "warning",
"passed": true,
"detail": ""
},
{
"id": "expiry:national_id",
"label": "national_id — not expired",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "format:cin:national_id",
"label": "national_id — CIN number is well-formed",
"severity": "warning",
"passed": true,
"detail": ""
},
{
"id": "adult:national_id",
"label": "national_id — holder is 18+",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "required:photo_id",
"label": "Document establishing the account holder provided",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "expiry:recorded:id_expiry",
"label": "The identity document on file is not expired",
"severity": "critical",
"passed": true,
"detail": ""
},
{
"id": "screening",
"label": "Sanctions screening — no matches; PEP not list-screened",
"severity": "info",
"passed": true,
"detail": "screened against 23000 sanctions entries. The bundle carries no PEP list, so politically-exposed status rests on the client's declaration, not on a list check."
},
{
"id": "completeness",
"label": "KYC/KYB data completeness (61%)",
"severity": "warning",
"passed": false,
"detail": "missing 11 required data point(s): street1, city, province, postal_code, phone, email, source_of_funds, account_type"
}
],
"critical_failures": [],
"flags": [
{
"id": "completeness",
"label": "KYC/KYB data completeness (61%)",
"severity": "warning",
"passed": false,
"detail": "missing 11 required data point(s): street1, city, province, postal_code, phone, email, source_of_funds, account_type"
}
],
"completeness": {
"required": 28,
"present": 17,
"missing": [
"street1",
"city",
"province",
"postal_code",
"phone",
"email",
"source_of_funds",
"account_type",
"third_party",
"sin/ssn",
"pep_foreign/pep_domestic/pep_hio/pep"
],
"percent": 61
},
"policy": {
"id": null,
"version": 0,
"source": "legacy",
"regime": "none",
"regulator": null,
"purpose": "onboarding",
"overrides_refused": []
},
"registry": null,
"case_id": "00000000-0000-4000-8000-000000000001"
}{
"detail": "Invalid or revoked API key"
}{
"detail": {
"code": "kyc_scope_not_allowed",
"message": "This workspace is not enabled for the partner KYC API."
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"code": "rate_limit_exceeded",
"message": "Too many requests. Please slow down."
}{
"code": "internal_error",
"message": "An unexpected error occurred",
"details": null
}Authorizations
API key created in the console. Scopes: kyc:extract, kyc:verify, kyc:eid; bank:read, bank:write (Growth plan, enabled per workspace by Sahl).
Body
A profile and the per-file extractions that back it.
Your own id for the client (see /extract). With one, the verdict is filed on the case for (workspace, environment, reference) and the answer carries case_id. Documents whose document_id came from /extract are linked to it.
1 - 64^[A-Za-z0-9_.:-]+$sandbox (default) or production.
sandbox, production Client name (a person) or legal name (an entity), for the case. Up to 255 characters.
255The client profile, as an object of field keys to values: names, date_of_birth, address, id_type, id_number, id_expiry, occupation, income and the other data points. Unknown keys are ignored.
The documents entries that /extract returned, sent back unchanged.
Client kind: individual, corporation, partnership, charitable_org, trust, estate (aliases: entity, business, kyb, charity, fiducie, societe, succession). Decides which document establishes the account holder. Null falls back on entity.
True for a business (KYB). Used when kind is null.
Ask for the identity document. False is honoured only while the workspace policy does not lock identity verification, or on a periodic review. A refused switch is listed in policy.overrides_refused.
Sanctions screening of every party on the file. False is honoured only while the policy does not lock the sanctions screen.
Extra Canadian AML and PEP screening for a Canadian client. Null means the workspace policy decides. It needs eID provider credentials on the workspace.
Checks only you can run (a duplicate client, your own blocklist). They are added to the verdict and can block it. An id starting eid: or policy: comes back prefixed partner:.
Show child attributes
Show child attributes
onboarding (default) or periodic_review. A review does not re-verify identity; screening and every other lock still apply.
onboarding, periodic_review Response
OK
True when no critical check failed. Warnings do not change it.
Show child attributes
Show child attributes
Checks with passed: false and severity critical.
Show child attributes
Show child attributes
Everything that needs a person: failed critical and warning checks.
Show child attributes
Show child attributes
How many of the required data points for this client kind are present in values. The completeness check is a warning below 80 percent.
Show child attributes
Show child attributes
Which workspace policy the call ran under, and which request switches it refused.
Show child attributes
Show child attributes
What Corporations Canada lists for a federal (CBCA) corporation, normalised. Null when the registry was not consulted or the corporation was not found.
Only with a reference.