# Create a Session Source: https://documentation.idenfy.com/age-estimation/create-session Create an age estimation session with the iDenfy Partner API: request auth, token response, and the insufficient funds error to handle. **Requirements:** * **API key pair** (API key + secret) * **Age Estimation** feature enabled on your contract (contact iDenfy to activate) * **Finances** available for Age Estimation For how the feature works, what each outcome means, and how billing works, see the [Age Estimation Overview](/guides/dashboard/age-estimation/overview) guide. This documentation focuses on the API integration. ## Create a Session Authenticate with your **API key pair** — API key as the username, API secret as the password, over HTTP Basic. Sessions are scoped to your partner account, so you only ever see your own. For the full request and response schemas, every field's constraints and defaults, and an interactive playground, see the [**API Reference**](/api-reference/age-estimation/create-session) page for this endpoint. Creating a session pre-checks your [Age Estimation finances](/guides/dashboard/age-estimation/billing); if they can't cover the session the request is rejected -- see [Errors](#errors). ### Example (Partner API) ```http theme={"system"} POST /age-estimation/token/ Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json { "min_age": 18, "confidence_threshold": 85, "buffer": 2, "escalation": "DOC", "save_photo": true, "expiry_minutes": 60, "success_redirect": "https://partner.example.com/ok", "underage_redirect": "https://partner.example.com/denied", "webhook_url": "https://partner.example.com/hooks/age", "client_id": "user-42" } ``` ```json theme={"system"} { "token": "b7c1…", "session_url": "https://capture.idenfy.example/?token=b7c1…", "expires_at": "2026-07-14T12:00:00+00:00", "min_age": 18, "confidence_threshold": 85.0, "buffer": 2, "escalation": "DOC", "retry_limit": 3, "save_photo": true, "expiry_minutes": 60, "client_id": "user-42" } ``` *** ## Errors | Status | Message | When | | ------ | -------------------------------------------------------------- | ------------------------------------------------ | | `402` | `"Action not allowed due to lack of funds or exceeded limit."` | Age Estimation finances cannot cover the session | The response body identifies which finances are short: ```json theme={"system"} { "message": "Action not allowed due to lack of funds or exceeded limit.", "code": "insufficient_finances", "detail": { "detail": "Action not allowed due to lack of funds or exceeded limit.", "missing_limits": [], "missing_additional_step_limits": [], "missing_funds": null, "missing_pool_funds": [ { "fund_pool": "AGE_ESTIMATION", "missing": 3.0 } ], "expired_expenses": [] } } ``` When handling this response: * Read `missing_pool_funds` to identify which finances are short. The response uses `fund_pool` naming for what the guides call Age Estimation finances. * `missing_funds` stays `null` -- it covers general funds only, so **do not** read it to detect exhausted Age Estimation finances. * `missing` is the shortfall in your account currency, and `0` when no Age Estimation finances are configured. Insufficient funds return **`402`**, not `403`. This matches iDenfy's other token-creation endpoints -- see [ID Error Messages](/kyc/id-error-messages#post-apiv2token-errors). `403` is reserved for an account that lacks access to the endpoint or feature. *** ## What's Next Once you have a `session_url`, send the end user to it to complete the selfie capture. When the session finishes, the result is delivered via the [result webhook](/age-estimation/webhooks) — this is the only way to receive it programmatically, so configure one. Past sessions can be listed and inspected by signing in to the dashboard; see [Session List](/guides/dashboard/age-estimation/dashboard#session-list). # Age Estimation Webhooks Source: https://documentation.idenfy.com/age-estimation/webhooks Receive age estimation results via HTTP POST webhook callbacks from iDenfy with signed payloads, per-session URL overrides, and idempotent delivery. When a session reaches a terminal state, a result notification is sent to your endpoint. ## Where It's Sent iDenfy resolves the destination in this order: 1. The token's `webhook_url`, if set (per-session override). 2. Otherwise, the webhook URL configured on your account's **Age Estimation** notification (notification event type `AGE_ESTIMATION`) -- this is the default used when a token has no `webhook_url`. 3. If neither is configured, no notification is sent. The result is then only visible in the dashboard -- there is no Partner API endpoint for retrieving sessions, so configure a webhook if you need the result in your own systems. If your Age Estimation notification is configured with a signing key, the webhook body is signed so you can verify authenticity. See [Callback Signing](/security/callback-signing). ## Payload For the full payload schema and every field's type, see the [**API Reference**](/api-reference/webhooks/age-estimation-result) page for this webhook. Only two statuses are ever delivered -- `COMPLETED` and `FAILED`. For what the accompanying `outcome` means, see [Statuses and Outcomes](/guides/dashboard/age-estimation/overview#statuses-and-outcomes). The `estimatedAge` reported is the established age: when a document step-up produced an age, that exact document age is used; otherwise it is the AI face-estimated age. `scanRef` carries the step-up scan reference, or the token id when there is no scan ref. The notification does not distinguish a document that was accepted cleanly from one that was accepted but flagged for possible fraud -- both report the same outcome. ## Idempotency Delivery may be retried, so handle notifications idempotently (e.g. keyed on `scanRef` / `clientId`). # Create AML Profile Source: https://documentation.idenfy.com/aml/create-profile Learn how to run a single AML check against a person or company using the iDenfy API, including request parameters and response handling. **Requirements** * **API** key pair * Services **enabled** on your environment (done by iDenfy staff) * Credits **for each** service used ## AML Check Flow AML check and profile flow For definitions of match types, datasets, and result fields, see [AML Key Terms and Concepts](/guides/dashboard/aml/aml-key-terms-concepts). ## Create AML Check For full request and response schemas, see the [**API Reference**](/api-reference/aml-checks/create-aml-check). Use the AML check creation endpoint to screen a person or company. The API will return matched profiles from sanctions, PEPs, and adverse media databases based on your configured filters. `companyName` accepts up to **200 characters**, matching the limit used for company names in [business verification](/kyb/overview). Longer values are rejected with a validation error. # AML Dummy Results Source: https://documentation.idenfy.com/aml/dummy-results Test your AML screening integration with predefined dummy entities for sanctions, PEPs, and adverse media checks in the iDenfy sandbox environment. **Requirements** * **API** key pair * **Development** environment * Test **credits** *** When integrating AML services, you can use the entities below to trigger suspected results: | Trigger Type | Name/Value to Use | | ------------- | ----------------- | | Company | `GoPayments` | | Person | `Manfred Weber` | | Adverse Media | `Cliff Hazard` | The **Development** environment is only meant for **integration** testing. Checking other entities **might not** return results. # AML Migration Guide Source: https://documentation.idenfy.com/aml/migration-guide Migrate your AML Monitoring integration from v2 to v3, with breaking changes, endpoint mapping, and step-by-step upgrade guidance. ## Overview iDenfy introduced AML Monitoring v3 with an upgraded screening engine. **Existing v2 integrations continue to work** — the API automatically handles backward compatibility and your webhooks will look exactly as they always have. There is no announced shutdown date for v2 compatibility. However, the mapping layer exists for continuity, not as a permanent solution. We recommend planning migration to v3 to ensure long-term stability and access to the full capabilities of the screening engine. This guide covers: * What changed between v2 and v3 * Request body field changes with examples * The complete webhook payload reference * The recommended migration path and a complete migration checklist *** ## What Changed | Event | Status transition | | -------------------------- | ------------------------------- | | Initial screening complete | `PENDING` → `ACTIVE` or `ALERT` | | New match found | → `ALERT` | | Match resolved | → `ACTIVE` | ### Status Field Names v3 introduced a new `status` field with updated values. The existing `alertStatus` field continues to return v2 values for all integrations. | v2 (`alertStatus`) | v3 (`status`) | | ------------------ | ------------- | | `ACCEPTED` | `ACTIVE` | | `ALERT` | `ALERT` | | `DECLINED` | `STOPPED` | | `PENDING` | `PENDING` | Both fields are present in all webhook payloads. If you are on v2, use `alertStatus` and ignore `status`. ### Request Body Fields When migrating to v3 endpoints, the request body structure changes. v3 uses a nested structure — a top-level object wrapping an `amlCheck` object with separate `input` (who to screen) and `filter` (what to screen for) sub-objects. **Person monitoring:** | Area | v2 field | v3 field | Notes | | ------------- | --------------------------- | ---------------------------- | ------------------------------------ | | First name | `name` | — | Combined into `fullName` | | Last name | `surname` | — | Combined into `fullName` | | Full name | — | `amlCheck.input.fullName` | Single combined field | | Subject type | `type: "PERSON"` | `userType: "PERSON"` | Renamed | | Date of birth | `dateOfBirth` | `amlCheck.input.dateOfBirth` | Moved into nested input | | Nationality | `nationality` | `amlCheck.input.nationality` | Moved into nested input | | Gender | — | `amlCheck.input.sex` | New optional field: `M`, `F`, or `O` | | Adverse media | `monitorAdverseMedia: true` | — | Legacy feature, not supported in v3 | | Auto-renewal | `autoExpirationExtension` | `isSubscribed` | Renamed, same boolean behavior | **Company monitoring:** | Area | v2 field | v3 field | Notes | | ------------ | ----------------- | ---------------------------- | ------------------ | | Company name | `name` | `amlCheck.input.companyName` | Renamed and nested | | Subject type | `type: "COMPANY"` | `userType: "COMPANY"` | Renamed | | Country | `nationality` | `amlCheck.input.country` | Renamed and nested | The `name` + `surname` → `fullName` change is the most common cause of silent failures. If you send `name` and `surname` separately to a v3 endpoint, the fields are ignored and the check runs with no name. **Example v3 request body (person):** ```json theme={"system"} { "userType": "PERSON", "isSubscribed": true, "tags": [], "amlCheck": { "input": { "fullName": "John Doe", "nationality": "GBR", "dateOfBirth": "1980-01-15", "sex": "M" }, "filter": { "datasets": ["PEP", "SAN"] } } } ``` ### Datasets v3 lets you control which screening databases to check via the `amlCheck.filter.datasets` array. This replaces the implicit fixed set from v2, where adverse media was a separate boolean toggle. | Dataset | Description | | ------------- | --------------------------------------------------------------------- | | `PEP` | All PEP tiers — shorthand that expands to current, former, and linked | | `PEP-CURRENT` | Active politically exposed persons | | `PEP-FORMER` | Former PEPs | | `PEP-LINKED` | Associates and family members of PEPs | | `SAN` | All sanctions — shorthand for current and former | | `SAN-CURRENT` | Active sanctions | | `SAN-FORMER` | Expired or lifted sanctions | `datasets` is required. Omitting it will result in a validation error. Specify at least one dataset value from the table above. ### False Positive Handling v2 and v3 handle false positives differently — there is no direct 1:1 equivalent endpoint. * **v2** (`POST /api/v2/add-whitelist`) marked an entire monitoring subject as whitelisted using their `monitoringId`. * **v3** (`DELETE /aml/monitorings/{id}/profiles/{profileId}/`) removes a specific matched profile from the results, leaving the monitoring record and any other matches intact. The v3 approach is more granular — you dismiss individual matches rather than the whole subject. The `profileId` is returned inside each match entry in the monitoring response and webhook payload. Store or pass through this ID in your integration to support false positive dismissal. *** ## Webhook Reference Both v2 and v3 send the same webhook payload structure. v3 adds the `status` field and an optional `amlCheck` object — both can be safely ignored if you have not yet migrated. ### Headers | Header | Value | | ------------------- | ------------------------------------------------------------------- | | `Idenfy-Event-Type` | `AML_MONITORING` | | `Content-Type` | `application/json; charset=utf-8` | | `User-Agent` | `iDenfy/1.0` | | `Idenfy-Signature` | HMAC-SHA256 signature — only present if a signing key is configured | ### Payload Fields If you are on v3, use the `amlCheck` object from the webhook payload for all screening results. The top-level fields below exist only for backward compatibility with v2 integrations and should not be relied on in new or migrated integrations. **Top-level (v2 compatibility fields):** | Field | Type | Description | | -------------------- | -------------- | ---------------------------------------------------------- | | `monitoringId` | string (UUID) | Unique identifier for this monitoring record | | `name` / `surname` | string | Subject's name | | `nationality` | string | ISO country code | | `dob` | string \| null | Date of birth | | `isActive` | boolean | Whether monitoring is still running | | `expiration` | string | Monitoring expiry date | | `alertStatus` | string | v2 status: `ACCEPTED`, `ALERT`, `DECLINED`, `PENDING` | | `status` | string | v3 status: `ACTIVE`, `ALERT`, `STOPPED`, `PENDING` | | `pepsStatus` | string | `NOT_CHECKED`, `FLAGS_FOUND`, `FALSE_POSITIVE`, or `CLEAR` | | `sanctionsStatus` | string | Same values as `pepsStatus` | | `adverseMediaStatus` | string | Same values as `pepsStatus` | | `results[]` | array | Per-category check results (see below) | **`amlCheck` — v3 screening results (use this on v3):** The `amlCheck` array contains the full World-Check screening output, with one entry per matched profile and a `datasets` list on each. Every entry carries a `resourceId`, which you pass as the `profileId` path parameter to retrieve the profile or dismiss it as a false positive. Refer to the [API Reference](/api-reference/aml-checks/create-aml-check) for the complete schema. **`results[]` — v2 compatibility, per-category check:** | Field | Type | Description | | ---------------------- | ------ | ---------------------------------------- | | `serviceName` | string | Name of the check that ran | | `serviceGroupType` | string | Category, e.g. `AML_NAMES_CHECK` | | `status.overallStatus` | string | `SUSPECTED`, `NOT_SUSPECTED`, or `ERROR` | | `data[]` | array | Matched profiles (see below) | **`data[]` — matched profile:** | Field | Type | Description | | ------------------ | -------------- | ------------------------------------------------ | | `listName` | string | `PEPS` or `SANCTION` | | `name` / `surname` | string | Matched entity's name | | `nationality` | string | Matched entity's nationality | | `dob` | string \| null | Matched entity's date of birth | | `score` | integer | Match confidence (0–100) | | `pepLevel` | integer | PEP tier 1–4 (present for PEP matches only) | | `category` | string | e.g. `Head of Government` | | `reason` | string | Why this entity is listed | | `whitelisted` | boolean | Whether you have marked this as a false positive | | `isActive` | boolean | Whether the entity is still active on the list | *** ## Migrating to v3 ### AML Single Check Flow Use `POST /aml/checks/` to screen a subject once without ongoing monitoring. Submit a person or company for screening. The response includes a check ID and any matched profiles. `POST /aml/checks/` — Screen a subject against sanctions, PEPs, and adverse media. Matches are returned in the `amlCheck` and `adverseMedia` arrays. Each entry contains a `resourceId` you can use in the next step. Use the check `id` and the match's `resourceId` from the previous response to fetch the complete profile record — all sanctions entries, PEP tiers, and adverse media sources, regardless of the filters applied during the check. `GET /aml/checks/{id}/profiles/{profileId}/` — Fetch full profile detail for a specific match. Profile data is not filtered by the check's configured datasets. Retrieve the full profile to see all available information for a matched entity. *** ### AML Monitoring Flow Monitoring is continuous screening — the system re-screens the entity daily and sends webhooks whenever status changes. Register a person or company for ongoing daily screening. The response returns a `monitoringId` used in all subsequent calls. `POST /aml/monitorings/` — Start ongoing screening with automatic status change alerts. Use `PATCH /aml/monitorings/{id}/` to extend the monitoring period or attach organizational tags. The system fires an `AML_MONITORING` webhook each time the screening status changes. See the [Webhook Reference](#webhook-reference) above for the full payload and delivery details. Poll the monitoring record at any time to get the current status and latest results — useful for reconciling state if a webhook was missed. `GET /aml/monitorings/{id}/` — Fetch a single monitoring record. `GET /aml/monitorings/` — List all monitoring records. Pause, resume, or remove monitoring records as your compliance requirements change. `POST /aml/monitorings/{id}/stop/` or `/start/` — Pause or resume without deleting. `DELETE /aml/monitorings/{id}/` — Permanently remove a monitoring record. To dismiss a specific false positive match without stopping monitoring, use `DELETE /aml/monitorings/{id}/profiles/{profileId}/`. See [False Positive Handling](#false-positive-handling) above for details. Export the full screening history for a monitoring record as a PDF for audit trails and compliance records. `POST /aml/monitorings/{id}/pdf/` — Download a full-history PDF report. *** ## Complete Migration Checklist Use this as a final review before cutting over to v3. **API endpoints:** | v2 endpoint | v3 endpoint | | -------------------------------------- | ------------------------------------------------------------------------------ | | `POST /api/v2/add-aml-user` | `POST /aml/monitorings/` | | `POST /api/v2/get-monitoring-callback` | `GET /aml/monitorings/{id}/` | | `POST /api/v2/get-aml-users` | `GET /aml/monitorings/` | | `POST /api/v2/delete-monitoring-user/` | `DELETE /aml/monitorings/{id}/` | | `POST /api/v2/generate-pdf-aml` | `POST /aml/monitorings/{id}/pdf/` | | `POST /api/v2/add-whitelist` | No direct equivalent — see [False Positive Handling](#false-positive-handling) | **Request body — persons:** * Combine `name` + `surname` → `amlCheck.input.fullName` * Rename `type: "PERSON"` → `userType: "PERSON"` * Move `nationality` → `amlCheck.input.nationality` * Move `dateOfBirth` → `amlCheck.input.dateOfBirth` * Remove `monitorAdverseMedia` — adverse media is not supported in v3 * Rename `autoExpirationExtension` → `isSubscribed` **Request body — companies:** * Rename `name` → `amlCheck.input.companyName` * Rename `type: "COMPANY"` → `userType: "COMPANY"` * Rename `nationality` → `amlCheck.input.country` **Webhook handler:** * Read `status` instead of (or alongside) `alertStatus` * Update status value comparisons: `ACCEPTED` → `ACTIVE`, `DECLINED` → `STOPPED` * Store `profileId` from match entries if you support false positive dismissal Existing monitoring records created via v2 remain accessible. v2 and v3 records coexist in the system — your historical data is not affected by migration. # Create Monitoring Source: https://documentation.idenfy.com/aml/monitoring-create Set up ongoing AML monitoring for a person or company via the iDenfy API with automatic daily screening, alerts, and change notifications. ## Create Monitoring Set up ongoing AML monitoring for a person or company. Once created, the system will automatically screen the entity on a daily basis and notify you of any changes. For full request and response schemas, see the [**API Reference**](/api-reference/aml-monitorings/create-aml-monitoring). *** ## Update Monitoring The PATCH method allows you to add a **monitoring extension** (yearly) and add **tags** for better sorting. Use the update endpoint to extend monitoring periods or add organizational tags to existing monitoring entries. For full request and response schemas for the update operation, see the [**API Reference**](/api-reference/aml-monitorings/partially-update-aml-monitoring). # Manage Monitoring Source: https://documentation.idenfy.com/aml/monitoring-manage Update, pause, or deactivate AML monitoring profiles via the iDenfy API to manage ongoing customer due diligence and compliance screening. ## Delete Monitoring Remove a monitored entity from ongoing AML screening. Once deleted, daily checks will no longer be performed for this profile. For full request and response schemas, see the [**API Reference**](/api-reference/aml-monitorings/delete-aml-monitoring). *** ## Start and Stop Monitoring Pause or resume ongoing monitoring for a specific entity without deleting the monitoring profile entirely. For full request and response schemas, see the [**API Reference**](/api-reference/aml-monitorings/startstop-aml-monitoring). # Monitoring PDF Source: https://documentation.idenfy.com/aml/monitoring-pdf Generate downloadable PDF reports for AML monitoring entries via the iDenfy API for compliance audits and record-keeping purposes. ## Generate Monitoring PDF Report Generate a downloadable PDF report for an AML monitoring entry. This report includes the full history of screening results and is useful for compliance record-keeping and audit purposes. For full request and response schemas, see the [**API Reference**](/api-reference/aml-monitorings/generate-aml-monitoring-pdf). # Retrieve Monitoring Source: https://documentation.idenfy.com/aml/monitoring-retrieve Retrieve AML monitoring results, screening alerts, and compliance status for individual or all monitored entities via the iDenfy API endpoints. ## Retrieve Single User Retrieve the monitoring status and results for a specific monitored entity. For full request and response schemas, see the [**API Reference**](/api-reference/aml-monitorings/retrieve-aml-monitoring). *** ## Retrieve All Users List all entities currently under AML monitoring, including their current status and latest screening results. For full request and response schemas, see the [**API Reference**](/api-reference/aml-monitorings/list-aml-monitorings). # AML Screening API Source: https://documentation.idenfy.com/aml/overview Use iDenfy's AML Screening API to run sanctions, PEP, and adverse media checks against customers with single checks and ongoing monitoring. **AML v2 compatibility is maintained but not permanent.** v2 integrations continue to work while you plan migration. For long-term stability, we recommend moving to v3 endpoints. See the [Migration Guide](/aml/migration-guide) for what to change. The AML Screening API lets you run sanctions, PEP, and adverse media checks against persons and companies, and set up ongoing monitoring with automated daily alerts. ## Authentication All AML endpoints use HTTP Basic Authentication with your API key pair: ``` Authorization: Basic {base64(apiKey:apiSecret)} ``` ## Available Operations | Operation | Description | | ---------------- | --------------------------------------------------------- | | **Single Check** | Run a one-time AML check on a person or company. | | **Monitoring** | Enroll a subject for ongoing daily screening with alerts. | | **PDF Reports** | Generate compliance-ready PDF reports from check results. | ## Next Steps Screen a person or company against sanctions, PEPs, and adverse media. Enable ongoing screening with automatic alerts. Get screening results and match details. Step-by-step dashboard guide for AML. # Retrieve AML Profile Source: https://documentation.idenfy.com/aml/retrieve-profile Retrieve AML screening results and matched profiles for a completed check via the iDenfy API, including sanctions and PEP hit details. **Requirements** * **API** key pair * A previous [AML check](/aml/create-profile) that returned profiles ## AML Check Flow — Retrieve Profile AML check and profile flow For definitions of match types, datasets, and result fields, see [AML Key Terms and Concepts](/guides/dashboard/aml/aml-key-terms-concepts). Information inside profiles is not filtered by check filters. Profile information will contain all conditions and data regardless of the filters applied during the check. ## Retrieve Profile For full request and response schemas, see the [**API Reference**](/api-reference/aml-checks/retrieve-aml-check-profile). Use the profile retrieval endpoint to get detailed information about a matched AML profile, including all associated sanctions, PEP entries, and adverse media records. ``` GET https://ivs.idenfy.com/aml/checks/{id}/profiles/{profileId}/ Authorization: Basic {base64(apiKey:apiSecret)} ``` ### Path Parameters | Parameter | Description | | ----------- | ---------------------------------------------------------------------------------------- | | `id` | UUID of the AML check — the `id` returned by [`POST /aml/checks/`](/aml/create-profile). | | `profileId` | The `resourceId` of the match you want to expand, taken from the check response. | Every match in the check response carries its own `resourceId`: ```json theme={"system"} { "id": "0a1b2c3d-4e5f-6789-abcd-ef0123456789", "userType": "PERSON", "amlCheck": [ { "resourceId": "1a2b3c4d5e6f7890", "name": "Manfred Weber", "score": 92, "datasets": ["SAN_CURRENT", "PEP_CURRENT"] } ] } ``` Treat `resourceId` as an opaque string and copy it verbatim — do not parse or construct it. Matches also appear in the `adverseMedia` array, and those `resourceId` values work the same way. ### Response The response shape depends on the `userType` of the original check: a person check returns an individual profile, a company check returns a business profile. Both share the following fields. | Field | Description | | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | | `resourceId` | Identifier of this profile. Also used to [generate a profile PDF](/api-reference/aml-checks/generate-aml-check-profile-pdf). | | `version` | Increments whenever iDenfy's research team edits the profile. | | `isDeleted` / `deletionReason` | Whether the profile was withdrawn from the database, and why. | | `datasets` | Datasets this profile belongs to, e.g. `SAN_CURRENT`, `PEP_FORMER`, `RRE`. | | `sanEntries` | Sanctions, split into `current` and `former`. | | `pepEntries` | PEP listings, split into `current` and `former`, with the overall `pepTier`. | | `rreEntries` | Adverse media — Reputational Risk Exposure. | | `relEntries` | Regulatory enforcement actions. | | `poiEntries` / `insEntries` / `griEntries` | Profiles of Interest, Insolvency Register, and Gambling Risk Intelligence entries. | | `evidences` | Source documents and articles behind the entries. | | `individualLinks` / `businessLinks` | Related people and companies connected to this profile. | Individual profiles add `firstName`, `lastName`, `datesOfBirth`, `nationalities`, `isDeceased`, `ddEntries` (Disqualified Directors), and `pepByAssociationEntries`. Business profiles add `name`, `businessTypes`, `activities`, and `soeEntry` (State-Owned Enterprise). Store `version` alongside your review decision. A changed `version` means the underlying record was updated and the match may need re-review, even if nothing about your own check has changed. ## Next Steps Generate a compliance-ready PDF for a single matched profile. Enroll the subject for daily re-screening with alerts. # AML Single PDF Source: https://documentation.idenfy.com/aml/single-pdf Generate downloadable PDF reports for single AML screening checks via the iDenfy API for compliance documentation and audit trails. ## Generate PDF Report Generate a downloadable PDF report for a single AML check profile. This is useful for compliance record-keeping and audit purposes. For full request and response schemas, see the [**API Reference**](/api-reference/aml-checks/generate-aml-check-pdf). # Create session Source: https://documentation.idenfy.com/api-reference/age-estimation/create-session /openapi/age-estimation.yaml post /age-estimation/token/ Creates an age estimation session. Your Age Estimation finances are pre-checked; insufficient finances reject the request with `402`. # Create AML check Source: https://documentation.idenfy.com/api-reference/aml-checks/create-aml-check /openapi/aml.yaml post /aml/checks/ # Generate AML check PDF Source: https://documentation.idenfy.com/api-reference/aml-checks/generate-aml-check-pdf /openapi/aml.yaml post /aml/checks/{id}/pdf/ # Generate AML check profile PDF Source: https://documentation.idenfy.com/api-reference/aml-checks/generate-aml-check-profile-pdf /openapi/aml.yaml post /aml/checks/{id}/profiles/{profileId}/pdf/ # Retrieve AML check profile Source: https://documentation.idenfy.com/api-reference/aml-checks/retrieve-aml-check-profile /openapi/aml.yaml get /aml/checks/{id}/profiles/{profileId}/ # Create AML monitoring Source: https://documentation.idenfy.com/api-reference/aml-monitorings/create-aml-monitoring /openapi/aml.yaml post /aml/monitorings/ # Delete AML check profile Source: https://documentation.idenfy.com/api-reference/aml-monitorings/delete-aml-check-profile /openapi/aml.yaml delete /aml/monitorings/{id}/profiles/{profileId}/ # Delete AML monitoring Source: https://documentation.idenfy.com/api-reference/aml-monitorings/delete-aml-monitoring /openapi/aml.yaml delete /aml/monitorings/{id}/ # Generate AML Monitoring PDF Source: https://documentation.idenfy.com/api-reference/aml-monitorings/generate-aml-monitoring-pdf /openapi/aml.yaml post /aml/monitorings/{id}/pdf/ # List AML monitorings Source: https://documentation.idenfy.com/api-reference/aml-monitorings/list-aml-monitorings /openapi/aml.yaml get /aml/monitorings/ # Partially update AML monitoring Source: https://documentation.idenfy.com/api-reference/aml-monitorings/partially-update-aml-monitoring /openapi/aml.yaml patch /aml/monitorings/{id}/ # Retrieve AML monitoring Source: https://documentation.idenfy.com/api-reference/aml-monitorings/retrieve-aml-monitoring /openapi/aml.yaml get /aml/monitorings/{id}/ # Start/Stop AML monitoring Source: https://documentation.idenfy.com/api-reference/aml-monitorings/startstop-aml-monitoring /openapi/aml.yaml post /aml/monitorings/{id}/{action}/ # Create session Source: https://documentation.idenfy.com/api-reference/bank-card-verification/create-session /openapi/bank-card.yaml post /bank-card/tokens/ Creates a standalone bank card verification session. Your finances are pre-checked; insufficient finances reject the request with `402`. # Generate bank verification token Source: https://documentation.idenfy.com/api-reference/bank/generate-bank-verification-token /openapi/bank.yaml post /bank/tokens/ # List bank verification account transactions Source: https://documentation.idenfy.com/api-reference/bank/list-bank-verification-account-transactions /openapi/bank.yaml get /bank/verifications/{verificationId}/accounts/{accountId}/transactions/ # Add new beneficiary Source: https://documentation.idenfy.com/api-reference/beneficiaries/add-new-beneficiary /openapi/kyb.yaml post /kyb/forms/{companyId}/beneficiaries/ # Delete beneficiary Source: https://documentation.idenfy.com/api-reference/beneficiaries/delete-beneficiary /openapi/kyb.yaml delete /kyb/forms/{companyId}/beneficiaries/{id}/ # List beneficiaries Source: https://documentation.idenfy.com/api-reference/beneficiaries/list-beneficiaries /openapi/kyb.yaml get /kyb/forms/{companyId}/beneficiaries/ # Partially update beneficiary Source: https://documentation.idenfy.com/api-reference/beneficiaries/partially-update-beneficiary /openapi/kyb.yaml patch /kyb/forms/{companyId}/beneficiaries/{id}/ # Retrieve beneficiary Source: https://documentation.idenfy.com/api-reference/beneficiaries/retrieve-beneficiary /openapi/kyb.yaml get /kyb/forms/{companyId}/beneficiaries/{id}/ # Update beneficiary Source: https://documentation.idenfy.com/api-reference/beneficiaries/update-beneficiary /openapi/kyb.yaml put /kyb/forms/{companyId}/beneficiaries/{id}/ # Change company status Source: https://documentation.idenfy.com/api-reference/companies/change-company-status /openapi/kyb.yaml post /kyb/companies/{id}/change-status/ Note that the status cannot be changed from `PENDING` and `PROCESSING` statuses. # Delete company Source: https://documentation.idenfy.com/api-reference/companies/delete-company /openapi/kyb.yaml delete /kyb/companies/{id}/ # Generate company PDF Source: https://documentation.idenfy.com/api-reference/companies/generate-company-pdf /openapi/kyb.yaml post /kyb/companies/{id}/pdf/ # List companies Source: https://documentation.idenfy.com/api-reference/companies/list-companies /openapi/kyb.yaml get /kyb/companies/ # Re-run company automation Source: https://documentation.idenfy.com/api-reference/companies/re-run-company-automation /openapi/kyb.yaml post /kyb/companies/{id}/automation/ # Retrieve all company info Source: https://documentation.idenfy.com/api-reference/companies/retrieve-all-company-info /openapi/kyb.yaml get /kyb/companies/{id}/ # List sessions Source: https://documentation.idenfy.com/api-reference/face-auth-sessions/list-sessions /openapi/face-authentication.yaml get /api/v2/facial-authentication-sessions/ # Retrieve session Source: https://documentation.idenfy.com/api-reference/face-auth-sessions/retrieve-session /openapi/face-authentication.yaml get /api/v2/facial-authentication-sessions/{tokenString}/ # List GOV ordered documents Source: https://documentation.idenfy.com/api-reference/gov-orders/list-gov-ordered-documents /openapi/kyb.yaml get /api/v2/gov-ordered-documents/ # Order GOV document Source: https://documentation.idenfy.com/api-reference/gov-orders/order-gov-document /openapi/kyb.yaml post /api/v2/gov-ordered-documents/document-order/ # Retrieve available documents to order Source: https://documentation.idenfy.com/api-reference/gov-orders/retrieve-available-documents-to-order /openapi/kyb.yaml get /api/v2/gov-ordered-documents/available-documents/ # Retrieve GOV ordered document Source: https://documentation.idenfy.com/api-reference/gov-orders/retrieve-gov-ordered-document /openapi/kyb.yaml get /api/v2/gov-ordered-documents/{id}/ # Add new beneficiary document Source: https://documentation.idenfy.com/api-reference/kyb-documents/add-new-beneficiary-document /openapi/kyb.yaml post /kyb/forms/{companyId}/beneficiaries/{beneficiaryId}/documents/ # Add new document Source: https://documentation.idenfy.com/api-reference/kyb-documents/add-new-document /openapi/kyb.yaml post /kyb/forms/{companyId}/documents/ # Delete beneficiary document Source: https://documentation.idenfy.com/api-reference/kyb-documents/delete-beneficiary-document /openapi/kyb.yaml delete /kyb/forms/{companyId}/beneficiaries/{beneficiaryId}/documents/{id}/ # Delete document Source: https://documentation.idenfy.com/api-reference/kyb-documents/delete-document /openapi/kyb.yaml delete /kyb/forms/{companyId}/documents/{id}/ # List beneficiary documents Source: https://documentation.idenfy.com/api-reference/kyb-documents/list-beneficiary-documents /openapi/kyb.yaml get /kyb/forms/{companyId}/beneficiaries/{beneficiaryId}/documents/ # List documents Source: https://documentation.idenfy.com/api-reference/kyb-documents/list-documents /openapi/kyb.yaml get /kyb/forms/{companyId}/documents/ # Partially update beneficiary document Source: https://documentation.idenfy.com/api-reference/kyb-documents/partially-update-beneficiary-document /openapi/kyb.yaml patch /kyb/forms/{companyId}/beneficiaries/{beneficiaryId}/documents/{id}/ # Partially update document Source: https://documentation.idenfy.com/api-reference/kyb-documents/partially-update-document /openapi/kyb.yaml patch /kyb/forms/{companyId}/documents/{id}/ # Retrieve beneficiary document Source: https://documentation.idenfy.com/api-reference/kyb-documents/retrieve-beneficiary-document /openapi/kyb.yaml get /kyb/forms/{companyId}/beneficiaries/{beneficiaryId}/documents/{id}/ # Retrieve document Source: https://documentation.idenfy.com/api-reference/kyb-documents/retrieve-document /openapi/kyb.yaml get /kyb/forms/{companyId}/documents/{id}/ # Update beneficiary document Source: https://documentation.idenfy.com/api-reference/kyb-documents/update-beneficiary-document /openapi/kyb.yaml put /kyb/forms/{companyId}/beneficiaries/{beneficiaryId}/documents/{id}/ # Update document Source: https://documentation.idenfy.com/api-reference/kyb-documents/update-document /openapi/kyb.yaml put /kyb/forms/{companyId}/documents/{id}/ # Create new KYB form Source: https://documentation.idenfy.com/api-reference/kyb-forms/create-new-kyb-form /openapi/kyb.yaml post /kyb/forms/ # List KYB forms Source: https://documentation.idenfy.com/api-reference/kyb-forms/list-kyb-forms /openapi/kyb.yaml get /kyb/forms/ List KYB forms associated with KYB token. There can be *one* or *zero* items in the list, indicating that the KYB form *was* or *was not* created. # Partially update KYB form info Source: https://documentation.idenfy.com/api-reference/kyb-forms/partially-update-kyb-form-info /openapi/kyb.yaml patch /kyb/forms/{id}/ # Retrieve KYB form info Source: https://documentation.idenfy.com/api-reference/kyb-forms/retrieve-kyb-form-info /openapi/kyb.yaml get /kyb/forms/{id}/ # Submit KYB form Source: https://documentation.idenfy.com/api-reference/kyb-forms/submit-kyb-form /openapi/kyb.yaml post /kyb/forms/{id}/submit/ Submit a filled KYB form for review. The form will be submitted and you will not be able to edit this KYB form any further unless additional information will be requested during a manual review. After submission, automatic blacklist and automation processes are executed. Then this KYB form will be reviewed by humans. After manual review, you may receive a webhook callback. # Update KYB form info Source: https://documentation.idenfy.com/api-reference/kyb-forms/update-kyb-form-info /openapi/kyb.yaml put /kyb/forms/{id}/ # Delete questionnaire answers Source: https://documentation.idenfy.com/api-reference/kyb-questionnaires/delete-questionnaire-answers /openapi/kyb.yaml delete /kyb/forms/{companyId}/questionnaires/{id}/answers/ # List questionnaires Source: https://documentation.idenfy.com/api-reference/kyb-questionnaires/list-questionnaires /openapi/kyb.yaml get /kyb/forms/{companyId}/questionnaires/ # Retrieve all questionnaires' answers Source: https://documentation.idenfy.com/api-reference/kyb-questionnaires/retrieve-all-questionnaires-answers /openapi/kyb.yaml get /kyb/forms/{companyId}/questionnaires/answers/detail/ # Retrieve questionnaire Source: https://documentation.idenfy.com/api-reference/kyb-questionnaires/retrieve-questionnaire /openapi/kyb.yaml get /kyb/forms/{companyId}/questionnaires/{id}/ # Retrieve questionnaire answers Source: https://documentation.idenfy.com/api-reference/kyb-questionnaires/retrieve-questionnaire-answers /openapi/kyb.yaml get /kyb/forms/{companyId}/questionnaires/{id}/answers/ # Update questionnaire answers Source: https://documentation.idenfy.com/api-reference/kyb-questionnaires/update-questionnaire-answers /openapi/kyb.yaml put /kyb/forms/{companyId}/questionnaires/{id}/answers/ # Generate KYB form token Source: https://documentation.idenfy.com/api-reference/kyb-token/generate-kyb-form-token /openapi/kyb.yaml post /kyb/tokens/ # Partially update KYB form token Source: https://documentation.idenfy.com/api-reference/kyb-token/partially-update-kyb-form-token /openapi/kyb.yaml patch /kyb/tokens/{tokenString}/ # Retrieve KYB session info Source: https://documentation.idenfy.com/api-reference/kyb-token/retrieve-kyb-session-info /openapi/kyb.yaml get /kyb/info/ Various info for KYB session. # Update KYB form token Source: https://documentation.idenfy.com/api-reference/kyb-token/update-kyb-form-token /openapi/kyb.yaml put /kyb/tokens/{tokenString}/ # Add identification to blocklist Source: https://documentation.idenfy.com/api-reference/kyc-blocklist/add-identification-to-blocklist /openapi/kyc.yaml post /kyc/identifications/{scanRef}/blocklists/{blocklistSource}/ # Remove identification from blocklist Source: https://documentation.idenfy.com/api-reference/kyc-blocklist/remove-identification-from-blocklist /openapi/kyc.yaml delete /kyc/identifications/{scanRef}/blocklists/{blocklistSource}/ # Generate KYC token Source: https://documentation.idenfy.com/api-reference/kyc-token/generate-kyc-token /openapi/kyc.yaml post /api/v2/token Creates a KYC verification session token. Pass the returned `authToken` to your frontend or SDK to launch the verification flow. # List identifications Source: https://documentation.idenfy.com/api-reference/kyc-verifications/list-identifications /openapi/kyc.yaml get /kyc/identifications/ # Request additional information from client Source: https://documentation.idenfy.com/api-reference/kyc-verifications/request-additional-information-from-client /openapi/kyc.yaml post /kyc/identifications/{scanRef}/request-information/ # API Reference Source: https://documentation.idenfy.com/api-reference/overview Browse interactive API documentation for all iDenfy endpoints including KYC, KYB, AML, and bank verification with a built-in playground. ## Interactive API Playground All endpoints are documented with request/response schemas and an interactive playground. Use the **sidebar** to navigate between API sections: * **Identity Verification** — session creation, status retrieval, webhooks * **Business Verification** — company management, document ordering, registry checks * **AML Screening** — single checks, monitoring, PDF reports * **Bank Verification** — token creation, account transactions ## Authentication All endpoints require **HTTP Basic Auth** with your API key and secret: ```bash theme={"system"} curl -X POST https://ivs.idenfy.com/api/v2/token \ -u "API_KEY:API_SECRET" \ -H "Content-Type: application/json" \ -d '{"clientId": "user-123"}' ``` See [Authentication](/authentication) for details. ## Base URL ``` https://ivs.idenfy.com ``` Same URL for sandbox and production — your API key determines the mode. See [Environments](/environments). ## Integration Guides For step-by-step integration instructions (not just endpoint reference), see: | Product | Guide | | --------------------------- | ---------------------------------------------- | | ID Verification (KYC) | [KYC Overview →](/kyc/overview) | | Business Verification (KYB) | [KYB Overview →](/kyb/overview) | | AML Screening | [AML Overview →](/aml/overview) | | Bank Verification | [Bank Overview →](/bank-verification/overview) | # Create POA check Source: https://documentation.idenfy.com/api-reference/poa/create-poa-check /openapi/kyc.yaml post /api/v2/poa-checks/ # Create registry center check Source: https://documentation.idenfy.com/api-reference/registry-center-checks/create-registry-center-check /openapi/kyb.yaml post /api/v2/registry-center-checks/ # List registry center checks Source: https://documentation.idenfy.com/api-reference/registry-center-checks/list-registry-center-checks /openapi/kyb.yaml get /api/v2/registry-center-checks/ # List SOS filing documents Source: https://documentation.idenfy.com/api-reference/sos-reports/list-sos-filing-documents /openapi/kyb.yaml get /api/v2/sos-filing-documents/ # Order SOS filing document Source: https://documentation.idenfy.com/api-reference/sos-reports/order-sos-filing-document /openapi/kyb.yaml post /api/v2/sos-filing-documents/ # Retrieve SOS filing document Source: https://documentation.idenfy.com/api-reference/sos-reports/retrieve-sos-filing-document /openapi/kyb.yaml get /api/v2/sos-filing-documents/{id}/ # Account check Source: https://documentation.idenfy.com/api-reference/webhooks/account-check /openapi/bank.yaml webhook accountCheck This notification is sent when an account social media check is completed. # Age estimation result Source: https://documentation.idenfy.com/api-reference/webhooks/age-estimation-result /openapi/age-estimation.yaml webhook ageEstimationResult This notification is sent when an age estimation session reaches a terminal state (either the estimate resolved, or a document step-up concluded). # Aml monitoring Source: https://documentation.idenfy.com/api-reference/webhooks/aml-monitoring /openapi/aml.yaml webhook amlMonitoring This notification is sent when an AML monitoring user is checked, accepted or declined. # Aml monitoring expiration Source: https://documentation.idenfy.com/api-reference/webhooks/aml-monitoring-expiration /openapi/aml.yaml webhook amlMonitoringExpiration This notification is sent when an AML monitoring user is nearing expiration or expires. # Bank card verification completed Source: https://documentation.idenfy.com/api-reference/webhooks/bank-card-verification-completed /openapi/bank-card.yaml webhook bankCardVerificationCompleted This notification is sent when a bank card verification is completed. # Bank verification Source: https://documentation.idenfy.com/api-reference/webhooks/bank-verification /openapi/bank.yaml webhook bankVerification This notification is sent when a bank verification is completed. # Company aml review Source: https://documentation.idenfy.com/api-reference/webhooks/company-aml-review /openapi/kyb.yaml webhook companyAmlReview This notification is sent when an AML review status is manually updated for a company or it's beneficiaries. # Company delete Source: https://documentation.idenfy.com/api-reference/webhooks/company-delete /openapi/kyb.yaml webhook companyDelete This notification is sent when a company is deleted. # Company expiration Source: https://documentation.idenfy.com/api-reference/webhooks/company-expiration /openapi/kyb.yaml webhook companyExpiration This notification is sent when a company verification is nearing expiration or expires. # Company info request Source: https://documentation.idenfy.com/api-reference/webhooks/company-info-request /openapi/kyb.yaml webhook companyInfoRequest This notification is sent when additional company info is requested and when the company form token expires. # Company review Source: https://documentation.idenfy.com/api-reference/webhooks/company-review /openapi/kyb.yaml webhook companyReview This notification is sent when a company verification is completed. # Company submit Source: https://documentation.idenfy.com/api-reference/webhooks/company-submit /openapi/kyb.yaml webhook companySubmit This notification is sent when company information is submitted. # Document expiration Source: https://documentation.idenfy.com/api-reference/webhooks/document-expiration /openapi/kyc.yaml webhook documentExpiration This notification is sent when a client's identity verification document is nearing expiration or expires # Facial authentication Source: https://documentation.idenfy.com/api-reference/webhooks/facial-authentication /openapi/face-authentication.yaml webhook facialAuthentication This notification is sent when client's facial authentication session ends, either by success, failure or expiration. # Gov ordered document Source: https://documentation.idenfy.com/api-reference/webhooks/gov-ordered-document /openapi/kyb.yaml webhook govOrderedDocument This notification is sent when a gov registers document, which was ordered using the API, is delivered. # Identification Source: https://documentation.idenfy.com/api-reference/webhooks/identification /openapi/kyc.yaml webhook identification This notification is sent when a client completes an identity verification. Legacy, use `ID_VERIFICATION_AUTO_FINISHED`, `ID_VERIFICATION_MANUAL_FINISHED`, `ID_VERIFICATION_EXPIRED` and `ID_VERIFICATION_CANCELLED` instead. # Identification auto finished Source: https://documentation.idenfy.com/api-reference/webhooks/identification-auto-finished /openapi/kyc.yaml webhook identificationAutoFinished This notification is sent when an identity verification is completed. # Identification cancelled Source: https://documentation.idenfy.com/api-reference/webhooks/identification-cancelled /openapi/kyc.yaml webhook identificationCancelled This notification is sent when an identity verification is cancelled by the user or the system. # Identification expired Source: https://documentation.idenfy.com/api-reference/webhooks/identification-expired /openapi/kyc.yaml webhook identificationExpired This notification is sent when an identity verification expires. # Identification manual finished Source: https://documentation.idenfy.com/api-reference/webhooks/identification-manual-finished /openapi/kyc.yaml webhook identificationManualFinished This notification is sent when an identity verification is manually approved or denied. # Identification resubmitted Source: https://documentation.idenfy.com/api-reference/webhooks/identification-resubmitted /openapi/kyc.yaml webhook identificationResubmitted This notification is sent when a client resubmits an identity verification. # Sos report Source: https://documentation.idenfy.com/api-reference/webhooks/sos-report /openapi/kyb.yaml webhook sosReport This notification is sent when a SOS filing report is delivered. # Video call finished Source: https://documentation.idenfy.com/api-reference/webhooks/video-call-finished /openapi/kyc.yaml webhook videoCallFinished This notification is sent when a video call is finished. # Authentication Source: https://documentation.idenfy.com/authentication Authenticate with the iDenfy API using HTTP Basic Auth with your API key and secret. Includes code examples in cURL, Python, and Node.js. ## API Key Authentication All server-side API calls use **HTTP Basic Auth** with your API Key and API Secret. ```bash cURL theme={"system"} curl -X POST https://ivs.idenfy.com/api/v2/token \ -u "YOUR_API_KEY:YOUR_API_SECRET" \ -H "Content-Type: application/json" \ -d '{"clientId": "user-123"}' ``` ```python Python theme={"system"} import requests response = requests.post( "https://ivs.idenfy.com/api/v2/token", auth=("YOUR_API_KEY", "YOUR_API_SECRET"), json={"clientId": "user-123"} ) ``` ```javascript Node.js theme={"system"} const response = await fetch("https://ivs.idenfy.com/api/v2/token", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Basic " + Buffer.from("YOUR_API_KEY:YOUR_API_SECRET").toString("base64"), }, body: JSON.stringify({ clientId: "user-123" }), }); ``` ```php PHP theme={"system"} $ch = curl_init("https://ivs.idenfy.com/api/v2/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_USERPWD, "YOUR_API_KEY:YOUR_API_SECRET"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(["clientId" => "user-123"])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = json_decode(curl_exec($ch), true); ``` The `Authorization` header is: `Basic base64(API_KEY:API_SECRET)` ## Get Your Keys 1. Log in to [iDenfy Dashboard](https://admin.idenfy.com) 2. Go to **Settings → API Keys** 3. Select **Generate** [Detailed guide →](/guides/dashboard/settings/api-keys) ## Two Types of Auth | Auth type | Used for | Where | | --------------------------------- | --------------------------- | ---------------------------- | | **Basic Auth** (API Key + Secret) | All server-side API calls | Your backend only | | **authToken** | Client-side verification UI | iFrame, redirect, mobile SDK | The flow: ``` Backend (Basic Auth) → POST /api/v2/token → returns authToken Frontend (authToken) → Verification UI → results via webhook to backend ``` The `authToken` is short-lived and scoped to one verification. It's safe to pass to the client. **Never expose your API Secret in client-side code** — browser JavaScript, mobile apps, or public repos. Use it only on your server. # Create a Bank Card Session Source: https://documentation.idenfy.com/bank-card/create-session Create a standalone bank card verification session with the iDenfy API, including expected cardholder details, session URL, mobile code, and redirects. **Requirements:** * **API key pair** (API key + secret) * **Bank Card Verification** enabled on your account (contact iDenfy -- not self-service) * The **standalone** flow enabled on your account * **Finances** available for Bank Card Verification For how the card check works, what each verdict means, and how the dashboard side is configured, see the [Bank Card Verification](/guides/dashboard/features/bank-card-verification) guide. This documentation focuses on the API integration. This page covers the **standalone** flow -- a card check that runs on its own token, with no identity verification behind it. To run the same check as an extra step inside a KYC session, set `bankCardVerification` when [generating an identity verification token](/kyc/generate-token) instead. ## Create a Session Authenticate with your **API key pair** -- API key as the username, API secret as the password, over HTTP Basic. Sessions are scoped to your partner account, so you only ever see your own. For the full request and response schemas, every field's constraints and defaults, and an interactive playground, see the [**API Reference**](/api-reference/bank-card-verification/create-session) page for this endpoint. `expectedName` is the only required field -- the cardholder name read from the card is compared against it. Supplying `expectedLastFour` (exactly four digits) adds a second check against the card's actual last four digits. Creating a session pre-checks your finances; if they can't cover the check the request is rejected -- see [Errors](#errors). ### Example (Partner API) ```http theme={"system"} POST /bank-card/tokens/ Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json { "expectedName": "Jane Doe", "expectedLastFour": "4242", "lifetime": 3600, "sessionLength": 30, "generateMobileCode": true, "successUrl": "https://partner.example.com/ok", "failUrl": "https://partner.example.com/denied" } ``` ```json theme={"system"} { "tokenString": "b7c1…", "expiration": "2026-08-26T13:00:00Z", "isValid": true, "sessionUrl": "https://ui.idenfy.com/?bcvToken=b7c1…", "mobileCode": "48120537" } ``` *** ## Sending the User to the Session Redirect the end user to the returned `sessionUrl`, or embed it in an iFrame. **Embedding it yourself?** Your frame must grant camera access to the card capture origin, or card capture fails while document upload keeps working. See [Required Attributes](/kyc/iframe-redirect#required-attributes) for the `allow` attribute. * **Mobile code.** When `generateMobileCode` is set, the response also carries an eight-digit `mobileCode`. Show it to the user so they can open the session in the iDenfy mobile app instead of following the link. * **Desktop hand-off.** Desktop users are offered a QR code and an SMS link so they can finish on a phone camera. The desktop screen advances to the result on its own once the phone is done. Nothing is required from you. * **Redirects.** `successUrl` and `failUrl` send the user back to your page once the check resolves. An **expired** session never redirects -- handle that case on your side, off the back of the webhook. The flow is available in all [37 supported languages](/resources/supported-languages), switchable mid-flow. *** ## Session Lifetime Two independent clocks govern a session. | Clock | Field | Default | Range | Starts | | ----------------- | --------------- | ------- | ------------- | ------------------------------------------------ | | Link lifetime | `lifetime` | 1 hour | up to 30 days | when the session is created | | Capture countdown | `sessionLength` | -- | 1--60 minutes | at the capture step, not when the link is opened | `lifetime` is set in **seconds**; `sessionLength` in **minutes**. The end user gets three capture attempts by default, configurable per account. The counter is never shown to them, and a poor-quality capture does not spend an attempt on its own. *** ## Errors | Status | Message | When | | ------ | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | `402` | `"Action not allowed due to lack of funds or exceeded limit."` | Your finances cannot cover a bank card verification. Contact your account manager, or support team. | *** ## What's Next Once the user finishes, the verdict is delivered to your endpoint. There is no Partner API endpoint for retrieving a standalone session, so configure a webhook if you need the result in your own systems -- see [Bank Card Webhooks](/bank-card/webhooks). # Bank Card Verification Webhooks Source: https://documentation.idenfy.com/bank-card/webhooks Receive standalone bank card verification results from iDenfy: match statuses, no-match reasons, the card data returned, and how the KYC-linked result differs. When a bank card verification reaches a verdict, a result notification is sent to your endpoint with the event type `BANK_CARD_VERIFICATION_COMPLETED`. There is no Partner API endpoint for retrieving a standalone session, so this is the only way to receive the result programmatically -- configure a webhook. ## Where It's Sent The destination is the webhook URL configured on your account's **Bank Card Verification** notification. Set it up under [Settings → System Notifications](/guides/dashboard/settings/system-notifications-webhooks-emails). If the notification is configured with a signing key, the body is signed so you can verify authenticity -- see [Callback Signing](/security/callback-signing). ## Payload For the full payload schema and every field's type, see the [**API Reference**](/api-reference/webhooks/bank-card-verification-completed) page for this webhook. Only a **full match** counts as a success. | `status` | Meaning | | -------------- | -------------------------------------------------------------------- | | `MATCH` | Every requested check passed. | | `NO_MATCH` | At least one check failed. `noMatchReason` says which. | | `NOT_COMPARED` | No comparison was reached -- the card data could not be established. | When `status` is `NO_MATCH`, `noMatchReason` carries the cause: | `noMatchReason` | Meaning | | ------------------ | -------------------------------------------------------------------------------------------------- | | `NAME_MISMATCH` | A cardholder name was read, but it does not match `expectedName`. | | `NUMBER_MISMATCH` | The card's last four digits do not match the `expectedLastFour` you supplied. | | `NAME_NOT_FOUND` | No cardholder name could be read from the card. | | `NUMBER_NOT_FOUND` | No card number could be read from the card. | | `LIVENESS_FAILED` | The capture was not a genuine physical card -- for example a photo of a screen, or a printed copy. | `nameMatch` and `lastFourMatch` report the two component checks individually. `lastFourMatch` is `null` when you did not supply an `expectedLastFour`, since nothing was compared. Only `firstSix`, `lastFour` and `expiryDate` are ever returned. The **full card number is never sent**, and the CVV is never captured at any point. Card capture and image processing run in a dedicated environment certified to PCI-DSS v4.0.1, and no card imagery is retained once processing completes. The verdict is final. There is no manual review step for a bank card check, and a verdict that has been reached is never overwritten. ## Standalone Vs. KYC-Linked The same card check serves two entry points, and they report differently: * **Standalone** -- a session created through [Create a Bank Card Session](/bank-card/create-session) delivers its own `BANK_CARD_VERIFICATION_COMPLETED` notification, carrying the payload above. * **Inside a KYC session** -- the result instead arrives as a nested `bankCardVerification` object on the [identity verification webhook](/kyc/webhooks), with the same fields. A `NO_MATCH` there marks the verification **Suspected** for review rather than denying it -- see [Suspected Status](/kyc/suspected-status). ## Idempotency Delivery may be retried, so handle notifications idempotently, keyed on `id`. # Bank Verification API Source: https://documentation.idenfy.com/bank-verification/overview Integrate iDenfy's Bank Verification API to verify customer bank accounts and financial information with session creation and webhook callbacks. **Requirements** * **API** key pair * **Webhook** setup * Bank verification **credits** *** ## Bank Verification API Integration ### Creating a Bank Verification Session For full request and response schemas for session creation, see the **API Reference** tab. **Creating a redirection link** Append the generated `tokenString` to the URL `https://bank-verification.ui.idenfy.com/?token=` to provide to the end-user. Example: `https://bank-verification.ui.idenfy.com/?token=LVS8YgSTTVuXAHiur10yCabIAWLizUlX` ### Webhook Response Once the end-user completes bank verification, you will receive a [webhook notification](/guides/dashboard/settings/system-notifications-webhooks-emails) with the response. For the full webhook response schema, see the **API Reference** tab. *** ## Listing Account Transactions Retrieve transaction history for a verified bank account. For full request and response schemas, see the **API Reference** tab. ## Next Steps Full bank verification API endpoint reference. Step-by-step guide for bank verification in the dashboard. # Best Practices Source: https://documentation.idenfy.com/best-practices Security, UX, and compliance best practices for your iDenfy integration covering API credentials, webhook security, and session management. ## Security ### Protect Your API Credentials * Store API Key and Secret in environment variables, never in code * Never expose credentials in client-side JavaScript or mobile app bundles * Rotate API keys periodically and immediately if compromised ### Secure Your Webhooks * Implement [callback signing](/security/callback-signing) verification on every webhook * [Whitelist iDenfy IP addresses](/security/ip-whitelisting) on your webhook endpoint * Use HTTPS with a valid TLS certificate * Respond to webhooks within 10 seconds ### Session Creation * Create verification sessions server-side only * Sessions are single-use and short-lived — create a new one for each verification * Never reuse or cache tokens ## User Experience ### Reduce Drop-Off * Explain what documents are accepted before starting verification * Show progress indicators during verification * Provide clear error messages when verification fails * Allow re-verification with a single click * Test on mobile — most verifications happen on phones ### Camera and Document Tips * Advise users to ensure good lighting * Suggest removing document from plastic sleeves * Let users hold the device however they prefer — document capture works in both portrait and landscape, and rotating mid-flow keeps their progress * Test iFrame camera permissions across browsers ## Compliance ### Data Handling * Only collect data fields required by your compliance obligations * Implement data retention policies aligned with regulatory requirements * Provide customers access to their verification status * Document your verification process for auditors ### Record Keeping * Store `scanRef` for each verification in your database * Download and archive [verification PDFs](/kyc/pdf-generation) for compliance records * Log all webhook events with timestamps # Environments Source: https://documentation.idenfy.com/environments Learn how iDenfy sandbox and production environments work with a single base URL, and how your API key pair determines the active mode. ## Single URL, Two Modes iDenfy uses **one base URL** for both sandbox and production: ``` https://ivs.idenfy.com ``` Your **API key pair** determines which mode you're in — not the URL. Sandbox keys return test results, production keys trigger real verifications. Your code stays the same, only the keys change. | | Sandbox | Production | | ------------- | --------------------------------- | ------------------------------------- | | **Base URL** | `https://ivs.idenfy.com` | `https://ivs.idenfy.com` | | **API keys** | Sandbox key pair | Production key pair | | **Documents** | Dummy results, no real processing | Real document verification | | **Credits** | Not consumed | Consumed per verification | | **Webhooks** | Delivered to your test endpoint | Delivered to your production endpoint | Since the URL is identical, you can switch between sandbox and production by swapping API keys in your environment variables — no code changes needed. ## Sandbox The sandbox lets you: * Test your integration end-to-end without real documents * Simulate different outcomes (approved, denied, suspected) * Validate webhook handling with predictable payloads * Test error scenarios and edge cases See [Testing & Sandbox](/guides/testing-sandbox) for step-by-step instructions. ## Switching to Production Set your production webhook URL in [Dashboard → Settings](/guides/dashboard/settings/system-notifications-webhooks-emails). Implement [callback signing](/security/callback-signing) and [IP whitelisting](/security/ip-whitelisting). Verify all verification outcomes are handled correctly. See the [go-live checklist](/guides/testing-sandbox#go-live-checklist). Replace sandbox keys with production keys in your environment variables. # Face Auth iFrame Source: https://documentation.idenfy.com/face-authentication/iframe Embed iDenfy face authentication in your web page using an iFrame for seamless returning-user biometric re-verification without redirects. ## iFrame Integration To use face authentication with an iFrame, insert the verification platform URL directly into your iFrame tag: ``` https://face.authentication.idenfy.com/?token={{token}} ``` The `token` query string parameter is obtained after [generating a token](/face-authentication/token-generation). After the process is finished, you may close the iFrame and display a desired page to your client. | Query String Parameter | Example Value | | ---------------------- | ---------------------------- | | `token` | `3FA5TFPA2ZE3LMPGGS1EGOJNJE` | Example redirect URL: `https://face.authentication.idenfy.com/?token=3FA5TFPA2ZE3LMPGGS1EGOJNJE` ### Code Example ```html theme={"system"} ``` *** ## Webhook You can receive information when face authentication actions are performed by [setting up](/guides/dashboard/settings/system-notifications-webhooks-emails) a `FACIAL_AUTHENTICATION` notification type webhook. ### Possible `status` Values | Name | Description | | ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `SUCCESS` | Authentication is successful. This message is also sent upon successful enrollment. | | `FAILED` | Authentication failed due to fraudulent activity or other possible vulnerabilities. This message is also sent upon enrollment failure. | | `EXPIRED` | Face authentication token expired before the user started the process. | | `CANCELED` | Face authentication session was canceled by the user. | ### Possible `failReason` Values | Value | Description | | ----------------------------- | --------------------------------------------------------------------- | | `FACE_MISMATCH` | The face does not match the enrolled reference photo. | | `FAKE_FACE` | A spoofing attempt was detected (e.g., printed photo, screen replay). | | `VIRTUAL_CAMERA` | A virtual or emulated camera was used instead of a physical device. | | `FACE_NOT_FOUND` | No face was detected in the captured image. | | `TOO_MANY_FACES` | More than one face was detected in the frame. | | `FACE_ANGLE_TOO_LARGE` | The face was turned too far from a frontal position. | | `FACE_TOO_SMALL` | The face occupies too small a portion of the frame. | | `FACE_CLOSE_TO_BORDER` | The face is too close to the edge of the image. | | `FACE_TOO_CLOSE` | The face is too close to the camera. | | `FACE_CROPPED` | Part of the face is cut off or outside the frame. | | `FACE_IS_OCCLUDED` | The face is partially covered (e.g., by a mask, hand, or object). | | `EYES_CLOSED` | The person's eyes are closed. | | `FAILED_TO_PREDICT_LANDMARKS` | Facial landmark detection failed. | | `PROBABILITY_TOO_SMALL` | The face-match confidence score is below the required threshold. | | `FAKE_CAPTURE` | The capture process was tampered with or bypassed. | | `DUPLICATE_IMAGE` | The same image was submitted more than once. | ### Webhook Response Example (EXPIRED) ```json theme={"system"} { "id": "8d471b4c-3822-4547-aec5-a9d0cc0aa105", "scanRef": "8df398bb-7340-11ee-9aec-0221b1f59063", "clientId": "FD155HLZ5Z", "status": "EXPIRED", "token": "UbYZnDdrTElsSDBQFeNkd8MxI9CpSEO0qR5jtRcz", "type": "AUTHENTICATION", "method": "FACE_MATCHING", "facePhoto": null, "failReason": null, "ipAddress": null } ``` *** ## iFrame Console Status Values Information about the face authentication statuses is available in the browser console on the `data` object. | Name | Description | | ---------- | ----------------------------------------------------------- | | `APPROVED` | The user completed face authentication and it was approved. | | `FAILED` | The user completed face authentication but it failed. | To assess the face authentication session, evaluate the [webhooks](#webhook) sent from the back-office. The statuses in the iFrame console are complementary. # Face Authentication API Source: https://documentation.idenfy.com/face-authentication/overview Use iDenfy's Face Authentication API to re-authenticate returning users with biometric face matching for account login, high-risk actions, and periodic checks. The Face Authentication API is a service for **re-authenticating returning users** by comparing their live face to a biometric template captured during a previous identity verification. Unlike a full KYC verification, Face Authentication does not require document scanning. The user simply takes a selfie, which is matched against their original verification photo. This makes it ideal for: * **Account login** -- add biometric security as a second factor * **High-risk actions** -- confirm the user's identity before transactions, withdrawals, or profile changes * **Periodic re-verification** -- ensure the same person is still using the account over time ## How It Works 1. **Create a Face Authentication session** using the [Create Face Auth Session](/face-authentication/token-generation) endpoint, referencing the user's original `scanRef`. 2. **Launch the authentication session** via the [iFrame / Redirect URL](/face-authentication/iframe) or a native SDK. 3. **Receive the result** through a webhook callback indicating whether the face matched. ## Prerequisites You must have at least one successful identity verification with iDenfy. The original verification's `scanRef` is required to create the authentication session. ## Next Steps Create a face authentication session via API. Embed the authentication flow in your application. # Create Face Auth Session Source: https://documentation.idenfy.com/face-authentication/token-generation Create a face authentication session token via the iDenfy API using a previous verification scanRef for biometric re-authentication. **Requirements** * **API** key pair * A **successful** verification already completed (`scanRef`) * Face authentication session creation via API **enabled** (done by iDenfy staff) * Face authentication **credits** Verify users quickly with face authentication -- compares a live face to the ID document photo using matching and passive liveness detection. *** ## Introduction This guide covers session creation and checking whether your user can use face authentication. You need the session token for SDK initialization or iFrame integration. Check the authentication status first to verify whether your user has completed identification (verified with face and document). *** ## 1. Check Face Authentication Status **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/identification/facial-auth/{scanRef}/check-status/?method=FACE_MATCHING` Once you call the endpoint using the `scanRef`, the response will contain one of the following authentication types: | Name | Description | | ---------------- | ------------------------------------------------------ | | `AUTHENTICATION` | The user can authenticate by face | | `ENROLLMENT` | The user must be enrolled before they can authenticate | | `IDENTIFICATION` | The user must perform a full identification again | `ENROLLMENT` is only excluded when you pass `method=FACE_MATCHING`, as in the endpoint above. Omit the parameter or request active liveness and the response can also be `ENROLLMENT`. If verification with the provided `scanRef` does not exist (deleted or invalid), the endpoint returns status code **404**. **Response example:** ```json theme={"system"} { "type": "AUTHENTICATION" } ``` *** ## 2. Create the Session Token **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/partner/authentication-info` If the authentication type is `IDENTIFICATION`, use the regular identification endpoint for creating a session. See the [session creation guide](/kyc/generate-token). `IDENTIFICATION` cannot be passed as `type` on this endpoint — creation accepts only `AUTHENTICATION` or `ENROLLMENT`. ### Request Parameters | Key | Required | Description | | --------------------- | -------- | -------------------------------------------------------------------------------------- | | `scanRef` | Yes | The completed verification the user authenticates against | | `method` | Yes | `FACE_MATCHING` or `ACTIVE_LIVENESS` | | `type` | No | `AUTHENTICATION` (default) or `ENROLLMENT` | | `lifetime` | No | Session duration in **seconds**. Default `3600` (1 hour), minimum `0`, maximum 30 days | | `locale` | No | Forces a specific locale | | `generateDigitString` | No | Returns a `digitString` for the mobile app flow | * `FACE_MATCHING` supports authentication only. * `ACTIVE_LIVENESS` authentication fails unless the user was enrolled first with `type: ENROLLMENT`. When `generateDigitString` is `true`, `lifetime` is additionally capped by a partner-level setting that defaults to **24 hours**. The 30-day maximum does not apply to these sessions, and a longer `lifetime` returns an error. Creation returns **400** — not 404 — if the `scanRef` is invalid or deleted. Insufficient face authentication credits also return **400**. `generateDigitString` is optional. If provided, it returns an 8-digit `digitString` to be used for face authentication on the iDenfy mobile app, or sent to the user as an SMS short link. The flow is as follows: 1. Your system calls the API endpoint to create a face authentication session, and a verification code is returned. 2. On your platform, you prompt the user to open the iDenfy app and enter the returned `digitString` code. 3. The user takes a selfie, closes the app, and returns to your platform. 4. Once your system receives the results via webhook, it either allows the user to proceed or prompts them to retry by generating a new code. The code has no separate lifetime — it expires with the session. ### Request Example ```json theme={"system"} { "scanRef": "scanRef", "type": "AUTHENTICATION", "method": "FACE_MATCHING", "generateDigitString": true } ``` ### Response Example ```json theme={"system"} { "token": "3FA5TFPA2ZE3LMPGGS1EGOJNJE", "type": "AUTHENTICATION", "maxAttemptCount": 1, "digitString": "12345678", "locale": "en" } ``` | Field | Description | | ----------------- | ------------------------------------------------------------------------ | | `token` | Session token. Use it for SDK initialization or to build the session URL | | `type` | `AUTHENTICATION` or `ENROLLMENT` | | `maxAttemptCount` | Always `1` — a session allows a single attempt | | `digitString` | 8-digit code, returned only when `generateDigitString` was `true` | | `locale` | Session locale | The response contains no expiry value and no session URL. Build the URL yourself from the `token` — see [Face Auth iFrame](/face-authentication/iframe). # Address Verification Source: https://documentation.idenfy.com/fraud-prevention/address-verification Verify customer addresses against official records using the iDenfy address verification API endpoint with country and address parameters. **Requirements** * **API** key pair * Finances to perform **address verification** *** ## Verify Address **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/address-verification` ### Request Parameters | Parameter | Type | Required | Explanation | | --------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------- | | `address` | String | Yes | Address for verification. Maximum length: 255 characters — longer values are rejected with a validation error. | | `country` | String | No | 2-digit ISO country code, e.g. "LT" | ### No Match Found If the address cannot be matched at all, the endpoint returns **`404 Not Found`** instead of a response body with `status: UNVERIFIED`. `UNVERIFIED` is only returned when a match *is* found but its verification code indicates the match is unverified or reverted — your integration needs to handle both the 404 case and the `UNVERIFIED` status. You are only charged when a match is found. No funds are consumed when the endpoint returns `404`. ### Response Values | Key | Type | Explanation | | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `address` | String | Address that was used to perform address verification. | | `country` | String | Country that was passed during the address verification process. | | `status` | String | Status of the address. Possible values: `VERIFIED`, `PARTIALLY_VERIFIED`, `UNVERIFIED`. | | `quality` | String | Quality score of the address. Possible values: `EXCELLENT`, `GOOD`, `AVERAGE`, `POOR`, `BAD`. | | `accuracy` | Integer | Accuracy of the address information. Maximum value is `100`. A lower value is returned if, for example, the postcode in the request differs from the actual postcode derived from the provided address. | `BAD` also covers the case where the provider returns no quality code at all — `quality` is never `null`. Treat `BAD` as "poor quality or quality unknown." ### Request Example ```json theme={"system"} { "address": "Baršausko g. 59, LT-51423 Kaunas", "country": "LT" } ``` ### Response Example ```json theme={"system"} { "address": "Baršausko g. 59, LT-51423 Kaunas", "country": "LT", "status": "VERIFIED", "quality": "GOOD", "accuracy": 99 } ``` # AI Proof of Address Source: https://documentation.idenfy.com/fraud-prevention/ai-poa Verify utility bills and proof of address documents automatically using iDenfy AI-powered document analysis with base64 file upload. **Requirements** * API key pair * Finances for PoA [COMPARE type](/kyc/additional-steps) *** ## AI POA Verification **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/poa-checks/` ### Request Structure | Key | Required | Type | Explanation | | ----------------- | -------- | ------ | -------------------------------------------------------------------------------------------- | | `file` | Yes | String | Base64 encoded document file. Supported formats: jpeg, jpg, png, gif, webp, heic, heif, pdf. | | `providedName` | No | String | Full name of the user. Will be compared against the data retrieved from the PoA document. | | `providedAddress` | No | String | Address for verification. Will be compared against the data retrieved from the PoA document. | ### Response Structure | Key | Type | Explanation | | ----------------- | ------- | ------------------------------------------------------------------------------------------------------------ | | `id` | String | PoA check identifier. | | `created` | String | Timestamp indicating when the PoA check was created. | | `updated` | String | Timestamp indicating when the PoA check was last updated. | | `issueDate` | String | Issue date retrieved from the Proof of Address document. | | `documentType` | String | Type of document. Possible values: `UTILITY_BILL`, `BANK_STATEMENT`, `GOVERNMENT_LETTER`, `LEASE_AGREEMENT`. | | `hasLogo` | Boolean | `true` if the document contains a company or provider logo; otherwise `false`. | | `nameMatch` | Boolean | `true` if the provided name matches the one on the document; otherwise `false`. | | `addressMatch` | Boolean | `true` if the provided address matches the one on the document; otherwise `false`. | | `dateValid` | Boolean | `true` if the document is not older than 3 months; otherwise `false`. | | `overallStatus` | String | Overall result of the comparison. Possible values: `MATCH`, `NO_MATCH`, `NOT_COMPARED`. | | `name` | String | Full name retrieved from the PoA document. | | `address` | String | Full address retrieved from the PoA document. | | `partner` | Object | Object containing partner environment-related information. | | `fileType` | String | File type of the uploaded document. Possible values: `PDF`, `JPG`, `PNG`. | | `providedName` | String | Name value that was provided when the check was initiated. | | `providedAddress` | String | Address value that was provided when the check was initiated. | | `file` | String | URL to download the uploaded file. | ### Request Example ```json theme={"system"} { "file": "iVBORw0KGgoAAAANSUhEUgAAAxoAAAC6CAYAAAApyZWVuc2hvdO8Dvz4AAAA[...]", "providedName": "John Smith", "providedAddress": "4344 Poco Mas Drive, Dallas, FL, 33009" } ``` ### Response Example ```json theme={"system"} { "id": "aa4e1453-abc0-4649-84ab-d6a65984329b", "created": "2024-10-21T06:10:31.559212Z", "updated": "2024-10-21T06:10:31.559246Z", "issueDate": "2021-11-15", "documentType": "Electricity bill", "hasLogo": true, "nameMatch": false, "addressMatch": true, "dateValid": false, "overallStatus": "NO_MATCH", "name": "Leslie Holden", "address": "4344 Poco Mas Drive Dallas, FL, 33009", "partner": { "id": 2253, "created": "2023-10-11T14:09:40.458303Z", "companyName": "iDenfy Techsupport TEST", "environment": "TESTING", "isActive": true }, "fileType": "png", "providedName": "John Smith", "providedAddress": "4344 Poco Mas Drive, Dallas, FL, 33009", "file": "https://s3.eu-west-1.amazonaws.com/[...]" } ``` # Fraud Probability Source: https://documentation.idenfy.com/fraud-prevention/fraud-probability Calculate fraud probability scores based on multiple risk signals like email, phone, IP, and device data using the iDenfy fraud API. **Requirements** * **API** key pair * Fraud probability **credits** *** ## Estimate Fraud Probability **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/fraud/estimate-fraud-probability` Although none of the parameters below are individually required, the request must contain **at least one** of them. ### Request Parameters | Key | Required | Type | Constraints | Explanation | | --------------------------- | -------- | ------ | ----------------------- | ----------------------------------------------- | | `user_agent` | No | String | Max length 512 | The HTTP `User-Agent` header of the browser | | `accept_language` | No | String | -- | The HTTP `Accept-Language` header of the device | | `ip_address` | No | String | `ipv4` or `ipv6` format | User's IP address | | `first_name` | No | String | Max length 255 | User's first name | | `last_name` | No | String | Max length 255 | User's last name | | `email_address` | No | String | Max length 255 | User's email address | | `email_domain` | No | String | Max length 255 | The domain of the `email_address` | | `street_address` | No | String | Max length 255 | The first line of the user's living address | | `city` | No | String | Max length 255 | User's city | | `country` | No | String | Country alpha-2 code | User's country | | `postal_code` | No | String | Max length 255 | The postal/zip code of user's living address | | `phone_number` | No | String | Max length 255 | User's phone number without country code | | `phone_country_code` | No | String | Max length 4 | User's phone country code (e.g. +370) | | `credit_card_number_6` | No | String | Length 6 | The first 6 digits of the user's payment card | | `credit_card_last_4_digits` | No | String | Length 4 | The last 4 digits of the user's payment card | ### Request Example ```json theme={"system"} { "user_agent": "Mozilla/5.0 (Android 7.0; Mobile; rv:54.0) Gecko/54.0 Firefox/54.0", "accept_language": "en-US,en;q=0.8", "ip_address": "64.236.213.12", "first_name": "John", "last_name": "Smith", "email_address": "john@gmail.com", "email_domain": "gmail.com", "street_address": "123 Address Rd.", "city": "Boston", "country": "US", "postal_code": "34455", "phone_number": "3439007998", "phone_country_code": "1", "credit_card_number_6": "410608", "credit_card_last_4_digits": "9930" } ``` ### Response Example ```json theme={"system"} { "fraud_level": "LOW" } ``` ### Fraud Levels | Key | Type | Possible Values | | ------------- | -------- | --------------------------------------------------------------- | | `fraud_level` | `String` | `VERY_LOW`, `LOW`, `MEDIUM`, `HIGH`, `VERY_HIGH`, `NOT_CHECKED` | # Fraud Prevention API Source: https://documentation.idenfy.com/fraud-prevention/overview Use iDenfy's Fraud Prevention API to detect fraud with AI risk scoring, VPN and proxy detection, phone validation, and address verification checks. ## Fraud Prevention API Overview iDenfy's fraud prevention API tools work alongside identity verification or as standalone API checks. Use them to add extra layers of trust before onboarding a customer. ## Available Tools AI-powered risk scoring. Combine KYC, KYB, and AML signals into a single risk score with customizable rules and weights. Detect if a user is behind a VPN, proxy, or Tor during verification. Returns risk level and IP details. AI-generated fraud probability score based on multiple signals from the verification session. Validate phone number format, carrier, and line type without contacting the user. Verify phone ownership by sending an SMS or call with a confirmation code. Verify customer addresses against official postal and government records. AI-powered verification of utility bills, bank statements, and other proof of address documents. *** ## When to Use What | Use case | Tool | Integration | | ------------------------------------ | -------------------------------------------------------------- | -------------------------------------------------------- | | Score overall risk of a verification | [Risk Assessment](/fraud-prevention/risk-assessment) | During KYC (via token parameter `riskAssessmentProfile`) | | Block VPN/proxy users | [Proxy Check](/fraud-prevention/proxy-check) | During KYC (via token parameter `checkIpProxy`) | | Validate a phone number before SMS | [Phone Validation](/fraud-prevention/phone-validation) | Standalone API call | | Confirm phone ownership | [Phone Verification](/fraud-prevention/phone-verification) | During KYC or standalone | | Check if address is real | [Address Verification](/fraud-prevention/address-verification) | Standalone API call | | Verify a utility bill document | [AI Proof of Address](/fraud-prevention/ai-poa) | During KYC (via `additionalSteps`) or standalone | Most fraud prevention tools can be enabled **automatically during KYC** by setting parameters in the [session creation](/kyc/generate-token) request, or called as **standalone API endpoints** independently of verification. ## Next Steps Configure AI-powered risk scoring. Detect VPN, proxy, and Tor usage. Verify phone ownership via SMS. Verify utility bills and bank statements. # Phone Validation Source: https://documentation.idenfy.com/fraud-prevention/phone-validation Validate phone number format, carrier information, and line type using the iDenfy phone validation API for fraud prevention checks. **Requirements** * **API** key pair * Service **enabled** (done by iDenfy staff) * Number validation **credits** Phone Number Risk Scoring for Instant Validation -- receive risk scores, filter invalid numbers, and get detailed phone insights in one call. *** ## Validate Phone Number **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/fraud/validate-phone` ### Request Structure If the provided phone number is not in [E.164](https://en.wikipedia.org/wiki/E.164) format or it is not a mobile phone number, the server may return an empty string `""`. | Key | Required | Type | Constraints | Explanation | | ------------------ | -------- | -------- | --------------------------------------------------- | --------------------------------------- | | `phone_number` | Yes | `String` | [E.164](https://en.wikipedia.org/wiki/E.164) format | Phone number with country code to check | | `current_location` | No | `String` | Country alpha-2 code | Current IP address location | ### Response Structure | Key | Type | Constraints | Explanation | | ---------------------- | ------ | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `risk_score` | Float | Min 0, Max 99 | Calculated score indicating how risky the phone number is. | | `country_code` | String | Country alpha-2 code | Two character country code for the phone number. | | `current_network` | String | -- | The full name of the carrier the phone number is associated with. | | `current_route` | String | `mobile`, `landline`, `landline_premium`, `landline_tollfree`, `virtual`, `unknown`, `pager` | The type of network the phone number is associated with. | | `original_network` | String | -- | The full name of the original carrier for the phone number. | | `availability` | String | `unknown`, `reachable`, `undeliverable`, `absent`, `bad_number`, `blacklisted` | Whether the phone number can be called. Applicable to mobile numbers only. | | `validity` | String | `unknown`, `valid`, `not_valid`, `inferred`, `inferred_not_valid` | Whether the number is valid. `inferred_not_valid` means it could not be determined and is likely invalid. Applicable to mobile numbers only. | | `roaming` | String | `unknown`, `roaming`, `not_roaming` | Whether the phone number is outside its home carrier network. | | `roaming_country` | String | Country alpha-2 code | If roaming, the country the phone number is roaming in. | | `roaming_network_name` | String | -- | If roaming, the carrier network the phone number is roaming in. | | `request_id` | String | Max length 40 | The unique identifier for your request. | ### Request Example ```json theme={"system"} { "phone_number": "+12025550163", "current_location": "US" } ``` ### Response Example ```json theme={"system"} { "risk_score": 10.0, "country_code": "US", "current_network": "United States Premium", "current_route": "unknown", "original_network": "United States Premium", "availability": "unknown", "validity": "not_valid", "roaming": "unknown", "roaming_country": null, "roaming_network_name": null, "request_id": "fcecf6e6-1ad7-4d5e-98a8-cc9b2d5575eb" } ``` # Phone Verification Source: https://documentation.idenfy.com/fraud-prevention/phone-verification Verify phone number ownership by sending an SMS or call verification code via the iDenfy API for customer identity and fraud checks. **Requirements** * **API** key pair * Service **enabled** (done by iDenfy staff) * Number verification **credits** Verify identity seamlessly using phone number OTP -- fast verification for genuine users (under 30 seconds), global coverage, 2FA security, and automated onboarding. *** ## Step 1: Send SMS with Verification Code **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/fraud/send-sms` Calling this endpoint sends an SMS message containing a verification code to your user. ### Request Structure | Key | Required | Type | Constraints | Default | Explanation | | -------------- | -------- | -------- | --------------------------------------------------- | -------- | ----------------------------------------------------------------------- | | `phone_number` | Yes | `String` | [E.164](https://en.wikipedia.org/wiki/E.164) format | -- | Phone number with country code to receive the verification code via SMS | | `sender_name` | No | `String` | Max length 11 | `iDenfy` | Name or number displayed as the sender | ### Response Structure | Key | Type | Explanation | | ------------ | -------- | -------------------------------------------- | | `request_id` | `String` | You will need this for the verification step | ```json theme={"system"} { "phone_number": "+12025550163", "sender_name": "The Sender" } ``` ```json theme={"system"} { "request_id": "3d50e1584e0946e789e0185c009aaadf" } ``` **Example SMS message sent to your user:** ``` The Sender code: 1234. Valid for 5 minutes. ``` *** ## Step 2: Verify User-Entered Code **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/fraud/verify-sms` After you send the verification code, your user enters the code they received and you verify whether it is valid. ### Request Structure | Key | Required | Type | Constraints | Explanation | | --------------- | -------- | -------- | ---------------------------- | ------------------------------------------------------- | | `request_id` | Yes | `String` | Min length 32, Max length 40 | The `request_id` returned from the SMS sending endpoint | | `received_code` | Yes | `String` | Length 4 | Numerical verification code entered by the user | ### Response Structure | Key | Type | Explanation | | ------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------- | | `is_verified` | `Bool` | `true` if the code was valid. `false` if the code was invalid, already validated, or the wrong code was provided too many times. | ```json theme={"system"} { "request_id": "3d50e1584e0946e789e0185c009aaadf", "received_code": "1234" } ``` ```json theme={"system"} { "is_verified": true } ``` # Proxy Check Source: https://documentation.idenfy.com/fraud-prevention/proxy-check Detect proxy, VPN, and Tor usage during identity verification sessions using the iDenfy proxy check API with IPv4 and IPv6 support. **Requirements** * **API** key pair * Service **enabled** (done by iDenfy staff) * Finances to perform **proxy check** *** ## IP Address Proxy Check This service checks an IP address and returns its risk level. **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/fraud/proxy-check` ### Request Parameters | Key | Required | Type | Constraints | Explanation | | ------------ | -------- | -------- | -------------- | ------------------- | | `ip_address` | Yes | `String` | `ipv4`, `ipv6` | IP address to check | **Request example:** ```json theme={"system"} { "ip_address": "64.236.213.12" } ``` ### Response Values | Key | Type | Constraints | | ------------ | -------- | --------------------------------------------------------------- | | `risk_level` | `String` | `VERY_LOW`, `LOW`, `MEDIUM`, `HIGH`, `VERY_HIGH`, `NOT_CHECKED` | **Response example:** ```json theme={"system"} { "risk_level": "LOW" } ``` *** **Automatic proxy check on approved verifications** You can enable this setting in the dashboard. When enabled, a proxy check is performed for each approved ID verification before sending the [result webhook](/kyc/webhooks). The result appears in the `clientIpProxyRiskLevel` field of the webhook's `data` object. # Risk Assessment Source: https://documentation.idenfy.com/fraud-prevention/risk-assessment Score verification sessions for fraud risk using iDenfy AI-powered risk assessment profiles with configurable rules and thresholds. **Requirements** * **API** key pair * RA **credits** * RA **profile** created via the [dashboard](/guides/dashboard/risk/how-to-setup-and-configure-risk-assessment) Advanced Customer Risk Assessment Service -- automate KYC, KYB, and AML risk assessments with customizable rules and weights. *** ## How It Works 1. **Create an RA profile** in the [dashboard](/guides/dashboard/risk/how-to-setup-and-configure-risk-assessment) — define sections, questions, and risk weights. 2. **Retrieve the profile** via API to get the section/question keys you need for requests. 3. **Run an RA check** by posting answers (keyed by section and question) against the profile. 4. **Receive a risk score and level** (`VERY_LOW` through `VERY_HIGH`) in the response. Section and question keys (e.g., `bXUsmLJeMI`, `lib-YHlTleSKmo`) are dynamic — they are generated when you create your RA profile. Always retrieve the profile first to get the correct keys for your requests. *** ## RA Profiles ### Retrieve All RA Profiles **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/risk/assessment-profiles/` **Response example:** ```json theme={"system"} [ { "id": "dd121b5c-e3ef-4197-b036-8b7e872f6678", "name": "RA profile name" } ] ``` ### Retrieve Specific RA Profile **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/risk/assessment-profiles/{id}/` #### Request Parameter | Key | Required | Explanation | Type | | ---- | -------- | -------------------------------------------------------- | ------- | | `id` | Yes | A unique integer value identifying this risk assessment. | Integer | **Response example:** ```json theme={"system"} { "id": "61fbe03e-961c-4c6f-a2cd-801083ddbe0d", "name": "Name", "description": "", "sections": [ { "key": "bXUsmLJeMI", "name": "Category", "weight": 100, "questions": [ { "choices": [ { "key": "XOCgRfvUlu", "title": "Yes" }, { "key": "QQALQApLKI", "title": "No" } ], "key": "lib-YHlTleSKmo", "name": "Is shareholder PEP?", "title": "Is shareholder PEP?", "type": "SELECT", "riskLevels": [], "riskLevelDefault": "LOW" }, { "choices": [], "key": "lib-AEgWHKDkwF", "name": "Shareholder residency", "title": "Shareholder residency", "type": "COUNTRY", "riskLevels": [], "riskLevelDefault": "MEDIUM" } ] } ] } ``` *** ## RA Check **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/risk/assessment-profiles/{id}/check/` ### Request Parameters | Parameter | Location | Required | Type | Explanation | | ---------- | -------- | -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | Path | Yes | String | The RA Profile ID for the assessment. Must be a legitimate ID retrieved from [RA profiles](#ra-profiles). | | `sections` | Body | Yes | Object | Object containing section keys and their corresponding values, filled according to the specific profile. Retrieve profile structure from [RA profiles](#ra-profiles). | | `name` | Body | Yes | String | Full name of the person that should be checked. | ```json theme={"system"} { "sections": { "bXUsmLJeMI": { "lib-YHlTleSKmo": { "value": ["XOCgRfvUlu"] }, "lib-AEgWHKDkwF": { "value": ["HU"] } } }, "name": "Matthew Collins" } ``` ```json theme={"system"} { "id": "17CRlVRrxUa91BAMvMdeYP", "name": "Matthew Collins", "sections": [ { "key": "bXUsmLJeMI", "name": "Category", "weight": 100, "questions": [ { "key": "lib-YHlTleSKmo", "name": "Is shareholder PEP?", "type": "SELECT", "title": "Is shareholder PEP?", "choices": [ { "key": "XOCgRfvUlu", "title": "Yes" }, { "key": "QQALQApLKI", "title": "No" } ], "riskLevels": [], "riskLevelDefault": "LOW", "answers": [ { "key": "XOCgRfvUlu", "answer": "Yes", "riskLevel": "LOW", "riskScore": 2 } ] }, { "key": "lib-AEgWHKDkwF", "name": "Shareholder residency", "type": "COUNTRY", "title": "Shareholder residency", "choices": [], "riskLevels": [], "riskLevelDefault": "MEDIUM", "answers": [ { "key": "HU", "answer": null, "riskLevel": "MEDIUM", "riskScore": 3 } ] } ], "riskScore": 5, "maxRiskScore": 5 } ], "riskScore": 100, "riskLevel": "VERY_HIGH", "comment": null, "createdAt": "2024-05-16T08:57:04.654818Z", "updatedAt": "2024-05-16T08:57:04.654821Z", "updateRequired": false, "stateChangeEvent": "INITIAL", "companyId": null, "partner": { "id": 2253, "created": "2023-10-11T14:09:40.458303Z", "companyName": "Name Of Environment TESTING", "environment": "TESTING", "isActive": true }, "profile": { "id": "61fbe03e-961c-4c6f-a2cd-801083ddbe0d", "name": "Name" }, "riskLevelChangedBy": null } ``` *** ## Retrieve RA Checks ### Retrieve All RA Checks **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/risk/assessments/` **Response example:** ```json theme={"system"} { "count": 2, "next": null, "previous": null, "results": [ { "id": "17CRlVRrxUa91BAMvMdeYP", "name": "Matthew Collins", "riskLevel": "VERY_HIGH", "createdAt": "2024-05-16T08:57:04.654818Z", "updateRequired": false }, { "id": "F1WQIFa7EdHAvjanJ0pAKc", "name": "Sarah Robins", "riskLevel": "VERY_LOW", "createdAt": "2024-05-07T12:50:03.816388Z", "updateRequired": false } ] } ``` ### Retrieve Specific RA Check **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/risk/assessments/{id}/` **Response example:** ```json theme={"system"} { "id": "Fi6cT2FO0AoDYyPljKhM41", "name": "Matthew Collins", "sections": [ { "key": "OxTPlZAfHZ", "name": "Second category", "weight": 100, "questions": [ { "key": "lib-NObsdcmGfe", "name": "Is shareholder PEP?", "type": "SELECT", "title": "Is shareholder PEP?", "choices": [ { "key": "HAwWshlziF", "title": "Yes" }, { "key": "WuZBsvsyWC", "title": "No" } ], "riskLevels": [], "riskLevelDefault": "HIGH", "answers": [] }, { "key": "lib-tRdubSLIVr", "name": "Country of Incorporation", "type": "COUNTRY", "title": "Country of Incorporation", "choices": [], "riskLevels": [], "riskLevelDefault": "LOW", "answers": [] } ], "riskScore": 0, "maxRiskScore": 0 } ], "riskScore": 0, "riskLevel": "VERY_LOW", "comment": null, "createdAt": "2024-05-06 09:45:02.405602+00:00", "updatedAt": "2024-05-06 09:45:02.405609+00:00", "updateRequired": false, "stateChangeEvent": "INITIAL", "companyId": null, "partner": { "id": 670, "created": "2022-08-08T06:37:32.765693Z", "companyName": "Mantas Tech", "environment": "DEVELOPMENT", "isActive": true }, "profile": { "id": "dd121b5c-e3ef-4197-b036-8b7e872f6678", "name": "RA profile name" }, "riskLevelChangedBy": null } ``` *** ## Update Existing RA Check **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/risk/assessments/{assessment-id}` ### Request Parameters | Parameter | Location | Required | Type | Explanation | | --------------- | -------- | -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------- | | `assessment-id` | Path | Yes | String | The ID of the RA check. Must be a legitimate ID received from [retrieving all RA checks](#retrieve-ra-checks). | | `sections` | Body | Yes | Object | Section keys from the questionnaire. Required if answers are being changed. Structure must follow the [RA check request](#ra-check) format. | | `name` | Body | Yes | String | Full name of the person being checked. Required if the name is being changed. Structure must follow the [RA check request](#ra-check) format. | The request body (containing `sections` and `name`) is only needed if modifying existing answers or details. ```json theme={"system"} { "sections": { "bXUsmLJeMI": { "lib-YHlTleSKmo": { "value": ["QQALQApLKI"] }, "lib-AEgWHKDkwF": { "value": ["EE"] } } }, "name": "Matthew Collins" } ``` ```json theme={"system"} { "id": "17CRlVRrxUa91BAMvMdeYP", "name": "Matthew Collins", "sections": [ { "key": "bXUsmLJeMI", "name": "Category", "weight": 100, "questions": [ { "key": "lib-YHlTleSKmo", "name": "Is shareholder PEP?", "type": "SELECT", "title": "Is shareholder PEP?", "choices": [ { "key": "XOCgRfvUlu", "title": "Yes" }, { "key": "QQALQApLKI", "title": "No" } ], "riskLevels": [], "riskLevelDefault": "LOW", "answers": [ { "key": "XOCgRfvUlu", "answer": "Yes", "riskLevel": "LOW", "riskScore": 2 } ] }, { "key": "lib-AEgWHKDkwF", "name": "Shareholder residency", "type": "COUNTRY", "title": "Shareholder residency", "choices": [], "riskLevels": [], "riskLevelDefault": "MEDIUM", "answers": [ { "key": "HU", "answer": null, "riskLevel": "MEDIUM", "riskScore": 3 } ] } ], "riskScore": 5, "maxRiskScore": 5 } ], "riskScore": 100, "riskLevel": "VERY_HIGH", "comment": null, "createdAt": "2024-05-16 08:57:04.654818+00:00", "updatedAt": "2024-05-16 08:57:04.654821+00:00", "updateRequired": false, "stateChangeEvent": "INITIAL", "companyId": null, "partner": { "id": 2253, "created": "2023-10-11T14:09:40.458303Z", "companyName": "Name Of Environment TESTING", "environment": "TESTING", "isActive": true }, "profile": { "id": "61fbe03e-961c-4c6f-a2cd-801083ddbe0d", "name": "Name" }, "riskLevelChangedBy": null } ``` # Choosing Your Integration Source: https://documentation.idenfy.com/guides/choosing-integration Compare iDenfy API, SDK, iFrame, redirect, and no-code integration methods side by side to find the best approach for your use case. ## Integration Methods at a Glance | Method | Best for | Time to integrate | UI control | Platform | | -------------- | ----------------------- | ----------------- | ------------------------- | ------------------------ | | **Redirect** | Fastest setup | \~1 hour | iDenfy-hosted | Web | | **iFrame** | Embedded web experience | \~2 hours | Embedded, limited styling | Web | | **Mobile SDK** | Native mobile apps | \~1 day | Full UI customization | iOS, Android | | **Direct API** | Full custom flows | \~1 week | Complete control | Any | | **No-code** | Non-technical teams | \~15 minutes | Plugin-configured | Shopify, WordPress, etc. | *** ## Decision Tree **Yes** → Use the [Mobile SDK](/sdks/overview). It provides native performance, camera access, and liveness detection optimized for mobile. **No** → Continue to Step 2. **Yes** → Use the [Direct API](/kyc/direct-processing). You control every screen and interaction. Most complex, but maximum flexibility. **No** → Continue to Step 3. **Yes** → Use the [iFrame](/kyc/iframe-redirect). Embeds the verification flow in your page. Users never leave your domain. **No** → Use the [Redirect](/kyc/iframe-redirect). Simplest option — redirect users to iDenfy's hosted verification page and get results via webhook. *** ## Detailed Comparison **How it works:** Create a session → redirect user to `redirectUrl` → receive webhook. **Pros:** * Fastest to implement (one API call) * iDenfy handles all UI, camera, liveness * Always up to date — no SDK version management * Works on any device/browser **Cons:** * User leaves your site during verification * No UI customization * Less seamless user experience [Redirect documentation →](/kyc/iframe-redirect) **How it works:** Create a session → embed iFrame with `redirectUrl` → receive webhook. **Pros:** * User stays on your site * Simple implementation * Auto-updated UI **Cons:** * Limited styling (CSS overrides only) * Camera permissions can be tricky in iFrames * Some browsers restrict third-party iFrame features [iFrame documentation →](/kyc/iframe-redirect) **How it works:** Create session → pass `authToken` to SDK → receive callback + webhook. **Pros:** * Native camera and NFC access * Full UI customization (colors, fonts, screens) * Optimized liveness detection * Offline capability for some steps **Cons:** * Requires SDK version management * Separate Android/iOS implementations * Larger app size (\~15-30MB) [Android SDK →](/sdks/android/quickstart) | [iOS SDK →](/sdks/ios/quickstart) **How it works:** Your app handles document capture → send images via API → receive webhook. **Pros:** * Complete UI/UX control * Works on any platform * Can integrate into existing flows **Cons:** * Most development effort * You handle camera, image quality, UX * Must implement error handling for all edge cases [Direct processing →](/kyc/direct-processing) **How it works:** Install plugin → configure in admin panel → verification works. **Pros:** * No coding required * Quick setup (minutes) * Pre-built for popular platforms **Cons:** * Limited to supported platforms * Less customization * Plugin update dependency [Integrations →](/integrations/overview) # Data Residency Source: https://documentation.idenfy.com/guides/compliance/data-residency Learn where iDenfy processes and stores verification data across EU data centers and explore available data residency configuration options. ## Processing Locations iDenfy processes verification data in **EU-based data centers**, ensuring compliance with European data protection regulations. | Data type | Processing location | Storage location | | ------------------------- | ------------------- | ---------------- | | Document images | EU | EU | | Biometric data (liveness) | EU | EU | | Extracted personal data | EU | EU | | AML screening data | EU | EU | | API logs | EU | EU | ## Data Residency Options For customers with specific data residency requirements: | Option | Description | Availability | | ------------------ | ------------------------------------------------------- | --------------------------------------------------------------- | | **EU (Default)** | All data processed and stored within the European Union | All customers | | **Custom regions** | Data processing in specific jurisdictions | Enterprise plans — [book a demo](https://idenfy.com/demo-page/) | Data residency configurations apply to data at rest. Transient processing may involve EU-based infrastructure regardless of residency configuration. Contact your account manager for detailed data flow documentation. ## Sub-Processors iDenfy uses a limited set of sub-processors for service delivery. A current list of sub-processors is available upon request as part of the Data Processing Agreement (DPA). All sub-processors are: * Contractually bound to equivalent data protection obligations * Located within the EU/EEA, or covered by Standard Contractual Clauses * Subject to regular security assessments ## Certifications | Certification | Scope | | -------------- | ------------------------------------------- | | SOC 2 Type II | Security, availability, and confidentiality | | ISO 27001 | Information security management | | GDPR compliant | EU data protection regulation | Need a Data Processing Agreement, sub-processor list, or security questionnaire response? Contact **[dpo@idenfy.com](mailto:dpo@idenfy.com)** or your account manager. # Compliance Source: https://documentation.idenfy.com/guides/compliance/overview Review iDenfy certifications, security standards, and regulatory compliance including ISO 27001, SOC 2 Type II, eIDAS, and GDPR readiness. Trust is the foundation of identity verification. iDenfy is built to meet the strictest regulatory and security standards so you can verify identities with confidence. *** ## Certifications and Standards ### ISO/IEC 27001:2022 Continuously certified since 2020. iDenfy holds an ISO/IEC 27001:2022 certificate (No. 1512120135) issued by TÜV Thüringen under DAkkS accreditation. This certificate covers the development and provision of identity and business verification, fraud prevention and Anti-Money Laundering software. Our most recent surveillance audit found zero non-conformities. ### SOC 2 Type II Independently audited for security, availability and confidentiality. iDenfy's SOC 2 Type II report covers a full 12-month examination period, certified by House of CPA. The report confirms that our controls are properly designed and operate effectively over time. It provides customers and their auditors with documented assurance on how we handle and store data in production. ### eIDAS Conformity Certified for remote identity proofing under EU regulation. iDenfy holds an eIDAS Declaration of Conformity (No. eIDAS250020) issued by the Electrotechnical Testing Institute (EZU) in Prague, covering remote ID proofing using video identification assessed against Regulation (EU) No. 910/2014, ETSI TS 119 461, and ISO/IEC 30107-3:2023. This makes iDenfy one of the few identity verification providers certified to the highest European standards for electronic identification and trust services. ### iBeta / ISO 30107 Liveness and presentation-attack-detection tested. iDenfy's liveness checks and anti-spoofing analysis are independently tested under iBeta and ISO/IEC 30107-3 presentation-attack-detection (PAD) methodology, covering both Level 1 (print and screen attacks) and Level 2 (mask and deepfake-grade attacks). See [SLA & Uptime](/guides/compliance/sla-uptime) for testing details. ### PCI-DSS v4.0.1 Card capture and card image processing for [Bank Card Verification](/guides/dashboard/features/bank-card-verification) run in a dedicated environment certified to PCI-DSS v4.0.1, fully separated from the rest of the platform. No card imagery is retained once processing completes. ### GDPR Fully compliant with the EU General Data Protection Regulation (2016/679). Designated Data Protection Officer, documented Data Processing Agreement (DPA), and all personal data stored within the EU. ### Additional Regulatory Alignment Beyond GDPR, iDenfy's compliance program aligns with CCPA, AML/KYC due diligence obligations, the 5th and 6th EU Anti-Money Laundering Directives (AMLD5/6), PSD2, and FATF recommendations. See [Mapping Features to Requirements](#mapping-features-to-requirements) below for how specific features support each framework. ### Cyber Insurance All iDenfy products are backed by cyber insurance and Technology Errors & Omissions coverage, underwritten at Lloyd's of London. *** ## How iDenfy Handles Compliance ### Data Processing | Area | How we handle it | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Data minimization** | Only required data fields are collected per your verification configuration. We process only what is necessary for the verification purpose. | | **Processing locations** | All data is processed and stored on Amazon AWS Europe (Dublin, Ireland). Data is not transferred outside the EU unless Standard Contractual Clauses are in place. | | **Data residency** | EU-based infrastructure by default. Configurable data residency options available upon request. | | **Retention** | Configurable retention periods with automatic deletion. Default retention follows regulatory requirements (up to 10 years for AML-related records). Customer accounts are removed 60 days after closure. Bank card imagery is an exception and is never retained after processing. | | **Sub-processors** | All sub-processors are documented, contractually bound, and subject to equivalent data protection obligations. Amazon AWS operates under a carve-out approach in our SOC 2 report. | | **Data subject requests** | Responded to within 30 days per GDPR. Customers can export their data at any time before account closure. | ### Audit Trail Every verification produces a complete audit trail including: * Timestamp of each verification step * Document images and extracted data (OCR, MRZ) * Liveness check results with anti-spoofing analysis * Face matching results (document photo vs. selfie) * AML screening results (PEP, sanctions, adverse media) * Manual review decisions by in-house KYC experts (if applicable) * Downloadable PDF verification reports for your compliance records All audit logs are protected with read-only access, file integrity monitoring, and retention of up to 10 years for critical records. ### Security Measures | Measure | Detail | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **Encryption in transit** | TLS 1.2-1.3 on all connections | | **Encryption at rest** | AES-256-GCM on all stored data (databases, object storage, volumes, backups), with additional safeguards applied to biometric data | | **Key management** | Managed key service with automatic rotation at least every 12 months | | **Callback signing** | [Webhook payloads signed](/security/callback-signing) to ensure integrity and authenticity | | **API access control** | [IP whitelisting](/security/ip-whitelisting) available for API access restriction | | **Web Application Firewall** | WAF with anti-DDoS protection | | **Intrusion detection** | Endpoint detection and response (EDR) with cloud-native threat monitoring | | **Network security** | Default deny-all firewall rules; only business-justified traffic permitted | | **Vulnerability management** | Continuous automated scanning and regular penetration testing | | **Vulnerability SLAs** | Critical: 48 hours. High: 7 days. Medium: 1 month | ### Reliability * Role-based access control with mandatory multi-factor authentication (MFA) * Regular penetration testing (see Vulnerability Management above) * 24/7 infrastructure and security monitoring * 99.9% uptime SLA — see [SLA & Uptime](/guides/compliance/sla-uptime) for full details and service credits ### Incident Response * Dedicated Incident Response Team (CEO, Security Officer, CTO) * Response SLAs from immediate (catastrophic) to 2-3 business days (insignificant) * Client breach notification within 8-24 hours of occurrence * Data Protection Authority notification within 72 hours * Root cause analysis and post-incident review after every incident * Incident Response Plan tested annually * Zero security incidents in the past 12 months ### Secure Development * Agile/Scrum methodology with security integrated into every sprint * All code reviewed via pull requests by engineers trained in secure coding * Reviewed against OWASP Top 10 and SANS attack patterns * Vulnerability scanning before every production deployment * Separate development, staging, and production environments * Production data never used in test/dev environments * Annual secure coding training (OWASP principles) for all engineers *** ## Data Protection Roles iDenfy acts as a **Data Processor** when performing identity verification on behalf of clients. Your organization remains the Data Controller and determines the purposes and legal bases for processing. iDenfy acts as a **Data Controller** only for its own website, marketing, and recruitment activities. A standard Data Processing Agreement (DPA) is available for all customers. *** ## Mapping Features to Requirements | Requirement | iDenfy Feature | Relevant Framework | | ----------------------------- | ---------------------------------------------------- | ------------------------------------ | | Customer identification | [ID Verification (KYC)](/kyc/overview) | AML 5/6AMLD, MiCA, PSD2 | | Beneficial owner verification | [Business Verification (KYB)](/kyb/overview) | AML 5/6AMLD, Company Law | | Sanctions & PEP screening | [AML Screening](/aml/overview) | AML 5/6AMLD, OFAC, EU Sanctions | | Ongoing monitoring | [AML Monitoring](/aml/monitoring-create) | AML 5/6AMLD | | Liveness / biometric check | [3D Liveness Detection](/kyc/overview) | eIDAS (Level of Assurance), PSD2 SCA | | Proof of address | [AI PoA Verification](/fraud-prevention/ai-poa) | AML CDD, Gambling regulations | | Data retention & deletion | [Identification Deletion](/kyc/deletion) | GDPR Art. 17 | | Fraud risk assessment | [Risk Scoring](/fraud-prevention/risk-assessment) | PSD2, Internal risk policies | | Re-authentication | [Face Authentication](/face-authentication/overview) | PSD2 SCA, eIDAS | *** ## Regulatory Framework Guides Data protection for processing EU customer data. Covers data minimization, retention, right to erasure, and cross-border transfers. Anti-Money Laundering customer due diligence requirements for financial institutions. EU electronic identification and trust services regulation. Sector-specific requirements: fintech (MiCA, PSD2), crypto (Travel Rule), gambling. Need a Data Processing Agreement (DPA), SOC 2 report, or security questionnaire response? Contact **[dpo@idenfy.com](mailto:dpo@idenfy.com)** or your account manager. # SLA and Uptime Source: https://documentation.idenfy.com/guides/compliance/sla-uptime Review iDenfy Service Level Agreement details including 99.9% API uptime targets, measurement methodology, and service credit policies. ## Service Availability | Service | Target uptime | Measurement period | | ------------------------- | ----------------------- | ------------------ | | ID Verification API | 99.9% | Monthly | | Business Verification API | 99.9% | Monthly | | AML Screening API | 99.9% | Monthly | | Dashboard | 99.5% | Monthly | | Mobile SDKs | Dependent on API uptime | — | Uptime is calculated as: **(Total Minutes - Downtime) / Total Minutes x 100** Uptime is measured as the percentage of time the service responds to API requests with non-5xx status codes, excluding scheduled maintenance windows, customer-caused issues, force majeure, and third-party service outages. *** ## Service Credits If iDenfy fails to meet the uptime commitment, you are entitled to service credits: | Monthly Availability | Service Credit | | ----------------------------------- | ------------------- | | Below 99.90% and at or above 99.50% | 5% of monthly fees | | Below 99.50% and at or above 99.00% | 10% of monthly fees | | Below 99.00% | 20% of monthly fees | * **Credit cap:** 20% of monthly fees for affected services * **Claim deadline:** Written request within 30 calendar days of the incident * Credits are non-transferable and cannot be exchanged for cash * Full SLA terms: [idenfy.com/agreement/#conditions](https://idenfy.com/agreement/#conditions) *** ## Verification Performance | Metric | Target | | ------------------------- | ----------------------------- | | Automated data processing | 0.02 seconds | | User journey completion | \~30 seconds | | Manual review turnaround | On average takes 3 min (24/7) | | Auto approval rate | \~89% fully automatic | | With manual review | Up to 99% approval | | Implementation timeline | 1 week or less | ### Verification Accuracy | Document type | Accuracy | False Positive Rate | False Negative Rate | | ---------------- | ------------ | ------------------- | ------------------- | | ID cards | 99.8% | 0.2% | 1.8% | | Driving licenses | 99.4% | 0.6% | 5.5% | | Face matching | Above 99.99% | FAR below 0.01% | FRR below 2% | Face matching tested to iBeta Level 1 and Level 2 standards. *** ## Scheduled Maintenance * Maintenance window: **01:00-07:00 (GMT+3)** * Customers notified at least **24 hours** in advance * Scheduled during low-traffic periods * Zero-downtime deployments used where possible * Emergency maintenance may occur outside scheduled windows with immediate notification *** ## Incident Response ### Priority Levels | Priority | Description | Response time | | ---------- | ----------------------------------------------------------------------- | ----------------------------------------------- | | **High** | Service fully unavailable or system malfunction making tasks impossible | 30 minutes (working hours), 2 hours (off-hours) | | **Normal** | Major feature degraded but service still usable | Standard support during working hours | | **Low** | Minor issue with no significant service impact | Best effort | ### Security Incident Response For security incidents, a dedicated Incident Response Team follows escalated SLAs: | Severity | Response time | | ---------------- | ------------- | | **Catastrophic** | Immediate | | **Major** | 2-4 hours | | **Moderate** | 4-6 hours | | **Minor** | 6-12 hours | * Client breach notification: **Within 8-24 hours** of occurrence * Impact assessment provided: **Within 24 hours** * Root cause analysis conducted after every incident * Incident Response Plan tested annually ### Recovery Objectives | Component | RPO (Recovery Point Objective) | RTO (Recovery Time Objective) | | ------------------------- | -------------------------------- | ----------------------------- | | Core platform databases | 24 hours | 4 hours | | Blob/binary storage | 0 hours (continuous replication) | 72 hours | | Infrastructure durability | 99.999999999% (eleven 9s) | — | All backups are encrypted to the same standard as production data (AES-256-GCM) and monitored via audit logging. *** ## Status Monitoring Monitor iDenfy service status at **[status.idenfy.com](https://status.idenfy.com/)**. Subscribe to status updates for real-time incident notifications via email or webhook. *** ## Monthly Reporting All customers receive a monthly report covering: * Verification preventions and outcomes * Service malfunctions (date, time, duration, explanation) * Uptime statistics for the billing period *** ## Support Channels | Channel | Availability | Best for | | -------------------------------------------------------------------------------------------- | ---------------------------------- | ---------------------------------------- | | [Jira Service Desk](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) | 24/7 ticket submission | Technical issues, bugs, API questions | | Account manager | Business hours (09:00-18:00 GMT+3) | Contract, features, escalation | | Enterprise Slack channel | Business hours | Dedicated support for enterprise clients | | [techsupport@idenfy.com](mailto:techsupport@idenfy.com) | Business hours | Technical support requests | | [info@idenfy.com](mailto:info@idenfy.com) | Business hours | General inquiries | | [Sign up](https://idenfy.com/pricing-plans-v4/) / [Book demo](https://idenfy.com/demo-page/) | — | New accounts, pricing | For production-critical issues, contact your account manager directly for fastest escalation. Include your `scanRef` or API key identifier in any support request. Free business consultations are available during working hours for all customers. *** ## Data Retention by Plan | Plan | Retention period | | ------- | ------------------------------------------------------------ | | Startup | 3 years | | Silver | 5 years | | Gold | 8 years | | Custom | Configurable (immediate deletion, 30 days, or up to 8 years) | # Age Estimation Billing Source: https://documentation.idenfy.com/guides/dashboard/age-estimation/billing How iDenfy bills age estimation: the dedicated Age Estimation finances it draws on, when each estimation fee applies, and what the document step-up costs. Age Estimation is billed against **Age Estimation finances** -- allocated to your account separately from your general funds. * Both the age-estimation fee and the document step-up fee draw on those finances. The step-up is charged as an **Age Estimation Document Scan**, so your general document scan credits are never used and it does not appear against your document scan usage. * **Without available Age Estimation finances the feature is unavailable**, no matter how much general balance the account holds -- session creation is rejected. * The age-estimation fee is charged once per terminal result, on both `COMPLETED` and `FAILED`. Sessions that merely expire are not charged. * The Age Estimation Document Scan fee follows standard document verification billing: charged when the document check completes, and on failure only if your account is configured to charge all completed verifications. * Age Estimation finances can carry their own expiration, independent of your other funds. At session creation your Age Estimation finances are pre-checked for both applicable fees; if they can't cover the session the request is rejected -- see [error responses](/age-estimation/create-session#errors) for how this surfaces on the API. # Age Estimation Dashboard Source: https://documentation.idenfy.com/guides/dashboard/age-estimation/dashboard Create age estimation sessions from the iDenfy dashboard and browse results with status filter groupings, session detail views, and document step-up links. Age Estimation sessions created via the API or the dashboard can be browsed from the dashboard's Age Estimation section. Viewing session data requires the **View age estimation data** permission, which is enabled for all partners by default; creating sessions requires the `MANAGE_AGE_ESTIMATION` permission on your manager account. For what the statuses and outcomes below mean, see the [Age Estimation Overview](/guides/dashboard/age-estimation/overview#statuses-and-outcomes). ## Creating a Session **Create new** on the Age Estimation page opens the **New estimation** form, split across two tabs: **General settings** and **Verification redirects**. Between them you set the age requirement, when to fall back to ID verification, and how each session behaves. The New estimation form in the iDenfy dashboard, showing the General settings tab with fields for minimum age, safety margin in years, a toggle for ID verification on uncertain results, retry limit, a toggle for saving the selfie photo, and a link expiry time dropdown, above the verification URL field and Create button. ### General Settings | Setting | Description | | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Minimum age** | The age a person must reach to pass the check, for example 18. Accepts 1--120. | | **Safety margin (years)** | How close an estimate can be to the minimum age before it counts as uncertain, rather than a clear pass or fail. A wider margin marks more results as uncertain, and what happens to them then depends on the ID verification setting below. With a minimum age of 18 and a margin of 2, estimates from 16 to 20 count as uncertain. Accepts 0--20, and cannot exceed the minimum age. | | **ID verification for uncertain results** | When on, an uncertain result asks the person to scan an ID document, and the photo in the document is compared with their selfie to confirm their age. The check is charged as an Age Estimation Document Scan from your [Age Estimation finances](/guides/dashboard/age-estimation/billing). Turn it off to end the session as **Uncertain** instead. | | **Retry limit** | How many times a person can retake the selfie after a technical problem, such as poor lighting, before the check fails. Accepts 1--3. | | **Save selfie photo** | Keep the selfie so you can review it or check accuracy later. Turn it off to store no image -- and if ID verification runs, the user and document data aren't saved either. | | **Link expiry time** | How long the estimation link stays valid after it's created, chosen from a preset list. | ### Verification Redirects | Setting | Description | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Success / Underage / Uncertain redirect URL** | Where to send the person after each outcome. Leave empty to show the standard result screen. | | **Webhook URL** | Where to send the final result. Falls back to your account's Age Estimation notification URL when empty -- see [Age Estimation Webhooks](/age-estimation/webhooks). | **Create** submits both tabs at once -- the session is created with everything entered across General settings and Verification redirects. The verification URL then appears in the bar at the bottom of the page, with a button to copy it. ## Session List Sessions are grouped by their final status: | Group | Meaning | | ------------------- | ------------------------------------------------------------------------------------------ | | **Results** | Completed sessions with outcome **Success** or **Underage**. | | **Needs Attention** | Outcome **Uncertain** / **Face Mismatch** / **Attempts Exceeded**, or a technical failure. | | **In Progress** | Awaiting or undergoing capture, not yet expired. | | **Expired** | Lapsed without a result. | Each row shows the session ID, its status and outcome, the estimated age, and the creation date. Sessions can be filtered by client ID and creation date, sorted by creation date, and searched by session ID or client reference. A session that escalated to a document check can also be found by its step-up scan reference. ## Session Detail Opening a session shows: * **Result** -- status, outcome, and the estimated age. * **Settings** -- the session ID, when it was created and when it expires, plus the session's configuration: minimum age, safety margin, step-up mode, retry limit, and whether the selfie was saved. * **Media** -- the analyzed selfie, when saving photos was enabled for that session. If **Save selfie photo** was off, **Selfie storage is off** is shown in its place. * **ID verification** -- if the session escalated to a document check, a block showing the check method, its result, and when it ran. That verification is billed as an Age Estimation Document Scan from your [Age Estimation finances](/guides/dashboard/age-estimation/billing), so it won't appear against your document scan usage. With **Save selfie photo** on, the block links through to the underlying identity verification, so you can review the document and any fraud flags raised on it. With it off, the block shows the check details only and does not link through -- the document and personal data were used to establish the age and nothing was stored. Such verifications also stay out of the identity verification review list and are never sent to manual review. * **Estimated age** -- not shown when the age came from a document step-up rather than the AI estimate, since the document gives an exact date of birth. Fields that have no value yet -- on a session that is still pending, or one that expired without a result -- are shown as **—**. A step-up document that was accepted but flagged for possible fraud still resolves the age estimation session normally (**Success** / **Underage**). The fraud flag is not shown on the age estimation session itself -- open the linked identity verification to review it. # Age Estimation Overview Source: https://documentation.idenfy.com/guides/dashboard/age-estimation/overview How iDenfy's selfie-based age estimation works: the session flow, document step-up outcomes, and the statuses and outcomes a session can resolve to. Looking for **Age Verification** instead? That's a different, simpler feature -- a min/max age restriction applied during a full KYC verification, based on the scanned document's date of birth. See [Age Verification](/guides/dashboard/kyc/age-verification). Age Estimation checks whether an end user meets a minimum age requirement using a single selfie -- no document scan required in the common case. It's suited for age-gating use cases (e.g. alcohol, gambling, adult content) where you need a fast yes/no decision without putting every user through a full identity verification. When the AI model isn't confident enough to decide on its own, the session can automatically step up to a document check, which reads an exact date of birth from the ID. Sessions can be created and reviewed [from the dashboard](/guides/dashboard/age-estimation/dashboard), or created programmatically -- see [API integration](#api-integration). Charges draw on finances allocated to Age Estimation; see [Age Estimation Billing](/guides/dashboard/age-estimation/billing). Results reach your systems through the [result webhook](/age-estimation/webhooks). To list past estimations, filter them, or inspect an individual session, sign in to the dashboard -- there is no Partner API endpoint for retrieving sessions. ## How a Session Flows You create a session with the desired settings. You get back a verification link and an expiry time. You send the end user to the verification link; they complete the selfie on the hosted capture page. The AI produces an age estimate: * Confident and above the minimum age → **Success**. * Confident and below the minimum age → **Underage**. * Not confident (within the safety margin) → **step-up**, if enabled: * document step-up enabled → a document check is created and the age is read from the ID's date of birth (see [Step-Up Outcomes](#step-up-outcomes)). * document step-up disabled → the session resolves as **Uncertain**. When the session finishes, iDenfy sends a result notification to your webhook (if set), redirects the user to the matching redirect URL (if configured), and shows the outcome in the dashboard. ## Step-Up Outcomes A document step-up ends in one of the following ways. Note that the document's date of birth is an **exact** age, so it is compared directly against the minimum age -- the safety margin applies only to the fuzzy AI estimate and is not used here. | Document check result | What happens | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Document accepted** | The date of birth is read and the ID portrait is compared against the capture selfie. On a match the session resolves as **Success** (age ≥ minimum) or **Underage**. | | **Document accepted but flagged for possible fraud** | Treated the same as accepted: the document was read successfully, so its age is used and the session resolves as **Success** or **Underage**. The fraud flag is retained by iDenfy for review and is **not** currently reported in the result notification. | | **Document rejected** | The age could not be established from the ID, so the session resolves as **Uncertain**. This is terminal -- the end user is not re-prompted for another ID. | | **Face did not match** | The ID does not appear to belong to the person who took the selfie; the session resolves as **Face Mismatch**. This is terminal. | | **Step-up abandoned or lapsed** | The end user backed out, or the document session expired before completion. The session stays live and the end user can start a step-up again, subject to the retry limit. | **Fraud-flagged documents are accepted.** iDenfy may flag a document session for possible fraudulent activity even when the document itself was read and the face matched. Because the purpose of the step-up is to establish the age, such a session yields a normal **Success** / **Underage** result rather than **Uncertain**. If your own risk policy needs to act on the fraud signal, contact iDenfy -- surfacing it in the result notification is planned but not yet available. ## Statuses and Outcomes A session has a lifecycle **status**, and once it finishes, an **outcome**. The values below are what the API returns; the dashboard shows the same values as labels. **Status** | Value | Meaning | | ------------ | --------------------------------------------------------------------- | | `PENDING` | Created, awaiting/undergoing capture. | | `PROCESSING` | Reserved lifecycle state. | | `COMPLETED` | Finished with a definitive result. | | `FAILED` | Finished unsuccessfully (technical failure or unrecoverable outcome). | | `EXPIRED` | Session lapsed without a terminal result. | **Outcome** | Value | Dashboard label | Meaning | | ------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SUCCESS` | Success | Meets the minimum age. | | `UNDERAGE` | Underage | Below the minimum age. | | `UNCERTAIN` | Uncertain | Inconclusive: an uncertain estimate with the step-up disabled, a document step-up whose document was rejected, or a technical failure during the step-up. | | `FACE_MISMATCH` | Face Mismatch | Step-up document face did not match the selfie. | | `ATTEMPTS_EXCEEDED` | Attempts Exceeded | Retry limit reached without a decision. | ## API Integration Create a session from your backend, with the full request schema and error responses. Receive the outcome as soon as a session finishes. # AML Available Sanctions Lists Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-available-sanction-lists Browse the complete list of global sanctions, PEP, and watchlist databases screened by iDenfy AML, organized by region and country. iDenfy screens against sanctions lists from every major regime worldwide. Below is the full list organized by region. *** ## Americas | Country | Source | List | | ----------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Argentina** | Ministry of Justice and Human Rights | Public Registry of Individuals and Entities linked to Acts of Terrorism (REPET) | | **Canada** | Global Affairs, Government of Canada | Sanctions under UN Act, Special Economic Measures Act, Justice for Victims of Corrupt Foreign Officials Act, Freezing Assets of Corrupt Foreign Officials Act | | **Canada** | Public Safety, Government of Canada | Canadian Government Sanctions (Listed Terrorist Entities) | | **Panama** | Financial Analysis Unit (UAF) | UAF National Sanctions List | | **Trinidad and Tobago** | Financial Intelligence Unit (FIU) | Notices and High Court Orders Under Anti-terrorism Act | | **USA** | OFAC | SDN List (30+ programs), non-SDN lists (SSI, FSE, NS-PLC, CAPTA, NS-MBS, NS-CMIC) | | **USA** | Department of State | Section 7031(c) Designations, Foreign Terrorist Organizations, CAATSA Section 231(e), Bureau of International Security Nonproliferation Sanctions | *** ## Asia-Pacific | Country | Source | List | | --------------- | ------------------------------------ | ------------------------------------------------------------------ | | **Australia** | Australian National Security | Listed Terrorist Organisations | | **Australia** | Dept of Foreign Affairs and Trade | Autonomous Sanction List, Consolidated List | | **Bangladesh** | Central Bank | Domestic Sanctions List | | **China** | Ministry of Foreign Affairs | Chinese Ministry of Foreign Affairs | | **China** | Ministry of Public Security | Terrorist List | | **China** | Taiwan Affairs Office | Anti-Secession Law | | **India** | Ministry of Home Affairs | Banned Organisations, Designated Terrorists, Unlawful Associations | | **Indonesia** | Financial Transaction Reports Centre | DTTOT, Proliferation WMD List | | **Japan** | Ministry of Finance | Economic Sanctions | | **Japan** | National Public Safety Commission | Terrorist Lists | | **Japan** | METI | METI List, Ukraine Response List | | **South Korea** | Financial Services Commission | KOFIU Financial Restrictions | | **South Korea** | Ministry of Economy and Finance | Payment Guidelines for International Peace | | **Malaysia** | Ministry of Home Affairs | Ministry of Home Affairs List | | **New Zealand** | Police Force | Designated Terrorists | | **New Zealand** | Ministry of Foreign Affairs | Russia Sanctions Regulations 2022 | | **Pakistan** | NACTA | Proscribed Persons and Entities | | **Philippines** | Anti-Money Laundering Council | Sanctions Freeze Orders, Listed Terrorist Organizations | | **Singapore** | Ministry of Home Affairs | Ministry of Home Affairs List | | **Singapore** | Monetary Authority | Designated Individuals and Entities | | **Sri Lanka** | Ministry of Defence | Sanctions on Terrorism and Terrorism Financing | | **Taiwan** | Ministry of Justice | Counter-Terrorism Financing Act Sanctions | | **Thailand** | Anti-Money Laundering Office | Designated Lists | | **Vietnam** | Ministry of Public Security | Terrorism-related Organisations and Individuals | *** ## Europe | Country | Source | List | | --------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | **Belgium** | Federal Public Service Finance | National Financial Sanctions | | **Bulgaria** | Council of Ministers | Financing of Terrorism Act List | | **Czechia** | Ministry of Foreign Affairs | National Sanctions List | | **EU** | European Union Council | 55+ programs covering Afghanistan, Belarus, China, Iran, Russia, Syria, Ukraine, terrorism, cyber, human rights, and more | | **France** | Ministry of Economy/Finance | DG Treasury Restrictive Measures | | **Georgia** | Government | Otkhozoria-Tatunashvili List | | **Kazakhstan** | Financial Monitoring Committee | Terrorism and Extremism Financing List | | **Kyrgyzstan** | State Service of Financial Intelligence | Consolidated Sanctions List | | **Latvia** | Financial Intelligence Unit | Sanction Lists | | **Lithuania** | Ministry of the Interior | Financial Crime Investigation Service, Migration Travel Ban | | **Malta** | Sanctions Monitoring Board | Sanctioned Entities | | **Monaco** | Minister of State | National Asset Freezing List | | **Netherlands** | Dutch Government | National Terrorism Sanctions List | | **Poland** | Ministry of Interior | Persons and Entities Subject to Sanctions | | **Serbia** | Directorate for Prevention of Money Laundering | Domestic List of Terrorists | | **Switzerland** | SECO | Sanctions List | | **Tajikistan** | National Bank | Designated Terrorists | | **Turkey** | Ministry of Interior | Most Wanted Terrorists | | **Turkey** | MASAK | Asset Freeze Lists (A, B, C, D) | | **Ukraine** | National Security and Defence Council | NSDC Sanctions List | | **UK** | HMT/OFSI | 30+ programs covering Afghanistan, Belarus, Counter-Terrorism, Iran, Russia, Syria, and more | | **UK** | Home Office | Proscribed Terrorist Groups | | **Uzbekistan** | Department for Combating Economic Crimes | Foreign and Uzbekistani Citizens Lists | *** ## Middle East and Africa | Country | Source | List | | ---------------- | ------------------------------------------------------- | -------------------------------------------------------------- | | **Bahrain** | Ministry of Foreign Affairs | Bahrain Terrorist List | | **Egypt** | Money Laundering and Terrorist Financing Combating Unit | EMLTFCU List | | **Iran** | Ministry of Foreign Affairs | Iran Sanctions List | | **Israel** | Ministry of Defence | Counter Terror Financing Lists, Seizures of Terrorist Property | | **Jordan** | Technical Committee for UNSC Resolution Implementation | National List of Terrorists | | **Lebanon** | Internal Security Forces | National Terrorism and Financing List | | **Nigeria** | Nigeria Sanctions Committee | Sanctions List | | **Qatar** | National Counter Terrorism Committee | National List of Terrorists | | **Saudi Arabia** | Presidency of State Security | Permanent Counter Terrorism Committee | | **Tunisia** | National Anti-Terrorist Commission | NATC List | | **UAE** | Committee for Import/Export Control | National List of Terrorist Individuals and Entities | *** ## International | Organization | List | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **United Nations Security Council** | Resolution 751 (Al-Shabaab), Resolutions 1267/1989/2253 (ISIL/Al-Qaida), Resolution 1518 (Iraq/Kuwait), Resolution 1533 (DRC), Resolution 1591 (Sudan), Resolution 1636 (Lebanon), Resolution 1718 (DPRK), Resolution 1970 (Libya), Resolution 1988 (Taliban), Resolution 2048 (Guinea-Bissau), Resolution 2127 (CAR), Resolution 2140 (Yemen), Resolution 2206 (South Sudan), Resolution 2653 (Haiti) | # AML Check Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-check Run a single AML screening check against sanctions, PEPs, and adverse media databases from the iDenfy dashboard with step-by-step guide. For detailed explanations of AML terms, datasets, and filters, visit [AML - Key Terms & Concepts](/guides/dashboard/aml/aml-key-terms-concepts) ## Dashboard Navigation for AML Check 1. In the dashboard, navigate to the ***AML verifications*** section 2. Select ***AML check*** 3. In the top right corner, *click* ***Check AML*** image-20251015-135249.png *** ## AML Check — Quick Guide Use this form to create a new AML (Anti-Money Laundering) check for a person or company. It screens your subject against selected datasets such as **Sanctions**, **PEPs**, and others. *** ### 1. Enter Subject Details Fill in the identifying information for the person or company you want to screen. * **Full name** — required. * **Client ID** — optional internal reference. * **Date of birth / Gender** — helps narrow results. * **Address or nationality** — adds context and reduces false matches. Make sure all required fields are completed before continuing. *** ### 2. Apply Filters Fine-tune your search by selecting which datasets and parameters to use. * **Datasets** — select what to check (e.g., *PEP*, *Sanction*, *Adverse Media*). * **Matching threshold** — sets how closely the results must match. * **PEP status** — include current, former, or linked PEPs. * **Sanctions status** — include current or former sanctions. * **Sanction databases** — specify or exclude certain lists if needed. Adjust these filters depending on your screening requirements. *** ### 3. Create or Discard Once all required information is filled in: * Click **Create** to start the AML check. * Click **Discard** to cancel. If the “Create” button is disabled, review the form and complete any missing fields. image-20251015-135815.png After submission, the system returns a list of potential matches. Review each one to confirm whether it refers to your subject. *** ## Check Results AML check results ### Search Parameters Displays the details used in the check — your reference for what was searched. The top row shows the subject identity: * **Full name** — the entered name of the person or company * **Address or nationality** — country or region used in the search * **Date of birth** — full or partial, if provided Expand the row to see the full screening configuration: | Field | Description | | ---------------------- | -------------------------------------------- | | **Matching threshold** | Minimum similarity score used (e.g. 95%) | | **Birth year range** | DOB range applied to narrow results | | **PEP tier** | Which PEP tiers were included (Tier 1, 2, 3) | | **PEP status** | PEP CURRENT, PEP FORMER, PEP LINKED | | **Sanctions status** | SAN CURRENT, SAN FORMER | | **Datasets** | Screening databases included (e.g. PEP, SAN) | | **Sanction databases** | Any sanction lists excluded from screening | *** ### Check Status | Column | Description | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------- | | **Check status** | Current review state: `Flags found` (unreviewed matches exist), `True positive`, `False positive`, `Under review`, or `Clear` | | **Check ID** | Unique identifier for this check | | **Client ID** | Your internal customer reference | | **Status set by** | The user who last changed the status | | **Status set at** | When the status was last changed | | **Comment** | Optional review note | | **Check date** | When the screening ran | *** ### Found Matches When matches exist, each row in the table is a potential profile. Review each one — small differences such as birth year or nationality often determine whether a match is genuine or false. | Column | Description | | -------------------------- | ----------------------------------------------------------------------- | | **Full name** | Matched entity's name as listed in the dataset | | **Date of birth** | If available in the source | | **Address or nationality** | Country or region linked to the record | | **Datasets** | Which databases triggered the match (e.g. `PEP CURRENT`, `SAN CURRENT`) | | **Match score** | Confidence level (0–100) showing how close the match is to your subject | | **Select status** | Mark the match as `True positive`, `False positive`, or `Under review` | | **Comment** | Add context or reasoning for future reference | Click any matched row to open its full profile — see [AML Profiles](/guides/dashboard/aml/aml-profiles) for a full description of all tabs and fields. *** ## Additional Functions Inside *Check* image-20251017-101711.png The toolbar at the bottom of the check provides the following actions: * **History** — previous screening runs and rechecks for this check * **Comments** — internal notes left by managers * **Recheck** — runs a new screening with adjusted filters; each recheck consumes one credit * **Add to monitoring** — enrols the subject in ongoing daily screening; opens the monitoring creation pop-up pre-filled with the subject's details * **Save** — saves any pending status changes on matched profiles image-20251017-102102.png *** ## Download Click **Download PDF** in the page header to export the check report, including search parameters, check status, and all matched profiles. # AML Screening from Identity Verifications Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-from-verification Run AML checks and add subjects to monitoring directly from completed KYC identity verifications in the iDenfy dashboard — manually or automatically. AML checks and monitoring can be linked to a specific KYC identity verification, associating the screening result with the subject who completed the verification. There are three ways to do this. *** ## Automatic Checks for All Verifications You can configure iDenfy to run an AML check automatically for every completed identity verification, without any manual action. Enable this in [AML & Fraud Prevention settings](/guides/dashboard/settings/aml-fraud-prevention#anti-money-laundering-aml). Once active, PEP, Sanctions, and Adverse Media checks run for all identity verifications as part of the verification flow. *** ## From the Verification Page To run a check or add a subject to monitoring from a specific verification: 1. Open the identity verification 2. Click **View AML** in the toolbar at the bottom of the page 3. Select one of the two options from the dropdown: * **Check AML** — runs a one-time AML check using the subject's details from the verification * **Add to monitoring** — opens the monitoring creation form pre-filled with the subject's name, nationality, and date of birth *** ## From the AML Check Window Using Scan Ref To associate an AML check with a verification using its reference ID: 1. Copy the **scanRef** from the identity verification 2. Navigate to **AML Verifications** → **AML Check** 3. Click **Check AML** in the top right corner 4. In the pop-up, select **Verification** 5. Paste the scanRef into the **Verification scan ref** field 6. Select what to screen for: **PEPs & Sanctions**, **Adverse media**, or both # AML Key Terms and Concepts Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-key-terms-concepts Learn essential AML screening terminology including person and company types, datasets, matching filters, and result interpretation. *** ## Types **Person:** full name, date (or year) of birth, nationality, and (if available) ID numbers. **Company:** legal name, registration number, country, and known aliases. The more accurate the data, the fewer false matches. If two people share the same name, **date of birth + country**, usually confirms the right one. *** ## Datasets ### For Individuals * **PEP** — all Politically Exposed Persons: current, former, and linked. * **PEP-CURRENT** — only current public figures holding active positions. * **PEP-FORMER** — only former public figures who previously held positions of power. * **PEP-LINKED** — people associated with a PEP (family, close contacts). * **SAN** — all sanctions, including current and former listings. * **SAN-CURRENT** — only currently sanctioned individuals. * **SAN-FORMER** — only previously sanctioned individuals. * **RRE** — Reputational Risk Exposure: adverse media where an authority has taken action. See [RRE Dataset Overview](/guides/dashboard/aml/rre-overview). * **REL** — Regulatory Enforcement Lists: fines, bans, warnings, or official enforcement actions. * **POI** — Profiles of Interest: regions or entities connected to higher risk. * **DD** — Disqualified Directors dataset. * **INS** — Insolvency Register. *** ### For Businesses * **PEP** — all Politically Exposed Persons: current, former, and linked. * **PEP-LINKED** — associates or family members of a PEP. * **SAN** — all sanctions, both current and former. * **SAN-CURRENT** — only active sanctions. * **SAN-FORMER** — only previously listed sanctions. * **RRE** — Reputational Risk Exposure: adverse media where an authority has taken action. See [RRE Dataset Overview](/guides/dashboard/aml/rre-overview). * **REL** — Regulatory Enforcement Lists. * **POI** — Profiles of Interest. * **INS** — Insolvency Register. * **SOE** — all State-Owned Enterprises: current and former. * **SOE-CURRENT** — currently state-owned entities. * **SOE-FORMER** — entities that were formerly state-owned. **Tip:** You don’t always need all datasets. Most teams include **Sanctions (SAN)** and **PEP**, and add **RRE** or **REL** for additional context. **RRE and REL are both adverse media, but they behave differently.** RRE is editorially assessed, category-based, and applies financial thresholds to some crime types. REL aggregates published enforcement entries with no thresholds. Screening both is what closes the gap between them — see [RRE Dataset Overview](/guides/dashboard/aml/rre-overview). *** ## Filters — How Strict the Search Is **Match threshold:** Defines how closely a record must match your subject. * Higher threshold = stricter, fewer false positives (but may miss small variations). * Lower threshold = broader, catches more potential matches (but increases noise). **Birth-year tolerance:** Adds a small ± range when you’re not certain about the exact birth date. **PEP options:** Select whether to include current, former, or linked individuals. **Sanctions status:** Limit to current listings or include previously removed ones. **Regions & sources:** Narrow your search to specific countries or datasets when relevant to your business. *** ## Results If the provided details match anyone in the databases, you’ll receive potential profiles to review: * **Name and identifiers** — who the record is about. * **Why it matched** — name, date of birth, or country similarity. * **Source** — which list, register, or article it came from. * **Confidence signals** — matching elements like DOB or nationality. *** ## Good Habits * Always use the subject’s full legal name. * Add date of birth and country whenever possible. * Record a short reason when dismissing a false match. * Stay consistent as a team in how you review and escalate. * Run a new check whenever key information changes (new role, country, or large transaction). *** ## Quick Glossary * **AML check:** screening for potential financial crime or compliance risk. * **Profile:** a potential match that requires review. * **PEP:** a public figure or close contact who carries higher corruption risk. * **Adverse media / RRE:** criminal conduct reported by official sources or by media covering official action — not negative press in general. * **Sanctions:** official “do not deal” lists from governments or international bodies. * **False positive:** a result that looks similar but is not your subject. * **Monitoring:** scheduled or automatic re-checks over time. # AML Monitoring Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-monitoring Set up and manage continuous AML monitoring with daily sanctions, PEP, and adverse media screening for individuals and companies in the iDenfy dashboard. ## Monitoring Vs. Single Check AML Monitoring performs a **recurring daily check** on a subject — scanning them against PEP, Sanctions, and Adverse Media databases every 24 hours for as long as monitoring is active. A single AML check runs once and returns results immediately. You can also start monitoring directly from any completed AML check result (within an ID verification or a standalone AML check) by clicking **Add Monitoring** at the bottom of the finding. *** ## Creating AML Monitoring There are two ways to start monitoring a subject. ### From the AML Monitoring List Navigate to **AML Verifications** → **AML Monitoring** and click **New Monitoring** in the top right corner. AML Monitoring list with New Monitoring button A pop-up window will appear. Fill in the subject's details: New monitoring creation pop-up ### From a Verification Window Open any ID verification, then click **View AML** in the toolbar at the bottom of the page. A dropdown appears with two options: * **Add to monitoring** — opens the monitoring creation pop-up pre-filled with the subject's details from the verification * **Check AML** — runs a one-time AML check instead Using **Add to monitoring** from a verification is the fastest way to enrol a verified subject — their name, nationality, and date of birth are carried over automatically. ### Fields | Field | Required | Description | | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Type** | Yes | `Person` or `Company` | | **Full name / Company name** | Yes | For persons, enter the full name as a single combined field. Company names accept up to 200 characters | | **Date of birth** | No | Persons only. Improves match accuracy by narrowing results to the correct age range | | **Nationality / Country** | No | Improves screening accuracy by filtering results to the relevant jurisdiction | | **Gender** | No | Persons only. `Male`, `Female`, or `Other` | | **AML Tags** | No | Up to 5 custom tags (max 100 characters each) for filtering and organizing the monitoring list. Configured in [AML Settings](/guides/dashboard/settings/anti-money-laundering-aml#aml-monitoring-tags) | | **Auto monitoring extension** | No | Extends the 365-day monitoring period automatically each year. Enabled by default — each renewal costs one credit | All monitoring entries use the AML matching thresholds, filters, and dataset configuration set in your [AML Settings](/guides/dashboard/settings/anti-money-laundering-aml). These cannot be adjusted per-entry at creation time. Adverse Media monitoring cannot be enabled on its own — it requires PEP & Sanctions screening to be active on your contract. *** ## Filtering the Monitoring List The monitoring list has two tabs — **Person** and **Company** — to switch between individual and business records. If a subject is not visible, confirm you are on the correct tab. Use the **sort dropdown** to order results: | Option | Description | | ---------------------------------------- | ----------------------------------------------- | | Check date newest / oldest | Order by when the monitoring record was created | | AML check date newest / oldest | Order by the last PEP & Sanctions screening run | | Adverse media check date newest / oldest | Order by the last adverse media screening run | *** ## Monitoring Results Opening a monitoring record shows three sections: the search parameters the record was created with, the current monitoring status, and all matched profiles (findings). AML monitoring results page overview ### Search Parameters Displays the subject details and screening configuration used for this monitoring record. The top row shows: * **Full name** — the monitored subject's name * **Address or nationality** — country code used in screening * **Date of birth** — if provided at creation Expand the row to see the full configuration: | Field | Description | | ---------------------- | ------------------------------------------------- | | **Matching threshold** | Minimum similarity score used (e.g. 95%) | | **Birth year range** | DOB range applied to narrow results | | **PEP tier** | Which PEP tiers were included (Tier 1, 2, 3) | | **PEP status** | PEP CURRENT, PEP FORMER, PEP LINKED | | **Sanctions status** | SAN CURRENT, SAN FORMER | | **Datasets** | Screening databases included (e.g. PEP, SAN, RRE) | | **Sanction databases** | Any sanction lists excluded from screening | *** ### Monitoring Status Summarises the current state of the monitoring record: | Column | Description | | ------------------- | ----------------------------------------------------------------------------------------------- | | **Review status** | `Flags found` if at least one unresolved match exists; `Clear` otherwise | | **Monitoring ID** | Unique identifier for this monitoring record | | **Client ID** | Your internal reference, set at creation | | **Status set by** | The user who last changed the status | | **Status set at** | When the status was last changed | | **Comment** | Optional review note | | **AML tags** | Tags assigned to this record for filtering | | **Check date** | The date of the most recent update to the finding (e.g., new evidence or changes to sanctions). | | **Expiration date** | When monitoring expires (365 days from creation unless auto-renewed) | *** ### Found Matches Matched profile in AML monitoring Each matched profile row shows the following columns: | Column | Description | | -------------------------- | -------------------------------------------------------------------------- | | **Full name** | Matched entity's name, with alias match shown as a badge if applicable | | **Date of birth** | Matched entity's date of birth | | **Address or nationality** | Country associated with the matched profile | | **Datasets** | Which screening databases flagged this profile (e.g. `SAN CURRENT`, `POI`) | | **Match score** | Confidence score (0–100) for the name match | | **Status** | Set to **True positive** or **False positive** to review the finding | | **Comment** | Add an internal note to the finding | | **Delete** | Permanently hide the profile from this monitoring record (see below) | Each monitoring entry displays up to 30 findings. Clicking a matched profile row opens the full profile viewer. See [AML Profiles](/guides/dashboard/aml/aml-profiles) for a description of all tabs and fields. ### Reviewing and Resolving Findings **True positive** — confirms the finding as a genuine match. The monitoring record stays in Alert until all findings are resolved. **False positive** — marks the finding as not relevant to the monitored subject. The finding is hidden from view. However, if the screening provider updates the underlying record (detectable by a changed update date), the profile may reappear on the next daily check — marking as False Positive is not permanent suppression. **Delete (trash icon)** — permanently removes the profile from this monitoring record. The profile ID is added to the record's hidden list and filtered out on every subsequent daily check, even if the screening provider updates the record. Use this when the profile is definitively not the monitored subject. If you added a subject to monitoring from an AML check, any findings you already resolved in that check are carried over automatically. Only new findings detected after monitoring started require review. Resolving findings does **not** automatically change the monitoring status from Alert to Active. After dismissing false positives, a manager must manually click **Start** on the monitoring record to re-evaluate the remaining findings and restore Active status. ### Other Actions **Page header:** * **Delete results** — removes all current findings from this monitoring record (the monitoring record itself remains active and continues daily screening) * **Download PDF** — exports the full monitoring record as a PDF for audit and compliance purposes **Bottom toolbar:** * **Auto renewal** — toggles automatic extension of the monitoring period each year; each renewal consumes one credit * **Logs** — shows a full audit trail of status changes and screening events for this record * **History** — previous screening runs and rechecks * **Comments** — internal notes left by managers on this record * **Recheck** — manually triggers a new screening run outside the daily cycle; consumes one credit * **Update monitoring** — saves any pending changes to the record (active when edits are unsaved) * **Stop monitoring** — disables further checks for this subject; can be restarted at any time # Name Matching Logic Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-name-matching-logic Understand how the AML engine scores names, handles cultural variations, and combines identity signals into a final match decision. The matching engine runs two parallel tracks — fuzzy name matching and semantic matching — and combines them into a single final score. *** ## Track 1 — Fuzzy Name Matching Before any comparison happens, names go through several preparation steps. **Cultural Affinity Detection** A machine learning model identifies the cultural origin of a name (Russian, Chinese, French, Arabic, etc.) and applies the appropriate matching logic. For example, "John Smith" and "Smith John" are treated as equivalent under Western naming conventions — that assumption does not apply to Chinese names. **Normalization** Names are stripped of special characters and converted to a standard format. "Timothée Dupont-Giguère" becomes "TIMOTHEE DUPONT GIGUERE". Legal entity suffixes such as "Ltd." or "N.P.L." are also standardized. **Tagging and Weighting** Each part of a name is assigned a semantic role: FIRSTNAME, LASTNAME, MIDDLENAME, ABBREVIATION, and so on. A name like "Mugabe, R G" is parsed so that "Mugabe" is tagged as LASTNAME, "R" as both FIRSTNAME and ABBREVIATION, and "G" as MIDDLENAME/ABBREVIATION. These tags determine how much weight each part carries in the final score — surnames count more than middle names. **Candidate Selection and Scoring** The engine searches the watchlist for potential matches, tolerating a wide range of variations: * Inverted or doubled letters, missing letters, similar-sounding letters across languages * Split or merged words * Common aliases (Robert / Bob) * Patronyms, teknonyms, and abbreviations * Full transliterations from non-Latin scripts Each name token is scored individually. Exact matches score 100; fuzzy matches score 75–99 depending on closeness. Missing or unexpected tokens apply downward penalties, and surname mismatches carry a heavier penalty than middle name mismatches. *** ## Track 2 — Semantic Matching Running in parallel, this track covers everything that is not a name: date of birth (compared by year, month, and day with configurable tolerance), country, gender, and other identifiers. Each field is scored based on how reliable and relevant it is to the potential match. *** ## Final Stage — Metascore Both tracks feed into the Metascore, which combines everything into a single number. The weights are configurable based on your data quality: * A reliable country match can boost the score by **15–25 points** * A DOB mismatch applies roughly a **20-point penalty** * A weak name match (e.g. 89) can be pushed **over the threshold** if DOB and country both align * A perfect name match (100) can be suppressed to **\~82** if other data points contradict the watchlist record This two-directional adjustment keeps false positives low without sacrificing real hits. *** ## Match Threshold Only matches scoring at or above the threshold are returned. There are two places it is set, with **different defaults**: | Where it is set | Default | Range | | -------------------------------------------------------------------------------------------------- | ------- | ------ | | Dashboard → **Settings** → **Anti-Money Laundering (AML)** → **AML matching threshold percentage** | 95 | 75–100 | | `filters.threshold` on a one-off AML check request | 85 | 75–100 | The per-request `threshold` is honored for **one-off AML checks only**. [AML monitoring](/guides/dashboard/aml/aml-monitoring), AML triggered by an identity verification, and the previous AML API version all use the partner-level setting — a per-request value is ignored or unavailable there. 75 is the floor. Requesting a lower value does not widen the search; it is silently raised to 75. *** ## Birth-Year Range By default the date of birth must match exactly. Widen it with `filters.dateOfBirthMatching` — `EXACT` (default), `SAME_YEAR`, or `WITHIN_ONE_YEAR` through `WITHIN_FIVE_YEARS`. The dashboard equivalent is **AML birth year range** in AML settings. If you are seeing an unexpected number of false positives or missed matches, the match threshold and birth-year range are the first settings to review. See [AML Key Terms and Concepts](/guides/dashboard/aml/aml-key-terms-concepts) for a full breakdown of available filters. # AML Profiles Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-profiles Interpret matched AML profiles in the dashboard, including sanctions entries, PEP roles, associations, and supporting evidence sources. A profile opens whenever you click a matched result — whether from an AML check or an AML monitoring record. The profile viewer is the same in both contexts. Profile data is not filtered by the check or monitoring filters. All conditions and information from the screening provider are shown regardless of what datasets were selected. *** ## Profile Header The top of the profile shows the matched entity's name, a row of dataset badge chips indicating which screening databases flagged them (for example `SAN CURRENT`, `PEP CURRENT`, `POI`), and a **Download PDF** button to export the full profile. *** ## Profile Details The default tab. Contains three cards: ### Core Details Main identifying information: * **First name / Middle name / Surname** — name components as listed in the dataset * **Gender** * **Photo** — if available in the source * **Aliases** — alternate spellings and translations that may appear on official lists ### Personal Details Supporting data to confirm identity: * **Nationality** * **Date of birth** * **Addresses** — known addresses with a type label (for example, `Registered`, `Business`) ### Identifiers Official IDs and references from international sanctions or regulatory bodies. Examples include: * UK Sanctions reference * EU reference number * OFAC SDN ID * HM Treasury reference * UN reference Use these to trace where the record originates and verify authenticity. *** ## Sanctions Lists all sanctions restrictions associated with this profile, split into **Current** and **Former** sub-tabs. Each row in the table shows: | Column | Description | | -------------------- | -------------------------------------------------------------------------------- | | **Sanction list** | The issuing body or list name (e.g. OFAC SDN, HM Treasury, EU Consolidated List) | | **Sanction types** | The type of sanction (e.g. asset freeze, travel ban) | | **Sanction measure** | The specific restriction in effect | | **Added date** | When the entry was added to the list | Expand any row to see the underlying evidence: * **View source** — opens the original source document URL in a new tab. * **View PDF** — opens an Acuris-generated PDF containing the source record. Shown only when an Acuris PDF is available; serves as a fallback when the original source URL is broken or unavailable. * **Captured** — when iDenfy captured this data * **Published** — the official publication date * **Title** — the document or order title * **Datasets** — which screening databases include this evidence * **Summary** — a plain-text description of the sanction * **High Credibility Score** — indicates the evidence comes from an authoritative primary source Evidence row expanded showing View source and View PDF links *** ## PEPs Lists politically exposed person classifications, split into **Current**, **Former**, and **PEP by association** sub-tabs. Each row shows: | Column | Description | | ---------------- | --------------------------------------------------------------------- | | **Position** | The political role or title held | | **Segment** | The PEP tier or category (e.g. Head of Government, Regional Official) | | **Data capture** | When this role was recorded | Expand any row to view evidence and source details, following the same structure as the Sanctions tab. *** ## Associations Related individuals and entities connected to this profile, split into three sub-tabs: * **Relatives & close associations** — family members and personal associates * **Business associates** — professional connections * **Associated businesses** — companies or organizations linked to this profile Each entry shows the associated name, dataset badges indicating why they appear, and a description of the relationship. *** ## Other Datasets Additional risk and regulatory data, split into sub-tabs: * **Reputation Risk Exposure (RRE)** — adverse media entries tied to official action. Each entry carries a category, a snippet, a source link, and (where copyright allows) a PDF of the evidence. See [RRE Dataset Overview](/guides/dashboard/aml/rre-overview) * **Regulatory Enforcement List (REL)** — regulatory enforcement actions * **Profile of Interest (POI)** — persons or entities flagged for heightened scrutiny * **Gambling Risk Intelligence** — risk data specific to gambling-related exposure # AML Screening Overview Source: https://documentation.idenfy.com/guides/dashboard/aml/aml-screening-sanctions-peps How iDenfy AML screening checks persons and companies against sanctions lists, PEP registries, and adverse media, with optional ongoing monitoring alerts. AML (Anti-Money Laundering) screening lets you check persons and companies against global sanctions lists, politically exposed persons (PEP) registries, and adverse media sources — and enroll them in ongoing monitoring with automated alerts. ## AML Features | Feature | Description | | ---------------------------- | ------------------------------------------------------------------- | | **Company AML Check** | Check companies against international sanctions lists. | | **Person AML Check** | Check individuals against international sanctions and PEPs lists. | | **Adverse Media Check** | Scan companies and individuals for adverse media. | | **AML Monitoring** | Monitor companies and individuals against sanctions and PEPs lists. | | **Adverse Media Monitoring** | Monitor companies and individuals for adverse media. | ## Key Capabilities * Screen global sanctions, PEPs, and watchlists * Filter adverse media and reduce false positives * Receive instant automated AML risk notifications * Automated ongoing daily AML screening * Ensure compliance with automated audit reports Visit the iDenfy AML Screening product page for more information. ## Next Steps Run a sanctions, PEP, or adverse media check from the dashboard. Set up ongoing monitoring with alerts. Manage and review AML subject profiles. Understand sanctions lists, PEPs, and match logic. # Compliance and Monitoring Tab Source: https://documentation.idenfy.com/guides/dashboard/aml/compliance-monitoring-tab Navigate the compliance and monitoring tab in iDenfy to review audit logs, AML statuses, blocklist matches, and monitoring subjects. ### Comments and Audit Logs These two cards provide a chronological history of the case. * **Comments:** An internal notebook for your team. Use this to leave notes about manual verifications or decisions. * **Action:** Type in the text box at the bottom and click **Comment** to add a note. * **Audit Logs:** A read-only system record that tracks every action, including automated system checks (e.g., "\[AUTOMATION] Done website audit"), user actions (e.g., "\[DemoUser] Added comment"), and client actions taken through a [request update](/guides/dashboard/kyb/request-update-kyb) link. Client actions include "Form re-submitted without changes" when the client submits the form without editing anything. *** ### Compliance Information (AML) This section breaks down the screening results for every person and company involved (Directors, Shareholders, UBOs). * **No flags:** The entity passed screening against sanctions and watchlists. * **Flags found:** Potential matches were found (e.g., Adverse Media, PEPs). * **Action:** Click **View AML** or **View Adverse media** next to a name to review and resolve the match. *** ### Automation Statuses This card details the result of every automation rule configured for your workflow. **Understanding Rule Statuses** | Status | Meaning | | ------------------- | ------------------------------------------------------------------------------------------- | | COMPLETED | Rule ran successfully and returned a result. | | FAILED | Rule encountered an error during execution. | | SKIPPED | Rule didn't apply (conditions not met). | | BLOCKED | A previous rule with a "BLOCK" action already denied the company, so this rule did not run. | | INSUFFICIENT\_FUNDS | The partner account does not have enough credits to run this specific check. | Understanding Rule Actions Each rule is configured with an "Action" that dictates what happens if the rule is triggered: | Action | Consequence | | ----------- | --------------------------------------------------------------------------------- | | DO\_NOTHING | Informational only. The check runs, but the company is not flagged automatically. | | FLAG | The company is flagged for manual review. | | BLOCK | The company is automatically denied. | *** ### Blocklist Statuses This section shows exactly which data fields were cross-referenced against your internal blocklists. **Check Results** | Status | Meaning | | ------- | ---------------------------------------------------------------------------------- | | CHECKED | The field contained data and was successfully validated against blocklist rules. | | SKIPPED | The field was empty or missing in the company profile, so it could not be checked. | What gets checked? The system attempts to screen the following data points if they are present: * **Company Info:** Name, Registration Number, Country, City, Address, Postcode, Activity Code, Domain. * **Applicant Info:** Name, Email, Phone, Personal Number, IP Address. * **Persons (UBO/Rep):** Nationality, Country of Residence. ### Monitoring Subjects Enroll specific entities into ongoing monitoring to detect future changes in their status (e.g., appearing on a sanctions list next month). * **Add from the list:** Select entities already known in this application. * **Create new:** Add a new entity manually. *** ### Troubleshooting and Support Quick answers to common questions about this tab: 1. **Why are blocklist fields showing "SKIPPED"?** This means the company data is incomplete. If a field (like "Postcode") is empty in the application, the blocklist cannot check it. 2. **Why are multiple automation rules "BLOCKED"?** An earlier rule in your workflow (one with a **BLOCK** action) has already denied the company. To save resources, the system stops running subsequent rules. 3. **What does "INSUFFICIENT\_FUNDS" mean?** The automation failed because the account lacks the credits required for that specific third-party check. Credits must be topped up to run these rules. 4. **Why wasn't the company flagged even though the automation ran?** Check the rule's **Action** setting. If it is set to **DO\_NOTHING**, the rule will complete successfully without generating a flag, regardless of the finding. # RRE Categories in Scope Source: https://documentation.idenfy.com/guides/dashboard/aml/rre-in-scope The six core Reputational Risk Exposure categories with their subcategories, financial thresholds, and the criteria that qualify a profile. RRE content is organised into **six core categories** plus **one auxiliary legacy category**. Each subcategory has its own qualifying criteria, and some carry a financial threshold. Across every category, the baseline requirement is the same: the subject must be **wanted, charged, indicted, prosecuted, convicted, or sentenced**, evidenced by an official source or by media reporting on official action. *** ## 1. Terrorism No financial threshold. Assessed qualitatively. | Subcategory | What qualifies | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------- | | **1.1 Proliferation of Weapons of Mass Destruction** | Proceedings in relation to international terrorism | | **1.2 Terrorist Financing and Support** | Proceedings in relation to international terrorism | | **1.3 Violent Crimes with Terrorist Connection** | Proceedings for participation in violent crimes with an established terrorist connection | **Domestic terrorism is excluded.** So are violent crimes such as mass shootings and hate crimes, unless there is evidence of a terrorist connection. *** ## 2. Organised Crime No financial threshold. Assessed qualitatively. | Subcategory | What qualifies | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **2.1 Traffic and Distribution of Narcotics** | Organised drug trafficking where the crime involves three or more perpetrators, or the volume of proceeds indicates criminal organisation | | **2.2 Illicit Arms Trafficking** | Organised arms trafficking under the same criteria | | **2.3 Smuggling or Illicit Trafficking in Goods** | Organised goods trafficking and smuggling under the same criteria | | **2.4 OCGs and Gangs** | Proceedings relating to affiliation with a known criminal group, or criminal activity in collusion between two or more entities, or generating large proceeds | *** ## 3. Modern Slavery No financial threshold. Assessed qualitatively. | Subcategory | What qualifies | | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **3.1 Human Trafficking and Exploitation** | Proceedings for trafficking of humans by an organised criminal group, or by one or two perpetrators using coercion or deceit and involving movement of the victims | | **3.2 Labour Trafficking and Exploitation** | As above, in a labour context | | **3.3 Sex Trafficking and Exploitation** | As above, in a sexual exploitation context | *** ## 4. Financial Crime and Fraud This is the category where thresholds bite hardest — nearly every subcategory carries one. | Subcategory | Threshold | What qualifies | | ------------------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- | | **4.1 Financial and Non-Financial Fraud** | USD 10,000 | Criminal, corporate or commercial fraud generating over USD 10,000 in proceeds, or defrauding victims by USD 10,000 or more | | **4.2 Money Laundering** | USD 10,000 | Laundering of criminal proceeds valued at or above USD 10,000, by individuals or companies | | **4.3 Tax Offences** | USD 10,000 | Tax crimes with proceeds valued at or above USD 10,000 | | **4.4 Embezzlement** | USD 10,000 | Embezzlement of assets valued at or above USD 10,000 | | **4.5 Counterfeiting of Currency** | USD 10,000 | Counterfeiting of USD 10,000 or above | | **4.6 High-Value Theft and Robbery** | USD 10,000 | Theft and robbery generating proceeds valued at or above USD 10,000 | | **4.7 Insider Trading** | USD 10,000 | Insider trading and market manipulation at or above the threshold | | **4.8 Unexplained Wealth** | GBP 50,000 | Proceedings relating to wealth that cannot be accounted for, at or above GBP 50,000 | | **4.9 Failure to Comply with Relevant Financial Regulations** | USD 10,000 | Proceedings for non-compliance with financial regulations at or above the threshold | Thresholds are given in USD or the equivalent in another currency. Where the reporting contains no financial figure, relevance is judged on additional factors instead — organised crime, terrorism, modern slavery, financial crime and fraud, bribery and corruption, or cybercrime indicators. The USD 10,000 figure can look low. It is a prioritisation floor, not the only test — the qualitative criteria still apply, and a case that clears the number but fails those criteria is not captured. *** ## 5. Bribery and Corruption No financial threshold. Assessed qualitatively. | Subcategory | What qualifies | | ------------------------------------------------------------------------ | ---------------------------------------------------------------------- | | **5.1 Being Bribed** | Proceedings for accepting a bribe | | **5.2 Bribing Another Person** | Proceedings for offering or giving a bribe | | **5.3 Bribing a Foreign Public Official** | Proceedings for bribery of an official in another jurisdiction | | **5.4 Failure of a Relevant Commercial Organisation to Prevent Bribery** | Proceedings against an organisation for failing to prevent bribery | | **5.5 Corrupt Practices** | Proceedings for corrupt conduct not covered by the subcategories above | *** ## 6. Cybercrime | Subcategory | Threshold | What qualifies | | ----------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------ | | **6.1 Identity Theft** | — | Proceedings or regulatory action for identity theft | | **6.2 Scams** | USD 10,000 | Scams generating over USD 10,000 | | **6.3 Hacking** | — | Proceedings or regulatory action for failure to prevent a data breach, or for participation in cyber-attacks | | **6.4 Credit Card / Payment Fraud** | USD 10,000 | Involvement in credit card or payment fraud valued at or above USD 10,000 | *** ## 7. Other Alleged Offences The auxiliary category, and the only one built on **low-credibility** evidence: content that would fit categories 1–6 but has **no evidence of official action**, plus other offence types that are not explicitly out of scope. This category is legacy only. It holds existing profiles created under earlier methodology, and applies to currently out-of-scope crime. **New content is not created under it** — anything added after January 2020 requires evidence of official action. *** ## Not Listed Does Not Mean Not Covered The category list describes how content is *classified*, not an exhaustive list of qualifying crimes. A crime that appears under no explicit category or subcategory is still captured if it predicates money laundering or can be classified under an existing subcategory. **Environmental crime** is the clearest illustration. It is not a named RRE category, and wildlife crime is explicitly out of scope — yet environmental offences are routinely captured: * **Under Terrorism** — where a terrorist organisation funds itself through activity such as illicit ivory trafficking, or commits environmental damage as part of its operations. * **Under Organised Crime** — where organised groups profit from illegal disposal of commercial, industrial or radioactive waste and launder the proceeds. * **Under Bribery and Corruption** — where an environmental offence generating proceeds was facilitated by bribing public officials. Both the briber and the official are profiled. * **Under Financial Crime and Fraud — Money Laundering** — where proceeds from an environmental crime are laundered at or above the threshold. This route applies to cases that do not meet the qualitative criteria of any other subcategory; if they do, they are classified there instead. *** ## Related Pages What RRE is, which evidence qualifies, and how it differs from REL. Topics that are deliberately excluded, and the exceptions that pull them back in. # RRE Out of Scope Source: https://documentation.idenfy.com/guides/dashboard/aml/rre-out-of-scope Topics deliberately excluded from Reputational Risk Exposure content, the reasoning behind each exclusion, and the exceptions that override them. The exclusion list matters as much as the category list. It explains why a story you have read about a customer does not appear as an RRE profile — and it is deliberate, not a coverage gap. The organising principle: RRE captures **criminal conduct with a money laundering nexus, evidenced by official action**. Topics that fail that test are excluded, even when they are genuinely damaging to a subject's reputation. Exclusion is topic-level, not subject-level. An excluded topic does not shield a subject — the same person or company is still profiled if separate conduct falls inside a category. *** ## Violence Without a Terrorist Connection | Excluded | | ----------------------------------------------------------------------------------------- | | Mass shootings and mass murder without a terrorist connection | | Violent crimes — murder, grievous bodily injury, assault — without a terrorist connection | **Why:** these are serious crimes, but they do not generate laundered proceeds. Where a terrorist connection exists, the conduct is captured under Terrorism instead. *** ## Opinion, Criticism and Speech | Excluded | | ----------------------------------------------------------------------------------------- | | Hate speech, including racism and insulting religion | | Criticism of politicians over their political views, policies or agenda | | Criticism of public officials for alleged incompetence or failure to perform their duties | | Criticism of countries and governments | **Why:** criticism is not criminal conduct, and political commentary is not a risk signal. Including it would fill profiles with opinion rather than evidence. *** ## Commercial and Civil Matters | Excluded | | ---------------------------------------------------------------------------------------------------------- | | Bankruptcy, except fraudulent bankruptcy | | Distressed company news | | Anti-trust news — abuse of a dominant market position, bid-rigging, price-fixing | | Patent, copyright and intellectual property disputes | | Civil court cases, except where they fall under Financial Crime and Fraud and clear the relevant threshold | **Why:** commercial failure and civil disputes are not predicate offences. Fraudulent bankruptcy is the exception, and it is captured under Financial Crime and Fraud. *** ## Low-Severity Offences | Excluded | | ------------------------------------------------------------------------------------ | | Misdemeanours, including by low-level (Tier 3) PEPs and candidates for public office | | Petty crimes | | Traffic offences and driving under the influence, including by PEPs | **Why:** the proceeds, where any exist, fall far below any meaningful threshold. A PEP's parking ticket is not an AML signal. *** ## Sexual Offences and Mistreatment | Excluded | | ---------------------------------------------------------------------------------------------------------------------------- | | Sexual offences, including against children, except where linked to organised crime or modern slavery | | High-net-worth individuals mistreating household or domestic staff, except where linked to organised crime or modern slavery | The exception carries real weight here. Where either topic involves an organised criminal group or trafficking and exploitation, it is fully in scope under **Modern Slavery** or **Organised Crime**. *** ## Other Exclusions | Excluded | | ------------------------------------------------------------------------- | | Whistle-blowers and dissidents | | Animal cruelty and wildlife crime, except where linked to organised crime | | Generic advance-fee scam schemes | **Why:** whistle-blowers and dissidents are subjects of allegations rather than official action, and profiling them would turn the dataset against the people reporting wrongdoing. Wildlife crime returns to scope the moment an organised group is behind it — see [Not listed does not mean not covered](/guides/dashboard/aml/rre-in-scope#not-listed-does-not-mean-not-covered). *** ## What to Do with an Excluded Topic An excluded topic is not a dead end for your own risk assessment — it is simply not carried by this dataset. Two options remain open: * **Check the other datasets.** Regulatory Enforcement Lists (REL) carry no financial threshold, so enforcement action that RRE filters out on value may still appear there. Profiles of Interest (POI) covers heightened-scrutiny entities. * **Record it in your own review.** Where your policy treats an excluded topic as material, document the decision on the case rather than expecting a screening hit to raise it for you. *** ## Related Pages What RRE is, which evidence qualifies, and how it differs from REL. The six core categories, their subcategories, and the thresholds that apply. # RRE Dataset Overview Source: https://documentation.idenfy.com/guides/dashboard/aml/rre-overview Understand what the Reputational Risk Exposure (RRE) dataset covers, which evidence qualifies, and how RRE differs from regulatory enforcement data. **RRE** stands for **Reputational Risk Exposure**. It is the adverse media dataset used in AML screening, and it is narrower than the phrase "negative news" suggests. An RRE profile is created for a person or company that is named as **wanted, charged, indicted, prosecuted, convicted, or sentenced** in connection with criminal activity that falls under one of the defined RRE categories. The trigger is not the existence of bad press — it is documented action by an authority. A story that is merely unflattering, critical, or speculative does not create an RRE profile. Without evidence of official action, there is nothing to record. *** ## RRE Vs. REL Both datasets are described as "adverse media", but they are built differently. | | **RRE** — Reputational Risk Exposure | **REL** — Regulatory Enforcement Lists | | -------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Source** | Official records and mass media reporting on official action | Lists published by regulators, law enforcement, anti-corruption and disciplinary bodies | | **Processing** | Analysed and categorised by an editorial team before and after publication | Aggregated as published, with minimal editorial intervention | | **Content** | Categorised criminal conduct with supporting evidence | Structured enforcement entries, notes and article snippets | | **Thresholds** | Financial thresholds apply to some categories | No financial thresholds applied | Because thresholds apply only to RRE, the same event can appear in one dataset but not the other. A media report on money laundering below the financial threshold is not captured as RRE, but if a regulator published an entry about the same case, it is captured as REL. Screening both datasets is what closes that gap. *** ## Which Evidence Qualifies Evidence is ranked by credibility, and the rank determines whether a profile can be created at all. | Priority | Evidence type | How it is used | | ------------ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | **High** | Official sources — websites of government bodies, agencies and courts | Preferred basis for all new content | | **Medium** | Mass media outlets and other reputable sources such as NGOs and think tanks, **reporting on official action** | Used only where official evidence is unavailable | | **Low** | Reputable media reporting an offence with no evidence of or reference to official action | Treated as an allegation; maps to the legacy category only | | **Excluded** | Social media, forums, blogs, Wikipedia-style sites, and subject self-disclosure | Not used as evidence in any form | Medium-credibility evidence is accepted where official evidence genuinely cannot be obtained — a lack of transparency in the jurisdiction, restricted access to primary records, delayed publication of official information, or restrictive data protection legislation. *** ## Why the Scope Looks the Way It Does The RRE categories are not an arbitrary list of bad things. They are derived from the internationally recognised categories of **predicate offences** — the crimes whose proceeds are laundered — as set out in global AML standards and in EU and UN money laundering legislation. The practical consequence: RRE is scoped to criminal conduct with a money laundering nexus, not to reputational harm in general. That is why a violent crime with no terrorist connection sits outside the dataset while a mid-sized fraud sits inside it. *** ## Financial Thresholds Some categories carry a financial threshold, meaning reports are prioritised where the proceeds are valued at or above that amount. Most categories carry no threshold and are assessed qualitatively instead, against criteria defined per subcategory. Where a threshold applies but the reporting contains no financial detail, relevance is assessed against additional factors — indicators of organised crime, terrorism, modern slavery, financial crime and fraud, bribery and corruption, or cybercrime. See [RRE Categories in Scope](/guides/dashboard/aml/rre-in-scope) for the thresholds per category. *** ## Review and Retention Profiles are reviewed on an event-driven basis rather than a fixed calendar. Media monitoring and monitored enforcement sources are tracked against keywords derived from the RRE categories, and profiles are created or updated as relevant information becomes available. Retention follows two rules: * **10 years** for entities with no new relevant information during that period. * **Longer than 10 years** for entities that also carry other risk categories, such as sanctions or PEP status. *** ## How RRE Appears on a Profile Four elements support each RRE entry: * **Rep.Risk category** — the RRE category applied to the profile, based on one or more articles. * **Snippet** — a short summary of the relevant detail: the subject's involvement, the nature of the crime, and the outcome of proceedings. * **URL** — a link to the article in its original location. Links can expire if a publisher delists the article or changes its site structure; when that happens, the snippet and category remain authoritative. * **Document** — a PDF printout of the evidence or article. It is available only where the source's copyright policy permits redistribution. Under a restrictive policy no PDF is shown, and the snippet carries the detail instead. *** ## Related Pages The six core categories, their subcategories, and the thresholds that apply. Topics that are deliberately excluded, and the exceptions that pull them back in. # Standalone Bank Card Verification Source: https://documentation.idenfy.com/guides/dashboard/bank-card/standalone-bank-card-verification How the standalone iDenfy bank card check works: consent and capture screens, retry attempts, session time limits, and end-user results. This page covers the **standalone** flow — the card check running on its own token, with no identity verification behind it. For the version that runs as an extra step inside a KYC session, see [Bank Card Verification](/guides/dashboard/features/bank-card-verification). Bank Card Verification confirms that a payment card belongs to the person presenting it. The end user photographs the card, or uploads a card-confirmation document. The cardholder name and card number read from it are compared against the name — and optionally the last four digits — supplied by the company that requested the check. Card capture and card image processing run in a dedicated environment certified to **PCI-DSS v4.0.1**, and no card imagery is retained once processing completes. *** ## Where to Find It The same card step serves two entry points. * **Inside a KYC session** — a step shown after identity document capture, only when the feature is enabled for that partner. The KYC verification **cannot be submitted** until the card step has resolved. * **As a standalone link** — bank card verification only, no identity verification required. Both settings that govern the feature live under [Settings → Know Your Customer → AML & Fraud Prevention](/guides/dashboard/settings/aml-fraud-prevention#bank-card-verification): **Bank card verification** turns it on, and **Bank card PDF upload** controls whether the upload option appears at all. Neither is self-service — [contact iDenfy](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to request access. *** ## The Standalone Flow
Four assurances, and a single **Agree & continue securely** button — there is no checkbox to tick. The screen is skipped entirely if consent was already given for this session.
Desktop users see a device screen first, offering a QR code and an SMS link. **Continue in app** appears only when the session carries a mobile code. The footer escape — *Don't have a smartphone? Continue on current device.* — lets them stay put. Once the phone finishes, the desktop advances to the result on its own; it polls in the background, so the user doesn't need to do anything on the original screen.
| Option | Availability | | ----------------------- | ------------------------------------------------------------------------------------------------------ | | **Capture with camera** | Always available | | **Upload a PDF** | Only when PDF upload is enabled for that partner. Otherwise the tile is hidden entirely, not disabled. | If only one method exists it is preselected. **Continue** stays disabled until a method is picked.
🔒 Only your card number and name are read – CVV is never captured or stored.
**Capture your card** shows a live view with a card frame. There is **no auto-capture** — the shutter is manual. A camera-switch button appears only if a second camera exists. **Inspect captured card** asks the three questions shown, then offers confirm or retake. There is no back button on this screen. If details are missing, **Flip your card** appears and the other side is requested. The back side is **always camera-captured**, even when the front was uploaded.
Is the card fully in frame? Is anything covering the card? Is all the text legible?
Accepted formats are **PNG, JPG, HEIF and PDF**, one file at a time. **The size hint and the real limit differ.** The control shows a 5 MB hint, but that isn't enforced in the browser — the server accepts up to **10 MB**. Files between the two still go through. Anything larger comes back rejected with a message. PDFs get no image preview; the file name is shown instead. **Review uploaded document** then asks whether it shows the card number, whether the name is visible, and whether it's the right document, before continue or upload again.
Does it show the card number? Is the name visible? Is it the right document?
If several cards are found in the document, **Which card are you verifying?** offers masked options — last four digits and expiry only — as many as were detected.
*** ## Quality Problems
Quality checks run **after submitting**, not live during capture. A problem opens a modal with an illustration, a single message, and one **Try again** button that re-prompts the same side. | Message group | Covers | | ------------- | --------------------------------------------------------------------------------------- | | Image quality | Blurry · glare · bad lighting | | Framing | Card not detected · move closer · card cut off · center your card | | Content | Multiple cards found | | Authenticity | Physical card required (a photo of a screen) · authentic card required (a printed copy) | Quality problems **spend no attempt** on their own. But three consecutive quality failures within one attempt do consume that attempt.
*** ## Attempts and Timers Three attempts by default, configurable per partner. **The counter is never shown to the user.** | Outcome | Spends an attempt? | | -------------------------------------------- | ------------------------------------------------------- | | `This document doesn't contain card details` | **Yes** — restarts from the front side | | `We couldn't confirm your card is genuine` | **Yes** — restarts from the front side | | Starting a fresh front capture mid-flow | **Yes** | | A quality problem | No — unless three land consecutively within one attempt | | `Verification temporarily unavailable` | No — retryable | ### Two Independent Clocks | Clock | Default | Range | Starts | | ----------------- | ------- | ------------- | ------------------------------------------------ | | Link lifetime | 1 hour | up to 30 days | when the link is issued | | Session countdown | — | 1–60 minutes | **at the capture step**, not when the link opens | A **Time left** indicator appears only if enabled for the partner, and is hidden during mobile capture. ### Timeouts Analysis waits up to **60 seconds**; camera and loading up to **15**. Failures show *Verification temporarily unavailable*, which is retryable and spends no attempt. Camera failures return the user to the method screen, so upload stays reachable. *** ## Limits and Behaviour **Embedding in your own page?** Your frame must grant camera access to the card capture origin, or card capture fails while document capture keeps working. This asymmetry is a frequent support cause — see [Redirect & iFrame](/kyc/iframe-redirect#required-attributes) for the `allow` attribute. **SMS limits.** One per session, one per phone number per 24 hours, and three requests per 15 minutes. Users in unsupported phone countries are told to scan the QR code instead. **Languages.** All [37 supported languages](/resources/supported-languages), switchable mid-flow, including right-to-left rendering for Arabic and Persian (Farsi). **What these screens don't have.** No **Cancel verification** button and no **Continue on mobile** button. There is no card-brand or country restriction, and **no manual review** — the result is final. *** ## Results ### Standalone One screen, no buttons. Only a **full match** counts as success. If redirect URLs were configured, success and failure hop straight back to your page — the expired case **never** redirects. ### Inside a KYC Session There is no result screen at all. The flow simply continues to the next step, and a mismatch is flagged to you rather than shown to the user. Results appear alongside the identity verification in [Verification Details](/guides/dashboard/kyc/verification-details). *** The card check as an additional step inside the identity verification flow, and how the verdict is decided. The Bank card verification and Bank card PDF upload settings that govern both flows. # Bank Verification in the Dashboard Source: https://documentation.idenfy.com/guides/dashboard/bank/bank-verification Verify customer bank accounts using the iDenfy open banking integration with support for 2,500+ EU banks and multiple data layers. ## What Is Bank Verification? To learn more about what bank verification is and how it’s used in the industry, see our [**blog post**](https://idenfy.com/blog/bank-account-verification-guide/?utm_content=undefined) If you’re interested in the bank verification services we provide, [**follow the link**](https://idenfy.com/bank-verification-service/) ## Supported Countries | Austria (AT) Belgium (BE) Bulgaria (BG) Croatia (HR) Cyprus (CY) Denmark (DK) Estonia (EE) Finland (FI) France (FR) | Italy (IT) Latvia (LV) Lithuania (LT) Luxembourg (LU) Malta (MT) Germany (DE) Greece (GR) Hungary (HU) Iceland (IS) Ireland (IE) | Netherlands (NL) Norway (NO) Poland (PL) Portugal (PT) Romania (RO) Slovakia (SK) Slovenia (SI) Spain (ES) Sweden (SE) | | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | *** ## Creating a Bank Verification Request To create a Bank Verification request from your side, follow this flow: ``` # KYC Integration Source: https://documentation.idenfy.com/kyb/kyc-integration Integrate KYC identity verification for beneficial owners within iDenfy KYB business verification using combined all-in-one API flows. You can combine Business verification and Identity verification services in an all-in-one solution. Depending on the specific integration and required use cases, the following approaches are available. ## Business Verification First Approach [Create a company](/kyb/collect-information) and afterward: * Create and send a new Identity verification token via the [**dashboard**](/guides/dashboard/kyb/company-page). * Set up [**custom rule automation for the Identity verification Token**](/guides/dashboard/risk/custom-rules), which will automatically send a new link to the related subjects of the Business verification form. * Create verification via [**API**](/kyc/generate-token) or [**dashboard**](/guides/dashboard/kyc/new-verification-via-dashboard) and once verification is done, add a new [**beneficiary via API**](/kyb/collect-information#beneficiaries) using the `scanRef` of completed Identity verification. *** ## Identity Verification First Approach Alternatively, you can onboard and perform Identity verifications first and then manage the Business verification form. In this case, make sure that the Identity verifications are completed: * Gather verification `scanRef` numbers and include them when creating a [**new Business verification session**](/kyb/generate-token#step-1-create-business-verification-form-session). * Add a new beneficiary **via API** (see [**beneficiaries**](/kyb/collect-information#beneficiaries)) using the existing Identity verification `scanRef`. The iDenfy recommended approach is to use [**Identity verification Token**](/guides/dashboard/risk/custom-rules) automation or create a new beneficiary [**via API**](/kyb/collect-information#beneficiaries). It is also possible to use **both services separately** and add a new beneficiary via API or dashboard depending on integration requirements. *** ## Reusing an Identity Verification Across Companies The same `scanRef` can be linked to a person's role (Director, Representative, or Beneficial Owner) on more than one company. There's no limit on how many companies can reference the same `scanRef`, so someone who sits on several company structures only needs to complete identity verification once. This works identically via API and via the [dashboard](/guides/dashboard/kyb/company-details-tab). A `scanRef` can be supplied when creating a company, when creating a token (see [`scanRefs`](/kyb/generate-token#step-1-create-business-verification-form-session)), or added later to an existing Director, Beneficiary, or Representative from the [Company Details](/guides/dashboard/kyb/company-details-tab) page. # Managing Company Source: https://documentation.idenfy.com/kyb/managing-company Update, view, and manage company verification records through the iDenfy dashboard or API for ongoing business verification management. You can manage companies either through the [iDenfy dashboard](/guides/dashboard/kyb/company-page) or via the API. ## Viewing Companies To view all submitted companies (or forms), use the dashboard or the API. For the **List Companies** endpoint (shows a list of all company reviews, including their status and details), see the **API Reference** tab for `kybCompaniesList`. *** ## Reviewing a Company To mark a company review as complete, change its status to `COMPLETED` using the API. For the **Change Status** endpoint (marks a company review as completed), see the **API Reference** tab for `kybCompaniesChangeStatusCreate`. You can also receive a webhook notification when a company is reviewed by enabling the `COMPANY_REVIEW` notification in your [Notification Settings](/guides/dashboard/settings/system-notifications-webhooks-emails). *** ## Re-Run KYB Automation You can programmatically trigger a KYB automation re-run for a specific company without opening the dashboard. For the **Re-run Automation** endpoint (`POST /kyb/companies/{id}/automation/`), see the **API Reference** tab for `kybCompaniesAutomationCreate`. A finance check is performed before the automation task is queued. On success, the endpoint returns a **202** status code confirming the automation task has been scheduled. If the automation cannot be started, an error response is returned with a reason. *** ## Retrieve All Company Information For the **Retrieve complete information about company** endpoint, see the **API Reference** tab for `kybCompaniesRetrieve`. ### Risk Assessment Results The response includes a `riskAssessment` object, so you can retrieve a company's risk scoring programmatically instead of opening the dashboard: | Field | Type | Description | | ----------- | ----------------- | ------------------------------------------------------------------- | | `id` | `string` | Identifier of the risk assessment result. | | `riskScore` | `integer \| null` | Overall risk score, `0`--`100`. | | `riskLevel` | `enum \| null` | `VERY_LOW`, `LOW`, `MEDIUM`, `HIGH`, `VERY_HIGH`, or `NOT_CHECKED`. | | `comment` | `string \| null` | Reviewer comment left on the assessment, if any. | The object is `null` when no risk assessment has been run for the company. See [Get Risk Assessment Results](/guides/dashboard/risk/get-risk-assessment-results) for how the score is calculated. *** ## Deleting a Company Companies can be removed from the dashboard or via the API. For the **Delete Company** endpoint (removes a company and its session from the system), see the **API Reference** tab for `kybCompaniesDestroy`. *** ## Request Update You can ask your client to update submitted data using the **Request More Information (RI)** functionality. ### Step 1: Request More Information [Initiate RI via dashboard](/guides/dashboard/general/request-update). To track and handle these updates, set up the [**COMPANY INFO REQUEST** webhook event](/kyb/webhooks). ### Step 2: Checking the Flow The data requested during RI may differ from the original form. To determine what fields are needed, retrieve the flow information. For the **Retrieve Flow** endpoint (shows the fields currently required during RI), see the **API Reference** tab for `kybInfoRetrieve`. ### Step 3: Update Any updates can be made using the same endpoints used in the initial Business verification flow, described in: * [Documents](/kyb/collect-information#documents) * [Beneficiaries](/kyb/collect-information#beneficiaries) * [Beneficiaries' Documents](/kyb/collect-information#beneficiaries-documents) * [Questionnaires](/kyb/collect-information#questionnaires) To check if a questionnaire is required, use the list endpoint and fill in the **first item**, especially if multiple are listed. See `kybFormsQuestionnairesList` in the API Reference. # KYB API – Business Verification Source: https://documentation.idenfy.com/kyb/overview Integrate iDenfy's KYB API to verify companies via registry data retrieval, beneficial owner screening, AML checks, and dashboard-based compliance reviews. ## KYB API Integration This section provides comprehensive information on integrating iDenfy's Know Your Business (**KYB**) API. You can leverage Business verification functionality either through the iDenfy dashboard interface or directly via our API. Both the API and the iDenfy dashboard support the creation and management of Business verification company profiles. For detailed instructions on using the dashboard for company management, refer to the [help center guide](/guides/dashboard/kyb/getting-started). This documentation primarily focuses on the implementation and usage of the Business verification API. ## Next Steps Create a business verification session via API. Gather company and beneficial owner data. Receive business verification results. Step-by-step dashboard guide for KYB. # KYB PDF Generation Source: https://documentation.idenfy.com/kyb/pdf-generation Generate downloadable PDF reports for completed business verification companies via the iDenfy KYB PDF generation API endpoint call. ## Generate PDF Generate a downloadable PDF report for a completed Business Verification (KYB) company, combining its checks and data into a single structured file. Use the `content` parameter to select which sections to include, or omit it to get the full default set. For full request and response schemas, see the [**Generate company PDF**](/api-reference/companies/generate-company-pdf) endpoint in the API Reference. ### Deny Reason When the company's verification result is **Denied**, the report prints the deny reason, so there is no need to read through the full report to find out why the company was declined. The reason shown is one of the custom [deny reasons](/guides/dashboard/settings/operational-settings#deny-reasons) configured for your account, or iDenfy's default reason when no custom reasons are set. It is printed on denied reports regardless of which sections you select with `content`. # Registry Reports Source: https://documentation.idenfy.com/kyb/registry-reports Retrieve company registry reports and available documents for business verification and compliance due diligence via the iDenfy API. **Requirements** * **API** key pair * Reports functionality **enabled** (done by iDenfy's staff) **Sample reports:** [Download here](https://github.com/idenfy/report-samples/archive/refs/tags/1.0.0.zip) *** ## Registry Reports ### Available Registry Report Documents **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/api/v2/gov-ordered-documents/available-documents/` | Parameter (query) | Type | Required | Sample/available values | | -------------------- | ------ | -------- | ------------------------ | | `countryCode` | String | Yes | 2-digit ISO country code | | `registrationNumber` | String | Yes | "12511182" | **Response example** ```json theme={"system"} { "products": [ { "id": "EBROFF_MzA0NjE3NjIxO0xUVV9CUzs0OzQ7RlMwMTI5_TFRVX0JT_QmFsYW5jZSBzaGVldA==_MzA0NjE3NjIx", "priceTag": "LTU_BS", "price": "0", "vatCharge": "0", "currency": "\u20ac", "productCode": "304617621;LTU_BS;4;4;FS0129", "companyCode": "304617621", "productDetails": [ { "keyField": "EFFECTIVE_DATE", "valueField": "2020-12-31", "documentCountField": 0 } ], "productFormat": "HTML", "productTitle": "Balance sheet", "displayDate": "2020-12-31", "type": "BALANCE_SHEET", "deliveryTimeMinutes": 5, "tierCode": "A", "tierValue": "1.00", "status": "NOT_ORDERED", "canOrder": true }, { "id": "304617621;LTU_BS;4;7;FS0229", "productCode": "304617621;LTU_BS;4;7;FS0229", "price": 1, "productFormat": null, "productTitle": "Balance sheet", "deliveryTimeMinutes": 5, "type": "BALANCE_SHEET", "displayDate": "2023-12-31", "priceTag": "LTU_BS", "vatCharge": "0", "currency": "\u20ac", "companyCode": "304617621", "productDetails": [ { "keyField": "EFFECTIVE_DATE", "valueField": "2020-12-31", "documentCountField": 0 } ], "productFormat": "HTML", "productTitle": "Profit and loss account", "displayDate": "2020-12-31", "type": "PROFIT_AND_LOSS_ACCOUNT", "deliveryTimeMinutes": 5, "tierCode": "A", "tierValue": "1.00", "status": "NOT_ORDERED", "canOrder": true } ] } ``` *** ### Order Registry Report Document **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/gov-ordered-documents/document-order/` | Parameter | Type | Required | Sample/available values | | -------------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------- | | `countryCode` | String | Yes | 2-digit ISO country code | | `registrationNumber` | String | Yes | "12511182" | | `companyName` | String | Yes | "Company Name" | | `productKey` | String | Yes | `id` of the document from the [available Registry Reports response](#available-registry-report-documents) | ```json theme={"system"} { "countryCode": "LT", "registrationNumber": "304617621", "companyName": "IDENFY", "productKey": "EBRON_RUJSX0NvbXBhbnlQcm9maWxlXzE=_MzA0NjE3NjIx__" } ``` Successful request / 200 OK with empty body. *** ### List Ordered Registry Report Documents **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/api/v2/gov-ordered-documents/` **Response example** ```json theme={"system"} [ { "id": "39e40532-8838-402b-a72e-ab39d1c43b16", "title": "Company Officials", "documentFormat": "PDF", "productKey": "EBRON_RUJSX0NvbXBhbnlPZmZpY2lhbHNfMQ==_MzA0NjE3NjIx__", "expectedDeliveryTime": "2024-01-02T09:51:53.643567Z", "price": 1.0, "deliveredAt": "2024-01-02T09:52:55.543725Z", "status": "FINISHED", "file": "https://s3.eu-west-1.amazonaws.com/..." }, { "id": "f0733089-c27e-47cb-b49d-e9950097aed2", "title": "Beneficial Ownership Report", "documentFormat": "PDF", "productKey": "ROWOFF_Q1pfVUJP_QmVuZWZpY2lhbCBPd25lcnNoaXAgUmVwb3J0_...", "expectedDeliveryTime": "2023-12-14T08:24:18.959072Z", "price": 5.0, "deliveredAt": "2023-12-14T09:21:58.768875Z", "status": "FINISHED", "file": "https://s3.eu-west-1.amazonaws.com/..." } ] ``` ### Retrieve Specific Registry Report Document **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/api/v2/gov-ordered-documents/{id}/` **:** `Report's unique number` **Response example** ```json theme={"system"} { "id": "39e40532-8838-402b-a72e-ab39d1c43b16", "title": "Company Officials", "documentFormat": "PDF", "productKey": "EBRON_RUJSX0NvbXBhbnlPZmZpY2lhbHNfMQ==_MzA0NjE3NjIx__", "expectedDeliveryTime": "2023-12-14T08:36:26.033428Z", "price": 1.0, "deliveredAt": "2024-01-02T09:52:55.543725Z", "status": "FINISHED", "file": "https://s3.eu-west-1.amazonaws.com/..." } ``` # Social Screening Source: https://documentation.idenfy.com/kyb/social-screening Screen companies across social media, web sources, and address audits using the iDenfy KYB social screening and audit API endpoints. ## Address, Website Audit Reports and Social Profile of Companies **Requirements** * API key pair * Credits **for each** desired service *** ### Address Audit **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/audits/address-audit/` **Request structure** | Parameter | Type | Required | Explanation | | --------- | ------ | -------- | ----------------- | | `address` | String | Yes | Address for audit | **Samples** ```json theme={"system"} { "address": "string" } ``` ```json theme={"system"} { "id": "f84211c0-5ffc-4955-8b6c-d2ac3c8dd768", "created": "2025-03-18T13:18:38.417600Z", "googleMapsUrl": "https://www.google.com/maps/search/...", "dataId": "0x46e7186363af0e71:0x76491c4f48ca5923", "type": ["Building"], "address": "Gri\u010diupio g. 7 Gri\u010diupio g. 7, Kaunas, 51372 Kauno m. sav., Lithuania", "associatedBodies": ["Gri\u010diupio g. 7-m"], "latitude": 54.9050526, "longitude": 23.963629899999997, "riskLevel": "VERY_LOW", "addressAuditImages": [ { "image": "IMAGE_FILE_RETURNED_HERE", "type": "STREET_VIEW" } ] } ``` *** ### Website Audit **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/audits/website-audit/` **Request structure** | Parameter | Type | Required | Explanation | | --------- | ------ | -------- | -------------------------------- | | `url` | String | Yes | Valid URL address of the website | **Samples** ```json theme={"system"} { "url": "https://idenfy.com/" } ``` ```json theme={"system"} { "id": "723ef8ad-c1ec-4d80-8632-5550ce67d3d1", "created": "2025-03-18T13:21:52.690606Z", "url": "https://idenfy.com/", "riskLevel": "VERY_LOW", "trustScore": 100, "blacklistScore": 0, "internalAuditScore": 100, "popularityScore": 100, "domainCreatedAt": "2017-09-08T12:19:34Z", "image": null, "websiteTitle": "Identity Verification Service | ID Verification - iDenfy", "websiteDescription": "Identity verification service for user onboarding. Mitigate fraud with instant ID verification. Meet Know Your Customer, AML regulations." } ``` *** ### Company Social Audit **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/audits/company-name-audit/` **Request structure** | Parameter | Type | Required | Explanation | | ------------- | ------ | -------- | ----------------------------------- | | `address` | String | Yes | Registration address of the company | | `companyName` | String | Yes | Name of the company | **Samples** ```json theme={"system"} { "address": "string", "companyName": "string" } ``` ```json theme={"system"} { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "descriptionByCompany": "string", "address": "string", "phoneNumber": "string", "industry": "string", "rating": 0, "socialMediaProfiles": { "property1": null, "property2": null }, "companyName": "string", "reviews": [{}] } ``` # SOS Reports Source: https://documentation.idenfy.com/kyb/sos-reports Order and retrieve Secretary of State filing reports for US company verification and compliance checks using the iDenfy KYB API tools. **Requirements** * **API** key pair * Reports functionality **enabled** (done by iDenfy's staff) *** ## Ordering SOS Document **Authorization:** `API key pair` **Method:** `POST` **Endpoint:** `https://ivs.idenfy.com/api/v2/sos-filing-documents/` **Request structure** | Parameter | Type | Required | | ------------- | ------ | -------- | | `companyName` | String | Yes | | `state` | String | Yes | | `city` | String | Yes | | `street` | String | Yes | | `postalCode` | String | Yes | The ordered report takes time to generate and will initially have status `IN_PROGRESS`. **Request example** ```json theme={"system"} { "companyName": "City and Borough of Juneau", "state": "AK", "city": "Juneau", "street": "155 S Seward St", "postalCode": "99801" } ``` *** ## List Documents **Authorization:** `API key pair` **Method:** `GET` **Endpoint:** `https://ivs.idenfy.com/api/v2/sos-filing-documents/` **Request structure** | Query Parameter | Type | Explanation | | --------------- | ------------------------------ | --------------------------------------------------------------------- | | `checkedAt` | Array of strings `` | Date-time filter for checked documents | | `status` | String | Enum: `FAILED`, `FINISHED`, `IN_PROGRESS`, `NOT_ORDERED`, `TIMED_OUT` | # KYB Webhooks Source: https://documentation.idenfy.com/kyb/webhooks Receive business verification results and status changes via webhook callbacks for company submit, review, AML, and expiration events. **Requirements** * Setting up **webhooks** requires **Admin** role * Set up [webhooks](/guides/dashboard/settings/system-notifications-webhooks-emails) * Your endpoint must have a valid **SSL** certificate for TLS webhooks to prevent delivery failures ## Setting Up Notifications To set up notifications, log in to your dashboard and navigate to [Settings > Notifications](/guides/dashboard/settings/system-notifications-webhooks-emails). *** ## Webhook Events for Companies The following webhook events are available for company-related notifications. For full payload details on each event, see the **API Reference** tab. | Event | API Reference | Description | | ------------------------ | -------------------- | -------------------------------------------------- | | **COMPANY SUBMIT** | `companySubmit` | Triggered when a company form is submitted | | **COMPANY REVIEW** | `companyReview` | Triggered when a company review is completed | | **COMPANY AML REVIEW** | `companyAmlReview` | Triggered when a company AML review is completed | | **COMPANY EXPIRATION** | `companyExpiration` | Triggered when a company verification expires | | **COMPANY INFO REQUEST** | `companyInfoRequest` | Triggered when additional information is requested | | **COMPANY DELETE** | `companyDelete` | Triggered when a company is deleted | *** ## Webhook Events for Reports | Event | API Reference | Description | | ------------------------ | -------------------- | ----------------------------------------------------------- | | **GOV ORDERED DOCUMENT** | `govOrderedDocument` | Triggered when a government ordered document status changes | *** ## Webhook Troubleshooting ### Ensure That * You have provided a valid callback endpoint (it does not contain typos and is a fully specified URL with HTTP schema, port, and domain name). * The provided endpoint can be reached from the internet. * Your SSL is set up correctly. The system can only send webhooks to URLs with valid SSL certificates. * You are truly not receiving a callback and your framework is not accidentally returning some other HTTP response (e.g. 422 or 500). ### Review Webhooks Sent via iDenfy Dashboard By going to **Settings** > **Notifications** > selecting **Recently sent** in the top right corner, you can search for specific notifications and see what was sent and what status was received from your server. 1. **Search field** - Use scanRef to search for specific notifications for verification. 2. **Response status** - The response received from your server: * **`0`** - No Response: No communication; server unreachable. * **`2xx`** - Success: Request successful, information returned. * **`3xx`** - Redirection: Further action needed, request redirected. * **`4xx`** - Client Errors: Your server could not handle the response. * **`5xx`** - Server Errors: Request valid, there is a problem with the server. 3. **Date and time** when the notification was sent. 4. **Resend** - Attempt to resend the webhook. 5. **Details** - Shows full information of what was sent in JSON format. Webhook troubleshooting in the iDenfy dashboard # Additional Steps Source: https://documentation.idenfy.com/kyc/additional-steps Request additional documents like utility bills or bank statements as part of the iDenfy verification flow using the additional steps API. **Requirements:** * API key pair * Additional step credits * Additional step session creation via API enabled (configured by iDenfy staff) * Additional step type set in your environment (configured by iDenfy staff) **Limitations:** * The Utility Bill document selection step does not validate the user's choice against the upload -- it only guides them on expected document types. * The Utility Bill document selection step is shown only when the step name is `UTILITY_BILL`. To skip it, use any different step name. * Contact iDenfy to change custom additional step texts (`name` and `description`). *** ## Generating Token with Additional Step ### UPLOAD Processing Type Use this when you simply want to store the document file as part of the verification without extracting or validating its contents. **When to use:** * You only need to attach the document to the verification record. * No analysis, extraction, or validation is required. **What happens:** * The system saves the document with the verification. * No automated checks or manual review are triggered. * No data is extracted or returned. ### COMPARE Processing Type Use this when you need to both extract data and compare it against values you provide. **When to use:** * You want to verify if the data in the document matches what you supplied during [token creation](/kyc/generate-token). * Example: Match the address on the document with `additionalData` sent during verification start. **What happens:** * The system extracts data from the document. * That data is compared with the values you provided via the `additionalData` key. * The API returns the comparison result. **Possible comparison results** (in `additionalData.status`): * `MATCH` * `NOT_MATCH` * `NOT_FOUND` * `NO_DATA` These are also included in the [webhook callback](/kyc/webhooks). ### EXTRACT Processing Type Use this when you need to extract address or data from the document but do not want to compare it to anything. **When to use:** * You want to read and extract data (e.g., address) from the document. * You do not need to validate it against pre-supplied data. **What happens:** * The system (AI or manual team) reads and extracts data from the document. * The extracted data is available in the verification UI and the [webhook callback](/kyc/webhooks). Do **not** rely on the `additionalData.status` field for the EXTRACT type. Since no matching is performed, the `status` field is not applicable. Focus only on the raw extracted data. *** ## Session Creation Request To [create a session](/kyc/generate-token) with a utility bill step, you do not need to pass anything extra. The custom additional step is included by default if configured in your environment settings. ### Minimal Request ```json theme={"system"} { "clientId": "123" } ``` ### Response Example ```json theme={"system"} { "message": "Token created successfully", "authToken": "cBqwefLQK6jEA20CJnq12r01cge00mlvPrjTGM4", "scanRef": "6a31253e-e10a-11eb-cc95-02cb49d118ed", "clientId": "2", "personScanRef": "2", "firstName": null, "lastName": null, "successUrl": null, "errorUrl": null, "unverifiedUrl": null, "callbackUrl": null, "locale": null, "country": null, "expiryTime": 3600, "sessionLength": 600, "documents": ["ID_CARD", "PASSPORT", "DRIVER_LICENSE", "RESIDENCE_PERMIT"], "dateOfBirth": null, "dateOfExpiry": null, "dateOfIssue": null, "nationality": null, "personalNumber": null, "documentNumber": null, "sex": null, "address": null, "showInstructions": true, "tokenType": "IDENTIFICATION", "utilityBill": true, "additionalSteps": { "ALL": { "ALL": { "UTILITY_BILL": { "type": "UPLOAD", "texts": { "en": { "name": "Please upload a proof of address document", "description": "Please make sure that the proof of address document is fully visible and is not older than 3 months. All information must be clearly visible including your full name, address, date of the document, and the document must be a legitimate utility bill or a bank statement, as handwritten papers are not accepted. Also, the utility bill must be in Latin alphabet. ID documents are not accepted as valid proof of address." }, "de": { "name": "Bitte laden Sie einen Adressnachweis hoch", "description": "Bitte achten Sie darauf, dass der Adressnachweis vollständig sichtbar und nicht älter als 3 Monate ist. Alle Informationen müssen deutlich sichtbar sein, einschließlich Ihres vollständigen Namens, Ihrer Adresse und des Datums des Dokuments, und das Dokument muss eine gültige Stromrechnung sein, ein Kontoauszug, da handschriftliche Papiere nicht akzeptiert werden. Außerdem muss die Stromrechnung im lateinischen Alphabet sein. Ausweisdokumente werden nicht als gültiger Adressnachweis akzeptiert." }, "es": { "name": "Cargue un comprobante de domicilio", "description": "Asegúrese de que el comprobante de domicilio esté completamente visible y no tenga más de 3 meses. Toda la información debe ser claramente visible, incluido su nombre completo, dirección, fecha del documento, y el documento debe ser una factura de servicios públicos legítima, un extracto bancario, no se aceptan documentos escritos a mano. También, la factura de servicios públicos debe estar en alfabeto latino. Los documentos de identidad no se aceptan como prueba válida de domicilio." } }, "fields": [], "settings": { "canUpload": true, "canCapture": true, "canUploadPDF": true } } } } }, "externalRef": null, "digitString": null } ``` *** ## Request with Address Data You can optionally include the expected user address details within the `additionalData` object when generating an identification token. **How provided data affects verification:** * **COMPARE steps:** If you provide the address in `additionalData`, it will be automatically cross-referenced against the submitted document. Without it, this comparison is skipped. * **EXTRACT steps:** No comparison is performed, so the provided address is stored as reference information alongside the extracted data. Proof of address documents are processed automatically and are not routed to manual review. **Document requirements for address proof:** When users submit proof of address documents (like utility bills), they must adhere to these standards: * **Age:** No older than 3 months. * **Clarity:** All text clear and unobstructed. * **Format:** Official documents only (no handwritten notes), using Latin characters. ### Request Example ```json theme={"system"} { "clientId": "123", "additionalData": { "UTILITY_BILL": { "address": "1234, Drive/Street, City/State, postcode, etc." } } } ``` The step name `UTILITY_BILL` in `additionalData` must match the step name configured in your environment's Custom Additional Step settings. ### Response The response structure is identical to the [minimal request response](#response-example) above, with these key differences: * `"type"` is set to `"EXTRACT"` (or whichever processing type you configured) instead of `"UPLOAD"` * `"fields"` contains the fields you requested (e.g., `["address"]`) * An `"additionalData"` object is included, echoing the address data you provided *** ## Upload or Re-Upload for Existing Verification ``` POST https://ivs.idenfy.com/api/v2/upload-additional-step Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` You can allow users to update or re-submit documents for custom additional steps after their initial verification attempt. This addresses scenarios such as: * Correcting a previously uploaded document that was deemed invalid (e.g., a utility bill older than three months). * Providing a required additional document after the main identity verification flow has been completed. When a new document is submitted this way, it overrides any data previously uploaded for that specific additional step during the earlier verification attempt. ### Request Example ```json theme={"system"} { "scanRef": "3f2d0e6a-0a37-11ec-a45b-025ad99a18e7", "image": "{{Base64 image}}", "step": "UTILITY_BILL", "additionalData": {} } ``` *** ## Additional Configurations ### Verification Without Custom Additional Step If a custom additional step is pre-configured on iDenfy's side but you need to create some tokens without it, pass an empty object for the step: ```json theme={"system"} { "additionalSteps": { "ALL": { "ALL": {} } } } ``` ### Multiple Custom Additional Steps If multiple custom additional steps are configured at the environment level, token creation includes all of them by default. To use only a specific step, specify it explicitly. For example, if `UTILITY_BILL` and `ADDITIONAL_DOCUMENT` are configured and you want only the latter: ```json theme={"system"} { "additionalSteps": { "ALL": { "ALL": ["ADDITIONAL_DOCUMENT"] } } } ``` ### Customization Options The default `UTILITY_BILL` step always includes a selection step from the user's perspective. This step is configurable on the partner environment level (if permissions are granted). Find it at **Settings > Configuration > Customisation > Allowed POA Documents** or contact iDenfy's tech support team to edit it. * Bank Statement * Electricity Bill * Water Bill * Credit Card Bill or Statement * Gas Bill * Telephone Bill * Bank Reference Letter * Internet Bill * Mortgage Statement or Contract * Company Payslip * Car or Home Insurance Policy * Municipality Bill or Government Tax Letter * Driver's License * Residence Permit * Official Letter from an Educational Institution * Lease Agreement for Your Residence * Letter of Employment * Authorized Change of Address Form * Car Registration * Other * Letter Issued by a Public Authority *** ## Managing Custom Additional Steps Per Request **Recommended approach: Server-side configuration.** Controlling custom additional steps by sending specific instructions with each API request is not the standard method and should only be used as a fallback. We strongly recommend configuring your custom additional steps within your iDenfy account settings whenever possible. If necessary, you can define or override the behavior of custom additional steps for individual verification requests. This is done by including a specifically structured `additionalSteps` object when [creating the verification session](/kyc/generate-token). If you use different types of additional steps, you must have sufficient credits for each type. ### Request Example ```json theme={"system"} { "clientId": "1", "additionalSteps": { "ALL": { "ALL": { "UTILITY_BILL": { "type": "COMPARE", "texts": { "en": { "name": "YOUR_PROVIDED_NAME_FOR_SECTION", "description": "YOUR_EXPLANATION_OF_THE_SECTION" } }, "fields": ["address"], "settings": { "canUpload": false, "canCapture": true, "canUploadPDF": false } } } } } } ``` # Data Retrieval Source: https://documentation.idenfy.com/kyc/data-retrieval Retrieve identity verification status, extracted document data, and uploaded files via the iDenfy API as a fallback to webhook delivery. **Webhooks are the recommended method for receiving verification results.** They deliver data efficiently as events happen. Use these endpoints **only** as a fallback: * If you suspect a [webhook](/kyc/webhooks) notification failed or missed data * To fetch details for a verification after it has already finished **Do not poll `/api/v2/status`** as part of your main integration flow. iDenfy does not support regular polling and may restrict your access. Some data fields may be `null` if the information was not present on the document or unreadable due to image quality. *** ## Verification Status ``` POST https://ivs.idenfy.com/api/v2/status Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` ### Request ```json theme={"system"} { "scanRef": "328c6766-934e-11ed-bb9b-025ad99a18e7" } ``` ### Response ```json theme={"system"} { "fraudTags": [], "mismatchTags": [], "autoDocument": "DOC_VALIDATED", "autoFace": "FACE_MATCH", "manualDocument": "DOC_VALIDATED", "manualFace": "FACE_MATCH", "scanRef": "328c6766-934e-11ed-bb9b-025ad99a18e7", "clientId": "W2GL2K333Y", "status": "APPROVED" } ``` ### Response Fields | Field | Description | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | Overall verification status: `APPROVED`, `DENIED`, `SUSPECTED`, `REVIEWING`, `ACTIVE`, `EXPIRED`. See [Status Handling](/guides/dashboard/kyc/status-handling) for what to do with each. | | `autoDocument` | Automated document check result (e.g., `DOC_VALIDATED`, `DOC_NOT_FOUND`). | | `autoFace` | Automated face check result (e.g., `FACE_MATCH`, `FACE_MISMATCH`). | | `manualDocument` | Manual review document result. Empty if not reviewed yet. | | `manualFace` | Manual review face result. Empty if not reviewed yet. | | `fraudTags` | Array of fraud indicators that can produce a `SUSPECTED` status. See [Suspected Status](/kyc/suspected-status) for examples. | | `mismatchTags` | Array of data mismatches between token data and document data. See [Suspected Status](/kyc/suspected-status) for examples. | | `scanRef` | Unique verification identifier. | | `clientId` | Your client identifier. | *** ## Verification Data ``` POST https://ivs.idenfy.com/api/v2/data Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` ### Request ```json theme={"system"} { "scanRef": "328c6766-934e-11ed-bb9b-025ad99a18e7" } ``` ### Response ```json theme={"system"} { "docFirstName": "JOHN", "docLastName": "SAMPLE BUTCH", "docNumber": "DE4878783", "docPersonalCode": null, "docExpiry": "2024-03-09", "docDob": "1965-03-10", "docDateOfIssue": "2014-03-09", "docType": "PASSPORT", "docSex": "MALE", "docNationality": "NL", "docIssuingCountry": "NL", "docTemporaryAddress": null, "docBirthName": null, "birthPlace": "LONDON", "authority": "BURG", "address": null, "mothersMaidenName": null, "driverLicenseCategory": null, "manuallyDataChanged": false, "fullName": "JOHN SAMPLE BUTCH", "orgFirstName": "JOHN", "orgLastName": "SAMPLE BUTCH", "orgNationality": "NEDERLANDSE", "orgBirthPlace": "LONDON", "orgAuthority": "BURG", "orgAddress": null, "selectedCountry": "NL", "ageEstimate": null, "clientIpProxyRiskLevel": null, "duplicateFaces": null, "duplicateDocFaces": null, "addressVerification": null, "additionalData": {}, "scanRef": "328c6766-934e-11ed-bb9b-025ad99a18e7", "clientId": "W2GL2K333Y" } ``` ### Key Data Fields | Field | Description | | ----------------------------------------- | ---------------------------------------------------------------------------- | | `docFirstName` / `docLastName` | Parsed name from document (standardized). | | `orgFirstName` / `orgLastName` | Original name as it appears on the document (may include native characters). | | `docNumber` | Document number. | | `docPersonalCode` | Personal/national code from document. | | `docExpiry` / `docDob` / `docDateOfIssue` | Document dates (format: `YYYY-MM-DD`). | | `docType` | Document type (`PASSPORT`, `ID_CARD`, `DRIVER_LICENSE`, etc.). | | `docSex` | Gender from document (`MALE`, `FEMALE`). | | `docNationality` / `docIssuingCountry` | ISO country codes. | | `selectedCountry` | Country the user selected during verification. | | `manuallyDataChanged` | `true` if a human reviewer corrected any OCR data. | | `fullName` | Combined full name. | | `ageEstimate` | Estimated age (if available). | | `clientIpProxyRiskLevel` | Proxy risk level (if proxy check enabled). | | `duplicateFaces` / `duplicateDocFaces` | Duplicate detection results (if enabled). | | `addressVerification` | Address verification result (if enabled). | | `additionalData` | Data from additional steps. | Any field can be `null`. Some fields in the original language may contain UTF-16 encoded characters. *** ## Verification Files ``` POST https://ivs.idenfy.com/api/v2/files Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` ### Request ```json theme={"system"} { "scanRef": "328c6766-934e-11ed-bb9b-025ad99a18e7" } ``` ### Response ```json theme={"system"} { "FACE": "https://...", "FRONT": "https://...", "fileUrls": { "FACE": "https://...", "FRONT": "https://..." }, "videoUrls": {}, "additionalStepPdfUrls": {} } ``` Always use URLs from `fileUrls` and `videoUrls`. Top-level file URLs outside these objects may be removed in the future. # Identification Deletion Source: https://documentation.idenfy.com/kyc/deletion Delete identity verification data and associated files via the iDenfy API for GDPR compliance using the scanRef identifier endpoint. **Requirements:** * API key pair * `scanRef` of the verification to delete *** ## Deleting Verification Data ``` POST https://ivs.idenfy.com/api/v2/delete Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` This endpoint removes data from iDenfy's system including client photos of their document and face, parsed document information, names, surnames, and other personal data. The only required parameter is `scanRef` of the verification. ### Request Example ```json theme={"system"} { "scanRef": "350e2420-8850-11e9-baa5-309c231b1bac" } ``` ### Response -- Success For successful API calls that correctly delete all data, there will be no message body -- just a response with a **200** status code. ### Response -- Failed Failed API calls return a message identifying the problem. ```json theme={"system"} { "message": "Token has not expired yet.", "identifier": "PARTNER_ERROR", "documentation": "", "severity": "NOT_SEVERE" } ``` In case of a malformed JSON body or API key/secret mismatch, you will receive a standard iDenfy API error response. For more details, see [error messages](/kyc/id-error-messages). # Direct Processing Source: https://documentation.idenfy.com/kyc/direct-processing Submit identity document images via a single API call for asynchronous server-side KYC verification — no SDK or user-facing session required. **Requirements:** * API key pair * **Direct Processing** feature enabled on your contract (contact iDenfy to activate) **Limitations:** * Does not support **3D liveness detection** or **short photo sequences**. Use a different integration type if these are required. * Maximum request size: **20 MB** (total across all images). * Cannot be used to update an existing verification. Use the [Request Update feature](/kyc/request-update) or re-verify using the same `clientId` via [session creation](/kyc/generate-token). * Digital ID types are not supported and will be rejected. *** ## How It Works Direct processing lets you submit document images in a single POST request. The API responds immediately — the actual OCR, face matching, fraud checks, and AML screening all run asynchronously after the response. Results are delivered via webhook. *** ## Endpoint ``` POST https://ivs.idenfy.com/api/v2/process Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` *** ## Request Parameters ### Required The verification session token generated beforehand via [session creation](/kyc/generate-token). * Must be valid, unused, and belong to the authorized partner. * Deactivated immediately after the request — cannot be reused. * Must not have questionnaire answers (`kyc_answers`) attached. * NFC must not be required for the session. ISO 3166-1 alpha-2 country code (e.g. `LT`, `US`, `DE`). Converted to uppercase automatically. Must be a valid recognized country code. A dictionary of Base64-encoded images, keyed by side: | Key | Description | Required | | --------------------- | ------------------------- | ---------------------------------------------------------------- | | `FRONT` | Document front | Always | | `BACK` | Document back | When the document type has a back side | | `FACE` | Selfie | Required for identification sessions; optional for document-only | | `UTILITY_BILL` | Utility bill image or PDF | When configured as a required step on the token | | `SECOND_UTILITY_BILL` | Second utility bill | When configured | **Supported formats:** PNG, JPG, JPEG, PDF. Encrypted or password-protected PDFs are rejected. ### Optional Specifies the document being submitted. Valid values: `ID_CARD`, `PASSPORT`, `DRIVER_LICENSE`, `RESIDENCE_PERMIT`. If omitted, the system automatically detects the document type from the `FRONT` image. If auto-detection fails, the request is rejected with an error. When `documentType` is provided, `BACK` becomes required if that document type has a back side. Set to `true` to skip photo quality checks (blur, glare, document detection). Useful when a valid photo fails standard detection. Does **not** skip data extraction or fraud checks — only the photo validation step. *** ## Verification Types The session `tokenType` set during [session creation](/kyc/generate-token) determines what images are expected: * **IDENTIFICATION (Default):** Requires a `FACE` image. Face matching runs against the document photo. * **DOCUMENT:** Document-only. Face step is removed automatically — no `FACE` image or liveness check required. Result is marked `FACE_NOT_CHECKED`. *** ## Additional Steps Some verification flows require extra document checks beyond the main identity document — for example, a utility bill for address verification. These are configured as additional steps on the token at [session creation](/kyc/generate-token), not in the `/v2/process` call itself. **How it works:** 1. **Token creation** — the partner sets up the token with `UTILITY_BILL` as a required additional step, and optionally passes a reference address to compare against via `additionalData`: ```json theme={"system"} { "additionalData": { "UTILITY_BILL": { "address": "123 Main St, City" } } } ``` 2. **Direct processing call** — the partner includes the utility bill image inside the `images` object alongside the main document images. No extra fields are needed in the `/v2/process` request body. 3. **Processing** — depending on the step configuration, the system will: | Mode | Behaviour | | --------- | -------------------------------------------------------------------------------------- | | `UPLOAD` | Stores the image; no analysis | | `EXTRACT` | Extracts the address from the bill; no comparison | | `COMPARE` | Extracts the address and checks it against the reference address from `additionalData` | *** ## Conditions and Rules | Condition | Rule | | ------------------------ | ----------------------------------------------------------------------------------------------- | | Partner access | Partner must have direct processing enabled in their contract — if not, the request is rejected | | Token with questionnaire | Not allowed. Token must have no `kyc_answers` attached | | NFC required token | Not allowed with direct processing | | `documentType` omitted | Only `FRONT` is mandatory; document type is auto-detected from the image | | `documentType` provided | `BACK` becomes required if that document type has a back side | | `FACE` image | Required when the session type includes face matching | | PDF submitted | Must not be password-protected | | Token reuse | Token is deactivated after one direct processing call | *** ## Request Examples **With explicit document type:** ```json theme={"system"} { "authToken": "3FA5TFPA2ZE3LMPGGS1EGOJNJE", "country": "LT", "documentType": "ID_CARD", "images": { "FRONT": "/9j/4AAQSkZJRgABAQAAAQABAAD/4...", "BACK": "/9j/4AAQSkZJRgABAQAAAQABAAD/4...", "FACE": "/9j/4AAQSkZJRgABAQAAAQABAAD/4..." } } ``` **With auto document type detection (documentType omitted):** ```json theme={"system"} { "authToken": "3FA5TFPA2ZE3LMPGGS1EGOJNJE", "country": "LT", "images": { "FRONT": "/9j/4AAQSkZJRgABAQAAAQABAAD/4...", "FACE": "/9j/4AAQSkZJRgABAQAAAQABAAD/4..." } } ``` *** ## Response A successful request returns HTTP **200** with no response body. Processing continues asynchronously. ### Error Response Failed requests return a JSON body identifying the problem: ```json theme={"system"} { "message": "No image provided for step 'BACK'", "identifier": "MISSING_VALUE", "documentation": "", "severity": "NOT_SEVERE" } ``` A `200 OK` with an error message body may indicate the document was not detected in the photo. If this happens: * Add `"skipAnalysis": true` to the request, or * Use a clearer photo with a fully visible document. See the full list of [error messages](/kyc/id-error-messages). *** ## What Happens After Once the request is accepted, processing runs asynchronously: 1. **OCR** extracts document fields — name, date of birth, expiry, document number, nationality, and more. 2. **Face matching** runs if a `FACE` image was provided. 3. **Fraud checks** and **AML/sanctions screening** run automatically. 4. **Results are delivered via webhook** to your configured endpoint. See [Webhooks](/guides/webhooks-overview) for payload details. # Dual Verification Flow Source: https://documentation.idenfy.com/kyc/dual-verification Run a silent second identity check on documents your user uploads during their first verification — no second UI session required. **Requirements:** * API key pair * **Direct Processing** enabled on your contract (contact iDenfy) * **Custom Additional Steps** enabled on your account (contact iDenfy) * Additional step credits *** ## Overview This pattern lets you verify two different identity documents from the same user while only showing them one verification UI. The user completes the standard flow and uploads the second document as a custom additional step. Your backend then silently runs a second verification on those files via direct processing — no second session for the user. Both verifications are linked by the same `clientId` and each produces its own webhook result. ```mermaid theme={"system"} %%{init: {'theme': 'base', 'themeVariables': {'fontFamily': 'Inter, sans-serif', 'fontSize': '11px', 'primaryColor': '#734BFB', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#5A2FE0', 'lineColor': '#9B7BFC', 'edgeLabelBackground': '#5A2FE0', 'edgeTextColor': '#ffffff'}}}%% flowchart TB subgraph r1[" "] direction LR A("`Create Token 1`") --> B("`Send verification link`") --> C("`User completes verification & uploads extra document`") --> D("`Webhook received`") end subgraph r2[" "] direction LR E{{"`Verification **APPROVED** and additional steps completed?`"}} -->|Yes| F("`Download files 1-hour window`") --> G("`Create Token 2 same **clientId**`") --> H("`**POST /api/v2/process** auto-detects doc type`") --> I("`Second webhook verification complete`") end D --> E E -->|No| Z("`Stop`") classDef step fill:#734BFB,stroke:#5A2FE0,color:#ffffff classDef user fill:#9B7BFC,stroke:#734BFB,color:#ffffff classDef decision fill:#5A2FE0,stroke:#4c1d95,color:#ffffff classDef stop fill:#ef4444,stroke:#dc2626,color:#ffffff classDef done fill:#22c55e,stroke:#16a34a,color:#ffffff class A,B,D,F,G,H step class C user class E decision class Z stop class I done style r1 fill:none,stroke:none style r2 fill:none,stroke:none ``` *** ## Step 1 — Create Token 1 (User-Facing) Token 1 needs a custom additional step that prompts the user to upload the extra document(s). The simplest setup is to have iDenfy support configure this as a **default on your account** — it then applies automatically to every session without any extra parameters in the token request. If you need per-request control instead (for example, to apply the step only on certain sessions), you can pass the `additionalSteps` object yourself when creating the token. See [Additional Steps](/kyc/additional-steps#managing-custom-additional-steps-per-request) for the full structure and options. Save the `scanRef` from the response — you'll use it to match the incoming webhook. For all token parameters, see [Create Verification Session](/kyc/generate-token). *** ## Step 2 — Send the User to Verification Redirect the user using the `authToken` from the Token 1 response. They complete the standard flow and then see the additional upload step(s) at the end. See [iFrame / Redirect](/kyc/iframe-redirect) for integration options. *** ## Step 3 — Receive Webhook and Download Files When the user finishes, your configured `callbackUrl` receives a webhook. Before proceeding, confirm two things: 1. **The main verification was approved** — check `status.overall`. Do not trigger the second verification if the primary identity check failed. 2. **The additional step was completed successfully** — check `status.additionalSteps`. This is independent of the main result: a user can pass the identity check but still fail or skip the extra upload. Only proceed if both statuses are positive. Then download the files: | Field | What it contains | | ------------------------ | ------------------------------------------------------------------------------------------------- | | `additionalSteps` | Map of step name → processing type, confirms which steps were completed | | `status.additionalSteps` | `"Additional step is valid"` / `"Additional step is invalid"` / `"Additional step was not found"` | | `fileUrls` | Pre-signed download URLs for image files, keyed by step name | | `additionalStepPdfUrls` | Pre-signed download URLs for PDF files, keyed by step name | For the full webhook payload structure and all status fields, see [KYC Webhooks](/kyc/webhooks). *** ## Step 4 — Create Token 2 (Silent) Create a second token using the **same `clientId`** to link it to the same person. This token is never shown to the user — it exists only to authorize the direct processing call. If your account has custom additional steps configured as a default, **disable them explicitly** on Token 2 by passing an empty `additionalSteps` object. The recommended approach here is to have iDenfy support configure the step as your account default and suppress it only for Token 2 this way: ```json theme={"system"} { "clientId": "user-123", "tokenType": "DOCUMENT", "additionalSteps": { "ALL": { "ALL": {} } } } ``` See [Additional Steps → Verification Without Custom Additional Step](/kyc/additional-steps#verification-without-custom-additional-step) for details on the suppression syntax. Additional points: * **No `successUrl` / `errorUrl`** — no one is watching this flow. * **No questionnaire** — direct processing is incompatible with KYC questionnaires. If your account attaches them by default, set `"questionnaire": null`. Save the `authToken` and `scanRef` from the response. *** ## Step 5 — Submit via Direct Processing Convert the files you downloaded in Step 3 to base64 and submit them to the direct processing endpoint using Token 2's `authToken`. Omit `documentType` — the system automatically detects the document type from the `FRONT` image. This means you can fully automate the second verification without knowing in advance what document the user uploaded. ```json theme={"system"} { "token": "", "country": "LT", "images": { "FRONT": "", "BACK": "" } } ``` A `200 OK` with no body means the request was accepted. Processing runs asynchronously and the result is delivered via a second webhook to your `callbackUrl`. Use the `scanRef` from Token 2 to identify which webhook belongs to which verification. For the full endpoint reference, parameters, and error handling, see [Direct Processing](/kyc/direct-processing). *** ## Tips **Check both statuses before proceeding** Only trigger the direct processing step after confirming both `status.overall` (main verification approved) and `status.additionalSteps` (document uploaded successfully). A passing identity check does not guarantee the additional step was completed. **File URLs are valid for 1 hour** The URLs in `fileUrls` and `additionalStepPdfUrls` are pre-signed and expire after one hour. Download the files as soon as the webhook arrives — do not store the URL and fetch it later. **Token 2 must not have a questionnaire** Direct processing rejects tokens with questionnaire answers attached. See the [Direct Processing conditions table](/kyc/direct-processing#conditions--rules) for the full list of token requirements. **Token 1 cannot be reused** The first token is deactivated the moment the user completes the flow. Create a fresh token (Token 2) for the direct processing call. # Dummy Results Source: https://documentation.idenfy.com/kyc/dummy-results Test identity verification outcomes with predefined dummy data and auto-results in the iDenfy development environment sandbox testing. **Requirements:** * API key pair * **DEV** environment * Finances added to your environment Dummy results only work in the **DEV** environment. Calling either endpoint from any other environment returns an error: | Environment | Error message | | ----------- | ------------------------------------------------------------------- | | DEMO | `"This endpoint is not available for DEMO partners."` | | TEST / PROD | `"This endpoint is not available for TESTING/PRODUCTION partners."` | **Why is DEMO excluded?** The DEMO environment is intended for showing the real verification flow to prospective clients. Dummy shortcuts would let partners simulate completed verifications without going through the actual process, which could give clients a misleading picture of what the product does. The restriction is intentional. *** ## Dummy Auto Results ``` POST https://ivs.idenfy.com/api/v2/token Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` You can create a session with a dummy auto status for verification in the development environment. The request must contain the same parameters as [session creation](/kyc/generate-token) plus `dummyStatus`, which defines the dummy session's auto result. | JSON key | Type | Description | | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `dummyStatus` | `String` | Auto status of the verification. Possible values: `APPROVED`, `DENIED`, `SUSPECTED`, `EXPIRED`. See [Verification Statuses](/guides/dashboard/kyc/verification-statuses#overall-status) for details. | ### Request Example ```json theme={"system"} { "dummyStatus": "APPROVED", "clientId": "100000", "firstName": "John Tom", "lastName": "Smith", "successUrl": "https://www.my-company.com/idenfy/success", "errorUrl": "https://www.my-company.com/idenfy/fail", "locale": "en", "showInstructions": true, "expiryTime": 600, "sessionLength": 600, "country": "lt", "documents": ["PASSPORT", "ID_CARD"], "dateOfBirth": "1990-12-20", "dateOfExpiry": "1990-12-20", "dateOfIssue": "1990-12-20", "nationality": "lt", "personalNumber": "123456789", "documentNumber": "123456", "sex": "M", "address": "Address", "tokenType": "IDENTIFICATION", "externalRef": "reference" } ``` ### Response Example A successful API call returns a JSON response with a `scanRef` that can be used to add a dummy manual status. ```json theme={"system"} { "message": "Dummy token and verification created successfully", "authToken": "pgYQX0z2T8mtcpNj9I20uWVCLKNuG0vgr12f0wAC", "scanRef": "ec6a7108-8c26-11e9-9758-309c231b1bac", "clientId": "100000", "firstName": "JOHN TOM", "lastName": "SMITH", "successUrl": "https://www.my-company.com/idenfy/success", "errorUrl": "https://www.my-company.com/idenfy/fail", "locale": "en", "showInstructions": true, "country": "lt", "expiryTime": 600, "sessionLength": 600, "documents": ["PASSPORT"], "dateOfBirth": "1990-12-20", "dateOfExpiry": "1990-12-20", "dateOfIssue": "1990-12-20", "nationality": "lt", "personalNumber": "123456789", "documentNumber": "123456", "sex": "M", "digitString": "4823657", "address": "Address", "tokenType": "IDENTIFICATION", "externalRef": "reference" } ``` *** ## Dummy Manual Result ``` POST https://ivs.idenfy.com/api/v2/add-dummy-status Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` You can add a dummy manual status for a verification in the development environment and receive the same webhook as after a real manual review. * The client's verification must already be created. If not, generate a new token with `dummyStatus` first. * For an approved verification, you need to provide both `FACE_MATCH` and `DOC_VALIDATED` statuses. ### Request Parameters | Key | Type | Description | | ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `scanRef` | `String` | A unique string identifying a client verification. | | `manualFaceMatchResult` | `String` | Dummy manual face status. Possible values: `FACE_MATCH`, `FACE_MISMATCH`, `NO_FACE_FOUND`, `TOO_MANY_FACES`, `FACE_TOO_BLURRY`, `FACE_UNCERTAIN`, `FACE_NOT_ANALYSED`, `FACE_NOT_CHECKED`, `FACE_ERROR`, `AUTO_UNVERIFIABLE`, `FAKE_FACE`. See [Verification Statuses → Face Status Values](/guides/dashboard/kyc/verification-statuses#face-status-values) for details. | | `manualDocumentValidity` | `String` | Dummy manual document status. Possible values: `DOC_VALIDATED`, `DOC_INFO_MISMATCH`, `DOC_NOT_FOUND`, `DOC_NOT_FULLY_VISIBLE`, `DOC_NOT_SUPPORTED`, `DOC_FACE_NOT_FOUND`, `DOC_TOO_BLURRY`, `DOC_FACE_GLARED`, `MRZ_NOT_FOUND`, `MRZ_OCR_READING_ERROR`, `BARCODE_NOT_FOUND`, `DOC_EXPIRED`, `COUNTRY_MISMATCH`, `DOC_TYPE_MISMATCH`, `DOC_DAMAGED`, `DOC_FAKE`, `DOC_ERROR`, `AUTO_UNVERIFIABLE`, `DOC_NOT_ANALYSED`, `DOC_NAME_ERROR`, `DOC_SURNAME_ERROR`, `DOC_EXPIRY_ERROR`, `DOC_DOB_ERROR`, `DOC_PERSONAL_NUMBER_ERROR`, `DOC_NUMBER_ERROR`, `DOC_DATE_OF_ISSUE_ERROR`, `DOC_SEX_ERROR`, `DOC_NATIONALITY_ERROR`. See [Verification Statuses → Document Status Values](/guides/dashboard/kyc/verification-statuses#document-status-values) for details. | ### Request Example ```json theme={"system"} { "scanRef": "unique_scan_ref", "manualDocumentValidity": "DOC_ERROR", "manualFaceMatchResult": "FACE_MATCH" } ``` A successful API call returns a response with a **200** status code. # Create Verification Session Source: https://documentation.idenfy.com/kyc/generate-token Create an identity verification session by generating an authentication token via the iDenfy API with minimal or advanced parameters. ``` POST https://ivs.idenfy.com/api/v2/token Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` *** ## Common Examples Start with these, then customize using the [full parameter reference](#all-parameters) below. The only required field is `clientId`: ```json theme={"system"} { "clientId": "user-123" } ``` Everything else uses your Dashboard defaults. Provide user data to cross-check against the document. Mismatches trigger `SUSPECTED` status: ```json theme={"system"} { "clientId": "user-123", "firstName": "John", "lastName": "Doe", "dateOfBirth": "1990-05-15" } ``` Lock verification to specific countries and document types: ```json theme={"system"} { "clientId": "user-123", "firstName": "John", "lastName": "Doe", "country": ["US", "GB", "DE"], "documents": ["PASSPORT", "ID_CARD"] } ``` All commonly used fields: ```json theme={"system"} { "clientId": "user-123", "firstName": "John", "lastName": "Doe", "dateOfBirth": "1990-05-15", "country": "US", "documents": ["PASSPORT", "ID_CARD"], "locale": "en", "expiryTime": 3600, "sessionLength": 600, "successUrl": "https://yourapp.com/verified", "errorUrl": "https://yourapp.com/failed", "callbackUrl": "https://yourapp.com/webhook" } ``` ### Code Examples ```bash cURL theme={"system"} curl -X POST https://ivs.idenfy.com/api/v2/token \ -u "YOUR_API_KEY:YOUR_API_SECRET" \ -H "Content-Type: application/json" \ -d '{"clientId": "user-123", "firstName": "John", "lastName": "Doe"}' ``` ```python Python theme={"system"} import requests response = requests.post( "https://ivs.idenfy.com/api/v2/token", auth=("YOUR_API_KEY", "YOUR_API_SECRET"), json={"clientId": "user-123", "firstName": "John", "lastName": "Doe"} ) token = response.json() # token["authToken"] → pass to frontend # token["redirectUrl"] → or redirect user here ``` ```javascript Node.js theme={"system"} const response = await fetch("https://ivs.idenfy.com/api/v2/token", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Basic " + btoa("YOUR_API_KEY:YOUR_API_SECRET"), }, body: JSON.stringify({ clientId: "user-123", firstName: "John", lastName: "Doe" }), }); const token = await response.json(); // token.authToken → pass to frontend // token.redirectUrl → or redirect user here ``` ```php PHP theme={"system"} $ch = curl_init("https://ivs.idenfy.com/api/v2/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_USERPWD, "YOUR_API_KEY:YOUR_API_SECRET"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "clientId" => "user-123", "firstName" => "John", "lastName" => "Doe" ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $token = json_decode(curl_exec($ch), true); ``` ```ruby Ruby theme={"system"} require "net/http" require "json" uri = URI("https://ivs.idenfy.com/api/v2/token") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request.basic_auth("YOUR_API_KEY", "YOUR_API_SECRET") request.content_type = "application/json" request.body = { clientId: "user-123", firstName: "John", lastName: "Doe" }.to_json token = JSON.parse(http.request(request).body) ``` *** ## Response ```json theme={"system"} { "message": "Token created successfully", "authToken": "pgYQX0z2T8mtcpNj9I20uWVCLKNuG0vgr12f0wAC", "scanRef": "ec6a7108-8c26-11e9-9758-309c231b1bac", "clientId": "user-123", "firstName": "JOHN", "lastName": "DOE", "redirectUrl": "https://ivs.idenfy.com/api/v2/redirect?authToken=pgYQX0z2T8...", "digitString": null, "expiryTime": 3600, "sessionLength": 600 } ``` **Key response fields:** | Field | Use it for | | ------------- | ----------------------------------------------------------------- | | `authToken` | Pass to iFrame, SDK, or redirect URL | | `redirectUrl` | Redirect user here for hosted verification | | `scanRef` | Unique verification ID — store this in your database | | `digitString` | 8-digit code for mobile app (only if `generateDigitString: true`) | *** ## What to Do Next After generating the token, send your user to verification: | Method | Code | When to use | | --------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | | **Redirect** | `window.location.href = token.redirectUrl` | Simplest. User leaves your site. | | **iFrame** | ` ``` **Embedding something other than `https://ui.idenfy.com`?** If your iFrame `src` is the redirect URL (`https://ivs.idenfy.com/api/v2/redirect?...`) or a custom UI domain, name the final UI origin in the allow list: ```html theme={"system"} allow="camera https://ui.idenfy.com; fullscreen https://ui.idenfy.com; clipboard-write https://ui.idenfy.com" ``` The default allowlist only covers the iFrame's own `src` origin, so permissions are lost after the cross-origin redirect. With a custom UI domain, use that domain here and in the `message` origin check below. **Skip the `sandbox` attribute.** Bank verification and Digital ID flows open popups, and sandboxing blocks them. If your security policy requires it, include at least: ```html theme={"system"} sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox" ``` `allow-popups` lets the popup open; `allow-popups-to-escape-sandbox` keeps the identity provider's login page working. ### Listening for Verification Results When the verification session ends, the iFrame posts a `message` event to the parent window. You **must** listen for this event to know the outcome. ```javascript theme={"system"} window.addEventListener("message", function (event) { // Verify the origin for security if (event.origin !== "https://ui.idenfy.com") return; // Native WebViews and some proxies stringify the payload — handle both forms let data = event.data; if (typeof data === "string") { try { data = JSON.parse(data); } catch { return; } } if (!data || typeof data !== "object") return; console.log("Status:", data.status); console.log("Manual status:", data.manualStatus); console.log("Auto suspected:", data.autoSuspected); console.log("Manual suspected:", data.manualSuspected); }); ``` #### Message Event Fields | Field | Type | Description | | ----------------- | ------- | --------------------------------------------------------------------- | | `status` | string | Automatic review result: `approved`, `failed`, or `unverified`. | | `manualStatus` | string | Manual (human) review result: `approved`, `failed`, or `waiting`. | | `autoSuspected` | boolean | `true` if the automatic check flagged the verification as suspicious. | | `manualSuspected` | boolean | `true` if a human reviewer flagged the verification as suspicious. | All status values are delivered **lowercase**. `manualStatus` will be `waiting` immediately after the session completes — the final manual review result is delivered asynchronously via [webhook](/kyc/webhooks). Do not treat `waiting` — or an `unverified` `status` — as a final state. Do **not** set `successUrl`, `errorUrl`, or `unverifiedUrl` when using the iFrame integration. These parameters cause the iFrame to redirect internally, which breaks the embedded flow. Use the `message` event instead to handle outcomes. ### Full HTML Example ```html theme={"system"} ``` *** ## Redirect Integration If you prefer a simpler integration without iFrame embedding, redirect your user to the iDenfy verification page. Your user leaves your site, completes verification, and returns to your redirect URL. ### Redirect URL ``` https://ivs.idenfy.com/api/v2/redirect?authToken={authToken} ``` Replace `{authToken}` with the token from the [session creation endpoint](/kyc/generate-token). When using redirect, you can configure `successUrl`, `errorUrl`, and `unverifiedUrl` during session creation. iDenfy will redirect the user back to the appropriate URL after the session ends. *** ## Why There Is No Web SDK iDenfy intentionally does not provide a JavaScript Web SDK. The iFrame approach is the recommended integration for web applications. **Benefits of the iFrame-only approach:** * **Always up to date** -- your integration automatically uses the latest UI, liveness detection, and document recognition without any code changes on your side. * **Lighter integration** -- no package to install, no bundle size impact, no dependency management. * **Future-proof** -- new features, supported documents, and UX improvements are available immediately. * **No version management** -- you never need to track SDK releases or handle breaking changes. *** ## Next Steps Receive real-time verification results on your server. Native Android and iOS SDKs for mobile apps. # Identity Verification API (KYC) Source: https://documentation.idenfy.com/kyc/overview Integrate iDenfy's Identity Verification API to verify customers with document checks, liveness detection, and AI plus human review. ## The Flow ``` Your server iDenfy Your user │ │ │ │── POST /api/v2/token ─────>│ │ │<── authToken, redirectUrl ─│ │ │ │ │ │── redirect user ──────────>│── show verification UI ───>│ │ │<── uploads doc + selfie ───│ │ │ │ │<── POST webhook ──────────│── AI + human review │ │ (APPROVED/DENIED) │ │ ``` ## Quick Integration (3 Steps) ```bash theme={"system"} curl -X POST https://ivs.idenfy.com/api/v2/token \ -u "API_KEY:API_SECRET" \ -H "Content-Type: application/json" \ -d '{"clientId": "user-123", "firstName": "John", "lastName": "Doe"}' ``` Response includes `authToken` and `redirectUrl`. [Full parameter reference →](/kyc/generate-token) **Simplest** — redirect to `redirectUrl`: ```javascript theme={"system"} window.location.href = data.redirectUrl; ``` **Embedded** — use iFrame: ```html theme={"system"} ``` **Mobile** — pass `authToken` to [Android](/sdks/android/quickstart) or [iOS](/sdks/ios/quickstart) SDK. ```json theme={"system"} { "status": { "overall": "APPROVED" }, "data": { "docFirstName": "JOHN", "docLastName": "DOE" }, "scanRef": "d2714c8a-...", "clientId": "user-123", "final": true } ``` When `final: true` — this is the definitive result. [Full webhook reference →](/kyc/webhooks) *** ## What Happens During Verification | Step | What iDenfy does | | -------------------- | ---------------------------------------------------------------- | | **Document capture** | User selects country + document type, takes photo (or uploads) | | **Liveness check** | 3D face liveness prevents spoofing (selfie with depth analysis) | | **AI analysis** | OCR extracts data, validates document authenticity, matches face | | **Human review** | Expert reviews edge cases — blurry docs, unusual documents | | **Result** | `APPROVED`, `DENIED`, or `SUSPECTED` delivered via webhook | ## Result Statuses A verification resolves to `APPROVED`, `DENIED`, or `SUSPECTED`. `SUSPECTED` does **not** mean failure — it means checks passed but flags were found for you to review. See [Status Handling](/guides/dashboard/kyc/status-handling) for what to do with each status. *** ## Features You Can Enable All configured via [session parameters](/kyc/generate-token) or [Dashboard settings](https://admin.idenfy.com): | Feature | Parameter | What it does | | -------------------- | ----------------------- | ------------------------------------------- | | Data comparison | `firstName`, `lastName` | Cross-checks your data against the document | | Country restriction | `country` | Limit accepted document countries | | Document types | `documents` | Limit accepted document types | | AML screening | `checkAml` | Auto-screen against sanctions/PEPs | | Proxy detection | `checkIpProxy` | Flag VPN/proxy usage | | Duplicate detection | `checkDuplicateFaces` | Detect same person verifying twice | | Face blacklist | `checkFaceBlacklist` | Block known fraudsters | | NFC chip reading | `nfcRequired` | Read document NFC chip for high assurance | | Age limit | `ageLimit` | Minimum age requirement | | Additional documents | `additionalSteps` | Request utility bills, bank statements | *** ## Pages in This Section | Page | When you need it | | ------------------------------------------- | ----------------------------------- | | [Create Session](/kyc/generate-token) | Creating a verification session | | [Redirect & iFrame](/kyc/iframe-redirect) | Showing the verification UI on web | | [Webhooks](/kyc/webhooks) | Receiving verification results | | [Data Retrieval](/kyc/data-retrieval) | Fetching results after verification | | [Additional Steps](/kyc/additional-steps) | Requesting extra documents | | [Direct Processing](/kyc/direct-processing) | Sending images via API (no UI) | | [Dummy Results](/kyc/dummy-results) | Testing with fake data | | [Deletion](/kyc/deletion) | GDPR data deletion | ## Next Steps Create a verification session via API. Show the verification UI on your website. Receive verification results in real-time. Native iOS and Android integration. # PDF Generation Source: https://documentation.idenfy.com/kyc/pdf-generation Generate downloadable PDF verification reports with extracted data and compliance details via the iDenfy identity verification API. **Requirements:** * API key pair * `scanRef` of the verification *** ## Generating a Verification PDF Report ``` POST https://ivs.idenfy.com/api/v2/generate-pdf Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` ### Report Contents The generated PDF report includes: * Verification data * Verification status * External Reference *(optional — enable the **External reference** checkbox in the Verification data section when generating the report from the dashboard)* * Miscellaneous data * AML data * LID data * Face photo * Document photos *** ## Request Parameters A unique string identifying a client verification. Language selection for the generated report. Possible values: `en`, `lt`. Whether to include main step photos (FRONT, FACE, BACK) in the generated PDF. Defaults to `true`. Whether to include additional step photos in the generated PDF. Defaults to `true`. ### Request Example ```json theme={"system"} { "scanRef": "350e2420-8850-11e9-baa5-309c231b1bac" } ``` ### Request Example -- with Language ```json theme={"system"} { "scanRef": "350e2420-8850-11e9-baa5-309c231b1bac", "language": "lt" } ``` ### Response -- Success After a successful API call, you will receive a PDF file in **Base64** format and a response with a **200** status code. # Request Update Source: https://documentation.idenfy.com/kyc/request-update Send update requests to end users for additional documents, risk assessment, or questionnaire completion via the iDenfy KYC API endpoint. Use this endpoint to generate a link that allows the end user to update information related to their verification. You can request one or more of the following: * **Questionnaire** — enable the questionnaire and choose a template for the ID verification process. * **Risk assessment** — enable the risk assessment for ID verification and select the template. * **Additional step (POA)** — enable an additional step for uploading files of proof of address or other required documents. * **Additional step (Bank card)** — request the user to scan their bank card to verify ownership. Set `bankCardVerification` to `true`, and optionally `bankCardExpectedLastFour` (exactly four digits) to also compare the card number. * **Send verification email** — request verification by sending a link to the selected email address. Request to update information modal If you have already requested updated information, this option will remain unavailable until the verification is **re-approved**. Attempting to generate a **second** update request while one is pending will result in an error. To check if a **Request Update** is already in progress, look for the status indicator on the verification dashboard. Request update example *** ## API Reference To generate an update request link, use the **Request Information Update** endpoint in the [KYC API Reference](/api-reference/overview). ``` POST https://ivs.idenfy.com/api/v2/request-update Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` A card check re-requested this way reports back on the identity verification webhook. To run a card check on its own, with no verification behind it, use [Create a Bank Card Session](/bank-card/create-session) instead. # Soft KYC Source: https://documentation.idenfy.com/kyc/soft-kyc Run lightweight identity verification using database checks without full document scanning via the iDenfy Soft KYC (eIDV) API endpoint. **Requirements:** * API key pair * Soft ID settings enabled (configured by iDenfy staff) * Finances added to your environment *** ## Generate Request ``` POST https://ivs.idenfy.com/api/v2/registry-center-checks/ Authorization: Basic {API_KEY}:{API_SECRET} Content-Type: application/json ``` For `US_15`, supply at least one of `dob` or `idNum` (full SSN or last 4 digits). Without either, the provider has only the name to match against. Do not rely on receiving a validation error when both are missing — enforcement of this rule is inconsistent. ### Supported Databases `database` is not a free-form string. Four values are supported, and **each takes a different request body**: | `database` | Required fields | Optional | | ---------- | ------------------------------------------------- | --------------------------------- | | `LT` | `checkedPersonalNumber` | `checkedDocumentType`, `clientId` | | `HU` | `checkedMrz` | `clientId` | | `UK` | `firstName`, `lastName`, `dateOfBirth`, `address` | `clientId` | | `US_15` | `firstName`, `lastName` (see below) | see below | There is no endpoint that lists the databases enabled for your account. Contact iDenfy to find out which ones you can call. ### Request Parameters (`US_15`) First name of the person to verify. Last name of the person to verify. Must be `US_15` for the field set below. Date of birth in `YYYY-MM-DD` format. Must place the person between 5 and 150 years old. Full SSN or last 4 digits. Must be exactly **4 or 9 digits** — any other length is silently dropped before the provider is called, so the check runs without it. Middle name of the person to verify. Year of birth. Ignored when `dob` is also sent. State code, exactly 2 characters (e.g., `CA`). City name, at least 2 characters. Primary address line. Secondary address line. Postal/ZIP code. Digits only. Phone number. Email address. Your own identifier for the person. Echoed back in the response and usable as a filter on the list endpoint. An empty string counts as "not sent". `"firstName": ""` returns a required-field error rather than an empty match. ### Request Example ```json theme={"system"} { "firstName": "John", "lastName": "Smith", "state": "CA", "database": "US_15", "yob": 1980, "dob": "1990-09-09", "city": "San Jose", "address1": "Benson str", "address2": "3914", "zip": "95128", "phone": "+1 (416) 555-5678", "idNum": "897884526", "email": "example.email@domain.com" } ``` ### Response Example ```json theme={"system"} { "id": "94f63296-7f3a-46d2-8558-ebd89224cb19", "firstName": "John", "lastName": "Smith", "middleName": null, "dob": "1990-09-09", "yob": 1980, "address1": "Benson str", "address2": "3914", "city": "San Jose", "state": "CA", "zip": "95128", "idNum": "897884526", "phone": "+14165555678", "email": "example.email@gmail.com", "firstNameStatus": "NO_MATCH", "lastNameStatus": "NO_MATCH", "middleNameStatus": null, "dobStatus": "NO_MATCH", "yobStatus": null, "address1Status": "NO_MATCH", "address2Status": "NO_MATCH", "cityStatus": "NO_MATCH", "stateStatus": "NO_MATCH", "zipStatus": "NO_MATCH", "idNumStatus": "NO_MATCH", "phoneStatus": "NO_MATCH", "emailStatus": "NO_MATCH", "database": "US_15" } ``` *** ## List/Retrieve Soft ID Verification Checks ``` GET https://ivs.idenfy.com/api/v2/registry-center-checks/ Authorization: Basic {API_KEY}:{API_SECRET} ``` The response is a plain, unpaginated array of every matching check. Narrow it with these query parameters: | Parameter | Description | | ----------------- | ------------------------------------------------------ | | `clientId` | Your own identifier, as sent on the check | | `name`, `surname` | First and last name | | `created` | Comma-separated date-time range | | `databases` | Comma-separated list, e.g. `US_15,UK` | | `status` | `MATCH`, `PARTIAL_MATCH`, `NO_MATCH`, or `NO_DATA` | | `checkedFields` | Restrict to checks where the given fields were checked | | `orderBy` | `created` or `-created` | **Understanding response fields:** In the response data, fields are categorized into two types: 1. **Informational fields:** Names like `firstName`, `lastName`, etc. These directly mirror the data you provided in the request and are not verified against the database. 2. **Status fields:** Names ending with `*Status`, like `firstNameStatus`, `lastNameStatus`. These indicate the outcome of verifying the corresponding informational field against the database. The system verifies each applicable field individually; there is no single overall verification status for the entire request. ### Possible Status Values | Status | Description | | --------------- | --------------------------------------------------------------------------------------- | | `MATCH` | The provided data matches the database record. | | `PARTIAL_MATCH` | The provided data partially matches the database record. | | `NO_MATCH` | The provided data does not match the database record, or the match is very weak. | | `INVALID` | The format of the provided input data was invalid. | | `NO_INPUT` | The corresponding input field was provided but contained blank or empty data. | | `NO_DATA` | No corresponding data was found in the database source for comparison. | | `null` | The corresponding input field was not included in the request or was explicitly `null`. | The thresholds that separate `MATCH` from `PARTIAL_MATCH` are defined by the upstream data provider and are not exposed on the response. `US_15` returns no score or confidence value — only the statuses above. (`UK` is the exception: its response includes an `addressStatusScore`.) ### Response Example ```json theme={"system"} [ { "id": "13c7c069-d4d8-405b-a442-3fe483068ca5", "firstName": "Jay Alan", "lastName": "Neander", "state": "IL", "middleName": null, "dob": "1981-08-31", "yob": null, "gender": "MALE", "address": null, "city": "Chicago", "zip": "60646", "phone": null, "maritalStatus": "MARRIED", "firstNameStatus": "NO_MATCH", "lastNameStatus": "NO_MATCH", "stateStatus": "NO_MATCH", "middleNameStatus": null, "dobStatus": "NO_MATCH", "yobStatus": null, "genderStatus": "NO_MATCH", "addressStatus": null, "cityStatus": "NO_MATCH", "zipStatus": "NO_MATCH", "phoneStatus": null, "maritalStatusStatus": "NO_DATA", "database": "US_1" }, { "id": "83cb0614-ff58-41e6-afac-6f24b8ff0072", "firstName": "Jay Adomas", "lastName": "Neander", "state": "IL", "middleName": null, "dob": null, "yob": null, "address": null, "city": null, "zip": null, "phone": null, "idNum": null, "firstNameStatus": "MATCH", "lastNameStatus": "MATCH", "middleNameStatus": null, "dobStatus": null, "yobStatus": null, "addressStatus": null, "cityStatus": null, "zipStatus": null, "phoneStatus": null, "idNumStatus": null, "database": "US_4" }, { "id": "a86aff0a-95a2-46a3-a9fa-27fabfef37f6", "firstName": "Thomas R", "lastName": "Ahern", "middleName": null, "dob": "1979-02-24", "yob": 1979, "address1": null, "address2": null, "city": null, "state": "NY", "zip": null, "idNum": null, "phone": null, "email": null, "firstNameStatus": "MATCH", "lastNameStatus": "MATCH", "middleNameStatus": null, "dobStatus": "MATCH", "yobStatus": null, "address1Status": null, "address2Status": null, "cityStatus": null, "stateStatus": "MATCH", "zipStatus": null, "idNumStatus": null, "phoneStatus": null, "emailStatus": null, "database": "US_15" } ] ``` *** ## Result Delivery and Errors A standalone Soft KYC check sends **no webhook**. Results arrive inline in the response and in the dashboard. Webhook delivery applies only when the check runs as part of an identity verification — and even then there is no webhook form for the `UK` database. A provider outage surfaces as **404** with `"Results for registry center check were not found"`. This reads like "no record matched", but it means the upstream source could not be reached — retry rather than treating it as a negative result. # Suspected Status Source: https://documentation.idenfy.com/kyc/suspected-status Understand why an iDenfy KYC verification resolves to SUSPECTED, which mismatch tags trigger it, and worked examples for common review cases. A verification resolves to `SUSPECTED` when the document and face checks themselves succeeded, but the system attached one or more `fraudTags` or `mismatchTags` to the result. `SUSPECTED` never appears without at least one of those tags present — it exists specifically to carry that signal to you. For the full list of every tag value and its plain-English meaning, see [Verification Statuses → Fraud Tags](/guides/dashboard/kyc/verification-statuses#fraud-tags) and [→ Mismatch Tags](/guides/dashboard/kyc/verification-statuses#mismatch-tags). ## Worked Examples The same shape repeats every time: `autoDocument`/`autoFace` (and `manualDocument`/`manualFace`, if reviewed) come back clean, but a tag is present. Only the tag differs. ### A Data Mismatch You created the session with `firstName: "Jon"`. The document reads "John". ```json theme={"system"} { "status": { "overall": "SUSPECTED", "mismatchTags": ["NAME"], "fraudTags": [], "autoDocument": "DOC_VALIDATED", "autoFace": "FACE_MATCH" }, "scanRef": "d2714c8a-...", "clientId": "user-123" } ``` The document and face are genuinely valid — the flag exists purely because the name you supplied doesn't exactly match the document. ### An Age Policy Flag You configured `ageLimit`, and the document's date of birth puts the client under it. ```json theme={"system"} { "status": { "overall": "SUSPECTED", "mismatchTags": ["UNDER_AGE"], "fraudTags": [], "autoDocument": "DOC_VALIDATED", "autoFace": "FACE_MATCH" } } ``` The document is real and the face matches — this tag exists only to enforce a policy you configured, not to flag a fake document. ### An AML/Watchlist Hit AML screening (`checkAml`) found the client on a PEPs or sanctions list. ```json theme={"system"} { "status": { "overall": "SUSPECTED", "fraudTags": ["AML_SUSPECTION"], "mismatchTags": [], "autoDocument": "DOC_VALIDATED", "autoFace": "FACE_MATCH" } } ``` Nothing about the document or selfie is in question — the flag is about who the person is, screened against an external list. ### A Duplicate Signal `checkDuplicateFaces` is enabled, and this selfie matches a face from a previous verification — possibly under a different `clientId`. ```json theme={"system"} { "status": { "overall": "SUSPECTED", "fraudTags": ["DUPLICATE_FACE"], "mismatchTags": [], "autoDocument": "DOC_VALIDATED", "autoFace": "FACE_MATCH" } } ``` This can mean one person opening a second account — which is sometimes abuse, and sometimes a legitimate returning user or a shared household device. The tag can't tell you which; only your context can. Wondering whether iDenfy will decide this for you, or how to build a procedure for resolving it? See [Status Handling](/guides/dashboard/kyc/status-handling#idenfy-does-not-evaluate-suspected). Each of the examples above is preloaded as a scenario in the playground below — a name mismatch, an age flag, a sanctions hit, a duplicate face — alongside a few this page doesn't cover, including the same registry mismatch tag raised against two different national databases. Configure a verification, then watch the statuses and tags it produces, the webhook your server receives, and what each tag costs the user. A presentation, not a live account — nothing here calls iDenfy. Opens in a new tab. ## Next Steps What to do with every overall status, not just SUSPECTED. Full definitions of every tag value. Clear a tag from the dashboard. Reactivate the token — POA, Risk Assessment, or Questionnaire cases only. # Verification Report Source: https://documentation.idenfy.com/kyc/verification-report Generate detailed identity verification reports with extracted data and compliance audit trails via the iDenfy dashboard or API endpoints. You can retrieve verification reports and associated data from iDenfy using two main methods: the Dashboard for bulk CSV reports, or the API for individual PDF reports and photos. ## Dashboard Reports (CSV) Generate comprehensive verification reports in CSV format directly from the iDenfy dashboard. These reports can cover multiple verifications within your chosen date range and include various data points. * **Instructions:** [Generating ID Verification Reports on the Dashboard](/guides/dashboard/settings/kyc-data-retrieval) ## API Retrieval (PDF and Photos) Programmatically retrieve specific verification details using our API: 1. **PDF Reports:** Download the full verification summary as a PDF using the [PDF Generation](/kyc/pdf-generation) endpoint. The report optionally includes the **External Reference** field — enable the checkbox in the Verification data section when generating the report from the dashboard. 2. **Verification Photos:** Get URLs for specific user verification photos (document images, face photos) using the [Data Retrieval](/kyc/data-retrieval) endpoint. Links to verification photos, whether obtained via API or webhook, are temporary and expire after **1 hour** for security reasons. If you need long-term access, please download and store the photos locally soon after retrieval. ## Bulk Downloading via API To efficiently download multiple PDF reports or photos using the API: 1. **Get `scanRef` List:** Generate a [Verification Report on the Dashboard](/guides/dashboard/settings/kyc-data-retrieval) for your desired date range, ensuring the report includes the `scanRef` column. The `scanRef` is the unique identifier for each verification. 2. **Iterate with API:** Create a script or application to loop through the list of `scanRef`s from the report. For each `scanRef`, call the appropriate API endpoint ([PDF Generation](/kyc/pdf-generation) or [Data Retrieval](/kyc/data-retrieval)) to download the corresponding file to your system. # KYC Webhooks Source: https://documentation.idenfy.com/kyc/webhooks Receive identity verification results and status changes via HTTP POST webhook callbacks from iDenfy with SSL certificate validation. Webhooks let your server receive verification results automatically as soon as they are available. iDenfy sends an HTTP POST request to your configured endpoint with a JSON payload describing the verification outcome. ## Prerequisites You must have an **Admin** role in the iDenfy dashboard to configure webhook endpoints. Go to **Settings → Notifications → Webhook URLs** in the dashboard and enter your callback URL. Your endpoint must be served over HTTPS with a valid, non-self-signed SSL certificate. If your endpoint does not return a **2xx** HTTP status code, iDenfy will retry delivery. Make sure your endpoint responds with `200 OK` promptly to avoid duplicate deliveries. A legacy **IDENTIFICATION** event exists that fires for all verification outcomes in a single webhook. While still supported, we recommend subscribing to the individual events listed below for more predictable integration logic. *** ## Webhook Events and Timing Verification results arrive at different times depending on how the verification was processed. The table below summarizes every event and when it fires. You can find all response bodies for webhooks in [API Reference → Identity Verification → Webhooks](/api-reference/overview) | Event | Timing | `final` flag | Description | | -------------------------------- | ----------------- | ------------ | --------------------------------------------------------------------------------------------------------- | | `IDENTIFICATION_AUTO_FINISHED` | Instant (seconds) | `true` | Automated review completed with a definitive result. No manual review will follow. | | `IDENTIFICATION_AUTO_FINISHED` | Instant (seconds) | `false` | Automated review completed but the result is preliminary — a manual review will follow. | | `IDENTIFICATION_MANUAL_FINISHED` | Minutes | `true` | A human reviewer has finalized the verification. Always final. | | `IDENTIFICATION_RESUBMITTED` | Instant (seconds) | `true` | Client submitted the requested information. No further review needed. | | `IDENTIFICATION_RESUBMITTED` | Instant (seconds) | `false` | Client submitted the requested information, but manual review of the submitted material is still pending. | | `IDENTIFICATION_CANCELLED` | Varies | — | The verification was cancelled before completion. | | `IDENTIFICATION_EXPIRED` | Delayed | — | The verification token expired before the user completed the flow. | Fires within seconds of the user completing the verification flow. The `IDENTIFICATION_AUTO_FINISHED` event is sent with one of two `final` flag values: * **`final: true`** — the automated system reached a conclusive decision. No manual review will follow. * **`final: false`** — the automated system produced a preliminary result. A follow-up `IDENTIFICATION_MANUAL_FINISHED` webhook will arrive once a human reviewer has made the final decision. If you want to act only on definitive results, wait for a webhook where `final` is `true`. When a verification requires human review, the `IDENTIFICATION_MANUAL_FINISHED` event fires once the reviewer submits their decision. This always carries `final: true`. Manual reviews typically complete within minutes but may take longer during peak periods. The `IDENTIFICATION_RESUBMITTED` event fires when an end-user completes a re-upload requested by your system via `POST /kyc/identifications/{scanRef}/request-information/`. **Flow:** 1. Your server calls `POST /kyc/identifications/{scanRef}/request-information/` — this reactivates the user's token and sends them an email with a re-upload link. No webhook fires at this point. 2. The user opens the link and uploads the requested documents or answers. 3. The user submits — **this** triggers `IDENTIFICATION_RESUBMITTED`. The `final` flag tells you whether to expect more activity: * **`final: true`** — submission is complete, no manual review needed. The case is resolved. * **`final: false`** — the submitted material (e.g. a utility bill) still requires manual review. Expect a follow-up `IDENTIFICATION_MANUAL_FINISHED` webhook. If the user never submits before the token expires, `IDENTIFICATION_EXPIRED` fires instead and no resubmission webhook is sent. If the user never completes the verification and the token reaches its `tokenExpiry` or the session exceeds `sessionLength`, the `IDENTIFICATION_EXPIRED` event fires automatically. The `IDENTIFICATION_CANCELLED` event fires when a verification is explicitly cancelled — either by the user abandoning the flow or by an API call. *** ## Verification Workflow The flowchart below shows the general webhook event flow. You can adjust, skip, or ignore events depending on your setup. Flowchart showing how webhook events flow through the iDenfy verification process *** ## Request Headers Every webhook delivery includes the following HTTP headers: | Header | Value | | ------------------- | -------------------------------------------------------------------------- | | `Idenfy-Event-Type` | Event name, e.g. `IDENTIFICATION_AUTO_FINISHED` | | `Content-Type` | `application/json; charset=utf-8` | | `Idenfy-Signature` | HMAC-SHA256 signature of the request body (if a signing key is configured) | Use `Idenfy-Signature` to verify that the request genuinely came from iDenfy. Compute the HMAC-SHA256 of the raw request body using your configured signing key and compare it against the header value. *** ## Callback Payload For the full webhook callback JSON structure and field definitions, see the **API Reference** tab. The callback body includes overall status, document data, face-match results, fraud indicators, and extracted personal information. If the session included a bank card ownership step, the result also arrives as a nested `bankCardVerification` object on this payload. A standalone card check -- one created without a verification session -- instead delivers its own `BANK_CARD_VERIFICATION_COMPLETED` event; see [Bank Card Verification Webhooks](/bank-card/webhooks). *** ## Re-Attempts and Retries iDenfy gives users a configurable number of chances to submit acceptable documents: * **Overall re-attempts** — the number of times a user may retry a failed verification with the same token. This defaults to **1** but is configurable per token at generation time. * **Per-step upload attempts** — for each individual upload step (e.g. a utility bill), users get up to **3** attempts before the step counts as failed. Re-attempt limits are configurable per token at generation time. See [Create Session](/kyc/generate-token) for details. *** ## Handling the Result For what to do with each overall status — including how to inspect and resolve a `SUSPECTED` result — see [Status Handling](/guides/dashboard/kyc/status-handling). *** ## Troubleshooting If you are not receiving webhooks, work through the following checklist: Confirm the URL configured in the dashboard is correct, publicly reachable, and not behind a firewall or VPN. Your certificate must be valid and issued by a trusted CA. Self-signed certificates are rejected. Your endpoint must respond with a **2xx** HTTP status code (e.g., `200 OK`). Any other status triggers retries. The request times out after **10 seconds**, so ensure your endpoint responds promptly. In the iDenfy dashboard, go to **Settings → Notifications → Recently sent** to inspect delivery attempts, response codes, and payloads. iDenfy will retry failed deliveries a configurable number of times with a fixed wait interval between attempts. If all retries are exhausted, you will receive a failure notification email (if configured) and the webhook will not be resent automatically. Use the **Resend** button in the dashboard to manually retry. *** ## Dashboard Review You can inspect all recently sent webhooks directly in the iDenfy dashboard: 1. Go to **Settings → Notifications → Recently sent**. 2. Review the list of delivered webhooks, including timestamps, HTTP response codes, and payload previews. 3. Use this view to debug integration issues or confirm that specific verification results were delivered. * **`0`** - No Response: No communication; server unreachable. * **`2xx`** - Success: Request successful, information returned. * **`3xx`** - Redirection: Further action needed, request redirected. * **`4xx`** - Client Errors: Your server could not handle the response. * **`5xx`** - Server Errors: Request valid, there is a problem with the server. 4. Use the **Resend** button to retry delivery for a specific notification. 5. Click **Details** to see the full JSON payload that was sent. Webhook troubleshooting view in the iDenfy dashboard # Quickstart Source: https://documentation.idenfy.com/quickstart Create your first iDenfy identity verification session in under 5 minutes with API key authentication, token generation, and redirect. This quickstart covers **Identity Verification (KYC)** — the most common starting point. For other products, jump directly to: * [Business Verification (KYB) →](/kyb/overview) * [AML Screening →](/aml/overview) * [Fraud Prevention →](/fraud-prevention/overview) ## Prerequisites Before you begin, you need: * An **iDenfy account** — [Sign up here](https://idenfy.com/pricing-plans-v4/) if you don't have one * **API Key** and **API Secret** — Generate them in [Settings → API Keys](/guides/dashboard/settings/api-keys) Keep your API Secret confidential. Never expose it in client-side code, public repositories, or frontend applications. *** ## Step 1: Create a Verification Session Create a verification session by calling the session creation endpoint. Use your API Key and Secret for Basic Auth. ```bash cURL theme={"system"} curl -X POST https://ivs.idenfy.com/api/v2/token \ -H "Content-Type: application/json" \ -u "YOUR_API_KEY:YOUR_API_SECRET" \ -d '{ "clientId": "unique-customer-id-123" }' ``` ```python Python theme={"system"} import requests response = requests.post( "https://ivs.idenfy.com/api/v2/token", auth=("YOUR_API_KEY", "YOUR_API_SECRET"), json={ "clientId": "unique-customer-id-123" } ) data = response.json() print(f"Token: {data['authToken']}") print(f"Redirect URL: {data['redirectUrl']}") ``` ```javascript Node.js theme={"system"} const response = await fetch("https://ivs.idenfy.com/api/v2/token", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Basic " + btoa("YOUR_API_KEY:YOUR_API_SECRET") }, body: JSON.stringify({ clientId: "unique-customer-id-123" }) }); const data = await response.json(); console.log(`Token: ${data.authToken}`); console.log(`Redirect URL: ${data.redirectUrl}`); ``` ```php PHP theme={"system"} $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://ivs.idenfy.com/api/v2/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_USERPWD, "YOUR_API_KEY:YOUR_API_SECRET"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "clientId" => "unique-customer-id-123" ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $data = json_decode($response, true); echo "Token: " . $data["authToken"]; ``` ```ruby Ruby theme={"system"} require "net/http" require "json" require "uri" uri = URI("https://ivs.idenfy.com/api/v2/token") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request.basic_auth("YOUR_API_KEY", "YOUR_API_SECRET") request.content_type = "application/json" request.body = { clientId: "unique-customer-id-123" }.to_json response = http.request(request) data = JSON.parse(response.body) puts "Token: #{data['authToken']}" ``` **Response:** ```json theme={"system"} { "authToken": "pgYQX0z2T8msB64gkl...", "scanRef": "d2714c8a-ec05-11ec-8ea0-0242ac120002", "clientId": "unique-customer-id-123", "redirectUrl": "https://ivs.idenfy.com/api/v2/redirect?authToken=pgYQX0z2T8msB64gkl..." } ``` *** ## Step 2: Redirect Your Customer Send your customer to the `redirectUrl` from the response. They will: 1. Select their document type and country 2. Upload or capture their ID document 3. Complete a liveness check (selfie) Redirect the user's browser to the `redirectUrl`: ```javascript theme={"system"} window.location.href = data.redirectUrl; ``` Embed the verification flow in your page: ```html theme={"system"} ``` [Full iFrame guide →](/kyc/iframe-redirect) Pass the `authToken` to the native SDK: ```kotlin theme={"system"} // Android IdenfyController.startIdentification(activity, authToken) ``` ```swift theme={"system"} // iOS IdenfyController.shared.startIdentification(authToken: authToken) ``` [Android SDK →](/sdks/android/quickstart) | [iOS SDK →](/sdks/ios/quickstart) *** ## Step 3: Receive Results Set up a webhook endpoint to receive verification results. Configure your webhook URL in [Dashboard → Settings → Webhooks](/guides/dashboard/settings/system-notifications-webhooks-emails). ```json Example webhook payload theme={"system"} { "final": true, "status": { "overall": "APPROVED", "autoDocument": "DOC_VALIDATED", "autoFace": "FACE_MATCH", "manualDocument": "DOC_VALIDATED", "manualFace": "FACE_MATCH" }, "scanRef": "d2714c8a-ec05-11ec-8ea0-0242ac120002", "clientId": "unique-customer-id-123", "data": { "docFirstName": "JOHN", "docLastName": "DOE", "docNumber": "AB1234567", "docExpiry": "2028-12-31", "selectedCountry": "US", "selectedDocType": "ID_CARD" } } ``` Use the [Testing & Sandbox](/guides/testing-sandbox) to simulate different verification outcomes before going live. *** ## What's Next? ### Continue with KYC Customize with country restrictions, document types, liveness, AML checks. Full webhook payload with all status codes and data fields. Compare redirect, iFrame, SDK, and no-code options. Everything to verify before switching to production. ### Explore Other Products Verify companies, retrieve registry data, screen beneficial owners. Screen against sanctions, PEPs, and adverse media. Risk scoring, proxy detection, phone and address verification. Re-authenticate returning users with biometric face matching. # Enterprise (Yearly) Source: https://documentation.idenfy.com/resources/billing/enterprise Learn about iDenfy enterprise yearly contracts with volume-based discounts, custom quotes, and flexible billing for high-volume verification. For businesses with higher or more predictable verification volumes, iDenfy provides **custom yearly contracts**. These are arranged directly with the **Sales Team** and tailored to your organization's needs. ## Pricing Structure Pricing is based primarily on **usage and verification volume**. There are two main billing models: | Billing model | What's billed | Per-unit price | | ---------------------------------- | ------------------------------------------------- | --------------- | | **Pay per approved verification** | Only successful (approved) verifications | Slightly higher | | **Pay per completed verification** | All completed verifications (approved and denied) | Lower | The "pay per approved" model offers more transparency, while "pay per completed" usually comes with a lower per-unit cost. ## Benefits of a Contract * **Lower unit prices** with **volume discounts** — the more verifications you process, the less you pay per check * **Custom quotes** for expected verification volumes, specific database checks, or specialized compliance requirements * **Tailored agreements** for industries with unique needs (financial services, gaming, crypto, insurance) * **Predictable costs** for budgeting and compliance planning ## Get a Quote Contact the iDenfy Sales Team to discuss a custom yearly contract that matches your verification needs and volume. # Invoices Source: https://documentation.idenfy.com/resources/billing/invoices View and manage your billing invoices, including details of each transaction, payment status, and download options for your records. ## Invoice Management You can find all your invoices by going to the ***dashboard*** → selecting ***Settings*** → ***Plan*** 1. Select the ***Invoices*** tab 2. Select the date you want to view the invoice for 3. Click ***Download*** for the invoice Screenshot of the invoices management interface in the dashboard settings, displaying a table with columns for invoice details such as ID, date, amount, and status, alongside download buttons for each invoice, in a clean web application layout with navigation menus on the left. ## Accounting Email Pay-As-You-Go partners can send billing communications to a dedicated address instead of the main account contact. Set it under ***Settings*** → ***Company details*** → ***General information*** → ***Accounting email***. * The field is **optional**. While it's empty, invoices and payment receipts continue to go to your contact email. * When set, it receives **only invoices and payment receipts**. Notification emails, contact email, and every other system message are unaffected. * One accounting email can be set per partner, and the address format is validated. # Billing & Pricing Source: https://documentation.idenfy.com/resources/billing/overview Compare iDenfy pricing models including pay-as-you-go monthly plans and enterprise yearly contracts, plus subscription and refund policies. iDenfy offers two main pricing models depending on your verification volume and business needs. ## Pricing Models Monthly plans (Basic and Premium) with a free trial. Best for low-to-mid verification volumes. Custom yearly contracts with volume discounts. Best for higher or specialized verification needs. ## Free Trial When you register, you get **14 days of free trial** or **10 KYC verifications** — whichever comes first. After the trial, your account converts to a paid monthly plan unless you cancel beforehand. # Pay-As-You-Go Source: https://documentation.idenfy.com/resources/billing/pay-as-you-go Compare iDenfy Basic and Premium pay-as-you-go monthly plans with pricing, overdraft limits, free trial details, and cancellation policy. ## Sign Up Register for a Pay-As-You-Go account at [idenfy.com/pricing-plans-v4/](https://idenfy.com/pricing-plans-v4/). In addition to email and password, you can sign up using **Continue with Google** or **Continue with Microsoft Entra ID**. After completing authentication, you will be prompted to enter your company details to finish account setup. *** ## Free Trial Once you register, you get **14 days of free trial** or **10 KYC verifications** — whichever comes first. ## Monthly Subscription Plans iDenfy offers two flexible pay-as-you-go plans: | Plan | Monthly minimum commitment | Overdraft (extra usage on credit) | | ----------- | -------------------------- | --------------------------------- | | **Basic** | \$135 | Up to **\$325** on credit | | **Premium** | \$325 | Up to **\$650** on credit | ## How It Works * **Minimal commitment** — cancel anytime * **No rollover** — monthly verifications do not carry over to the next month * **Overdraft on credit** — if you exceed your monthly limit, you can continue using services on credit up to your plan's overdraft allowance * **Overdraft billing** — any overdraft usage is billed with your next monthly payment The **minimal commitment** is the minimum monthly charge to keep using the service. It's billed monthly like a subscription, even if you haven't used all your verifications. Unused verifications **do not roll over** or accumulate. ## Next Steps Subscribe, change plans, or cancel. Refund eligibility and how to request a review. # Refunds Source: https://documentation.idenfy.com/resources/billing/refunds Understand iDenfy refund eligibility criteria, common refund scenarios after trial expiration, and how to submit a refund review request. ## Why Was My Card Charged After the Trial? When you sign up for an iDenfy trial, you accept the Terms and Conditions. According to these terms, once the trial period ends, the subscription **automatically converts to a paid monthly plan** unless you cancel it before the trial expiration date. If you do not cancel the subscription before the trial ends, the first monthly charge applies automatically. You can review the [Terms and Conditions](https://www.idenfy.com/terms-and-conditions.pdf). ## Can I Request a Refund? ### Eligible for a Refund When * Advertised services are not working or are not functioning as described * Your payment method was charged incorrectly, charged at the wrong time, or charged an incorrect amount ### Generally Not Approved Refund requests in the following scenarios are **generally not approved** and may only be refunded under exceptional circumstances, at iDenfy's discretion, following an internal review: * The subscription was not canceled before the trial period ended * The payment method was not removed after the trial * The account remained active after the trial expiration date * The service was not used after the trial, but the subscription remained active * The subscription was unintentionally left active after the billing date * The account was not actively monitored after trial activation * Dissatisfaction with the service after the trial period ended, despite successful trial usage * The service did not meet internal expectations or business needs after conversion to a paid plan * The account was created for testing purposes and left active after the trial * Trial expiration or billing notifications were overlooked ## How to Submit a Refund Request To request a refund review, send a free-form email to [**accounting@idenfy.com**](mailto:accounting@idenfy.com) and include: * Your company or account name * The date and amount of the charge * A clear explanation of why you believe the charge should be refunded * Any relevant supporting details or context The iDenfy accounting team will review your request and respond as soon as possible. ## How Can I Avoid Future Charges? To avoid future charges, ensure that your subscription is canceled before the next billing cycle. See [Subscription management](/resources/billing/subscription) for cancellation steps. If you need assistance, contact iDenfy support. # Subscription Management Source: https://documentation.idenfy.com/resources/billing/subscription Step-by-step guide to subscribing, upgrading, downgrading, or canceling your iDenfy plan from the dashboard business settings page. ## How to Subscribe To upgrade from a Trial to a Paid plan, you can use either of these options: ### Option 1: From Settings 1. Navigate to **Settings → Business settings → Plan** 2. Add your **Billing Details** and Payment Method 3. Select your desired **Plan** (Basic or Premium) 4. Confirm the subscription Once **14 days pass** OR **10 verifications are made** (whichever happens first), the Demo account converts to Production. ### Option 2: Go Live Now 1. Navigate to **Settings → Business settings → Plan** 2. Click the **Go Live Now** button 3. Add billing details ## Changing Plans You can adjust your plan at any time based on your changing volume needs: 1. Navigate to **Settings → Business settings → Plan** 2. Locate your current plan details and click **Change plan** 3. Select the new plan tier and confirm ### How Plan Changes Are Billed The billing behavior depends on the direction of the change and when it happens. **Upgrade (to a more expensive plan)** * Stripe charges immediately — the amount is the difference in minimum commitment between the old and new plans * The new plan activates as soon as payment succeeds * Usage already consumed in the current period carries over, so you are not double-charged **Downgrade (to a cheaper plan) or same-cost plan** * No immediate charge * Plan settings update right away, but the new pricing takes effect at the start of the next billing cycle **During free trial** * No charge regardless of plan change * New plan settings apply immediately * Billing starts normally when the trial ends ### Billing Cycle 1. A new account starts on a **30-day free trial** 2. When the trial expires, an invoice is generated and Stripe charges the stored payment method automatically 3. On successful payment → subscription activates for the next period 4. On failed payment → verifications are disabled and the system retries at **1 day** and **2 days** after the initial failure There is no proration — minimum commitments are always charged in full. If a payment is not confirmed within 30 minutes, the invoice is marked as failed. Contact support if an account is stuck in a payment-failed state. Invoices and payment receipts are sent to your account contact email unless you set a dedicated [accounting email](/resources/billing/invoices#accounting-email). ## Removing a Saved Bank Card 1. Navigate to **Settings → Subscription** 2. In the **Billing details** card, click **Edit** 3. In the modal that opens, scroll to the **Payment method** section 4. Click the **trash icon** next to the saved card to remove it You can also click **Replace with new card** in the same modal to swap payment methods in one step. Removing your credit card will cancel your subscription. Your plan stays active until the current period's expiry date, after which it will not renew. If your account has an outstanding balance (overdraft) at the time of removal, one final charge will be made to the card to cover it before the card is removed. ## How to Cancel (Unsubscribe) You can stop your subscription at any time: 1. Navigate to **Settings → Business settings → Plan** 2. Click **Cancel Subscription** The **Cancel Subscription** option is only visible if you have active payment information added. After cancellation, your service continues until the end of the current billing period, after which it stops. ## Account Deletion and Data Lifecycle iDenfy strictly adheres to GDPR and data retention policies. ### Trial Accounts * **Active:** 14 days * **Suspended:** After expiry, you cannot perform checks * **Deleted:** The environment is automatically deleted after approximately **30 days** of inactivity From an expired account screen you can **Log out** using the top bar and sign in to a different account, without clearing your browser cookies. ### Paid Accounts (Cancellation Logic) When you cancel a subscription or stop paying: 1. **Grace period (30 days)** — after your last valid billing period ends, you retain access to the dashboard for 30 days. You can view historical data but cannot perform new verifications. 2. **Scheduled deletion** — after the 30-day grace period, the account is permanently scheduled for deletion. 3. **Data removal** — all customer data is wiped from iDenfy servers in accordance with the Data Retention Policy: * **Basic / Premium:** \~2 years * **Enterprise:** up to 8 years ### Manual Account Deletion If you wish to delete your account immediately (Right to be Forgotten), contact **Support** or your **Account Manager**. # FAQ Source: https://documentation.idenfy.com/resources/faq Find answers to frequently asked questions about iDenfy integration including verification flow, webhooks, statuses, and manual review. ## Verification Flow iDenfy's AI **performs automatic verification** instantly and produces one webhook callback. A human reviewer then **performs manual verification** and produces a second webhook callback. If manual review is enabled for your account, you will receive up to two callbacks per verification: one automatic and one manual. * **Automatic only:** 1 callback after the AI finishes processing. * **Automatic + manual review:** 2 callbacks -- first the automatic result, then the manual reviewer's decision. No. Manual reviewers can only modify **OCR-extracted data** (names, dates, document numbers). They cannot replace or alter the photos submitted by the user. `SUSPECTED` means the system flagged potential issues but **did not outright reject** the verification. It is not a failure -- treat it as a signal that requires your own business logic to decide whether to accept or decline the user. `AUTO_UNVERIFIABLE` means the automatic system could not reach a definitive decision (for example, due to poor image quality). If manual review is enabled, a human reviewer will evaluate the submission next. If manual review is not enabled, you should prompt the user to retry. ## Tokens and Sessions * **`expiryTime`** -- how long the verification token is valid before the user starts the session (e.g., 3600 seconds). After this period the token cannot be used. * **`sessionLength`** -- how long the user has to complete the verification once they have opened the session (e.g., 600 seconds). This means your account has exhausted its verification credits. It is **not** a rate-limit error. Contact your iDenfy account manager to purchase additional credits. ## User Management iDenfy does **not** track or block repeat verifications on its own. If you want to prevent a user from verifying more than once, you must implement that logic on your side -- for example, by checking the `clientId` before generating a new token. `maxAttemptCount` limits how many times a single verification session can be used for submission attempts. Once the limit is reached, the session is invalidated and the user cannot retry with it. You would need to create a new session if you want to allow further attempts. ## Data and Matching Yes. iDenfy supports Unicode characters, so names in Cyrillic, Chinese, Arabic, and other scripts are handled correctly. When you supply expected values at token creation, iDenfy can cross-match them against the extracted document data. The supported fields are: * `DOCUMENT_NUMBER` * `PERSONAL_CODE` * `EXPIRY_DATE` * `DATE_OF_BIRTH` * `DATE_OF_ISSUE` You can configure the name-matching strategy when creating a token: | Mode | Behavior | | ----------- | --------------------------------------------- | | `ANY_NAME` | At least one name (first or last) must match. | | `ONE_NAME` | Exactly one name field must match. | | `ALL_NAMES` | All provided name fields must match. | ## Webhooks Check the following: 1. Your endpoint returns **HTTP 200** promptly. iDenfy may consider other status codes a failure. 2. The URL configured in the dashboard is publicly accessible (not `localhost`). 3. No firewall or security group is blocking iDenfy's IPs. See [IP Whitelisting](/security/ip-whitelisting). 4. If using callback signing, ensure you are reading the **raw body** for signature verification. See [Callback Signing](/security/callback-signing). ## Front-End Integration Chrome blocks camera access in cross-origin iframes by default. Add the `allow` attribute to your iframe element: ```html theme={"system"} ``` # Model Context Protocol (MCP) Source: https://documentation.idenfy.com/resources/mcp Install and configure the iDenfy Model Context Protocol server to give AI assistants like Cursor, Claude, and Windsurf access to these docs. This guide explains what the iDenfy MCP server is, how to install it, and how to use it when you work with iDenfy. ## What Is MCP? [Model Context Protocol](https://modelcontextprotocol.io) is an open standard that lets AI assistants connect to external tools and data sources. The iDenfy MCP server gives your AI assistant access to this documentation. Once it is connected, the assistant can search the docs and read full pages while it answers your questions or writes code. The iDenfy MCP server is read-only. It only serves public documentation. It does not have access to your API keys, dashboard, or verification data. ## Works with Every iDenfy Product The MCP server covers the full iDenfy documentation, so you can use it for any product in our platform: * [Identity Verification (KYC)](/kyc/overview) * [Business Verification (KYB)](/kyb/overview) * [AML Screening and Monitoring](/aml/overview) * [Fraud Prevention](/fraud-prevention/overview) * [Face Authentication](/face-authentication/overview) * [Bank Verification](/bank-verification/overview) * [Mobile SDKs](/sdks/overview), [API Reference](/api-reference/overview), and every guide under [Dashboard](/guides/dashboard/settings/create-dashboard-account) and [Compliance](/guides/compliance/overview) You can ask your AI assistant a question about any of these areas and it will search the right pages for you. ## What You Can Do with It Ask questions in plain language. The assistant searches every guide and API reference for you. Get the full content of a page by its path when a short snippet is not enough. Ask the assistant to draft KYC, KYB, or webhook code based on the current docs. Look up error codes, webhook fields, or parameter names without leaving your editor. ## Available Tools The iDenfy MCP server has two tools: | Tool | What it does | | ------------------------------- | --------------------------------------------------------------------------------- | | `search_idenfy_documentation` | Searches the docs and returns page titles, paths, and short snippets. | | `get_page_idenfy_documentation` | Returns the full content of a page by its path, for example `kyc/generate-token`. | The usual flow is simple: **search first** to find the right page, then **read the full page** if you need more detail. ## Install the MCP Server You do not need to install anything on your computer. The iDenfy MCP server runs online. You only need to add the server URL to your AI assistant. Server URL: `https://documentation.idenfy.com/mcp` ### Claude Desktop Open the [Claude Desktop](https://claude.ai/download) configuration file `claude_desktop_config.json` and add the server: ```json theme={"system"} { "mcpServers": { "idenfy-docs": { "url": "https://documentation.idenfy.com/mcp" } } } ``` Restart Claude Desktop. The iDenfy tools will show up in the tool list. ### Claude Code Run this command in your [Claude Code](https://claude.com/claude-code) terminal: ```bash theme={"system"} claude mcp add --transport http idenfy-docs https://documentation.idenfy.com/mcp ``` If you want to share the setup with your team, add it to `.mcp.json` in your project root: ```json theme={"system"} { "mcpServers": { "idenfy-docs": { "url": "https://documentation.idenfy.com/mcp" } } } ``` ### Cursor In [Cursor](https://cursor.com), open **Settings > MCP > Add new MCP server** and paste the server URL. The server will be ready to use in every workspace. ### ChatGPT Custom connectors are available on [ChatGPT](https://chatgpt.com) Pro, Business, Enterprise, and Edu plans. 1. Open **Settings > Connectors** in ChatGPT. 2. Click **Add custom connector**. 3. Set the name to `iDenfy Docs` and the MCP server URL to `https://documentation.idenfy.com/mcp`. Leave authentication set to **None**. 4. Save the connector. 5. In a new chat, open the tools menu and turn on the **iDenfy Docs** connector. On Business or Enterprise workspaces, a workspace admin may need to allow custom connectors before you can add one. ### Google Gemini You can connect the iDenfy MCP server to [Gemini](https://gemini.google.com) through the Gemini CLI or Gemini Code Assist. Open your Gemini settings file (for example `~/.gemini/settings.json`) and add the server: ```json theme={"system"} { "mcpServers": { "idenfy-docs": { "url": "https://documentation.idenfy.com/mcp" } } } ``` Restart Gemini. The iDenfy tools will show up in the tool list. ### Perplexity [Perplexity](https://www.perplexity.ai) supports MCP servers through **Connectors** in the Perplexity desktop app and the Comet browser. 1. Open **Settings > Connectors** in Perplexity. 2. Click **Add connector** and select **Custom MCP server**. 3. Set the name to `iDenfy Docs` and the URL to `https://documentation.idenfy.com/mcp`. 4. Save the connector and turn it on for the spaces where you want to use it. ### Other Clients Any tool that supports MCP can connect to the iDenfy server with the same URL. This includes [Zed](https://zed.dev), [Windsurf](https://windsurf.com), the [VS Code](https://code.visualstudio.com) MCP extension, and custom agents. Check your tool's documentation for the exact steps. ## How to Use It After you connect the server, you just talk to your assistant in plain language. You do not need to call the tools yourself. The assistant decides when to search the docs or read a full page. ### Find Information in the Docs ```text theme={"system"} How does iDenfy liveness detection work, and which parameters control it? ``` The assistant searches the docs, reads the right page, and tells you about active and passive liveness with the correct parameter names. ### Generate Integration Code ```text theme={"system"} Write a Python script that creates a KYC session with name and date of birth matching, and checks the webhook signature. ``` The assistant uses the [Create Verification Session](/kyc/generate-token) and [Callback Signing](/security/callback-signing) pages, so the code uses the right endpoint, the right fields, and the correct HMAC check. ### Debug a Failing Webhook ```text theme={"system"} My webhook handler returns 403 for every iDenfy request. What are the common reasons for a signature mismatch? ``` The assistant opens the troubleshooting section of the callback signing page and explains raw body handling, hex encoding, and proxy issues. ### Answer Compliance Questions ```text theme={"system"} Which documents does iDenfy support for Lithuanian citizens, and what are the NFC requirements for eIDAS high assurance? ``` The assistant searches the supported documents reference and the eIDAS guide and gives you one answer with the right sources. ## Best Practices The more detail you give, the better the search result. Instead of *"How do I create a session?"*, ask *"How do I create a KYC session with restricted countries and a custom callback URL?"*. Ask the assistant to include the page path or link in the answer. This way you can open the source and check the answer yourself. In an IDE like Claude Code or Cursor, let the assistant read both the iDenfy docs and your project. The code it writes will match your existing style instead of being generic. The iDenfy MCP server does not return credentials or customer data. Keep it that way on your side: do not paste your API key or secret into the chat. Use environment variables in the code instead. A full page uses more of the assistant's memory than a search snippet. Let the assistant search first, and only read the full page if the snippet is not enough. MCP reduces guesses because the assistant reads the real docs, but you should still review the code. Check signature verification, raw body handling, and how credentials are stored before you deploy. ## Example: Build a KYC Integration from Scratch You can build a full KYC integration in one conversation with your assistant: *"Explain the iDenfy KYC flow from session creation to webhook result."* The assistant describes the three steps: [create a session](/kyc/generate-token), send the user to the UI or SDK, and handle the [webhook result](/kyc/webhooks). *"Write the Node.js code that creates a session with data matching and returns `redirectUrl`."* The code uses the current endpoint and field names. *"Add an Express handler that checks the `Idenfy-Signature` header against the raw body."* The code follows the pattern from the [callback signing](/security/callback-signing) page. *"Which of these parameters are already set in the dashboard by default?"* The assistant checks the [Create Verification Session](/kyc/generate-token) parameter list and removes the ones you do not need. The result is a working draft based on the current docs, not old training data. ## Privacy and Scope * The MCP server only serves content from [documentation.idenfy.com](https://documentation.idenfy.com). * It does not have access to your dashboard, sessions, API keys, or customer data. * Your prompts and the doc content go through your AI assistant provider (for example [Anthropic](https://www.anthropic.com), [OpenAI](https://openai.com), [Google](https://ai.google), or [Perplexity](https://www.perplexity.ai)). Check your provider's data policy before you share sensitive information. ## Feedback If a search returns old or wrong results, or if a page is missing content you need, contact [support@idenfy.com](mailto:support@idenfy.com). Share the prompt you used and the page you expected to find. # Supported Browsers Source: https://documentation.idenfy.com/resources/supported-browsers Browsers supported by the iDenfy web-based identity verification flow across desktop and mobile, including redirect and iFrame integrations. iDenfy's web-based verification flow (redirect and iFrame integrations) is supported on the current and immediately preceding version of the following browsers: | Browser | Vendor | Notes | | ---------------- | --------- | ---------------------------------------------------------------------- | | Chrome | Google | | | Safari | Apple | | | Edge | Microsoft | | | Firefox | Mozilla | [3D liveness](/guides/dashboard/kyc/liveness-checks) is not supported. | | Samsung Internet | Samsung | | For the native mobile SDKs instead of the web flow, see the [Android](/sdks/android/quickstart) and [iOS](/sdks/ios/quickstart) quickstarts for their own OS and device requirements. # Supported Documents Source: https://documentation.idenfy.com/resources/supported-documents Browse 16,000+ supported identity document types across 200+ countries, including passports, ID cards, driver's licenses, residence permits, and digital IDs. ## Document Types
| API Value | Display Name | | ---------------------------- | -------------------------- | | `PASSPORT` | Passport | | `ID_CARD` | ID Card | | `DRIVER_LICENSE` | Driver License | | `RESIDENCE_PERMIT` | Residence Permit | | `VISA` | Visa | | `NATIONAL_PASSPORT` | National Passport | | `PAN_CARD` | PAN Card | | `AADHAAR` | Aadhaar | | `OLD_ID_CARD` | Old ID Card | | `MILITARY_CARD` | Military Card | | `ADDRESS_CARD` | Address Card | | `PROVISIONAL_DRIVER_LICENSE` | Provisional Driver License | | API Value | Display Name | | ------------------------- | ------------------------------------------------- | | `SMART_ID` | Smart-ID | | `MOBILE_ID` | Mobile-ID | | `BANK_ID_SE` | BankID (Sweden) | | `FREJA_EID` | Freja | | `BANK_ID_NO` | BankID (Norway) | | `FTN` | Finnish Trust Network (FTN) | | `MIT_ID` | MitID | | `IDIN` | iDIN | | `BANK_ID_CZ` | Bank iD (Czech Republic) | | `MOJE_ID` | MojeID (Czech Republic) | | `VERIMI` | Verimi | | `HANDY_SIGNATUR` | Handy-Signatur | | `ONE_ID` | OneID | | `YOTI_ID` | Yoti ID | | `CLEAR` | CLEAR | | `LA_WALLET` | LA Wallet | | `SAMSUNG_WALLET` | Samsung Wallet | | `DIGI_LOCKER` | DigiLocker | | `PHILIPPINES_NATIONAL_ID` | Digital National ID (Philippines) | | `PHILSYS_MATCH` | PhilSys Biometric Match | | `BRAZIL_CPF` | Brazil CPF check | | `BRAZIL_DIGITAL_CNH` | Brazil Digital CNH (Carteira digital de trânsito) |
Digital ID types are available to all partners, but some require activation by the iDenfy support team before they appear in your dashboard. DigiLocker, Digital National ID and PhilSys Biometric Match always do. If one you need is missing from **Allowed digital IDs** in [Document and Identity Verification settings](/guides/dashboard/settings/document-identity-verification), contact [support](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to have it enabled. **Document interpretation** — some document types map to standard categories: * Border Crossing → `VISA` * Asylum → `RESIDENCE_PERMIT` * Photo Card / Proof of Age Card / Travel Card / Voter Card → `ID_CARD` * Diplomatic ID → `ID_CARD` * Work Permit → `RESIDENCE_PERMIT` * Travel Passport → `PASSPORT` *** ## Countries and Supported Documents Physical documents list the sides captured (`FRONT`, `FRONT+BACK`). The **Digital IDs** column shows the schemes available for that country; a dash means none. | Country | Code | Physical Documents | Digital IDs | | -------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | | Afghanistan | AF | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Albania | AL | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Algeria | DZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | American Samoa | AS | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Andorra | AD | Driver License:FRONT, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Angola | AO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Anguilla | AI | Driver License:FRONT, Passport:FRONT, ID Card:FRONT+BACK | — | | Antarctica | AQ | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Antigua and Barbuda | AG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Argentina | AR | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Armenia | AM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Aruba | AW | Driver License:FRONT, ID Card:FRONT+BACK | iDIN | | Australia | AU | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Austria | AT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Handy-Signatur | | Azerbaijan | AZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bahamas | BS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bahrain | BH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Bangladesh | BD | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Barbados | BB | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Belarus | BY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Belgium | BE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Belize | BZ | Visa:FRONT+BACK, Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Benin | BJ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bermuda | BM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bhutan | BT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bolivia, Plurinational State of | BO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bonaire, Sint Eustatius and Saba | BQ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | iDIN | | Bosnia and Herzegovina | BA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Botswana | BW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Bouvet Island | BV | Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Brazil | BR | Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Brazil CPF check, Brazil Digital CNH (Carteira digital de trânsito) | | British Indian Ocean Territory | IO | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Brunei Darussalam | BN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Bulgaria | BG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Burkina Faso | BF | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Burundi | BI | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Cabo Verde | CV | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Cambodia | KH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Cameroon | CM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Canada | CA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Cayman Islands | KY | Driver License:FRONT, Passport:FRONT | — | | Central African Republic | CF | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Chad | TD | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Chile | CL | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | China | CN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Christmas Island | CX | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Cocos (Keeling) Islands | CC | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Colombia | CO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Comoros | KM | ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Congo | CG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Congo, The Democratic Republic of the | CD | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Cook Islands | CK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Costa Rica | CR | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Croatia | HR | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Cuba | CU | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Curaçao | CW | Driver License:FRONT, ID Card:FRONT+BACK | iDIN | | Cyprus | CY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Czechia | CZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Bank iD (Czech Republic), MojeID (Czech Republic) | | Côte d'Ivoire | CI | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Denmark | DK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | MitID | | Djibouti | DJ | ID Card:FRONT+BACK, Passport:FRONT | — | | Dominica | DM | Driver License:FRONT, Passport:FRONT | — | | Dominican Republic | DO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Ecuador | EC | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Egypt | EG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | El Salvador | SV | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Equatorial Guinea | GQ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Eritrea | ER | ID Card:FRONT+BACK, Passport:FRONT | — | | Estonia | EE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Smart-ID, Mobile-ID | | Eswatini | SZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Ethiopia | ET | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Falkland Islands (Malvinas) | FK | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Faroe Islands | FO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Fiji | FJ | Driver License:FRONT, Passport:FRONT, ID Card:FRONT+BACK | — | | Finland | FI | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Finnish Trust Network (FTN) | | France | FR | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | French Guiana | GF | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | French Polynesia | PF | Driver License:FRONT | — | | Gabon | GA | ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Gambia | GM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Georgia | GE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Germany | DE | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Verimi | | Ghana | GH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Gibraltar | GI | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Greece | GR | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Greenland | GL | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Grenada | GD | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Guadeloupe | GP | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Guam | GU | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Guatemala | GT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Guernsey | GG | Driver License:FRONT | — | | Guinea | GN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Guinea-Bissau | GW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Guyana | GY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Haiti | HT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Holy See (Vatican City State) | VA | Passport:FRONT | — | | Honduras | HN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Hong Kong | HK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Hungary | HU | Address Card:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Iceland | IS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | India | IN | Aadhaar:FRONT+BACK, Driver License:FRONT, PAN Card:FRONT, Passport:FRONT, ID Card:FRONT+BACK | DigiLocker | | Indonesia | ID | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Iran, Islamic Republic of | IR | Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Iraq | IQ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Ireland | IE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Isle of Man | IM | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Israel | IL | Visa:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Italy | IT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT, Old ID Card:FRONT+BACK | — | | Jamaica | JM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Japan | JP | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Jersey | JE | Driver License:FRONT | — | | Jordan | JO | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT | — | | Kazakhstan | KZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT, Residence Permit:FRONT+BACK | — | | Kenya | KE | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Kiribati | KI | ID Card:FRONT+BACK, Passport:FRONT | — | | Korea, Democratic People's Republic of | KP | Passport:FRONT, Visa:FRONT | — | | Korea, Republic of | KR | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Kuwait | KW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Kyrgyzstan | KG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Lao People's Democratic Republic | LA | Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Latvia | LV | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Smart-ID | | Lebanon | LB | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Lesotho | LS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Liberia | LR | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Libya | LY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Liechtenstein | LI | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Lithuania | LT | Visa:FRONT+BACK, Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | Smart-ID, Mobile-ID | | Luxembourg | LU | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Macao | MO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Madagascar | MG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Malawi | MW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Malaysia | MY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Maldives | MV | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Mali | ML | ID Card:FRONT+BACK, Passport:FRONT | — | | Malta | MT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Marshall Islands | MH | Driver License:FRONT, Passport:FRONT | — | | Martinique | MQ | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Mauritania | MR | ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Mauritius | MU | ID Card:FRONT+BACK, Passport:FRONT | — | | Mayotte | YT | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Mexico | MX | Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Micronesia, Federated States of | FM | Driver License:FRONT, Passport:FRONT | — | | Moldova, Republic of | MD | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Monaco | MC | ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Mongolia | MN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Montenegro | ME | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Montserrat | MS | Driver License:FRONT, Passport:FRONT | — | | Morocco | MA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Mozambique | MZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Myanmar | MM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Namibia | NA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Nauru | NR | Driver License:FRONT, Passport:FRONT | — | | Nepal | NP | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Netherlands | NL | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | iDIN | | New Caledonia | NC | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | New Zealand | NZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Nicaragua | NI | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Niger | NE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Nigeria | NG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Niue | NU | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Norfolk Island | NF | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | North Macedonia | MK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Northern Mariana Islands | MP | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Norway | NO | Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | BankID (Norway) | | Oman | OM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Pakistan | PK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Palau | PW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Palestine, State of | PS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Panama | PA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Papua New Guinea | PG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Paraguay | PY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Peru | PE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Philippines | PH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | Digital National ID (Philippines), PhilSys Biometric Match | | Pitcairn | PN | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Poland | PL | Visa:FRONT+BACK, Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Portugal | PT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Puerto Rico | PR | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Qatar | QA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Romania | RO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Russian Federation | RU | Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT, Passport:FRONT, National Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Rwanda | RW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Réunion | RE | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Saint Barthélemy | BL | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Saint Helena, Ascension and Tristan da Cunha | SH | Passport:FRONT | — | | Saint Kitts and Nevis | KN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Saint Lucia | LC | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Saint Martin (French part) | MF | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Saint Pierre and Miquelon | PM | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Saint Vincent and the Grenadines | VC | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Samoa | WS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | San Marino | SM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Sao Tome and Principe | ST | ID Card:FRONT+BACK, Passport:FRONT | — | | Saudi Arabia | SA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Senegal | SN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Serbia | RS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Seychelles | SC | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Sierra Leone | SL | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Singapore | SG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Sint Maarten (Dutch part) | SX | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | iDIN | | Slovakia | SK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Slovenia | SI | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Solomon Islands | SB | Driver License:FRONT, Passport:FRONT | — | | Somalia | SO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | South Africa | ZA | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | South Georgia and the South Sandwich Islands | GS | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | South Sudan | SS | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Spain | ES | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Sri Lanka | LK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Sudan | SD | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Suriname | SR | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Svalbard and Jan Mayen | SJ | Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Sweden | SE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | BankID (Sweden), Freja | | Switzerland | CH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Syrian Arab Republic | SY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Taiwan, Province of China | TW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Tajikistan | TJ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Tanzania, United Republic of | TZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Thailand | TH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Timor-Leste | TL | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Togo | TG | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT | — | | Tokelau | TK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Visa:FRONT | — | | Tonga | TO | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Trinidad and Tobago | TT | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Tunisia | TN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Turkmenistan | TM | Driver License:FRONT, Passport:FRONT, Visa:FRONT | — | | Turks and Caicos Islands | TC | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Tuvalu | TV | Driver License:FRONT, Passport:FRONT | — | | Türkiye | TR | Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Uganda | UG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Ukraine | UA | Driver License:FRONT, ID Card:FRONT+BACK, National Passport:FRONT, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | United Arab Emirates | AE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | United Kingdom | GB | Provisional Driver License:FRONT, Driver License:FRONT, Military Card:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | OneID, Yoti ID | | United States | US | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | CLEAR, LA Wallet, Samsung Wallet | | United States Minor Outlying Islands | UM | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Uruguay | UY | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Uzbekistan | UZ | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Vanuatu | VU | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Venezuela, Bolivarian Republic of | VE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Viet Nam | VN | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Virgin Islands, British | VG | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Virgin Islands, U.S. | VI | Visa:FRONT, Driver License:FRONT, ID Card:FRONT+BACK, Military Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Wallis and Futuna | WF | Driver License:FRONT, Military Card:FRONT+BACK, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | | Western Sahara | EH | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | XK | XK | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Yemen | YE | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Zambia | ZM | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK | — | | Zimbabwe | ZW | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT | — | | Åland Islands | AX | Driver License:FRONT, ID Card:FRONT+BACK, Passport:FRONT, Residence Permit:FRONT+BACK, Visa:FRONT | — | # Supported Languages Source: https://documentation.idenfy.com/resources/supported-languages iDenfy identity verification supports 37 languages including Latin and non-Latin scripts. Full locale code reference for KYC and KYB verification flows. Our identity verification (KYC) platform supports a wide range of languages, including both Latin and non-Latin scripts, so users can access the experience in the language that feels most natural to them. We currently support **37 languages** across all major world scripts, including full right-to-left (RTL) layout support for Arabic and Persian. *** ## Identity Verification (KYC) Languages | Language | Native name | Locale code | | ------------------- | ---------------- | ----------- | | English | English | `EN` | | Spanish | Español | `ES` | | French | Français | `FR` | | Russian | Русский | `RU` | | German | Deutsch | `DE` | | Italian | Italiano | `IT` | | Polish | Polski | `PL` | | Lithuanian | Lietuvių | `LT` | | Latvian | Latviešu | `LV` | | Estonian | Eesti | `ET` | | Swedish | Svenska | `SV` | | Czech | Čeština | `CS` | | Romanian | Română | `RO` | | Hungarian | Magyar | `HU` | | Japanese | 日本語 | `JA` | | Bulgarian | Български | `BG` | | Dutch | Nederlands | `NL` | | Portuguese | Português | `PT` | | Ukrainian | Українська | `UK` | | Slovak | Slovenčina | `SK` | | Slovenian | Slovenščina | `SI` | | Vietnamese | Tiếng Việt | `VI` | | Thai | ไทย | `TH` | | Hindi | हिन्दी | `HI` | | Indonesian | Bahasa Indonesia | `ID` | | Croatian | Hrvatski | `HR` | | Danish | Dansk | `DA` | | Finnish | Suomi | `FI` | | Greek | Ελληνικά | `EL` | | Norwegian | Norsk | `NO` | | Turkish | Türkçe | `TR` | | Serbian | Српски | `SR` | | Mandarin Chinese | 普通话 | `ZH` | | Traditional Chinese | 中文 繁體 | `ZH_TW` | | Korean | 한국어 | `KO` | | Arabic | العربية | `AR` | | Persian (Farsi) | فارسی | `FA` | *** ## Business Verification (KYB) Languages The KYB form currently supports a focused set of languages: | Language | Native name | Locale code | | ---------- | ----------- | ----------- | | English | English | `EN` | | Lithuanian | Lietuvių | `LT` | | Dutch | Nederlands | `NL` | | German | Deutsch | `DE` | | French | Français | `FR` | | Portuguese | Português | `PT` | | Spanish | Español | `ES` | # Android SDK Additional Features Source: https://documentation.idenfy.com/sdks/android/additional-features Enable NFC reading, document blur detection, localization, and other advanced features in the iDenfy Android SDK verification flow. ## Automatic Country and Document Detection This feature skips the country and document selection step without requiring data in the token. The system automatically detects your user's country via IP address and displays the accepted documents for that location. The captured document is also detected by the automated system. New Country & Document selection Contact our tech support via [**Jira customer portal**](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1/group/-1) for enabling this feature. ## Realtime Document Blur Glare Detection This feature provides real-time document blur and glare detection. A warning alert notifies users when blur or glare is detected in the camera feed. An additional warning also appears in the photo result view. Document Blur Glare ### Adding the Blur Glare Detection Dependency In the **app** level Gradle, add an additional **sdk-blurglaredetection** module with the same version as the **sdk-api** module: ```gradle theme={"system"} repositories { dependencies { implementation 'com.github.idenfy:sdk-api:9.1.1' implementation 'com.github.idenfy:sdk-blurglaredetection:9.1.1' } } ``` Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature. ## Trusted Service This feature requires users to rotate their document according to templates in a random sequence before capturing the document, in order to detect any inconsistencies: Trusted Service ### Adding the Trusted Service Dependency In the **app** level Gradle, add an additional **sdk-trustedservice** module with the same version as the **sdk-api** module: ```gradle theme={"system"} repositories { dependencies { implementation 'com.github.idenfy:sdk-api:9.1.1' implementation 'com.github.idenfy:sdk-trustedservice:9.1.1' } } ``` Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature. ## Document Recognition This feature provides real-time document recognition. Documents shown in FRONT and BACK steps will be automatically detected and captured, allowing for a better picture of the document. Document Recognition To seek a better result, documents that are **not fully visible** or **do not match** the selected **country** and **document type** will **NOT** be recognized and captured. As a result, the final verification status will be more accurate. Document Recognition Failure If a document cannot be recognized within a certain period of time (10 seconds), the SDK will fall back to regular photo capturing. Document Recognition Fallback This feature is still in an early stage. Minor bugs might occur. ### Adding the Document Recognition Dependency In the **app** level Gradle, add an additional **sdk-docrecognition** module with the same version as the **sdk-api** module: ```gradle theme={"system"} repositories { dependencies { implementation 'com.github.idenfy:sdk-api:9.1.1' implementation 'com.github.idenfy:sdk-docrecognition:9.1.1' } } ``` To enable Document Recognition, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ## Face Detection While taking a regular face photo, you can enable the face detection feature, which requires users to place their face into the marked area before taking a photo. For better success rate, faces that are far away from the camera will not pass. Face detection Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature. Face detection will apply to **both** KYC verification and face authentication flows. ## Face Auto Capture While taking a regular face photo, you can enable the face auto capture feature, which requires users only to place their face into the marked area. The face photo is then automatically captured. For better success rate, faces that are too close or far away from the camera will not pass. Face auto capture Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature. ## Advanced Liveness Detection Liveness The SDK provides an advanced liveness recognition feature. The liveness feature is not optimized for tablets. Verification performed via tablet will be automatically classified as **denied**. The new major liveness version is released every 6-12 months. Your app must update the liveness module after every major release. If the SDK is not updated, it can lead to **runtime crashes**. Contact support to enable the liveness feature. ## NFC Support The SDK provides NFC enhanced identity verification. NFC Reading For more integration details and potential advantages, contact the technical team via the [Dashboard](https://admin.idenfy.com/auth/login). After NFC is enabled for your client settings, in the **app** level Gradle add an additional **sdk-nfcreading** module with the same version as the **sdk-api** module: ```gradle theme={"system"} repositories { dependencies { implementation 'com.github.idenfy:sdk-api:9.1.1' implementation 'com.github.idenfy:sdk-nfcreading:9.1.1' } } ``` ### NFC Required If the NFC required feature is enabled, devices that do not support NFC will immediately fail verification. This is a security feature that ensures a person does not change devices **just to perform verification**. To enable verifications for **all devices**, your app can handle this scenario: 1. Create two different accounts: with NFC enabled and without. 2. Check if the device supports NFC before creating a verification session. 3. If the device supports NFC, create a verification session with the NFC-enabled account's credentials. If NFC is not supported, use the other account's credentials. ### NFC Optional If the NFC optional feature is enabled, the user is asked to perform document NFC reading **ONLY** if the **device** and **selected document** type support NFC chip reading. Otherwise, a regular identity verification will be performed. ## Virtual Camera Detection The SDK provides the ability to check whether a face photo was taken using a virtual camera. Such verifications will result in a FAILED status. Contact support to enable the virtual camera detection feature. ## Bank Verification Feature Use this feature to confirm the authenticity of your customer's bank account during the account verification process. This step requires your customer to provide personal information, ensuring the financial institution interacts with a legitimate individual rather than someone using forged documents or stolen data. Bank Verification To enable Bank Verification, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ## Bank Card Verification Use this feature to confirm that the bank card used during onboarding belongs to the person completing identity verification. When enabled via the `cardVerificationEnabled` partner setting, the SDK adds a bank card step after face capture, before results, letting the user photograph their card or upload a supporting document. To enable Bank Card Verification, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ## Custom KYC Questionnaire This feature allows you to create a custom questionnaire that users must fill in at the beginning of every identity verification process. The questionnaire can contain **required** or **optional** questions and a variety of **question types**. KYC Questionnaire To enable the custom KYC questionnaire feature, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ### Custom KYC Questionnaire Conditions Questionnaires can be created using conditions, based on answers to previous questions: KYC Questionnaire conditions ## Custom Privacy Policy This feature allows you to create a custom privacy policy that users must agree to at the beginning of every identity verification process. Along with the iDenfy privacy policy, an additional sentence is added with an alert dialog, that shows your privacy policy as an HTML that can be fully customized.
To enable the custom privacy policy feature, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ## Email Verification This feature requires users to verify their email address before their identity verification.
To enable the email verification feature, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ## Phone Number Verification This feature requires users to verify their phone number before their identity verification.
To enable the phone number verification feature, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). ## Request Update This feature allows you to collect updated verification information (POA documents, questionnaires, risk assessments) for an existing verification using a token from the [Request Update API](/kyc/request-update). ### Launching Starting the request update flow is the same as launching the SDK with a KYC token — just use the token from the [Request Update API](/kyc/request-update) instead. Follow the [quickstart guide](/sdks/android/quickstart#4-presenting-the-sdk) for the full launching instructions. ### Receiving Results Check for `IdenfyController.IDENFY_REQUEST_UPDATE_RESULT_CODE` in the activity result callback: ```kotlin theme={"system"} if (resultCode == IdenfyController.IDENFY_REQUEST_UPDATE_RESULT_CODE) { val requestUpdateResult = data?.getParcelableExtra( IdenfyController.IDENFY_REQUEST_UPDATE_RESULT ) when (requestUpdateResult) { InformationUpdateStatus.EXPIRED -> {} InformationUpdateStatus.COMPLETED -> {} else -> {} } } ``` ### Status Reference | Status | Description | | ----------- | ----------------------------------------------------------------- | | `EXPIRED` | The request update session was cancelled or the token has expired | | `COMPLETED` | The request update has been completed. | # Android SDK Additional Information Source: https://documentation.idenfy.com/sdks/android/additional-information Review iDenfy Android SDK size impact on APK files, version management details, and troubleshooting for common integration issues. ## SDK Size Impact on Applications * **sdk-api** with Advanced liveness module excluded increases \~10 MB of APK size * **sdk-api** module increases \~15 MB of APK size * **sdk-api** and **sdk-blurglaredetection** modules increase \~25 MB of APK size * **sdk-api** and **sdk-nfcreading** modules increase \~29 MB of APK size * **sdk-api** and **sdk-docrecognition** modules increase \~28 MB of APK size * **sdk-api** and **sdk-trustedservice** modules increase \~26 MB of APK size ## SDK-Specific Choices ### Internet Disconnect Since it is a requirement to have a **KYC session uninterruptible**, the user flow handles network disconnections as follows: If the network disappears for more than 5 seconds when the user is still in the camera windows, the user is returned to the **KYC initial screen**. If the network disappears for more than 5 seconds when the user is in any other window, the user's actions and **clicks are blocked** until the connection is restored. Internet disconnect # Customizing the Android SDK Flow Source: https://documentation.idenfy.com/sdks/android/customizing-flow Customize the iDenfy Android SDK verification flow with SSL pinning, screen skipping, localization, and other configuration options. The SDK provides various options for modifying the verification flow. ## SSL Pinning Support By default, the SDK does not utilize SSL pinning as suggested by **AWS services**. If you need this option, you can enable SSL pinning. Our SSL pinning implementation follows the [AWS recommendations](https://aws.amazon.com/premiumsupport/knowledge-center/pin-application-acm-certificate/) and uses pinning for the Root certificates. They are valid for more than 5 years. However, during this timeframe, major changes can occur and we might be forced to change SSL pinning. Such changes will be notified at least 1 month prior. We strongly encourage you to enable this feature only if you are planning to **actively update the SDK**. ```kotlin theme={"system"} val idenfySettingsV2 = IdenfyBuilderV2() .withAuthToken(authToken) .withSSLPinning(true) ... .build() ... ``` ## Localization By default the SDK provides the following translations: * English (en) GB * Polish (pl) PL * Russian (ru) RU * Lithuanian (lt) LT * German (de) DE * French (fr) FR * Italian (it) IT * Latvian (lv) LV * Romanian (ro) RO * Swedish (sv) SV * Spanish (es) ES * Estonian (et) ET * Czech (cs) CS * Bulgarian (bg) BG * Dutch (nl) NL * Ukrainian (uk) UK * Portuguese (pt) PT * Vietnamese (vi) VI * Slovak (sk) SK * Indonesian (id) ID * Thai (th) TH * Hindi (hi) HI * Hungarian (hu) HU * Danish (da) DA * Greek (el) EL * Croatian (hr) HR * Norwegian (no) NO * Serbian (sr) SR * Finnish (fi) FI * Turkish (tr) TR * Chinese (zh) ZH * Slovenian (sl) SL * Japanese (ja) JA * Korean (ko) KO * Chinese Traditional (zh-Hant) ZH-HANT * Arabic (ar) AR All keys are located [here](https://github.com/idenfy/iDenfyResources/tree/main/sdk/android/localization/). You can supply partial translations -- if you do not include a translation for a particular key, the SDK will use the default. To see changes, add the particular XML to your app target or copy only specific keys in your `strings.xml` and changes will take effect. ## Forcing a Specific Language The SDK uses the device's language configuration as its default language. To force a particular locale, use one of these methods: ### IdenfySettings ```kotlin theme={"system"} IdenfySettingsV2.IdenfyBuilderV2() .withSelectedLocale(IdenfyLocaleEnum.EN) ... ``` ### Along with Session Creation Set the locale during [session creation](/kyc/generate-token). If no locale is forced, the SDK will fall back to the device's selected language. ## Enabling Screenshot Blocking When enabled, any screenshots or screen recordings in camera fragments will result in a black screen. ```kotlin theme={"system"} IdenfySettingsV2.IdenfyBuilderV2() .withBlockScreenshotAndScreenRecording(true) ... ``` ## Skipping Parts of the Verification Flow The SDK provides a set of tools to omit some views, which you could implement in your own application for a fine-grained approach. For example, you might want to implement document selection and the document's issuing country selection in the same view instead of having two separate screens. All customization options listed below can be combined, e.g. you can skip document selection, document onboarding screen, and document issuing country selection at the same time. Contact tech support to enable any of these features in your account settings, since they are configured from the backend, not the SDK. Contact support via the [Dashboard](https://admin.idenfy.com/auth/login) using your account. ### Skip Document Issuing Country Selection Screen Create a verification session with the provided document issuing country. See the [session creation documentation](/kyc/generate-token#sending-request). Example JSON request body: ```json theme={"system"} { "clientId": "TEST_CLIENT_ID", "country": "lt" } ``` ### Skip Document Selection Screen Create a verification session with the provided document type. See the [session creation documentation](/kyc/generate-token#sending-request). Example JSON request body: ```json theme={"system"} { "clientId": "TEST_CLIENT_ID", "documents": ["PASSPORT"] } ``` ### Skip Document Onboarding Screen After you enable this feature, the SDK skips the onboarding screen. Your user can select a document from the documents list and goes directly to the camera screen. ## Blur and Glare Flow Changes If your account has enabled blur or glare detection, the SDK will include blur and glare checks in the photo validation. The SDK shows an unsuccessful result immediately after each step. With blur or glare To enable blur and glare detection, contact tech support via the [dashboard](https://admin.idenfy.com/auth/login). ## Passive Liveness Check If your account has enabled passive liveness check, the SDK will include a liveness check in photo validation. The SDK shows an unsuccessful result immediately after each step. Android Passive liveness To enable passive liveness check, contact tech support via the [dashboard](https://admin.idenfy.com/auth/login). ## Identity Verification Results Screen Changes If you have [implemented manual verification flow (step 11)](/kyc/webhooks#callbacks-with-auto-callback), it might be wise to disable the **Manual results view**, **DENIED**, and **APPROVED** views for better UX. You will most likely display a loading screen after the user completes the verification flow. With this feature, the SDK finishes during the loading screen without showing the actual status, letting you customize the experience. Immediate redirect To disable those views, apply the **immediate redirect feature**. After enabling immediate redirect: ### APPROVED Screen Will Not Be Visible If verification was approved, your user will not see a success screen. The SDK will close while displaying a loading screen, allowing you to show a success screen yourself. ### DENIED Screen Will Not Be Visible The denied screen will not be visible. The SDK will close while displaying a loading screen, allowing you to display an error screen yourself. ### Manual Verification Screen Will Not Be Visible The manual verification screen (shown [above](#callback-status-reference)) will be skipped. To enable immediate redirect, contact technical support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). If you would like to replace the results view with your own custom view and control the flow yourself, see the [UI Customization guide](/sdks/android/ui-customization). # Android SDK Face Authentication Source: https://documentation.idenfy.com/sdks/android/face-authentication Implement biometric face authentication in your Android app using the iDenfy SDK for fast 30-second returning user re-verification. Face Matching authentication works from Android SDK version 8.0.1. ## Introduction Face authentication is a tool to perform KYC checks once and then use the same scanRef to perform multiple verifications in just **30 seconds**. The flow only requires your user to take a regular face photo to perform the authentication. Face matching authentication ## Pre-Conditions A [successful verification](/kyc/generate-token#graphical-representation-of-token-generation-uml-activity) must be performed before initializing face authentication. For face authentication all you need is a scanRef, which is obtained during [session creation](/kyc/generate-token#receiving-response). ## Getting Started Follow the [iDenfy SDK integration guide](/sdks/android/quickstart), which is required for face authentication as well. After completing the steps and the application **compiles successfully**, you are ready to implement **face-auth specific** logic. You can also download **the sample app**, which supports face authentication. [Download here](https://github.com/idenfy/iDenfyResources/blob/main/sdk/android/tutorials/sample/idenfy_sample_android.zip). ### Handle Webhook Callback You will receive a webhook callback if it is your preferred way of handling results (recommended as it is more secure and reliable). The webhook structure is: ```json theme={"system"} { "token": "token", "clientId": "clientId", "scanRef": "scanRef", "status": "SUCCESS", "type": "AUTHENTICATION", "method": "FACE_MATCHING", "facePhoto": "https://s3.eu-west-1.amazonaws.com/production.users.storage/users_storage/users//FRONT.png?AWSAccessKeyId=&Signature=&Expires=" } ``` The `facePhoto` key is a String (URL), can be null, with a max length of 500. It provides a URL to download the selfie photo used for authentication. The `status` key has the following values: | Name | Description | | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SUCCESS` | The user completed face authentication flow and the authentication status, provided by an automated platform, is SUCCESS. | | `FAILED` | The user completed face authentication flow and the authentication status, provided by an automated platform, is FAILED. | | `CANCELED` | The user did not complete the face authentication flow and canceled it and the identification status, provided by an automated platform, is EXIT. | | `EXPIRED` | The user did not complete the face authentication flow, but did not cancel it explicitly and the identification status, provided by an automated platform, is EXPIRED. | To set your webhook URL, contact tech support via the [dashboard](https://admin.idenfy.com/auth/login). ### Handle Callback in SDK If you also want to handle results directly in the mobile app, implement the result handling in the SDK: ```Kotlin theme={"system"} private var identificationResultsCallback = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> val resultCode = result.resultCode val data = result.data if (resultCode == IdenfyController.IDENFY_FACE_AUTHENTICATION_RESULT_CODE) { val faceAuthenticationResult: FaceAuthenticationResult = data!!.getParcelableExtra(IdenfyController.IDENFY_FACE_AUTHENTICATION_RESULT)!! Toast.makeText(this, "Face Authentication Status: " + faceAuthenticationResult.faceAuthenticationStatus.status, Toast.LENGTH_SHORT).show() when (faceAuthenticationResult.faceAuthenticationStatus) { FaceAuthenticationStatus.SUCCESS -> { // The user completed authentication flow, was successfully authenticated } FaceAuthenticationStatus.FAILED -> { // The user completed authentication flow, was not successfully authenticated } FaceAuthenticationStatus.EXIT -> { // The user did not complete authentication flow } } } } ``` ### Check Face Authentication Status and Create the Session Before initializing the SDK, check whether your user can use face authentication and obtain an authToken. See the [Create Face Auth Session](/face-authentication/token-generation) documentation. ### Initialize SDK Pass the session token to start face authentication: ```Kotlin theme={"system"} val faceAuthenticationInitialization = FaceAuthenticationInitialization(token) IdenfyController.getInstance().initializeFaceAuthenticationSDKV2(requireActivity(), (requireActivity() as BaseActivity).identificationResultsCallback, faceAuthenticationInitialization) ``` ## Customization ### Immediate Redirect You can pass an additional boolean to set the immediate redirect feature. This controls whether you **receive results immediately** from the SDK without any additional result pages. The user completes the verification, a loading state appears and closes -- without showing the final status screen. ```Kotlin theme={"system"} val faceAuthenticationInitialization = FaceAuthenticationInitialization(token, true) ``` ### Face Detection You can enable face detection, which requires users to place their face into the marked area before taking a photo. Face detection Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature. Face detection will apply to **both** KYC verification and face authentication flows. ### Passive Liveness Detection While using face matching authentication, you can enable passive liveness detection to detect whether a selfie photo is genuine or not. Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature. This will apply to **both** KYC verification and face authentication flows. ### Auto Capture You can enable auto capture, which requires users to place their face into the marked area. The picture is then automatically taken and immediately processed: Face authentication auto capture Contact tech support via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1) to enable this feature for face authentication. ## UI Customization The UI can be customized the same as the [KYC verification flow](/sdks/android/ui-customization). Main [colors or styles](/sdks/android/ui-customization#customization-with-overriding-layouts-of-sdk) in the **styles.xml** or **colors.xml** files of your app target can be overridden, as well as the [layouts](/sdks/android/ui-customization#customization-with-overriding-layouts-of-sdk). Find colors, styles, and layouts in the [repository](https://github.com/idenfy/iDenfyResources/tree/main/sdk/android/). Face authentication flow has additional UI settings that can be passed using **IdenfyFaceAuthUIBuilder** along with **FaceAuthenticationInitialization**: ```kotlin theme={"system"} val idenfyFaceAuthUISettings = IdenfyFaceAuthUISettings.IdenfyFaceAuthUIBuilder() //Show or hide language selection button .withLanguageSelection(true) //Show or skip camera on boarding screen .withOnBoardingView(true) .build() val faceAuthenticationInitialization = FaceAuthenticationInitialization( token, idenfyFaceAuthUISettings = idenfyFaceAuthUISettings ) ``` # Android SDK Logging and Webhooks Source: https://documentation.idenfy.com/sdks/android/logging-webhooks Handle iDenfy Android SDK callbacks, lifecycle event logging, and verification event tracking using the logging handler and listeners. ## Logging The SDK provides a way to log user and SDK common actions (lifecycle events, navigation, camera changes). This can be useful for understanding specific scenarios or troubleshooting potential issues. To enable logging, provide your implementation of the **IdenfyLoggingHandlerUseCase** class: ```kotlin theme={"system"} val consoleLogging = ConsoleLoggingImpl() IdenfyController.getInstance().idenfyLoggingHandler = IdenfyLoggingHandlerUseCaseImpl(consoleLogging) ``` ```kotlin theme={"system"} class ConsoleLoggingImpl { fun log(event: String, message: String, token: String) { Log.d("fromIdenfySDK-$event", message) } } ``` ```kotlin theme={"system"} class IdenfyLoggingHandlerUseCaseImpl(private var consoleLoggingImpl: ConsoleLoggingImpl):IdenfyLoggingHandlerUseCase { override fun logEvent(event: String, message: String, token: String) { consoleLoggingImpl.log(event, message, token) } } ``` You only need to provide a concrete implementation of the **IdenfyLoggingHandlerUseCase** interface. If you also want to see OkHttp requests/responses and payload in **Logcat**, initialize the iDenfy SDK with `IdenfySDKLoggingEnum.FULL`: ```kotlin theme={"system"} val idenfySettingsV2 = IdenfySettingsV2.IdenfyBuilderV2() .withAuthToken(authToken) .withLogging(IdenfySDKLoggingEnum.FULL) .build() ``` ## User Events Webhooks (Optional) The SDK provides webhooks about events occurring throughout the verification process. Results are delivered while the verification process is active and the application is presenting SDK views. ### Declare a Class for Receiving Events Declare a class that implements `IdenfyUserFlowHandler` to call your backend service, log events, or apply changes: ```kotlin theme={"system"} class IdenfyUserFlowCallbacksHandler : IdenfyUserFlowHandler { /** * @param documentType Selected document type */ override fun onDocumentSelected(documentType: String) { Log.d("onDocumentSelected", documentType) } /** * @param issuingCountryCode Selected issuingCountryCode */ override fun onCountrySelected(issuingCountryCode: String) { Log.d("onCountrySelected", issuingCountryCode) } /** * @param photosUploaded indicated that photos have been uploaded */ override fun onPhotosUploaded(photosUploaded: Boolean) { Log.d("onPhotosUploaded", photosUploaded.toString()) } /** * @param processingStarted indicates that processing has started */ override fun onProcessingStarted(processingStarted: Boolean) { Log.d("onProcessingStarted", processingStarted.toString()) } } ``` ### Configure Application Class Set `IdenfyUserFlowController` to reference `idenfyUserFlowCallbacksHandler` in the application class: ```kotlin theme={"system"} class IdenfyApplication : MultiDexApplication() { override fun onCreate() { super.onCreate() val idenfyUserFlowCallbacksHandler = IdenfyUserFlowCallbacksHandler() IdenfyUserFlowController.setIdenfyUserFlowHandler(idenfyUserFlowCallbacksHandler) } } ``` You must set the webhooks handler in the **application** class to ensure that the listener is set again after the application process has stopped. # Android SDK Migration Guide Source: https://documentation.idenfy.com/sdks/android/migration-guide Upgrade between iDenfy Android SDK versions with step-by-step instructions, breaking change notes, and migration details for each release. This migration guide covers significant changes in the SDK API that might affect your integration. **No custom layouts?** If you have not overridden any SDK layouts or views, you typically only need to update the dependency version — no code changes required. ## \[9.0.x] -> \[9.1.0] ### RTL Layout Support Arabic locale support has been added. All SDK layouts now use `Start`/`End` constraints instead of `Left`/`Right` to properly support right-to-left (RTL) languages. If you have overridden any SDK layouts, you **must** migrate your custom layouts to use `Start`/`End` constraints instead of `Left`/`Right`. For example: * `layout_constraintLeft_toLeftOf` → `layout_constraintStart_toStartOf` * `layout_constraintRight_toRightOf` → `layout_constraintEnd_toEndOf` * `android:layout_marginLeft` → `android:layout_marginStart` * `android:layout_marginRight` → `android:layout_marginEnd` * `android:paddingLeft` → `android:paddingStart` * `android:paddingRight` → `android:paddingEnd` * `gravity="left" → gravity="start"` * `gravity="center|start" → gravity="center_vertical|start"` Also, `android:textAlignment="viewStart"` was added to TextViews for proper RTL text rendering. You can check our updated layouts [here](https://github.com/idenfy/iDenfyResources/blob/main/sdk/android/layouts/layout.zip). ## \[8.x.x] -> \[9.0.0] ### New iDenfy Privacy Policy View New privacy policy view is a required step for onboarding users. **idenfy\_fragment\_privacy\_policy\_v2.xml** was completely redone: New Privacy Policy ```xml theme={"system"} ``` A new color is used in this layout: ```xml theme={"system"} #F2F4F8 ``` ### Country and Document Selection Steps Combined Into One View A new Country & Document selection view was added, which combines the old two views into one. The new **idenfy\_fragment\_country\_and\_document\_selection\_fragment.xml** layout is added: New Country & Document selection ```xml theme={"system"} ``` New colors are used in this layout: ```xml theme={"system"} #734BFB #452D97 #EFEBFF ``` ### Auto Country and Document Detection Feature Along with this feature, a new card is presented in **idenfy\_fragment\_document\_camera\_preview\_session\_v2.xml** to show detected country and supported documents for it. An updated layout looks like this: New Country & Document selection ```xml theme={"system"} ``` ### Updated UI for iDenfy Splash Screen Both **idenfy\_fragment\_splash\_screen\_v2.xml** and **idenfy\_fragment\_face\_authentication\_splash\_screen\_v2.xml** were redone, we use simple white and black colors without complicated iDenfy gradients: New Splash Screen ```xml theme={"system"} ``` A new color is used in this layout: ```xml theme={"system"} #19181D ``` ## \[8.7.4] to \[8.7.5] ### Android Default Alert Dialogs Replaced with New XML Layout A new **idenfy\_dialog\_generic\_alert.xml** layout was added that replaces the default Android alert dialogs: ```xml theme={"system"} ``` ## \[8.6.2] to \[8.6.3] ### Updated Face Capture Oval Design Face Oval V2 Follow this migration guide point if you have overridden **idenfy\_fragment\_face\_camera\_preview\_session\_v2.xml**. A new **idenfy\_imageview\_face\_camera\_preview\_session\_oval\_face\_v2** oval ImageView was added, which replaces **idenfy\_imageview\_face\_camera\_preview\_session\_oval\_face** in **idenfy\_fragment\_face\_camera\_preview\_session\_v2.xml**: ```xml theme={"system"} ``` The `idenfy_imageview_face_camera_preview_session_oval_face` is still available but deprecated and will be removed in the future. ## \[8.5.x] to \[8.6.0] ### Added Realtime Blur Glare Detection in Document Capture Follow this migration guide point if you have overridden **idenfy\_fragment\_document\_camera\_preview\_session\_v2.xml**. With the latest realtime blur glare detection feature, a warning alert card was added to **idenfy\_fragment\_document\_camera\_preview\_session\_v2.xml**: ```xml theme={"system"} ``` ## \[8.5.x] to \[8.5.2] ### KYC Questionnaire FILE and IMAGE Questions Merged `idenfy_item_questionnaire_type_image_input_v2.xml` has been removed. ## \[8.4.x] to \[8.5.0] ### Added Face Detection Progress View to the Camera Drawer Follow this migration guide point if you have overridden **idenfy\_partial\_layout\_face\_camera\_preview\_session\_instructions\_topsheet\_root\_v2.xml**. With the latest face authentication auto capture feature, a progress bar was added to **idenfy\_partial\_layout\_face\_camera\_preview\_session\_instructions\_topsheet\_root\_v2.xml**: ```xml theme={"system"} ``` Along with the style: ```xml theme={"system"} ``` ## \[8.3.x] to \[8.4.0] ### Removed Dynamic OnBoarding View `.withConfirmationView(IdenfyOnBoardingViewTypeEnum.MULTIPLE_DYNAMIC)` option is no longer available in **IdenfyUISettingsV2**. Follow this migration guide point if you have implemented custom views of **idenfy\_fragment\_onboarding\_v2.xml** or **idenfy\_fragment\_face\_authentication\_initial\_view\_v2**. The **idenfy\_fragment\_onboarding\_v2.xml** and **idenfy\_fragment\_face\_authentication\_initial\_view\_v2.xml** layouts have changed and no longer have **idenfy\_cardview\_instructions\_description**, **idenfy\_constraint\_layout\_instructions\_description**, **idenfy\_iv\_instructions\_description**, **idenfy\_textview\_instructions\_description** views. You can safely remove them from your layouts. Also, **idenfy\_colors\_camera\_dynamic\_onboarding\_view\.xml** has been removed. Only **idenfyCameraOnBoardingViewBackgroundColor**, **idenfyCameraOnBoardingViewLoadingSpinnerColor**, **idenfyCameraDynamicOnBoardingViewProgressBarBackgroundColor** and **idenfyCameraDynamicOnBoardingViewProgressBarForegroundColor** have been moved to **idenfy\_colors\_camera\_static\_onboarding\_view\.xml**. ## \[8.2.x] to \[8.3.0] ### Removed Instructions Drawer Option from Camera View The instructions drawer has been removed. The top drawer will remain static as if instructions were disabled, and will only hold camera descriptions and the app bar. `.withInstructions(IdenfyInstructionsType.DRAWER)` option is no longer available in **IdenfyUIBuilderV2**. Follow this migration guide point if you have overridden **idenfy\_partial\_layout\_face\_camera\_preview\_session\_instructions\_topsheet\_root\_v2.xml** or **idenfy\_partial\_layout\_document\_camera\_session\_instructions\_topsheet\_root\_v2.xml**. The **idenfy\_partial\_layout\_face\_camera\_preview\_session\_instructions\_topsheet\_root\_v2.xml** and **idenfy\_partial\_layout\_document\_camera\_session\_instructions\_topsheet\_root\_v2.xml** layouts have changed and will no longer hold instructions UI. The layout height is static and is set to **@dimen/idenfy\_dimen\_document\_and\_face\_camera\_session\_view\_drawer\_height**: ```xml theme={"system"} ``` Many views have been removed from these layouts, and constraints for **idenfy\_textview\_camera\_session\_instructions\_information\_title** have changed: ```xml theme={"system"} ``` Also, **idenfy\_partial\_layout\_camera\_session\_instructions\_topsheet\_v2.xml** and **idenfy\_partial\_layout\_camera\_session\_instructions\_video\_view\_container\_v2.xml** have been removed. You can check the new layouts [here](https://github.com/idenfy/iDenfyResources/blob/main/sdk/android/layouts/layout.zip). All colors and styles related to the instructions drawer have been removed. See the updated [colors](https://github.com/idenfy/iDenfyResources/tree/main/sdk/android/colors) and [styles](https://github.com/idenfy/iDenfyResources/blob/main/sdk/android/styles/styles.zip). # Android SDK Quickstart Source: https://documentation.idenfy.com/sdks/android/quickstart Install and configure the iDenfy Android SDK with API Level 24+ support to run your first identity verification in an Android app. The SDK supports **API Level 24** and above. ## iDenfy Identity Verification Flow Below you can check a full regular flow. This flow can be customized and success results can be omitted as well. We recommend omitting them using our [immediate redirect feature](#identity-verification-results-screen-changes). ## Getting Started ### Obtain a Session Token The SDK requires a session token to start initialization. See the [session creation guide](/kyc/generate-token). ### Add the SDK Dependency In the **root** level (project module) Gradle, add the following repository: ```gradle theme={"system"} repositories { maven { url 'https://jitpack.io' } } ``` In the **app** level Gradle, add the following dependency with the **latest version**. The latest version is available from the [changelog](/sdks/android/migration-guide). ```gradle theme={"system"} repositories { dependencies { implementation 'com.github.idenfy:sdk-api:9.1.1' } } ``` If you are not using Advanced Liveness detection, you can reduce the SDK size by excluding the **sdk-liveness** module: ```gradle theme={"system"} repositories { dependencies { implementation ('com.github.idenfy:sdk-api:9.1.1') { exclude group: 'com.github.idenfy', module: 'sdk-liveness' } } } ``` If you are not overriding any custom views or applying customization, you can use the dynamic version. If you did make layout changes, do not use the dynamic version, since **runtime** crashes can occur. If you understand the disadvantages and still want to use the latest version, integrate the SDK as follows: ```gradle theme={"system"} repositories { dependencies { implementation 'com.github.idenfy:sdk-api:+' } } ``` ### Configure Android Studio The SDK uses Java 11. Verify that the version is configured: ```gradle theme={"system"} compileOptions { targetCompatibility 11 sourceCompatibility 11 } kotlinOptions { jvmTarget = "11" } ``` Also make sure that you have these lines in your **gradle.properties** file: ```gradle theme={"system"} android.useAndroidX=true ``` ### Configure the SDK Provide the following configuration: ```kotlin theme={"system"} val idenfySettingsV2 = IdenfySettingsV2.IdenfyBuilderV2() .withAuthToken("AUTH_TOKEN") .build() ``` ### Present the Verification Activity Create an instance of IdenfyController to start the verification flow: ```kotlin theme={"system"} IdenfyController.getInstance().initializeIdenfySDKV2WithManual( this, identificationResultsCallback, idenfySettingsV2 ) ``` ### Handle Verification Callbacks The SDK returns verification results using Activity Result Contract, which you pass during initialization. The SDK provides the `idenfyIdentificationResult` callback class. If your service uses only the [automatic (default) callback](/kyc/webhooks#default-callback), then you should only check `idenfyIdentificationResult.autoIdentificationStatus`. Since version 7.1.0, the SDK includes a SUSPECTED response. You can read about it [here](/kyc/webhooks#verification-status-table) and decide whether you would like it to impact your UI. ```kotlin theme={"system"} var identificationResultsCallback = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> val resultCode = result.resultCode val data = result.data if (resultCode == IdenfyController.IDENFY_IDENTIFICATION_RESULT_CODE) { val idenfyIdentificationResult: IdenfyIdentificationResult = data!!.getParcelableExtra( IdenfyController.IDENFY_IDENTIFICATION_RESULT )!! when (idenfyIdentificationResult.manualIdentificationStatus) { ManualIdentificationStatus.APPROVED -> { //The user completed a verification flow, was verified manually and the verification status, provided by a manual reviewer, is APPROVED. } ManualIdentificationStatus.FAILED -> { //The user completed a verification flow, was verified manually and the verification status, provided by a manual reviewer, is FAILED. } ManualIdentificationStatus.WAITING -> { //The user was only verified by an automated platform, not by a manual reviewer. } ManualIdentificationStatus.INACTIVE -> { //The user was only verified by an automated platform and still waiting for manual reviewing. } } when (idenfyIdentificationResult.autoIdentificationStatus) { AutoIdentificationStatus.APPROVED -> { //The user completed a verification flow and the verification status, provided by an automated platform, is APPROVED. } AutoIdentificationStatus.FAILED -> { //The user completed a verification flow and the verification status, provided by an automated platform, is FAILED. } AutoIdentificationStatus.UNVERIFIED -> { //The user did not complete a verification flow and the verification status, provided by an automated platform, is UNVERIFIED. } } Toast.makeText( this@MainActivity, "Auto - ${idenfyIdentificationResult.autoIdentificationStatus} \n" + "Manual - ${idenfyIdentificationResult.manualIdentificationStatus} \n", Toast.LENGTH_LONG ).show() } } ``` ## Callback Status Reference ### autoIdentificationStatus | Name | Description | | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | | `APPROVED` | The user completed a verification flow and the verification status, provided by an automated platform, is APPROVED. | | `FAILED` | The user completed a verification flow and the verification status, provided by an automated platform, is FAILED. | | `UNVERIFIED` | The user did not complete a verification flow and the verification status, provided by an automated platform, is UNVERIFIED. | ### manualIdentificationStatus | Name | Description | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `APPROVED` | The user completed a verification flow and was verified manually while waiting for the manual verification results in the iDenfy SDK. The verification status, provided by a manual review, is APPROVED. | | `FAILED` | The user completed a verification flow and was verified manually while waiting for the manual verification results in the iDenfy SDK. The verification status, provided by a manual review, is FAILED. | | `WAITING` | The user completed a verification flow and started waiting for the manual verification results in the iDenfy SDK. The user decided to stop waiting and clicked the "BACK TO ACCOUNT" button. The manual verification review is **still ongoing**. | | `INACTIVE` | The user was only verified by an automated platform, not by a manual reviewer. The verification performed by the user can still be verified by the manual review if your system uses the manual verification service. | The manualIdentificationStatus always returns INACTIVE unless your system [implemented manual verification flow (step 11)](/kyc/webhooks#callbacks-with-auto-callback). The manual verification screen looks like this: Manual flow To disable it, refer to the [immediate redirect feature](/sdks/android/customizing-flow#identity-verification-results-screen-changes). These SDK statuses are the same as **iFrame** integration statuses. The only difference is that the SDK returns INACTIVE if the manual verification screen was not opened during the verification session, instead of returning null as the iFrame does. Also, the iFrame does **not close automatically** since it can deliver results without closing itself. After the SDK finishes and closes itself, you will also receive a [webhook callback](/kyc/webhooks#verification-result-webhook-callback) to your backend system. It might be useful to **completely ignore the SDK status** and communicate between your app and your backend service about verification status. ## Samples Our [sample application](https://github.com/idenfy/iDenfyResources/blob/main/sdk/android/tutorials/sample/idenfy_sample_android.zip) demonstrates the integration of the iDenfy SDK. ## FAQ **1. Is there a possibility to change the verification results view?** Yes, it can be achieved by providing a [custom verification results view](/sdks/android/ui-customization#customization-by-providing-a-custom-verification-results-view). **2. How to change the position of the top titles?** Any component and its properties can be changed either by [overriding the XML layout](/sdks/android/ui-customization#customization-with-overriding-layouts-of-sdk) or providing a [custom Jetpack Compose view](/sdks/android/ui-customization#customization-by-providing-your-own-implementations-of-jetpack-compose-composables). **3. How do I report an issue within the SDK?** Please report any issue via the [Jira customer portal](https://idenfy-ivs.atlassian.net/servicedesk/customer/portal/1). Attach the SDK and Gradle versions you are using, and describe the problem in as much detail as possible. **4. When I override liveness fonts, the size does not change. Why is that?** Liveness font size is dynamically determined according to the screen resolution, and it **cannot be manually changed**. # Android SDK UI Customization Source: https://documentation.idenfy.com/sdks/android/ui-customization Customize iDenfy Android SDK colors, fonts, and UI elements programmatically or via XML layout files for a fully branded experience. The Android SDK provides various customization options with *programming code* or *XML files*. ## Getting Started ### Create IdenfyUISettingsV2 Create an instance of the IdenfyUISettingsV2 class: ```kotlin theme={"system"} val idenfyUISettingsV2 = IdenfyUISettingsV2.IdenfyUIBuilderV2() .build() ``` ### Update IdenfySettingsV2 ```kotlin theme={"system"} val idenfySettingsV2 = IdenfySettingsV2.IdenfyBuilderV2() .withIdenfyUISettingsV2(idenfyUISettingsV2) ... build() ``` The SDK currently supports several ways of customization. ### Which Approach Should You Use? | Approach | Complexity | Best for | | -------------------- | ---------- | -------------------------------------------------- | | Colors.xml overrides | Low | Brand color changes only | | Override XML layouts | Medium | Rearranging or hiding UI elements | | Jetpack Compose | High | Full control over layout, fonts, and animations | | Custom results view | Medium | Replacing the verification-results screen entirely | ## Customization Options ### Customization with IdenfyUISettingsV2 #### Camera OnBoarding View ```kotlin theme={"system"} IdenfyUISettingsV2.IdenfyUIBuilderV2() /** * OnBoarding View acts as additional screen, which helps the user to familiarize themselves with the current step * @param idenfyOnBoardingViewTypeEnum Defines onBoarding view type */ .withConfirmationView(idenfyOnBoardingViewTypeEnum: IdenfyOnBoardingViewTypeEnum) ... build() ``` The possible options of the Camera OnBoarding View: | IdenfyOnBoardingViewTypeEnum | Description | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `none` | OnBoarding view is skipped | | `multipleStatic` | Shows an onBoarding view before EVERY step of the verification process with a static instruction list (This is a default setting starting 7.x version) | #### Joined Country and Document Selection Since SDK version 9.0.0, this setting is enabled by default and the country and document selection views are joined into one. New Country & Document selection ```kotlin theme={"system"} IdenfyUISettingsV2.IdenfyUIBuilderV2() /** * An option to choose whether country and document selection views are joined or separate * @param withCountryAndDocumentSelectionJoined: sets the visibility of joined country and document selection view */ .withCountryAndDocumentSelectionJoined(withCountryAndDocumentSelectionJoined: Boolean) ... build() ``` #### Language Selection ```kotlin theme={"system"} IdenfyUISettingsV2.IdenfyUIBuilderV2() /** * Enables language selection window, which provides an option to change the locale * @param isLanguageSelectionNeeded Changes visibility of locale selection icon. */ .withLanguageSelection(isLanguageSelectionNeeded: Boolean) ... build() ``` #### Mismatch Tags Alert Visibility ```kotlin theme={"system"} IdenfyUISettingsV2.IdenfyUIBuilderV2() /** * An option to choose whether mismatch tags alert is visible * @param mismatchTagsAlert: set the visibility of mismatch tags alert */ .withMismatchTagsAlert(mismatchTagsAlert: Boolean) ... build() ``` #### Bottom Sheet Dialogs Since SDK version 9.1.0, this setting is enabled by default, it present dialogs as bottom sheets instead of centered alerts for iDenfy custom dialogs ```kotlin theme={"system"} IdenfyUISettingsV2.IdenfyUIBuilderV2() /** * An option to present dialogs as bottom sheets instead of centered alert dialogs * @param useBottomSheetDialogs: sets whether bottom sheet dialogs are used instead of alert dialogs */ .withBottomSheetDialogs(useBottomSheetDialogs: Boolean) ... build() ``` #### Document Camera Rectangle Visibility Since some documents are non-regular size, you can hide the camera rectangle. This way the whole screen is dedicated to document capturing. The rectangle can be hidden for **all** document types: ```kotlin theme={"system"} /** * Camera rectangle will be hidden for ALL countries and document types */ val idenfyUISettingsV2 = IdenfyUISettingsV2.IdenfyUIBuilderV2() .withDocumentFrameVisibility(DocumentCameraFrameVisibility.HiddenForAllCountriesAndDocumentTypes) .build() ``` Or for **specific countries and document types**: ```kotlin theme={"system"} /** * Camera rectangle will be hidden ONLY for Lithuanian passport */ val countryDocumentMap: MutableMap> = mutableMapOf() countryDocumentMap["LT"] = mutableListOf(DocumentTypeEnum.PASSPORT) val documentCameraFrameVisibility = DocumentCameraFrameVisibility.HiddenForSpecificCountriesAndDocumentTypes(countryDocumentMap) val idenfyUISettingsV2 = IdenfyUISettingsV2.IdenfyUIBuilderV2() .withDocumentFrameVisibility(documentCameraFrameVisibility) .build() ``` #### Adding Instructions in Camera Session The SDK provides informative instructions during the verification session. They can provide valuable information for the user and help tackle common issues: bad lighting, wrong document side, etc. Instructions can be customized by changing all UI elements or even using your MP4 video files. Instructions are configured by your backend settings and can be overridden with the SDK settings. **Using IdenfyInstructionsEnum dialog:** **Using IdenfyInstructionsEnum none:** Enable instructions in IdenfyUISettingsV2: ```kotlin theme={"system"} val idenfyUISettingsV2 = IdenfyUISettingsV2.IdenfyUIBuilderV2() .withInstructions(IdenfyInstructionsType.DIALOG) ... build() ``` ### Applying SDK-Wide Color Changes If **color and asset changes** are the only requirement, they can be easily customized by changing the main colors. | Color name | Description | Default color value | | ------------------------- | --------------------------------------------------------------------------------- | ------------------- | | `idenfyMainColorV2` | Defines the color of most single-colored assets and focused parts in the SDK. | #536DFE | | `idenfyMainDarkerColorV2` | Defines the color of some focused parts in the SDK, similar to idenfyMainColorV2. | #5D7CE4 | | `idenfyBackgroundColorV2` | Defines the background color. | #FBFBFB | | `idenfySecondColorV2` | Defines the text color. | #F2353B4E | **1. Override color names in your app module.** Create either a new `idenfy_colors.xml` or add the defined colors to your project. **2. Make color changes:** ```xml theme={"system"} #7CFC00 #7CFC00 ``` Colors are also applied to images that use a single color from *idenfy drawable resources*. If you override the provided images with icons using more than one color, you can disable the tint on images by overriding the layout styles with the removed tint attribute. **Before:** ```xml theme={"system"} ``` **After:** ```xml theme={"system"}