# Authentication Source: https://docs.smartcomply.com/authentication How to authenticate requests to the Smartcomply API. All requests to the Adhere API must include your secret key in the request headers. Requests without a valid key will return a `401 Unauthorized` error. ## Base URL ``` https://adhere-api.smartcomply.com ``` ## Getting Your API Key After completing your business KYC on the [Adhere dashboard](https://adhere-app.smartcomply.com): 1. Navigate to **Settings → API Keys** 2. Click **Generate Key** 3. Copy and store the key securely — it will not be shown again ## Request Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your secret API key | Yes | | `Content-Type` | `application/json` | Yes | ## Example Request ```bash theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22000000001"}' ``` ## Security Best Practices Never expose your secret key in client-side code, public repositories, or logs. * **Use environment variables** — store your key in `.env` files and load it at runtime, never hard-code it * **Use separate keys per environment** — maintain distinct keys for development, staging, and production * **Rotate keys periodically** — regenerate your key from the dashboard if you suspect it has been compromised * **Restrict key usage** — only share keys with services that strictly need them # Changelog Source: https://docs.smartcomply.com/changelog Release notes and updates for the Adhere API. ## May 2025 — v3 Launch **Adhere v3** is now the primary API version. v3 brings a cleaner endpoint structure, richer response data, and expanded country coverage. ### New in v3 * **User Journey Tracking** — New session-based API to track and validate transaction event sequences and flag out-of-order or suspicious behaviour in real time. * **OpenAPI Playground** — Every endpoint page now has a built-in interactive playground. Authenticate once with your API key and test requests directly from the docs. ### Improvements * Unified `x-access-token` header authentication across all endpoints. * Consistent JSON response structure: `{ status, data, message }` on all endpoints. * Activity codes for transaction monitoring consolidated and documented (200–221 safe, 450–457 suspicious). * Loan Fraud Check now supports an optional `run_aml_check` flag for both individual and business applications. *** ## March 2025 — v2 Updates * Added Ghana ID Card with Face verification. * Kenya credit reports (individual and business) added to the Credit Report suite. * Premium credit report added for Nigerian individuals. * Transaction screening expanded with full OFAC, UN, and EU sanctions list matching. *** ## 2024 — v1 Release * Initial release covering Nigerian KYC (BVN, NIN, VNIN, CAC, Driver's License, Passport, Voter's ID, NUBAN, Phone, TIN). * Kenya National ID (basic and advanced) and Passport verification. * Ghana ID Card verification. * Individual and business credit reports from CRC, First Central, and Credit Registry. * Transaction monitoring, card fraud detection, and KYC screening. * Loan fraud check for individuals and businesses. # Error Codes Source: https://docs.smartcomply.com/error_codes HTTP status codes and error responses returned by the Smartcomply API. The Adhere API uses standard HTTP status codes. Codes in the `2xx` range indicate success; `4xx` codes indicate a client error; `5xx` codes indicate a server-side issue. ## HTTP Status Codes | Code | Name | Description | | ----- | --------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `200` | OK | The request succeeded and data is returned in the response body. | | `400` | Bad Request | The request was malformed — a required parameter is missing, the value is invalid, or the request body is not valid JSON. | | `401` | Unauthenticated | The `x-access-token` header is missing or the key is invalid. | | `403` | Forbidden | The API key is valid but does not have permission to access this endpoint. | | `404` | Not Found | The requested resource does not exist. | | `422` | Unprocessable Entity | The request was well-formed but the data failed validation (e.g., an ID number that doesn't match the expected format). | | `500` | Internal Server Error | An unexpected error occurred on Smartcomply's end. | | `502` | Bad Gateway | A dependent upstream service is temporarily unavailable. | | `503` | Service Unavailable | The API is temporarily offline for maintenance. | | `504` | Gateway Timeout | The upstream service did not respond in time. | ## Error Response Format All error responses follow this structure: ```json theme={null} { "status": "failed", "data": [], "message": "A human-readable description of the error" } ``` ## Common Error Scenarios Ensure the `x-access-token` header is present and contains a valid, active secret key. Keys can be regenerated from the Adhere dashboard under **Settings → API Keys**. ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` Check the request body against the endpoint's parameter table. All required fields must be present and non-empty. ```json theme={null} { "status": "failed", "data": [], "message": "This field is required." } ``` The provided ID (BVN, NIN, etc.) could not be matched in the source database. Verify the number is correct and belongs to a real record. ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` These are rare and typically transient. Implement exponential back-off retry logic in your integration. If a `5xx` error persists for more than a few minutes, contact [support](mailto:adhere@smartcomply.com). ## Retrying Requests For `5xx` errors and network timeouts, retry with exponential back-off: | Attempt | Wait before retry | | --------- | ----------------- | | 1st retry | 1 second | | 2nd retry | 2 seconds | | 3rd retry | 4 seconds | Do **not** retry `4xx` errors — they indicate a problem with the request itself that must be fixed before retrying. # Introduction Source: https://docs.smartcomply.com/introduction Adhere by Smartcomply — identity verification, fraud detection, transaction monitoring, and credit data across Africa. Adhere by Smartcomply ## What is Adhere? **Adhere** is Smartcomply's developer API — a single integration that gives you access to identity verification, fraud detection, transaction monitoring, and credit reporting across Africa. Whether you're onboarding customers, assessing loan applications, or screening transactions in real time, Adhere provides the compliance infrastructure you need to build with confidence. **Currently supported countries:** Nigeria, Ghana, Kenya, Rwanda, and Uganda. ## What You Can Build Verify customer identities using BVN, NIN, national IDs, passports, driver's licenses, and more — across Nigeria, Kenya, Ghana, Rwanda, and Uganda. Score transactions in real time, screen against global sanctions lists, detect card fraud, and monitor user behaviour with AML checks and configurable alert thresholds. Pull individual and business credit histories from CRC, First Central, and Credit Registry — including full reports, scores, and history summaries. Assess individual and business loan applications using AI-driven fraud scoring, real-time credit bureau data, and financial analysis. ## Onboarding Suite The Adhere Onboarding Suite lets you verify customer identities at every step — from document checks and biometric matching to address verification and credit screening — all from a single API. Adhere Onboarding Suite Adhere Onboarding Suite ## Quick Links Make your first API call in under 5 minutes. How to authenticate your requests. Understand API error responses. ## Base URL All API requests use the following base URL: ``` https://adhere-api.smartcomply.com ``` ## Support Reach us at [adhere@smartcomply.com](mailto:adhere@smartcomply.com) or explore the [Postman collection](https://documenter.getpostman.com/view/55164637/2sBXwjxET7). # Android SDK Source: https://docs.smartcomply.com/libraries/android_sdk Integrate SmartComply identity verification and liveness detection into your Android app. # SmartComply Android SDK The SmartComply Android SDK delivers a fully self-contained identity verification flow for Android apps. Launch one Activity and the SDK handles session management, country and ID-type selection, document capture, identity verification, and liveness detection automatically. ## Features * **Single-Activity launch** — start verification with one Intent and receive a typed result back * **Two verification modes** — document photo capture or ID number data entry, configured from your Dashboard * **Guide-box document capture** — frames the ID card precisely so images are always clean and correctly cropped * **Liveness detection** — camera-based face challenge system (blink, turn head) runs automatically after identity verification * **Dynamic ID types** — channels and fields are fetched live from your Dashboard configuration * **Multi-country support** — renders a country picker automatically when more than one country is configured * **Dark and light mode** — theme adapts to the system setting; override via the launch intent *** ## Requirements * **Android API 24** (Android 7.0) or later * **Kotlin 1.9** or later * **Jetpack Compose** enabled in your module *** ## Installation ### 1 — Add Maven Central In `settings.gradle.kts` (already present in most projects): ```kotlin theme={null} dependencyResolutionManagement { repositories { google() mavenCentral() } } ``` ### 2 — Add the dependency In your app or feature module `build.gradle.kts`: ```kotlin theme={null} dependencies { implementation("io.github.386konsult:android-sdk:1.0.0") } ``` ### 3 — Enable Compose ```kotlin theme={null} android { buildFeatures { compose = true } } ``` *** ## Permissions The SDK declares these permissions automatically via manifest merge. You do not need to add them manually unless your project uses a custom manifest merge strategy: ```xml theme={null} ``` The SDK requests the `CAMERA` permission at runtime before the camera is used. Your app does not need to request it separately. *** ## Quick Start ### 1 — Register the result launcher In your `Activity` or `Fragment`: ```kotlin theme={null} import androidx.activity.result.contract.ActivityResultContracts import com.smartcomply.sdk.ui.SmartComplyActivity import com.smartcomply.sdk.types.FlowResult val verificationLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> val data = result.data ?: return@registerForActivityResult when (data.getStringExtra(SmartComplyActivity.RESULT_TYPE)) { SmartComplyActivity.TYPE_SUCCESS -> { val entryId = data.getIntExtra(SmartComplyActivity.RESULT_ENTRY_ID, -1) val status = data.getStringExtra(SmartComplyActivity.RESULT_STATUS) val verifiedName = data.getStringExtra(SmartComplyActivity.RESULT_VERIFIED_NAME) val idTypeName = data.getStringExtra(SmartComplyActivity.RESULT_ID_TYPE_NAME) // handle success } SmartComplyActivity.TYPE_FAILURE -> { val errorMsg = data.getStringExtra(SmartComplyActivity.RESULT_ERROR_MSG) // handle error } SmartComplyActivity.TYPE_CANCELLED -> { // user pressed back } } } ``` ### 2 — Launch verification ```kotlin theme={null} import com.smartcomply.sdk.client.Environment import java.util.UUID val intent = SmartComplyActivity.buildIntent( from = this, apiKey = "pk_live_xxxxxxxxxxxx", // your SmartComply API key clientId = UUID.randomUUID().toString(), // unique per verification attempt environment = Environment.PRODUCTION ) verificationLauncher.launch(intent) ``` ### Jetpack Compose If you are launching from a composable, use `rememberLauncherForActivityResult`: ```kotlin theme={null} import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.runtime.rememberCoroutineScope import com.smartcomply.sdk.ui.SmartComplyActivity import com.smartcomply.sdk.client.Environment import java.util.UUID @Composable fun StartVerificationButton() { val context = LocalContext.current val launcher = rememberLauncherForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> val data = result.data ?: return@rememberLauncherForActivityResult when (data.getStringExtra(SmartComplyActivity.RESULT_TYPE)) { SmartComplyActivity.TYPE_SUCCESS -> { /* handle success */ } SmartComplyActivity.TYPE_FAILURE -> { /* handle error */ } SmartComplyActivity.TYPE_CANCELLED -> { /* user cancelled */ } } } Button(onClick = { val intent = SmartComplyActivity.buildIntent( from = context, apiKey = "pk_live_xxxxxxxxxxxx", clientId = UUID.randomUUID().toString(), environment = Environment.PRODUCTION ) launcher.launch(intent) }) { Text("Verify Identity") } } ``` *** ## buildIntent Parameters ```kotlin theme={null} fun buildIntent( from: Context, apiKey: String, clientId: String, darkTheme: Boolean? = null, // null = follow system environment: Environment = Environment.PRODUCTION ): Intent ``` | Parameter | Default | Description | | ------------- | ------------ | -------------------------------------------------------------------------------- | | `from` | — | The calling `Context` | | `apiKey` | — | Your SmartComply API key — find it in the Dashboard | | `clientId` | — | A unique ID per verification attempt — use `UUID.randomUUID().toString()` | | `darkTheme` | `null` | `true` forces dark mode, `false` forces light, `null` follows the device setting | | `environment` | `PRODUCTION` | `PRODUCTION` for live verification, `SANDBOX` for testing | *** ## Result Extras Read from the `Intent` returned to your activity result callback. | Constant | Type | Present when | | ---------------------- | -------- | ------------------------------------------------------------------- | | `RESULT_TYPE` | `String` | Always — `"success"`, `"failure"`, or `"cancelled"` | | `RESULT_ENTRY_ID` | `Int` | `TYPE_SUCCESS` | | `RESULT_STATUS` | `String` | `TYPE_SUCCESS` — e.g. `"submitted"`, `"verified"` | | `RESULT_SUBMITTED_AT` | `String` | `TYPE_SUCCESS` — ISO 8601 timestamp | | `RESULT_VERIFIED_NAME` | `String` | `TYPE_SUCCESS` — full name from the identity provider, if available | | `RESULT_ID_TYPE_NAME` | `String` | `TYPE_SUCCESS` — e.g. `"National ID"`, `"BVN"` | | `RESULT_ERROR_MSG` | `String` | `TYPE_FAILURE` | *** ## Verification Flow The SDK steps through these states automatically. | Step | Description | | ----------------- | -------------------------------------------------------------------- | | Loading | Session creation and brand config fetch | | Welcome | Brand splash, country picker, and ID type selection | | Camera Permission | Requests camera permission at runtime before any camera is opened | | Document Capture | Camera view for the front (and back, if required) of the ID document | | ID Input | Form fields for data-mode verification (BVN, NIN, etc.) | | Liveness | Live camera challenge — blink, turn head | | Processing | Upload and backend verification in progress | | Success | Verification complete — shows a summary card, then calls back | | Failure | Unrecoverable error — shows the message and a retry button | *** ## SDK Configuration ```kotlin theme={null} data class SDKConfig( val apiKey: String, val clientId: String, val environment: Environment = Environment.PRODUCTION, val requestTimeoutMs: Long = 30_000L, val uploadTimeoutMs: Long = 120_000L, val maxUploadRetries: Int = 3, val debug: Boolean = false ) ``` | Parameter | Default | Description | | ------------------ | ------------ | --------------------------------------------------------- | | `apiKey` | — | Your SmartComply API key (required) | | `clientId` | — | Unique identifier per verification attempt (required) | | `environment` | `PRODUCTION` | `SANDBOX` for testing, `PRODUCTION` for live verification | | `requestTimeoutMs` | `30000` | Timeout in milliseconds for standard API calls | | `uploadTimeoutMs` | `120000` | Timeout in milliseconds for video upload | | `maxUploadRetries` | `3` | Automatic retry attempts on upload failure | | `debug` | `false` | Prints verbose network logs to Logcat when `true` | *** ## Error Handling `SmartComplyActivity` handles and displays all error states automatically. Common scenarios: | Scenario | Cause | Resolution | | -------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------- | | `TYPE_FAILURE` with `"401"` | Invalid or missing API key | Check your key in the SmartComply Dashboard | | `TYPE_FAILURE` — session expired | Session tokens have a 30-minute TTL | Generate a new `clientId` on the next launch | | `TYPE_CANCELLED` | User pressed back | Re-launch when the user is ready to retry | | Upload failed | Network instability | The built-in failure screen offers a retry; if retries are exhausted `TYPE_FAILURE` is returned | *** ## Advanced: Custom Host Activity If you need to embed the verification flow directly inside your own `ComponentActivity` instead of launching a separate screen, you can use `SmartComplyFlowScreen` as a Compose composable: ```kotlin theme={null} import com.smartcomply.sdk.SmartComply import com.smartcomply.sdk.client.SDKConfig import com.smartcomply.sdk.client.Environment import com.smartcomply.sdk.ui.SmartComplyFlowScreen import java.util.UUID val sdk = SmartComply( SDKConfig( apiKey = "pk_live_xxxxxxxxxxxx", clientId = UUID.randomUUID().toString(), environment = Environment.PRODUCTION ) ) // In your composable: SmartComplyFlowScreen( sdk = sdk, darkTheme = null, // null = follow system setting onComplete = { result -> // result.entryId, result.status, result.verifiedName, etc. }, onError = { message -> // unrecoverable error not handled by the built-in failure screen } ) ``` Your host `Activity` must be a `ComponentActivity` and must be in the foreground with an active window. Embedding `SmartComplyFlowScreen` inside a `Dialog` or bottom sheet will cause the camera to fail on some devices. *** ## ProGuard / R8 The SDK ships with its own consumer ProGuard rules. If you see obfuscation-related issues, add to your `proguard-rules.pro`: ``` -keep class com.smartcomply.sdk.** { *; } -keepattributes *Annotation* ``` # iOS SDK Source: https://docs.smartcomply.com/libraries/ios_sdk Integrate SmartComply identity verification and liveness detection into your iOS app with a single drop-in SwiftUI view. # SmartComply iOS SDK The SmartComply iOS SDK is a native Swift library that delivers a fully self-contained identity verification flow for iOS apps. Drop in one SwiftUI view and the SDK handles session management, country and ID-type selection, document capture, identity verification, and liveness detection automatically. ## Features * **Drop-in SwiftUI view** — `SmartComplyFlowView` manages the entire verification flow with no UI code required * **Two verification modes** — document photo capture or ID number data entry, configured from your Dashboard * **Guide-box document capture** — crops exactly what falls inside the ID card frame so the image sent to the backend is always clean * **Liveness detection** — face challenge system (blink, turn head) runs automatically after identity verification * **Dynamic ID types** — channels and fields are fetched live from your Dashboard configuration * **Multi-country support** — renders a country picker automatically when more than one country is configured * **Dark and light mode** — theme adapts to the system colour scheme; override with `preferredColorScheme` * **Automatic retry** — handles upload retries and session errors internally *** ## Requirements * **iOS 16.0** or later * **Swift 5.9** or later * **Xcode 15** or later * **iPhone X or later** — liveness detection requires a front-facing TrueDepth camera *** ## Installation The SDK is distributed via Swift Package Manager. ### Xcode (recommended) 1. Open your project in Xcode 2. Go to **File → Add Package Dependencies** 3. Enter the repository URL: `https://github.com/386konsult/ios-sdk` 4. Select **Exact Version** and enter `1.0.0` 5. Click **Add Package** and select the **SmartComplySDK** library ### Package.swift ```swift theme={null} dependencies: [ .package(url: "https://github.com/386konsult/ios-sdk", exact: "1.0.0") ], targets: [ .target( name: "YourApp", dependencies: [ .product(name: "SmartComplySDK", package: "ios-sdk") ] ) ] ``` *** ## Platform Setup Add the following key to your app's `Info.plist`: ```xml theme={null} NSCameraUsageDescription Camera access is required to photograph your ID document and complete liveness verification. ``` *** ## Quick Start ### 1. Create the SDK instance Create a `SmartComply` instance once — for example in your view model or app entry point. Generate a fresh `clientId` (UUID) for each new verification attempt. ```swift theme={null} import SmartComplySDK let sdk = SmartComply( config: SDKConfig( apiKey: "pk_live_xxxxxxxxxxxx", clientId: UUID().uuidString, // unique per verification attempt environment: .production ) ) ``` ### 2. Present the flow view Embed `SmartComplyFlowView` anywhere in your SwiftUI hierarchy. The SDK loads automatically when the view appears. ```swift theme={null} import SmartComplySDK struct ContentView: View { @State private var showVerification = false let sdk = SmartComply(config: SDKConfig(apiKey: "pk_live_...", clientId: UUID().uuidString)) var body: some View { Button("Verify Identity") { showVerification = true } .fullScreenCover(isPresented: $showVerification) { SmartComplyFlowView(sdk: sdk) { result in showVerification = false print("Entry ID:", result.entryId) print("Status:", result.status) if let name = result.verifiedName { print("Verified name:", name) } } } } } ``` The SDK manages the entire flow automatically. The exact steps depend on the verification mode configured in your Dashboard: **Document mode** (photo capture): 1. Creates a secure session 2. Displays a welcome screen with your brand name and ID type cards 3. Shows a country picker if multiple countries are configured 4. User photographs the front of their ID inside the guide box 5. Photographs the back if required (National ID, Driver's Licence, Voter's Card) 6. Runs liveness face challenges 7. Returns a `FlowResult` to your completion handler **Data mode** (ID number entry): 1. Creates a secure session 2. Displays a welcome screen with ID type selection 3. Shows a country picker if multiple countries are configured 4. User enters their ID number and any required fields 5. Identity is verified against the national database 6. Runs liveness face challenges 7. Returns a `FlowResult` to your completion handler *** ## SDK Configuration ```swift theme={null} public struct SDKConfig { public init( apiKey: String, clientId: String, environment: SDKEnvironment = .sandbox, requestTimeout: TimeInterval = 30, // seconds uploadTimeout: TimeInterval = 120, // seconds maxUploadRetries: Int = 3, debug: Bool = false ) } ``` | Parameter | Default | Description | | ------------------ | ---------- | --------------------------------------------------------------------------------- | | `apiKey` | — | Your SmartComply API key (required) | | `clientId` | — | A unique identifier per verification attempt — use `UUID().uuidString` (required) | | `environment` | `.sandbox` | `.sandbox` for testing; `.production` for live traffic | | `requestTimeout` | `30` | Timeout in seconds for standard API calls | | `uploadTimeout` | `120` | Timeout in seconds for video upload | | `maxUploadRetries` | `3` | Number of automatic retry attempts on upload failure | | `debug` | `false` | Prints verbose network logs to the console when `true` | *** ## FlowResult Delivered to your `onComplete` closure when the user completes the flow in-app. ```swift theme={null} public struct FlowResult { public let entryId: Int // liveness entry ID — use this to query results via the API public let status: String // e.g. "submitted" public let submittedAt: String? // ISO 8601 timestamp public let idTypeName: String? // e.g. "National ID", "BVN" public let verifiedName: String? // name returned by the identity provider (data mode only) } ``` > **Final verification results are delivered via webhook.** Once the backend completes processing, SmartComply sends a webhook event to the URL configured in your Dashboard. Set up your webhook endpoint to receive the final status, extracted fields, and any failure reasons. See the [Webhooks](/webhooks) guide for the full payload reference. *** ## Error Handling `SmartComplyFlowView` handles and displays error states automatically. For the headless API, all SDK methods throw on failure: ```swift theme={null} do { _ = try await sdk.createSession() } catch let error as SDKError { print("API error \(error.statusCode):", error.message) } catch { print("Network error:", error.localizedDescription) } ``` | Scenario | Cause | Resolution | | --------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------- | | `401 Unauthorized` | Invalid or missing API key | Check your key in the SmartComply Dashboard | | Session expired | Sessions expire after 2 hours and are single-use | Generate a new `clientId` and call `createSession()` again | | Camera permission denied | User denied camera access | The flow view shows a Settings deep-link automatically | | Upload failed after retries | Network instability | `maxUploadRetries` exhausted — the failure screen offers a retry | | Identity not found | ID number not found or details mismatched (data mode) | User is shown the reason and prompted to re-enter | # Postman Collection Source: https://docs.smartcomply.com/libraries/postman Import the Adhere API Postman collection to test endpoints without writing code. The Adhere Postman collection contains every API endpoint pre-configured with the correct URL, headers, and example request bodies. It's the fastest way to explore the API and test calls before integrating. ## Import the Collection Download and open [Postman](https://www.postman.com/downloads/) if you haven't already. Click the link below to open the collection in Postman directly: **[Open Adhere API in Postman →](https://documenter.getpostman.com/view/55164637/2sBXwjxET7)** Or copy the collection URL and use **File → Import → Link** inside Postman. In Postman, go to the collection's **Variables** tab and set `x-access-token` to your Adhere API key. Your API key is available in the [Adhere dashboard](https://adhere-app.smartcomply.com). Pick any endpoint from the collection, check the pre-filled body, and click **Send**. ## Collection Structure The collection mirrors the API reference and is organised by product area: | Folder | What's inside | | ---------------------------------- | ------------------------------------------------------------------------------------------ | | **Nigeria KYC** | BVN, NIN, VNIN, CAC, Driver's License, Passport, NUBAN, TIN, Voter's ID, Phone, Address | | **Kenya KYC** | National ID (basic & advanced), Business Registration, Alien ID, KRA PIN, Passport | | **Ghana KYC** | ID Card, ID Card with Face | | **Rwanda KYC** | National ID, Passport | | **Uganda KYC** | National ID | | **Biometrics** | Face Comparison, Face Liveness | | **Credit Reports** | CRC, First Central, Credit Registry (individual & business), Kenya credit | | **Fraud & Transaction Monitoring** | Transaction monitoring, card fraud, transaction screening, KYC search, limits & thresholds | | **Loan Fraud Check** | Individual and business fraud checks | | **User Journey** | Session events, session state, analytics, health check | ## Authentication All requests require the `x-access-token` header. Set it once at the collection level so it applies to every request automatically: 1. Click the collection name → **Edit** 2. Go to the **Variables** tab 3. Add a variable named `x-access-token` with your API key as the value 4. In each request's **Headers** tab, the header is already set to `{{x-access-token}}` Never share your API key publicly or commit it to source control. Use Postman environment variables to keep it out of shared workspaces. ## Base URL All endpoints in the collection use: ``` https://adhere-api.smartcomply.com ``` # Web SDK Source: https://docs.smartcomply.com/libraries/smartcomply_sdk Integrate Adhere identity verification and liveness detection into your web applications using the SmartComply Web SDK. # Adhere Web SDK The Adhere Web SDK enables you to rapidly and securely verify user identities and perform facial liveness checks directly in your web applications. The SDK mounts a drop-in widget over your application, handling document capture, identity verification, and liveness detection — all in one seamless flow. ## Features * **Drop-in UI Modal** — Responsive, animated widget that overlays your app via `SmartComplyFlow.open()`. * **CDN & npm Support** — Install via npm/yarn or load directly from a CDN with zero build steps. * **Dynamic Routing** — Automatically adapts document and verification requirements from your dashboard configuration. * **Single-Use Sessions** — `clientId` is your permanent integration key (from your SDK Config) and is reused for every session. Each `createSession()` call issues a fresh, single-use session token — that token, not the `clientId`, is what's scoped to one verification. * **Nigeria & Global Identity** — Supports BVN, NIN, passports, driver's licenses, voter's cards, and other document/data channels enabled in your dashboard. * **Two-Sided Document Capture** — Front is always required; back is required, optional, or not offered depending on the document type (e.g. NIN is optional-back, since not every physical NIN document has a usable reverse side). * **Hardware Agnostic Liveness** — Uses native webcam and MediaRecorder API for cross-platform compatibility. A single passive scan (blink + natural head movement) — no discrete step-by-step prompts. *** ## Installation ### Option 1 — CDN (No build step required, recommended) Add the script tag to your HTML: ```html theme={null} ``` The SDK is available globally as `window.SmartComplySDK`: ```javascript theme={null} const { SmartComplyFlow, SmartComply } = window.SmartComplySDK; ``` `@1` always resolves to the latest `1.x.x` release — bug fixes and new features reach your site automatically the moment we publish them, with **no code change on your end, ever**. We commit to never shipping a breaking change as a `1.x` release; if a breaking change is ever needed, it ships as `2.0.0`, and `@1` keeps serving the last safe `1.x` release until you deliberately opt in. This is the same versioning model used by most public JS SDKs (Stripe.js, Google Maps, etc.). Other CDN options: ```html theme={null} ``` `@1`/`@latest` re-resolve on **every page load** — that's what makes them self-updating, with no rebuild or redeploy needed on your side. An exact `@X.Y.Z` pin never moves until you manually change the number in your script tag. See [npmjs.com/package/smartcomply-web-sdk](https://www.npmjs.com/package/smartcomply-web-sdk) for release history. ### Option 2 — npm / yarn ```bash theme={null} npm install smartcomply-web-sdk # or yarn add smartcomply-web-sdk ``` ```javascript theme={null} import { SmartComplyFlow } from 'smartcomply-web-sdk'; ``` Unlike the CDN, npm has no auto-updating option — this is true for every npm package, not specific to ours. `npm install` resolves to the latest version **at the moment you run it**, then locks that exact version in `package-lock.json` (or `yarn.lock`); it will not change again on its own. Run `npm update smartcomply-web-sdk` periodically (or before each deploy) to pick up new fixes — this stays within the `^1.0.x` range already set in your `package.json`, and we commit to never shipping a breaking change within `1.x`, so it's always safe to run. Check [npmjs.com/package/smartcomply-web-sdk](https://www.npmjs.com/package/smartcomply-web-sdk) for the current version number. *** ## Quick Start — Drop-in Widget (Recommended) The easiest way to integrate is the drop-in widget. It handles the complete verification flow automatically. ```javascript theme={null} SmartComplyFlow.open({ apiKey: "your_api_key_here", clientId: "your_client_id_here", environment: "production", // sandbox is not currently available onComplete: (result) => { console.log("Verification complete:", result); // result = { entryId, sessionId, status, submittedAt } }, onError: (error) => { console.error("Verification failed:", error); }, onClose: () => { console.log("Widget closed."); } }); ``` Get your **API Key** and **Client ID** from your [Adhere Dashboard](https://adhere.smartcomply.com) — both come from your SDK Config and are permanent; reuse the same values for every session. What's single-use is the *session token* the SDK obtains internally via `createSession()` (30-minute expiry, revoked after submission) — you never see or manage that token directly through the drop-in widget. ### Configuration Parameters | Parameter | Type | Required | Description | | ------------- | -------- | -------- | -------------------------------------------------------------------------------------------------- | | `apiKey` | string | ✅ Yes | Your API key from the Adhere Dashboard | | `clientId` | string | ✅ Yes | Your permanent client ID from the Adhere Dashboard (SDK Config) — the same value for every session | | `environment` | string | No | `"production"` (default) | | `onComplete` | function | No | Callback fired when verification completes successfully | | `onError` | function | No | Callback fired on error | | `onClose` | function | No | Callback fired when the widget is closed | `sandbox` is not currently available — use `"production"` for all integration and testing today. This section will be updated once sandbox is back. ### Environment URLs | Environment | Base URL | | ------------ | ------------------------------------ | | `production` | `https://adhere-api.smartcomply.com` | *** ## Framework Examples ### React ```jsx theme={null} import { SmartComplyFlow } from 'smartcomply-web-sdk'; export default function VerifyButton() { const handleVerify = () => { SmartComplyFlow.open({ apiKey: process.env.REACT_APP_API_KEY, clientId: process.env.REACT_APP_CLIENT_ID, environment: "production", onComplete: (result) => console.log("Done:", result), onError: (err) => console.error("Error:", err), }); }; return ; } ``` ### Vue ```vue theme={null} ``` ### Plain HTML (CDN) ```html theme={null} ``` *** ## Headless API (Advanced) For full control over the UI, use the `SmartComply` class directly without the modal. ```typescript theme={null} import { SmartComply } from 'smartcomply-web-sdk'; const sdk = new SmartComply({ apiKey: "your_api_key_here", clientId: "your_client_id_here", environment: "production", }); const run = async () => { // 1. Create a session — sessions last 30 minutes and are single-use // (revoked as soon as liveness is submitted) await sdk.createSession(); // 2. Fetch SDK configuration — brand, theme, and available channels per country const config = await sdk.initializeConfig(); console.log("Verification type:", config.verification_type); console.log("Channels:", config.channels); // config.channels["nigeria"] is an array of: // { id, name, code?, requires_back_side?: boolean | "optional", fields: [...] } // 3a. Data verification (BVN/NIN/etc.) — validates against the government database const verifyResult = await sdk.onboarding.verify({ identity_type_id: 1, // channel id from config.channels fields: { bank_verification_number: "12345678901" } }); const identityCheckId = verifyResult.data?.identity_check_id; // 3b. Document verification — capture front (and back, if the channel's // requires_back_side is true or "optional") instead of step 3a. // const documentFront: Blob = /* from a file input or camera capture */; // const documentBack: Blob | undefined = /* only if the channel needs/offers one */; // 4. Run liveness check — requires an HTMLElement container for the camera. // Runs a single passive scan (blink + natural head movement); the // 3rd argument is a descriptive tag for your dashboard, not a live // prompt sequence the UI steps through. const container = document.getElementById("camera-container") as HTMLElement; const liveness = await sdk.liveness.startCheck( container, { identifier: "12345678901", identifier_type: "bvn", country: "NG", identity_check: identityCheckId, // link to the data-verification result above // document: documentFront, // for document verification instead // document_back: documentBack, }, ["BLINK", "TURN_HEAD"] ); console.log("Liveness status:", liveness.status); // "processing" — final // pass/fail result arrives via webhook, not this return value. }; run(); ``` *** ## onComplete Payload `onComplete` fires as soon as the user finishes their part of the flow (the "Verification Submitted" screen renders) — it is a **submission receipt, not a verification verdict**. Backend processing (face match, document read, government DB check) continues after this fires, and `status` is always `"processing"` here regardless of the eventual outcome. The real pass/fail result only ever arrives via [webhook](#receiving-results-webhook). ```json theme={null} { "entryId": 365, "sessionId": "da7623bd-9158-4b56-a9e4-4bccf3c0133f", "status": "processing", "submittedAt": "2026-06-05T23:11:22.873161+00:00", "verificationResult": { "status": "success", "code": "VERIFICATION_COMPLETE", "data": { "first_name": "Amara", "last_name": "Okafor", "identity_check_id": 123 } } } ``` `verificationResult` is only present for **data verification** (BVN/NIN) — it's the immediate government-database lookup result confirming the ID number matched a real record. It says nothing about the face match, which is still pending. It's absent for document verification and liveness-only flows. *** ## Receiving Results (Webhook) The backend delivers exactly one `liveness.completed` webhook per verification, to the URL configured in your SDK Config, once face matching (and OCR / government DB check, depending on the flow) has finished. This is the SDK's own webhook — configured per SDK Config and specific to `liveness.completed`. It's separate from the platform-wide webhook system described in [Webhooks](/webhooks) (transaction monitoring, general KYC module events, `{success, module, event, data}` shape). Both currently sign with HMAC-SHA256 and a `sha256=`-prefixed header, hex-encoded — verify against the raw request body either way. ### Payload shape ```json theme={null} POST https://your-server.com/webhook Content-Type: application/json X-Adhere-Signature: sha256= { "event": "liveness.completed", "verification_id": 42, "verification_type": "data_verification", "status": "passed", "failure_reason": null, "timestamp": "2026-08-08T10:15:00.000Z", "subject": { "identifier": "12345678901", "identifier_type": "National Identity Number (NIN)", "country": "nigeria" }, "biometrics": { "liveness_verified": true, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 70.0 }, "selfie_url": "https://.../autoshot.jpg", "face_analysis": { "gender": "Female", "dominant_emotion": "neutral", "face_quality": { "face_detected": true, "face_confidence": 0.98, "blur_score": 142.3, "is_blurry": false } } }, "activity": { "session_id": "da7623bd-9158-4b56-a9e4-4bccf3c0133f", "started_at": "2026-08-08T10:12:00.000Z", "submitted_at": "2026-08-08T10:14:30.000Z", "completed_at": "2026-08-08T10:15:00.000Z", "duration_seconds": 180 }, "request_context": { "ip": { "address": "102.67.1.66", "city": "Lagos", "country_code": "NG" }, "device": { "user_agent": "Mozilla/5.0 ...", "type": "desktop", "os": "Windows" } }, "customer_profile": { "first_name": "AMARA", "last_name": "OKAFOR", "other_name": null, "date_of_birth": "01-Jan-1997", "age": 29, "gender": "Female", "id_number": "12345678901", "serial_number": null, "occupation": null, "place_of_birth": null, "place_of_live": "...", "date_of_issue": null, "photo_url": null } } ``` For **document verification**, the same top-level shape applies, with `verification_type: "document_verification"` and a `document` block (OCR fields + document-to-selfie face match) instead of `customer_profile`: ```json theme={null} "document": { "status": "verified", "document_type": "passport", "is_expired": false, "first_name": "AMARA", "last_name": "OKAFOR", "date_of_birth": "1997-01-01", "age": 29, "gender": "Female", "nationality": "NGA", "document_number": "A12345678", "expiry_date": "2030-06-15", "issue_date": "2020-06-15", "issuing_authority": "...", "document_url": "https://.../document.jpg", "document_back_url": null, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 55.0, "threshold_percentage": 35.0, "reason": null, "selfie_url": "https://.../autoshot.jpg", "document_face_url": "https://.../document_face.jpg" } } ``` `document` also carries `place_of_birth`, `place_of_issue`, `address`, `district`, `division`, `location`, `sub_location`, `serial_number`, and `barcode_number` — `null` unless the specific document type carries that field (e.g. serial/barcode numbers mainly apply to newer Kenyan ID cards). `face_match.reason` is populated with a user-facing explanation when `verified` is `false` or the match was skipped. `status: "passed"` means **the check ran to completion — not that the person matched**. A face mismatch, low confidence score, or expired document still reports `status: "passed"`, with the real outcome recorded in `biometrics.face_match.verified` (and `document.is_expired` for document verification). `status: "failed"` is reserved for cases where the check itself couldn't run (service error, no selfie captured, government DB rejection). Never gate access on `status` alone — always check `face_match.verified`. `verification_id` matches the `entryId` your `onComplete` callback received. ### Verify the signature The signature header is `X-Adhere-Signature: sha256=` — note the `sha256=` prefix. It's computed over the exact compact-JSON bytes of the request body, so your handler must verify against the **raw body**, not a re-serialized copy of the parsed JSON (re-stringifying can produce different bytes and the signature will never match). ```javascript theme={null} const crypto = require("crypto"); app.post( "/webhook/smartcomply", express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }), (req, res) => { const signature = (req.headers["x-adhere-signature"] || "").replace(/^sha256=/, ""); const secret = process.env.WEBHOOK_SECRET.replace(/-/g, ""); const expected = crypto.createHmac("sha256", secret).update(req.rawBody).digest("hex"); const isValid = signature.length === expected.length && crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex")); if (!isValid) return res.status(401).send("Bad signature"); const { event, verification_id, status, biometrics, document } = req.body; // status === "passed" only means the check ran to completion — check // the real outcome before treating the user as verified: const faceMatched = biometrics?.face_match?.attempted ? biometrics.face_match.verified === true : true; // not attempted (e.g. NIN slip, CAC) — nothing to fail here const documentOk = document ? document.is_expired === false : true; if (event === "liveness.completed" && status === "passed" && faceMatched && documentOk) { markUserAsVerified(verification_id); } else if (event === "liveness.completed") { recordVerificationOutcome(verification_id, req.body); } res.json({ received: true }); } ); ``` *** ## Security Notes * **Client ID** — Permanent, from your SDK Config. Reuse the same `clientId` for every session — there's no per-session ID to generate. * **API Key** — Never expose your API key in client-side code in production. Use environment variables. * **Session Tokens** — The single-use part. Automatically obtained and managed by the SDK per verification via `createSession()`, expire after 30 minutes, and are revoked immediately once liveness is submitted. *** ## Troubleshooting | Error Code | HTTP | Cause | Fix | | ---------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | `INVALID_API_KEY` | 401 | Bad or missing `apiKey` | Check your `apiKey` value in the SDK Config | | `SDK_CONFIG_NOT_FOUND` | 404 | Invalid `clientId` | Check your `clientId` value — it should be the UUID from your SDK Config, not regenerated per session | | `INVALID_SESSION` | 401 | Session token missing, malformed, expired (30 min), or already revoked (a session is single-use — it's consumed once liveness is submitted) | Call `createSession()` again to get a fresh token; `clientId`/`apiKey` stay the same | | `VALIDATION_ERROR` | 400 | Missing or invalid fields in the request | Check `data.errors` in the response for which field failed | | `RETRY_LIMIT_EXCEEDED` | 429 | User exceeded the retry limit for confirmation/liveness attempts | The user must restart with a new session | | `INSUFFICIENT_BALANCE` | 402 | Wallet balance too low | Top up your wallet in the dashboard | | `Camera not available` | — | Browser blocked camera access | Ensure HTTPS and camera permissions are granted | # Account & Identity Verification Source: https://docs.smartcomply.com/pages/account_verification How to use Adhere to verify customer identities and bank accounts at onboarding. Verifying that a customer is who they claim to be — and that the bank account they provide is theirs — is the foundation of safe onboarding. Adhere gives you the tools to do this digitally, in seconds, without asking for paper documents. ## Confirm Identity Before Onboarding Use Nigeria's BVN or NIN to instantly confirm a customer's name, date of birth, and phone number against the central identity database. For Kenya, Ghana, Rwanda, and Uganda, verify against national ID and passport records. Verify an 11-digit Bank Verification Number and return the holder's full name, phone, and date of birth. Confirm identity against Nigeria's National Identity Number database. Verify Kenyan customers using their national ID number. Verify Ghana Card, Passport, Voter ID, SSNIT, or Driver's License numbers. ## Verify the Bank Account Belongs to Them Before disbursing funds or setting up a direct debit, confirm that the account number the customer provided is linked to their identity. Look up any Nigerian bank account number and return the account holder's name — so you can confirm it matches your customer's identity before processing any payment. ## Add a Biometric Layer For higher-risk onboarding flows, add a liveness check or face match to confirm the person presenting the ID is physically present. Compare a selfie against a reference image to confirm the same person. Detect whether the face in a submitted image is live, not a photo or video replay. ## Reduce Drop-Off Without Sacrificing Compliance Because every check returns a result in real time, your onboarding flow stays fast. Customers verify in the same session — no manual review queues, no document uploads, no back-and-forth. A typical verified onboarding flow looks like this: Ask the customer for their BVN, NIN, or national ID number — no document scan needed. Call the relevant Adhere endpoint. The response returns verified name, date of birth, and phone number within seconds. Call NUBAN verification to confirm the account number matches the verified name. For regulated or high-value flows, add a face liveness or comparison check before approval. # Lending & Loan Decisioning Source: https://docs.smartcomply.com/pages/lending How to use Adhere to verify borrowers, pull credit history, and detect fraudulent loan applications. Lending decisions depend on two things: knowing the borrower is real, and knowing they can repay. Adhere gives you both — identity verification, credit bureau data, and AI-driven fraud scoring — through a single API. ## Verify the Borrower's Identity First Before pulling any credit data, confirm the applicant is who they say they are. Use BVN, NIN, or national ID verification to match the submitted details against authoritative government records. Confirm name, phone, and date of birth against the Bank Verification Number registry. Verify the applicant's National Identity Number before processing their application. ## Pull Their Credit History Adhere connects to CRC, First Central, and Credit Registry — Nigeria's major credit bureaus — so you can retrieve a full picture of the applicant's borrowing history before making a decision. Number of loans, active facilities, delinquencies, and total outstanding balance from CRC. Summary-level credit data from First Central Credit Bureau. Detailed credit report including payment history and institution breakdown. Numeric credit score from First Central or CRC to feed directly into your decisioning model. ## Run a Loan Fraud Check The Loan Fraud Check endpoint combines the submitted application data with credit bureau information to produce a fraud risk score (0–100), a repayment assessment, and a recommendation — for both individual and business applicants. Score an individual application using income, employment, collateral, and credit history data. Assess a business loan application using company registration, revenue, and credit data. ## A Complete Lending Due-Diligence Flow Call BVN or NIN verification to confirm the applicant's name and date of birth match what they submitted. Retrieve a credit summary or full report from the bureau of your choice. Check for delinquencies, active loans, and total exposure. Submit the full application to the Loan Fraud Check endpoint. Receive a fraud risk score, key financial ratios, and a plain-language recommendation. Use the score against your risk threshold to approve, review, or decline — with a full audit trail from each API call. # Quickstart Source: https://docs.smartcomply.com/quickstart Make your first Smartcomply API call in under 5 minutes. ## Prerequisites Before you start, make sure you have: * A Smartcomply account — [sign up here](https://adhere-app.smartcomply.com/signup) * Completed your business KYC on the Adhere dashboard * Generated a secret key under **Settings → API Keys** ## Make Your First Request The example below verifies a Nigerian BVN. Replace `YOUR_SECRET_KEY` with your actual key. ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22000000001"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ bvn: "22000000001" }), } ); const data = await response.json(); console.log(data); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"bvn": "22000000001"}, ) print(response.json()) ``` ## Successful Response ```json theme={null} { "status": "success", "data": { "lastName": "OMOLE", "firstName": "ABRAHAM", "middleName": "ISAAC", "dateOfBirth": "1909-09-19", "phoneNumber1": "09011001100" }, "message": "Bank Verification Number details retrieved successfully" } ``` If you receive a `401`, check that your `x-access-token` header is set correctly. For a full list of error responses, see [Error Codes](/error_codes). ## Next Steps Learn how to secure and manage your API keys. Explore all identity verification endpoints. Understand all possible error responses. Set up real-time event notifications. # Face Comparison Source: https://docs.smartcomply.com/v3/biometrics/face_comparism POST /api/onboarding/biometrics/face/comparison Compare two face images to determine whether they belong to the same person. The Face Comparison endpoint uses biometric analysis to compare two face images and returns a confidence score indicating whether they depict the same individual. Use this for identity verification during onboarding or transaction approval. ## Endpoint ``` POST /api/onboarding/biometrics/face/comparison ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------------------- | | `image_url` | string | Yes | URL of the reference ID photo or database face image | | `selfie_url` | string | Yes | URL of the live selfie to compare against the reference | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/biometrics/face/comparison" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "image_url": "https://example.com/id_photo.jpg", "selfie_url": "https://example.com/selfie.jpg" }' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/biometrics/face/comparison", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ image_url: "https://example.com/id_photo.jpg", selfie_url: "https://example.com/selfie.jpg", }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/biometrics/face/comparison", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={ "image_url": "https://example.com/id_photo.jpg", "selfie_url": "https://example.com/selfie.jpg", }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | -------------------- | ------- | ------------------------------------------------- | | `data.status` | boolean | `true` if the faces match, `false` if they do not | | `data.response_code` | string | `"00"` indicates a successful comparison | | `data.message` | string | Human-readable match result | | `data.confidence` | integer | Match confidence percentage (0–100) | ```json theme={null} { "status": "success", "data": { "status": true, "response_code": "00", "message": "Face Match", "confidence": 100 }, "message": "Face comparison completed successfully" } ``` A `data.status` of `false` indicates the faces do not match. Use `data.confidence` to apply your own threshold for acceptance (e.g., require `>= 80` for a positive match). ### 400 Bad Request Returned when one or both image URLs are missing, inaccessible, or do not contain a detectable face. ```json theme={null} { "status": "failed", "data": [], "message": "Could not process one or both images" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Face Liveness Check Source: https://docs.smartcomply.com/v3/biometrics/face_liveliness POST /api/onboarding/biometrics/face/liveliness_check/ Verify that a submitted facial image belongs to a live person, not a photograph or pre-recorded video. The Face Liveness Check endpoint analyzes a live selfie video to confirm physical presence. It runs blink and motion analysis on the video to distinguish a real user from a photograph or pre-recorded video, then compares the face in the video to the face in the same video. For true liveness detection, send a selfie video. Sending a static image will perform a self-comparison, not a liveness check. ## Endpoint ``` POST /api/onboarding/biometrics/face/liveliness_check/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------- | | `image` | string | Yes | URL of the live selfie **video** to check for liveness. Supported formats: `.mp4`, `.mov`, `.webm`, `.avi`, `.m4v`. | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/biometrics/face/liveliness_check/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"image": "https://example.com/selfie_liveness.mp4"}' ``` A static image (e.g. `.jpg` or `.png`) will be processed in comparison mode against itself, so it will always appear to pass. For real liveness detection, send a selfie video captured by the user. ## Response ### 200 OK | Field | Type | Description | | ------------------------------- | ------- | ---------------------------------------------- | | `data.status` | boolean | `true` if liveness detected, `false` otherwise | | `data.detail` | string | Human-readable liveness result | | `data.response_code` | string | `"00"` indicates success | | `data.confidence` | number | Raw confidence score (0–1) | | `data.confidence_in_percentage` | number | Confidence as a percentage | | `data.verification.status` | string | `"VERIFIED"` or `"FAILED"` | | `data.verification.reference` | string | Unique reference for this check | ```json theme={null} { "status": "success", "data": { "status": true, "detail": "Liveliness Detected", "response_code": "00", "confidence": 0.9999987030029297, "confidence_in_percentage": 99.99987030029297, "verification": { "status": "VERIFIED", "reference": "067cbed9-acda-4d30-97c2-7f8e0c2ad687" }, "widget_info": {}, "session": {} }, "message": "Face Liveliness successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Kenya Business Credit Report Source: https://docs.smartcomply.com/v3/credit/business/Kenya_Business_Credit POST /api/onboarding/kenya/company_credit/ Retrieve a company's credit report in Kenya using their business registration number. The Kenya Business Credit Report endpoint provides a comprehensive record of a company's credit-related activities in Kenya, including loan accounts, payment timelines, credit utilization, and delinquency status. ## Endpoint ``` POST /api/onboarding/kenya/company_credit/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | ---------------------------------------------------------- | | `registration_number` | string | Yes | The Kenya business registration number (e.g. `PVT-ABC123`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya/company_credit/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "PVT-ABC123"}' ``` ## Response ### 200 OK ```json theme={null} { "status": "success", "data": {}, "message": "Kenya Company Credit Report retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # CRC Business Credit History Source: https://docs.smartcomply.com/v3/credit/business/crc-business_credit_history POST /api/onboarding/business/crc/ Retrieve a business's credit history from the CRC bureau using their registration number. The CRC Business Credit History endpoint provides a detailed record of a business's credit-related activities via the CRC bureau, including loan accounts, payment timelines, credit utilization, and delinquency status. ## Endpoint ``` POST /api/onboarding/business/crc/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | -------------------------------------- | | `registration_number` | string | Yes | The business RC or registration number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/business/crc/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "RC123456"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------------ | ------ | ------------------------------- | | `data._id` | string | Unique record ID | | `data.business_reg_no` | string | Business registration number | | `data.name` | string | Business name | | `data.address` | string | Registered address | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalNoOfActiveLoans` | number | Currently active loans | | `data.score.totalNoOfClosedLoans` | number | Closed loans | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.totalOutstanding` | number | Total outstanding balance | | `data.score.totalOverdue` | number | Total overdue amount | | `data.score.totalNoOfDelinquentFacilities` | number | Number of delinquent facilities | | `data.score.lastReportedDate` | string | Most recent bureau report date | | `data.searchedDate` | string | Date this report was retrieved | ```json theme={null} { "status": "success", "data": { "_id": "636e768d8215a2e2fb06cfde", "business_reg_no": "RC123456", "businessId": "64db7ab8a26e603218838892", "name": "CAPITALFIELD ASSET MGT LTD", "phone": "23408036732620", "dateOfRegistration": "2003-08-20", "address": "ELEGANZA HOUSE, 15B JOSEPH WESLEY STR, BROAD STREET, LAGOS NIGERIA", "score": { "totalNoOfDelinquentFacilities": 1, "lastReportedDate": "10/Nov/2022", "totalNoOfLoans": 24, "totalNoOfInstitutions": 12, "totalBorrowed": 567401372, "totalOutstanding": 19732, "totalOverdue": 19754, "totalNoOfPerformingLoans": 23, "totalNoOfClosedLoans": 17, "totalNoOfActiveLoans": 7, "crcReportOrderNumber": "W-0063381978/2022", "highestLoanAmount": 22980000 }, "searchedDate": "2023-11-23T16:16:47.279Z" }, "message": "CRC check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # First Central Business Credit History Source: https://docs.smartcomply.com/v3/credit/business/first-central_business_credit_history POST /api/onboarding/business/first_central/ Retrieve a business's credit history from the First Central bureau using their registration number. The First Central Business Credit History endpoint provides a comprehensive record of a business's credit-related activities via the First Central bureau, including loan accounts, payment timelines, credit utilization, and delinquency status. ## Endpoint ``` POST /api/onboarding/business/first_central/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | -------------------------------------- | | `registration_number` | string | Yes | The business RC or registration number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/business/first_central/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "RC123456"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------------ | ------ | ------------------------------- | | `data._id` | string | Unique record ID | | `data.business_reg_no` | string | Business registration number | | `data.name` | string | Business name | | `data.businessType` | string | Business type classification | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalNoOfActiveLoans` | number | Currently active loans | | `data.score.totalNoOfClosedLoans` | number | Closed loans | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.totalOutstanding` | number | Total outstanding balance | | `data.score.totalOverdue` | number | Total overdue amount | | `data.score.totalNoOfDelinquentFacilities` | number | Number of delinquent facilities | | `data.searchedDate` | string | Date this report was retrieved | ```json theme={null} { "status": "success", "data": { "_id": "636e768d8215a2e2fb06cfde", "business_reg_no": "RC123456", "businessId": "64db7ab8a26e603218838892", "name": "CAPITALFIELD ASSET MGT LTD", "phone": "23408036732620", "dateOfRegistration": "2003-08-20", "address": "ELEGANZA HOUSE, 15B JOSEPH WESLEY STR, BROAD STREET, LAGOS NIGERIA", "businessType": "SMALLANDMEDIUMSCALEENTERPRISE", "email": "capitalasset@gmail.com", "score": { "totalNoOfLoans": 9, "totalNoOfActiveLoans": 3, "totalNoOfClosedLoans": 6, "totalNoOfInstitutions": 2, "totalOverdue": 54931635, "totalBorrowed": 135582, "highestLoanAmount": 45194, "totalOutstanding": 54931635, "totalNoOfOverdueAccounts": 3, "totalNoOfPerformingLoans": 6, "totalNoOfDelinquentFacilities": 3, "firstCentralEnquiryResultID": "24327937" }, "searchedDate": "2023-11-23T16:17:16.672Z" }, "message": "First Central check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Premium Business Credit History Source: https://docs.smartcomply.com/v3/credit/business/premium_business_credit_history POST /api/onboarding/business/premium/ Retrieve a consolidated business credit report from both CRC and First Central bureaus. The Premium Business Credit History endpoint aggregates credit data from both the CRC and First Central bureaus, providing a unified view of a business's credit standing including loan history, performance summaries, director details, and credit enquiries. ## Endpoint ``` POST /api/onboarding/business/premium/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | -------------------------------------- | | `registration_number` | string | Yes | The business RC or registration number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/business/premium/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "RC123456"}' ``` ## Response ### 200 OK Each field in `data.score` is an array of objects with `source` (`"CRC"` or `"FIRST_CENTRAL"`) and `value` keys, providing per-bureau breakdowns. | Field | Type | Description | | ----------------------------- | ------ | -------------------------------------- | | `data.name` | string | Business name | | `data.businessType` | string | Business type | | `data.score.directors` | array | Directors per bureau | | `data.score.totalNoOfLoans` | array | Total loans per bureau | | `data.score.totalBorrowed` | array | Total borrowed per bureau | | `data.score.totalOutstanding` | array | Outstanding balance per bureau | | `data.score.totalOverdue` | array | Overdue amount per bureau | | `data.score.loanHistory` | array | Loan history per bureau | | `data.score.creditEnquiries` | array | Credit enquiries per bureau | | `data.score.loanPerformance` | array | Loan performance per bureau | | `data.score.bureauStatus` | object | Success/failure status for each bureau | ```json theme={null} { "status": "success", "data": { "_id": "636e768d8215a2e2fb06cfde", "business_reg_no": "RC123456", "name": "CAPITALFIELD ASSET MGT LTD", "businessType": "SMALLANDMEDIUMSCALEENTERPRISE", "score": { "totalNoOfLoans": [ {"source": "CRC", "value": 24}, {"source": "FIRST_CENTRAL", "value": 9} ], "totalBorrowed": [ {"source": "CRC", "value": 567401372}, {"source": "FIRST_CENTRAL", "value": 1004525869.55} ], "totalNoOfDelinquentFacilities": [ {"source": "CRC", "value": 1}, {"source": "FIRST_CENTRAL", "value": 0} ], "bureauStatus": { "crc": "success", "firstCentral": "success" } }, "searchedDate": "2023-11-23T16:17:36.391Z" }, "message": "Premium check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # CRC Credit History Source: https://docs.smartcomply.com/v3/credit/individual/CRC_Credit_History POST /api/onboarding/individual/crc_summary/ Retrieve an individual's credit history summary from the CRC bureau using their BVN. The CRC Credit History endpoint returns a summary of an individual's credit-related activities from the CRC bureau, including loan totals, repayment status, and outstanding balances. ## Endpoint ``` POST /api/onboarding/individual/crc_summary/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/crc_summary/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------------ | ------ | ------------------------------- | | `data.name` | string | Full name | | `data.gender` | string | Gender | | `data.dateOfBirth` | string | Date of birth | | `data.score.totalNoOfLoans` | string | Total loans on record | | `data.score.totalNoOfActiveLoans` | string | Currently active loans | | `data.score.totalNoOfClosedLoans` | number | Closed loans | | `data.score.totalBorrowed` | string | Total amount borrowed | | `data.score.totalOutstanding` | string | Total outstanding balance | | `data.score.totalOverdue` | string | Total overdue amount | | `data.score.totalNoOfDelinquentFacilities` | string | Number of delinquent facilities | | `data.score.lastReportedDate` | string | Most recent bureau report date | | `data.score.crcReportOrderNumber` | string | CRC report order number | | `data.searchedDate` | string | Date this report was retrieved | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "customerId": "505327", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfDelinquentFacilities": "0", "lastReportedDate": "30-SEP-2023", "totalNoOfLoans": "7", "totalNoOfInstitutions": "4", "totalNoOfActiveLoans": "6", "totalBorrowed": "3,541,267", "totalOutstanding": "1", "totalOverdue": "0", "maxNoOfDays": "0", "totalNoOfClosedLoans": 1, "crcReportOrderNumber": "W-0097884391/2023" }, "searchedDate": "2023-11-23T14:04:03.722Z" }, "message": "CRC Individual credit summary report details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # CRC Credit Score Source: https://docs.smartcomply.com/v3/credit/individual/CRC_Credit_Score POST /api/onboarding/individual/credit_scores_crc/ Retrieve an individual's FICO credit score from the CRC bureau using their BVN. The CRC Credit Score endpoint returns an individual's FICO credit score from the CRC bureau, along with a rating, contributing factors, and loan summary. ## Endpoint ``` POST /api/onboarding/individual/credit_scores_crc/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/credit_scores_crc/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------------ | ------ | ----------------------------------------------------------- | | `data.name` | string | Full name | | `data.score.totalNoOfDelinquentFacilities` | number | Number of delinquent facilities | | `data.score.hasLoans` | string | Whether the individual has active loans (`"YES"` or `"NO"`) | | `data.score.ficoScore.score` | number | Numeric FICO credit score | | `data.score.ficoScore.rating` | string | Credit rating (e.g. `"GOOD"`, `"FAIR"`, `"POOR"`) | | `data.score.ficoScore.reasons` | string | Factors influencing the score | | `data.score.lastReportedDate` | string | Most recent bureau report date | | `data.score.crcReportOrderNumber` | string | CRC report order number | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfDelinquentFacilities": 0, "hasLoans": "YES", "ficoScore": { "score": 717, "rating": "GOOD", "reasons": "Applicant is young relative to other applicants scored. The length of time accounts have been established is short." }, "lastReportedDate": "30-SEP-2023", "crcReportOrderNumber": "W-0097887747/2023" }, "searchedDate": "2023-11-23T14:25:54.210Z" }, "message": "Credit Scores individual CRC report details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # CRC Full Credit Report Source: https://docs.smartcomply.com/v3/credit/individual/CRC_full_credit_report POST /api/onboarding/individual/crc_full/ Retrieve an individual's full credit report from the CRC bureau, including loan history, performance, and enquiries. The CRC Full Credit Report endpoint returns a comprehensive credit report from the CRC bureau, including detailed loan history, repayment performance, credit enquiries, and employment history. ## Endpoint ``` POST /api/onboarding/individual/crc_full/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/crc_full/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------- | ------ | -------------------------------- | | `data.name` | string | Full name | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalNoOfActiveLoans` | number | Currently active loans | | `data.score.totalNoOfClosedLoans` | number | Closed loans | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.totalOutstanding` | number | Total outstanding balance | | `data.score.highestLoanAmount` | number | Highest single loan amount | | `data.score.creditEnquiries` | array | List of credit enquiries | | `data.score.loanPerformance` | array | Per-lender performance summaries | | `data.score.loanHistory` | array | Detailed loan-by-loan history | | `data.score.employmentHistory` | array | Employment records on file | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfDelinquentFacilities": 0, "lastReportedDate": "23/Nov/2023", "totalNoOfLoans": 29, "totalNoOfInstitutions": 6, "totalBorrowed": 4145267, "totalOutstanding": 1, "totalOverdue": 0, "totalNoOfPerformingLoans": 29, "totalNoOfClosedLoans": 27, "totalNoOfActiveLoans": 2, "highestLoanAmount": 1134330, "crcReportOrderNumber": "W-0097887830/2023", "creditEnquiries": [ {"loanType": "Overdraft", "date": "12-Oct-2023", "institutionType": "Micro Lenders"} ], "loanPerformance": [ {"loanProvider": "UNITED BANK FOR AFRICA", "loanAmount": "NGN 1,134,330", "status": "Open", "performanceStatus": "Performing"} ], "loanHistory": [ {"loanProvider": "UNITED BANK FOR AFRICA", "accountNumber": "SF099911020938", "type": "Term Loan", "loanAmount": "1134330", "performanceStatus": "Performing"} ], "employmentHistory": [ {"employerName": "ARM INVESTMENT MANAGERS", "address": "1 MEKUNWEN ROAD OYINKAN ABAYOMI ETI OSA", "dateReported": "31-jul-2023"} ] }, "searchedDate": "2023-11-23T14:26:42.196Z" }, "message": "CRC Full credit report details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Credit Registry Credit Summary Source: https://docs.smartcomply.com/v3/credit/individual/Credit_Registry_Credit_Summary POST /api/onboarding/individual/credit_registry_summary/ Retrieve an individual's credit summary from the Credit Registry bureau using their BVN. The Credit Registry Credit Summary endpoint returns a summary of an individual's credit-related activities from the Credit Registry bureau, including loan totals, repayment status, and outstanding balances. ## Endpoint ``` POST /api/onboarding/individual/credit_registry_summary/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/credit_registry_summary/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------------ | ------ | ------------------------------- | | `data.name` | string | Full name | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalNoOfActiveLoans` | number | Currently active loans | | `data.score.totalNoOfClosedLoans` | number | Closed loans | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.totalOutstanding` | number | Total outstanding balance | | `data.score.totalNoOfDelinquentFacilities` | number | Number of delinquent facilities | | `data.score.highestLoanAmount` | number | Highest single loan amount | | `data.searchedDate` | string | Date this report was retrieved | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfLoans": 16, "totalNoOfInstitutions": 5, "totalNoOfActiveLoans": 1, "totalNoOfClosedLoans": 15, "totalNoOfPerformingLoans": 16, "totalNoOfDelinquentFacilities": 0, "highestLoanAmount": 1134330, "totalBorrowed": 3761267, "totalOutstanding": 0, "totalOverdue": 0 }, "searchedDate": "2023-11-23T14:46:37.552Z" }, "message": "Credit Registry check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Credit Registry Full Credit Report Source: https://docs.smartcomply.com/v3/credit/individual/Credit_Registry_Full_Credit_Report POST /api/onboarding/individual/credit_registry_full/ Retrieve an individual's full credit report from the Credit Registry bureau, including loan history, creditors, and enquiries. The Credit Registry Full Credit Report endpoint returns a comprehensive credit report from the Credit Registry bureau, including loan history, repayment performance, creditor details, credit enquiries, and an enquiries summary. ## Endpoint ``` POST /api/onboarding/individual/credit_registry_full/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/credit_registry_full/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ----------------------------------- | ------ | ----------------------------------------------- | | `data.name` | string | Full name | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.creditors` | array | List of creditors with contact details | | `data.score.creditEnquiries` | array | List of credit enquiries with dates and reasons | | `data.score.creditEnquiriesSummary` | object | Enquiry counts for last 3, 12, and 36 months | | `data.score.loanPerformance` | array | Per-account repayment performance details | | `data.score.loanHistory` | array | Detailed loan-by-loan history | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfLoans": 16, "totalNoOfDelinquentFacilities": 0, "totalBorrowed": 3761267, "totalOutstanding": 0, "creditors": [ {"Subscriber_ID": "737248693595559931", "Name": "NewEdge Finance Limited", "Phone": "008618824674241"} ], "creditEnquiries": [ {"loanProvider": "Lifegate Microfinance Bank Limited", "reason": "KYCCheck", "date": "2023-11-23T00:00:00"} ], "creditEnquiriesSummary": { "Last3MonthCount": "3", "Last12MonthCount": "4", "Last36MonthCount": "6" }, "loanPerformance": [ {"loanProvider": "Sterling Bank Plc", "accountNumber": "0086575839", "status": "Open", "performanceStatus": "Performing"} ], "loanHistory": [ {"loanProvider": "Sterling Bank Plc", "accountNumber": "0086575839", "type": "", "status": "Open"} ] }, "searchedDate": "2023-11-23T14:47:42.824Z" }, "message": "Credit Registry check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Premium Individual Credit Report Source: https://docs.smartcomply.com/v3/credit/individual/Credit_Report_Premium POST /api/onboarding/individual/premium/ Retrieve an individual's consolidated credit report from both the Credit Registry and First Central bureaus. The Premium Individual Credit Report endpoint aggregates credit data from both the Credit Registry and First Central bureaus, providing a unified view of an individual's credit standing including loan history, creditors, performance, and enquiries. ## Endpoint ``` POST /api/onboarding/individual/premium/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/premium/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ----------------------------------- | ------ | ------------------------------- | | `data.name` | string | Full name | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.creditors` | array | List of creditors | | `data.score.creditEnquiries` | array | List of credit enquiries | | `data.score.creditEnquiriesSummary` | object | Enquiry counts by time period | | `data.score.loanPerformance` | array | Per-account performance details | | `data.score.loanHistory` | array | Detailed loan history | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfLoans": 16, "totalNoOfDelinquentFacilities": 0, "totalBorrowed": 3761267, "totalOutstanding": 0, "creditors": [ {"Subscriber_ID": "737248693595559931", "Name": "NewEdge Finance Limited"} ], "creditEnquiriesSummary": { "Last3MonthCount": "3", "Last12MonthCount": "4", "Last36MonthCount": "6" } }, "searchedDate": "2023-11-23T14:59:16.554Z" }, "message": "Premium check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Credit Registry History Advanced Source: https://docs.smartcomply.com/v3/credit/individual/Credt_Registry_History_Advanced POST /api/onboarding/individual/credit_registry_history_advanced/ Retrieve an individual's advanced credit history from the Credit Registry bureau with full loan and enquiry details. The Credit Registry History Advanced endpoint returns a detailed credit history report from the Credit Registry bureau, including loan performance per account, creditor contact details, and credit enquiry summaries. ## Endpoint ``` POST /api/onboarding/individual/credit_registry_history_advanced/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/credit_registry_history_advanced/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ----------------------------------- | ------ | ------------------------------------------------- | | `data.name` | string | Full name | | `data.score.totalNoOfLoans` | number | Total loans on record | | `data.score.totalBorrowed` | number | Total amount borrowed | | `data.score.creditors` | array | Creditors with subscriber IDs and contact details | | `data.score.creditEnquiries` | array | Credit enquiries with reason and date | | `data.score.creditEnquiriesSummary` | object | Enquiry counts for last 3, 12, and 36 months | | `data.score.loanPerformance` | array | Per-account performance with payment profiles | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "gender": "Male", "dateOfBirth": "29/12/1994", "score": { "totalNoOfLoans": 16, "totalNoOfDelinquentFacilities": 0, "totalBorrowed": 3761267, "totalOutstanding": 0, "creditors": [ {"Subscriber_ID": "737248693595559931", "Name": "NewEdge Finance Limited", "Phone": "008618824674241"} ], "creditEnquiries": [ {"loanProvider": "Lifegate Microfinance Bank Limited", "reason": "KYCCheck", "date": "2023-11-23T00:00:00"} ], "creditEnquiriesSummary": { "Last3MonthCount": "3", "Last12MonthCount": "4", "Last36MonthCount": "6" }, "loanPerformance": [ {"loanProvider": "Sterling Bank Plc", "accountNumber": "0086575839", "status": "Open", "paymentProfile": "NNNNNNNNNNNNNNNNNN0N0N00"} ] }, "searchedDate": "2023-11-23T14:47:42.824Z" }, "message": "Credit Registry check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Missing required fields" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # First Central Credit Score Source: https://docs.smartcomply.com/v3/credit/individual/First_Central_Credit_Score POST /api/onboarding/individual/credit_scores_first_central/ Retrieve an individual's credit score from the First Central bureau using their BVN. The First Central Credit Score endpoint returns an individual's consumer credit score from the First Central bureau, along with account condition summaries, outstanding debt totals, and score breakdown metrics. ## Endpoint ``` POST /api/onboarding/individual/credit_scores_first_central/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/credit_scores_first_central/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK | Field | Type | Description | | ---------------------------------------- | ------ | ---------------------------------------------- | | `data.score.totalConsumerScore` | string | Overall consumer credit score | | `data.score.description` | string | Risk rating (e.g. `"LOW RISK"`, `"HIGH RISK"`) | | `data.score.totalAccounts` | string | Total accounts on record | | `data.score.totalaccountinGoodcondition` | string | Accounts in good standing | | `data.score.totalaccountinBadcondition` | string | Accounts in bad standing | | `data.score.totalOutstandingDebt` | string | Total outstanding debt | | `data.score.totalAmountOverdue` | string | Total amount overdue | | `data.score.repaymentHistoryScore` | string | Repayment history score component | | `data.score.firstCentralEnquiryResultID` | string | First Central enquiry result ID | ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "ADELEKE EMMANUEL AYORINDE", "score": { "totalConsumerScore": "835", "description": "LOW RISK", "totalAccounts": "23", "scoreDate": "11/23/2023", "noOfAcctScore": "55/55", "totalaccountinGoodcondition": "23", "totalaccountinBadcondition": "0", "totalOutstandingDebt": "30,719.00", "totalAccountarrear": "0", "totalAmountOverdue": "0.00", "repaymentHistoryScore": "192/192", "totalAmountOwedScore": "165/165", "firstCentralEnquiryResultID": "37181617" }, "searchedDate": "2023-11-23T14:37:04.152Z" }, "message": "Credit Scores individual first central report details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # First Central Credit Summary Source: https://docs.smartcomply.com/v3/credit/individual/First_Central_Credit_Summary POST /api/onboarding/individual/first_central_summary/ Retrieve an individual's credit summary from the First Central bureau using their BVN. The First Central Credit Summary endpoint returns a summary of an individual's credit-related activities from the First Central bureau. ## Endpoint ``` POST /api/onboarding/individual/first_central_summary/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/first_central_summary/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "JOHN DOE", "score": {} }, "message": "First Central check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # First Central Full Credit Report Source: https://docs.smartcomply.com/v3/credit/individual/First_Central_Full_Credit_Report POST /api/onboarding/individual/first_central_full/ Retrieve an individual's full credit report from the First Central bureau using their BVN. The First Central Full Credit Report endpoint returns a comprehensive credit report from the First Central bureau, including loan history, repayment performance, and credit enquiries. ## Endpoint ``` POST /api/onboarding/individual/first_central_full/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `bvn` | string | Yes | The individual's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/individual/first_central_full/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22244545518"}' ``` ## Response ### 200 OK ```json theme={null} { "status": "success", "data": { "_id": "64f600608aaf9386c646de32", "bvn": "22244545518", "name": "JOHN DOE", "score": {} }, "message": "First Central check successful" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Kenya Individual Credit Report Source: https://docs.smartcomply.com/v3/credit/individual/Kenya_Individual_Credit POST /api/onboarding/kenya/individual_credit/ Retrieve an individual's credit report in Kenya using their national ID number. The Kenya Individual Credit Report endpoint provides a comprehensive record of an individual's credit-related activities in Kenya, including credit accounts, payment timelines, credit utilization, and delinquency status. ## Endpoint ``` POST /api/onboarding/kenya/individual_credit/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------------ | | `national_id` | string | Yes | The individual's Kenyan national ID number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya/individual_credit/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"national_id": "12345678"}' ``` ## Response ### 200 OK ```json theme={null} { "status": "success", "data": {}, "message": "Kenya Individual Credit Report retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # National ID Source: https://docs.smartcomply.com/v3/kyc/cote_d_ivoire/National_ID POST /api/onboarding/cote_divoire_kyc/national_id/ Verify a customer's identity using their Côte d'Ivoire national ID number (NNI). The Côte d'Ivoire National ID endpoint validates a national ID number (NNI) and returns the associated personal details from the national registry. ## Endpoint ``` POST /api/onboarding/cote_divoire_kyc/national_id/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------------------------------- | | `national_id` | string | Yes | The customer's Côte d'Ivoire national ID number (NNI) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/cote_divoire_kyc/national_id/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"national_id": "11715641589"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/cote_divoire_kyc/national_id/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ national_id: "11715641589" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/cote_divoire_kyc/national_id/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"national_id": "11715641589"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | -------------------- | ------- | ----------------------- | | `data.valid` | boolean | Whether the ID is valid | | `data.first_name` | string | Customer's first name | | `data.last_name` | string | Customer's last name | | `data.middle_name` | string | Middle name, if any | | `data.date_of_birth` | string | Date of birth | | `data.gender` | string | Gender | | `data.nationality` | string | Nationality | | `data.id_number` | string | National ID number | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "JEAN", "last_name": "KOUASSI", "middle_name": "", "date_of_birth": "1988-07-22", "gender": "Male", "nationality": "Ivorian", "id_number": "11715641589" }, "message": "National ID details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/canada/Passport POST /api/onboarding/document_verification/canada/passport Extract identity details from a Canadian passport using OCR. Verify a customer's Canadian passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/canada/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/canada/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/canada/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/canada/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, `nin` (if embedded), and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "JAMES", "last_name": "TREMBLAY", "full_name": "TREMBLAY JAMES", "date_of_birth": "1988-07-22", "gender": "M", "nationality": "CANADIAN", "id_number": "GA123456", "document_type": "passport", "expiry_date": "2027-09-30", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "TORONTO, ON", "issuing_authority": "GATINEAU, QC" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/cote_d_ivoire/Passport POST /api/onboarding/document_verification/cote_d_ivoire/passport Extract identity details from a Côte d'Ivoire passport using OCR. Verify a customer's Côte d'Ivoire passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/cote_d_ivoire/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/cote_d_ivoire/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/cote_d_ivoire/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/cote_d_ivoire/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, `nin` (if embedded), and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "KOFFI", "last_name": "YAO", "full_name": "YAO KOFFI", "date_of_birth": "1993-12-01", "gender": "M", "nationality": "IVORIAN", "id_number": "CI1234567", "document_type": "passport", "expiry_date": "2028-03-17", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "ABIDJAN", "issuing_authority": "ABIDJAN" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/ghana/Passport POST /api/onboarding/document_verification/ghana/passport Extract identity details from a Ghanaian passport using OCR. Verify a customer's Ghanaian passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/ghana/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/ghana/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/ghana/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/ghana/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, `nin` (if embedded), and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "KWAME", "last_name": "MENSAH", "full_name": "MENSAH KWAME", "date_of_birth": "1992-11-04", "gender": "M", "nationality": "GHANAIAN", "id_number": "G1234567", "document_type": "passport", "expiry_date": "2028-02-20", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "ACCRA", "issuing_authority": "ACCRA" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Kenya National ID Source: https://docs.smartcomply.com/v3/kyc/document_verification/kenya/Kenya_ID POST /api/onboarding/document_verification/kenya/kenya_id Extract identity details from a Kenyan national ID card using OCR. Verify a customer's Kenyan national ID card by uploading a photo — no manual ID entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). This is a two-sided document — supply both `document_front` and `document_back` for the most complete extraction. Kenya has two ID card generations in circulation: the older laminated design and the newer "Maisha Card." Fields specific to the Maisha Card (`serial_number`, `place_of_issue`, expiry date) will come back empty on an older card — that's expected, not an error. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/kenya/kenya_id ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Front of the ID card. JPG or PNG, max 5MB | | `document_back` | file | No | Back of the ID card. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/kenya/kenya_id" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/id_front.jpg" \ -F "document_back=@/path/to/id_back.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/id_front.jpg")); formData.append("document_back", fs.createReadStream("/path/to/id_back.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/kenya/kenya_id", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/kenya/kenya_id", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/id_front.jpg", "rb"), "document_back": open("/path/to/id_back.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ---------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.id_number` | string | The ID number | | `data.document_type` | string | `"kenya_id"` | | `data.expiry_date` | string | Maisha Card expiry date — only present on third-generation cards | | `data.issue_date` | string | Date of issue | | `data.place_of_issue` | string | Only present on third-generation "Maisha Card" IDs | | `data.serial_number` | string | Separate 9-digit card serial number — only present on third-generation "Maisha Card" IDs | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields printed on the card — see below | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "WANJIRU", "last_name": "KAMAU", "full_name": "KAMAU WANJIRU", "date_of_birth": "1995-03-10", "id_number": "34567890", "document_type": "kenya_id", "issue_date": "2019-05-14", "place_of_issue": "NAIROBI", "serial_number": "123456789", "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "district_of_birth": "NAIROBI", "district": "NAIROBI", "division": "CENTRAL", "location": "NAIROBI CENTRAL", "sub_location": "CBD", "barcode_number": "12345678", "mrz_line1": "IDKEN3456789012<<<<<<<<<<<<<<<", "mrz_line2": "9503109F2905147KEN<<<<<<<<<<<8", "mrz_line3": "KAMAU< **Extra Fields** — `extra_fields` carries whatever else the card printed beyond the fields listed above: `district_of_birth`, and — only when `document_back` was supplied — `district`, `division`, `location`, `sub_location`, `barcode_number`, and the three MRZ lines (`mrz_line1`/`mrz_line2`/`mrz_line3`, exactly as printed, including `<` fill characters — not decoded). Only fields actually present on the card are included. **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "This document is not supported for the selected ID type — please upload the correct document." } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/kenya/Passport POST /api/onboarding/document_verification/kenya/passport Extract identity details from a Kenyan passport using OCR. Verify a customer's Kenyan passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/kenya/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/kenya/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/kenya/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/kenya/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, `nin` (if embedded), and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "WANJIRU", "last_name": "KAMAU", "full_name": "KAMAU WANJIRU", "date_of_birth": "1995-03-10", "gender": "F", "nationality": "KENYAN", "id_number": "K1234567", "document_type": "passport", "expiry_date": "2029-08-15", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "NAIROBI", "issuing_authority": "NAIROBI" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Driver's License Source: https://docs.smartcomply.com/v3/kyc/document_verification/nigeria/Drivers_License POST /api/onboarding/document_verification/nigeria/drivers_license Extract identity details from a Nigerian driver's license using OCR. Verify a customer's Nigerian driver's license by uploading a photo — no manual license number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). This is a two-sided document — supply both `document_front` and `document_back` for the most complete extraction. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/nigeria/drivers_license ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Front of the driver's license. JPG or PNG, max 5MB | | `document_back` | file | No | Back of the driver's license. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/drivers_license" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/license_front.jpg" \ -F "document_back=@/path/to/license_back.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/license_front.jpg")); formData.append("document_back", fs.createReadStream("/path/to/license_back.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/drivers_license", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/drivers_license", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/license_front.jpg", "rb"), "document_back": open("/path/to/license_back.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ---------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.id_number` | string | The driver's license number | | `data.document_type` | string | `"drivers_license"` | | `data.expiry_date` | string | License expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Every other field the license printed — see below | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "GOODLUCK EBELE", "last_name": "JONATHAN", "full_name": "GOODLUCK EBELE JONATHAN", "date_of_birth": "1957-11-20", "gender": "M", "address": "STATE HOUSE", "id_number": "JTC0977DD", "document_type": "drivers_license", "expiry_date": "2030-11-20", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "height": "1.75M", "blood_group": "AB+", "place_of_residence": "FCT", "category": "PRIVATE", "license_class": "B", "endorsement": "P", "date_of_first_issue": "02-09-2011", "first_issued_state": "FCT", "facial_marks": "N", "glasses_required": "N", "replacement_count": "0", "renewal_count": "1", "next_of_kin_phone": "08072262207" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Extra Fields** — `extra_fields` carries every other field the license actually printed that doesn't have its own dedicated field above. Nigerian licenses print more of these than other countries' — expect anywhere from a few fields to the full set shown here, and expect `null`/absent fields to be dropped rather than sent as `null`, since a field that wasn't printed on the document isn't guessed at. **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # National ID Source: https://docs.smartcomply.com/v3/kyc/document_verification/nigeria/National_ID POST /api/onboarding/document_verification/nigeria/national_id Extract identity details from a Nigerian NIN slip or card using OCR. Verify a customer's Nigerian National Identification Number slip or card by uploading a photo — no manual NIN entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). This is a two-sided document — supply both `document_front` and `document_back` for the most complete extraction. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/nigeria/national_id ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Front of the NIN slip/card. JPG or PNG, max 5MB | | `document_back` | file | No | Back of the NIN card. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | `document_type` and `country` are not needed — this endpoint is already scoped to Nigerian National ID. ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/national_id" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/nin_front.jpg" \ -F "document_back=@/path/to/nin_back.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/nin_front.jpg")); formData.append("document_back", fs.createReadStream("/path/to/nin_back.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/national_id", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/national_id", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/nin_front.jpg", "rb"), "document_back": open("/path/to/nin_back.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ---------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.id_number` | string | The NIN printed on the document | | `data.document_type` | string | `"national_id"` | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Present if the card is the older two-sided format — see below | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "TUNDE", "last_name": "AYODELE", "full_name": "AYODELE TUNDE", "date_of_birth": "2002-02-16", "gender": "M", "id_number": "12345678901", "document_type": "national_id", "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Extra Fields** — the newer, one-sided NIN slip/card has no fields beyond what's listed above. The older, two-sided card prints more (`occupation`, `state`, `lga`, `ward`, `height`, `blood_group`, plus several back-side fields) — these come back in `extra_fields` when present, and are simply absent for the newer format rather than sent as `null`. **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request Returned for invalid input, or when the document fails OCR's own quality checks (blurry, wrong document type, glare, etc.). ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/nigeria/Passport POST /api/onboarding/document_verification/nigeria/passport Extract identity details from a Nigerian international passport using OCR. Verify a customer's Nigerian international passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/nigeria/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | `document_type` and `country` are not needed — this endpoint is already scoped to Nigerian passports. ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, `nin` (if embedded), and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "TUNDE", "last_name": "AYODELE", "full_name": "AYODELE TUNDE", "date_of_birth": "2002-02-16", "gender": "M", "nationality": "NIGERIAN", "id_number": "A12345678", "document_type": "passport", "expiry_date": "2030-01-01", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "LAGOS", "issuing_authority": "IKOYI, LAGOS" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Voter's Card Source: https://docs.smartcomply.com/v3/kyc/document_verification/nigeria/Voters_Card POST /api/onboarding/document_verification/nigeria/voters_card Extract identity details from a Nigerian Permanent Voter's Card (PVC) using OCR. Verify a customer's Nigerian Permanent Voter's Card (PVC) by uploading a photo — no manual voter ID entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). This is a two-sided document — supply both `document_front` and `document_back` for the most complete extraction. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/nigeria/voters_card ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the front of the PVC. JPG or PNG, max 5MB | | `document_back` | file | No | Photo of the back of the PVC. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/voters_card" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/pvc_front.jpg" \ -F "document_back=@/path/to/pvc_back.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/pvc_front.jpg")); formData.append("document_back", fs.createReadStream("/path/to/pvc_back.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/voters_card", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/nigeria/voters_card", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/pvc_front.jpg", "rb"), "document_back": open("/path/to/pvc_back.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ---------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.address` | string | Registered address printed on the card | | `data.id_number` | string | The Voter Identification Number (VIN) | | `data.serial_number` | string | The card's serial number | | `data.document_type` | string | `"voters_card"` | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields printed on the card — see below | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "TUNDE", "last_name": "AYODELE", "full_name": "AYODELE TUNDE", "date_of_birth": "2002-02-16", "gender": "M", "address": "12 ALLEN AVENUE, IKEJA, LAGOS", "id_number": "90F5A1B2C3D4E5F6", "serial_number": "SN00123456", "document_type": "voters_card", "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "occupation": "ENGINEER", "state": "LAGOS", "lga": "IKEJA", "ward": "WARD 5", "polling_unit_code": "PU001234", "date_of_registration": "2019-01-15" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Extra Fields** — `extra_fields` carries whatever else the PVC printed beyond the fields listed above (occupation, state, LGA, ward, polling unit code, registration date, batch/serial numbers). Only fields actually present on the card are included. **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/uk/Passport POST /api/onboarding/document_verification/uk/passport Extract identity details from a UK passport using OCR. Verify a customer's UK passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). UK document verification currently supports passports only — national ID, driver's license, and other UK document types are not yet available. ## Endpoint ``` POST /api/onboarding/document_verification/uk/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/uk/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/uk/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/uk/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "JAMES", "last_name": "SMITH", "full_name": "SMITH JAMES", "date_of_birth": "1988-07-22", "gender": "M", "nationality": "BRITISH", "id_number": "533018723", "document_type": "passport", "expiry_date": "2029-04-15", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "LONDON" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Passport Source: https://docs.smartcomply.com/v3/kyc/document_verification/usa/Passport POST /api/onboarding/document_verification/usa/passport Extract identity details from a United States passport using OCR. Verify a customer's United States passport by uploading a photo of the data page — no manual passport number entry required. OCR extraction plus a required face match against a selfie — no liveness check (no video, no blink/motion challenge). Passport is single-sided — only `document_front` is needed. `selfie_image` is required — the face extracted from the document is compared against it. This is a still-image comparison (not liveness). ## Endpoint ``` POST /api/onboarding/document_verification/usa/passport ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ---- | -------- | -------------------------------------------------------------------------- | | `document_front` | file | Yes | Photo of the passport data page. JPG or PNG, max 5MB | | `selfie_image` | file | Yes | A selfie to compare against the document's face photo. JPG or PNG, max 5MB | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/document_verification/usa/passport" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "document_front=@/path/to/passport.jpg" \ -F "selfie_image=@/path/to/selfie.jpg" ``` ```javascript Node.js theme={null} const formData = new FormData(); formData.append("document_front", fs.createReadStream("/path/to/passport.jpg")); formData.append("selfie_image", fs.createReadStream("/path/to/selfie.jpg")); const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/usa/passport", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY" }, body: formData, } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/document_verification/usa/passport", headers={"x-access-token": "YOUR_SECRET_KEY"}, files={ "document_front": open("/path/to/passport.jpg", "rb"), "selfie_image": open("/path/to/selfie.jpg", "rb"), }, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `status` | string | `"success"` on a successful extraction | | `data.full_name` | string | Extracted full name | | `data.first_name` | string | Extracted first name | | `data.last_name` | string | Extracted last name | | `data.date_of_birth` | string | Date of birth in `YYYY-MM-DD` format | | `data.gender` | string | Extracted gender | | `data.nationality` | string | Extracted nationality | | `data.id_number` | string | The passport number | | `data.document_type` | string | `"passport"` | | `data.expiry_date` | string | Passport expiry date | | `data.is_expired` | boolean | Whether `expiry_date` has already passed | | `data.photo` | string | Base64-encoded face photo extracted from the document | | `data.extra_fields` | object | Other fields OCR read from the data page — `place_of_birth`, `issuing_authority`, `nin` (if embedded), and `mrz_line1`/`mrz_line2` if the machine-readable zone was legible, exactly as printed | | `data.face_match` | object | Result of comparing the document's face against `selfie_image` — see below | | `data.face_match.attempted` | boolean | Whether a comparison was actually run | | `data.face_match.verified` | boolean \| null | `true`/`false` if the comparison ran; `null` if it couldn't (see Face Match Notes) | | `data.face_match.confidence_percentage` | number | Match confidence, 0–100 | | `data.face_match.selfie_image` | string | URL of the uploaded selfie | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "MICHAEL", "last_name": "JOHNSON", "full_name": "JOHNSON MICHAEL", "date_of_birth": "1991-04-18", "gender": "M", "nationality": "USA", "id_number": "543219876", "document_type": "passport", "expiry_date": "2029-06-12", "is_expired": false, "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "extra_fields": { "place_of_birth": "CALIFORNIA, USA", "issuing_authority": "UNITED STATES DEPARTMENT OF STATE" }, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 92.4, "selfie_image": "https://.../selfie.jpg" } }, "message": "Document details retrieved successfully" } ``` **Face Match Notes** — if the comparison service itself fails, `attempted` reflects whether a comparison was actually run and `verified` comes back `null` with a `reason` field explaining why — this is different from `verified: false`, which means the comparison ran and the faces didn't match. A face-match problem never blocks the underlying document data — the rest of `data` is still returned. ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "ID photo is too blurry — please retake in good lighting with a steady hand" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Ghana ID Card Source: https://docs.smartcomply.com/v3/kyc/ghana/ID_Card POST /api/onboarding/ghana_kyc/id_card/ Verify a customer's identity using their Ghana Card number. The Ghana ID Card endpoint validates a Ghana Card number and returns the associated personal details including name, date of birth, address, and photo. ## Endpoint ``` POST /api/onboarding/ghana_kyc/id_card/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ------------------------------------------------------------ | | `identification_number` | string | Yes | The customer's Ghana Card number (format: `GHA-000000000-0`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/ghana_kyc/id_card/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"identification_number": "GHA-000000000-0"}' ``` ## Response ### 200 OK | Field | Type | Description | | -------------------------- | ------ | ------------------------------- | | `data.FullName` | string | Full name | | `data.FirstName` | string | First name | | `data.LastName` | string | Last name | | `data.OtherNames` | string | Other names | | `data.DOB` | string | Date of birth (`YYYY-MM-DD`) | | `data.Gender` | string | Gender | | `data.PhoneNumber` | string | Registered phone number | | `data.Address` | string | Registered address | | `data.Country` | string | Country | | `data.IDNumber` | string | Ghana Card number | | `data.IssuanceDate` | string | Card issue date | | `data.ExpirationDate` | string | Card expiry date | | `data.Secondary_ID_Number` | string | Secondary identification number | | `data.Photo` | string | Base64-encoded ID photo | ```json theme={null} { "status": "success", "data": { "DOB": "2000-09-20", "Photo": "", "Gender": "Male", "Address": "OPHELIA JUNCTION, Barimah Close, ESSERESO, BOSOMTWE, ASHANTI, Ghana", "Country": "Ghana", "FullName": "Joe Leo Doe", "IDNumber": "GHA-000000000-0", "LastName": "Leo", "FirstName": "Joe", "OtherNames": "Leo", "PhoneNumber": "0000000", "IssuanceDate": "2020-08-07", "ExpirationDate": "2030-08-07", "Secondary_ID_Number": "AQ0000000" }, "message": "Ghana ID Card details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Ghana ID Card Advanced Source: https://docs.smartcomply.com/v3/kyc/ghana/ID_Card_with_face POST /api/onboarding/ghana_kyc/id_card_with_face/ Verify a customer's identity using their Ghana Card number alongside a selfie image. The Ghana ID Card Advanced endpoint verifies a customer's identity by matching their Ghana Card number against a submitted selfie image. Returns verified personal details and the registrant's photo on record. ## Endpoint ``` POST /api/onboarding/ghana_kyc/id_card_with_face/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ------------------------------------------------------------ | | `identification_number` | string | Yes | The customer's Ghana Card number (format: `GHA-000000000-0`) | | `selfie_image` | string | Yes | Base64-encoded selfie image for face matching | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/ghana_kyc/id_card_with_face/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "identification_number": "GHA-000000000-0", "selfie_image": "" }' ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------ | --------------------------------- | | `data.FullName` | string | Full name | | `data.FirstName` | string | First name | | `data.LastName` | string | Last name | | `data.DOB` | string | Date of birth | | `data.Gender` | string | Gender | | `data.Address` | string | Registered address | | `data.IDNumber` | string | Ghana Card number | | `data.IssuanceDate` | string | Card issue date | | `data.ExpirationDate` | string | Card expiry date | | `data.Photo` | string | Base64-encoded ID photo on record | ```json theme={null} { "status": "success", "data": { "DOB": "2000-09-20", "Photo": "", "Gender": "Male", "Address": "OPHELIA JUNCTION, Barimah Close, ESSERESO, BOSOMTWE, ASHANTI, Ghana", "Country": "Ghana", "FullName": "Joe Leo Doe", "IDNumber": "GHA-000000000-0", "LastName": "Doe", "FirstName": "Joe", "OtherNames": "Leo", "PhoneNumber": "0000000", "IssuanceDate": "2020-08-07", "ExpirationDate": "2030-08-07", "Secondary_ID_Number": "AQ0000000" }, "message": "Ghana ID Card Advanced details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # International Passport Source: https://docs.smartcomply.com/v3/kyc/ghana/International_Passport POST /api/onboarding/ghana_kyc/international_passport/ Verify a customer's identity using their Ghanaian international passport number. The Ghana International Passport endpoint validates a passport number and returns the associated personal details from the national registry. ## Endpoint ``` POST /api/onboarding/ghana_kyc/international_passport/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------- | ------ | -------- | --------------------------------------- | | `passport_number` | string | Yes | The customer's Ghanaian passport number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/ghana_kyc/international_passport/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"passport_number": "G3759982"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/ghana_kyc/international_passport/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ passport_number: "G3759982" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/ghana_kyc/international_passport/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"passport_number": "G3759982"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | -------------------- | ------- | ----------------------------- | | `data.valid` | boolean | Whether the passport is valid | | `data.first_name` | string | Customer's first name | | `data.last_name` | string | Customer's last name | | `data.middle_name` | string | Middle name, if any | | `data.date_of_birth` | string | Date of birth | | `data.gender` | string | Gender | | `data.nationality` | string | Nationality | | `data.id_number` | string | Passport number | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "JOHN", "last_name": "DOE", "middle_name": "", "date_of_birth": "1990-04-15", "gender": "Male", "nationality": "Ghanaian", "id_number": "G3759982" }, "message": "International Passport details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Driver's License Source: https://docs.smartcomply.com/v3/kyc/kenya/Drivers_License POST /api/onboarding/kenya_kyc/drivers_license/ Verify a customer's identity using their Kenyan driver's license number. The Kenya Driver's License endpoint validates a driver's license number and returns the associated personal details from the national registry. ## Endpoint ``` POST /api/onboarding/kenya_kyc/drivers_license/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | --------------------------------------------- | | `license_number` | string | Yes | The customer's Kenyan driver's license number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/drivers_license/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"license_number": "24478782"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/drivers_license/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ license_number: "24478782" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/drivers_license/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"license_number": "24478782"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | ------------------ | ------- | ---------------------------- | | `data.valid` | boolean | Whether the license is valid | | `data.id_number` | string | Driver's license number | | `data.full_name` | string | Customer's full name | | `data.phone` | string | Registered phone number | | `data.email` | string | Registered email address | | `data.nationality` | string | Nationality | ```json theme={null} { "status": "success", "data": { "valid": true, "full_name": "CHARLOTTE SARAH KWENA", "phone": "+254721583847", "email": "kwenacharlotte@gmail.com", "nationality": "KE", "id_number": "24478782" }, "message": "Driver's License details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Kenya Passport Source: https://docs.smartcomply.com/v3/kyc/kenya/Passport_Verification POST /api/onboarding/kenya_kyc/passport/ Verify a customer's identity using their Kenyan passport number. The Kenya Passport endpoint validates a passport number against the national registry and returns the associated personal details including name, dates, and a photo. ## Endpoint ``` POST /api/onboarding/kenya_kyc/passport/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------------------- | | `passport_number` | string | Yes | The customer's passport number (e.g. `A00000000`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/passport/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"passport_number": "A00000000"}' ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------ | ----------------------------- | | `data.First_Name` | string | First name | | `data.Surname` | string | Surname | | `data.Other_Name` | string | Other/middle name | | `data.Gender` | string | Gender | | `data.Date_of_Birth` | string | Date of birth | | `data.Citizenship` | string | Citizenship | | `data.Date_of_Issue` | string | Passport issue date | | `data.Place_of_Birth` | string | Place of birth | | `data.Photo` | string | Base64-encoded passport photo | ```json theme={null} { "status": "success", "data": { "Pin": "", "Clan": "", "Photo": "", "Family": "", "Gender": "M", "Surname": "Leo", "First_Name": "Joe", "Other_Name": "Doe", "Citizenship": "Kenyan", "Date_of_Birth": "2000-09-20 12:00:00 AM", "Date_of_Issue": "1/27/2000 12:00:00 AM", "Place_of_Birth": "NAIROBI", "Place_of_Live": "BOX 12345-00800 NAIROBI" }, "message": "Passport details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Alien ID Source: https://docs.smartcomply.com/v3/kyc/kenya/alien_ID POST /api/onboarding/kenya_kyc/alien_id/ Verify a customer's identity using their Kenya Alien Identification number. The Alien ID endpoint validates a Kenya Alien Identification number and returns the associated personal details from the national registry. ## Endpoint ``` POST /api/onboarding/kenya_kyc/alien_id/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------------ | | `alien_id` | string | Yes | The customer's Alien Identification number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/alien_id/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"alien_id": "1000000"}' ``` ## Response ### 200 OK | Field | Type | Description | | -------------------- | ------- | ----------------------- | | `data.valid` | boolean | Whether the ID is valid | | `data.id_number` | string | Alien ID number | | `data.first_name` | string | First name | | `data.last_name` | string | Last name | | `data.middle_name` | string | Middle name | | `data.date_of_birth` | string | Date of birth | | `data.gender` | string | Gender | | `data.nationality` | string | Nationality | ```json theme={null} { "status": "success", "data": { "valid": true, "id_number": "1000000", "first_name": "JAMES", "last_name": "KARIUKI", "middle_name": "MWANGI", "date_of_birth": "1990-04-15", "gender": "Male", "nationality": "Ugandan" }, "message": "Alien ID details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` # Business Registration Source: https://docs.smartcomply.com/v3/kyc/kenya/business_registration POST /api/onboarding/kenya_kyc/business_registration/ Verify a Kenyan business using its registration number and retrieve directors, shareholders, and beneficial owners. The Business Registration endpoint retrieves verified company information — including directors, beneficial owners, and shareholding structure — using a valid Kenya business registration number. ## Endpoint ``` POST /api/onboarding/kenya_kyc/business_registration/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | ---------------------------------------------------- | | `registration_number` | string | Yes | The business registration number (e.g. `PVT-ABC123`) | | `postal_code` | string | No | Postal code of the registered business address | | `postal_address` | string | No | Postal address number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/business_registration/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "PVT-ABC123", "postal_code": "00100", "postal_address": "1234"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------ | ------- | -------------------------------------------------------- | | `data.valid` | boolean | Whether the registration is valid | | `data.directors` | array | List of directors with identity and shareholding details | | `data.beneficial_owners` | array | List of beneficial owners with shareholding details | | `data.fiduciaries` | array | Fiduciary details if applicable | | `data.proprietors` | array | Proprietor details if applicable | ```json theme={null} { "status": "success", "data": { "valid": true, "success": true, "directors": [ { "name": "JAMES KARIUKI MWANGI", "gender": "Male", "address": "P.O BOX 1234 NAIROBI", "id_type": "National ID", "id_number": "A12345678", "occupation": "Director", "nationality": "Citizen", "phone_number": "N/A", "date_of_birth": "N/A", "shareholdings": 10, "shareholding_breakdown": [{"type": "ORDINARY", "number_of_shares": 10}] } ], "documents": {}, "fiduciaries": [], "proprietors": [], "beneficial_owners": [ { "name": "JAMES KARIUKI MWANGI", "gender": "Male", "address": "P.O BOX 1234 NAIROBI", "nationality": "Citizen", "phone_number": "N/A", "shareholdings": 10, "shareholder_type": "Individual", "registration_number": "N/A", "shareholding_breakdown": [{"type": "ORDINARY", "number_of_shares": 10}] } ] }, "message": "Business Registration details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` # KRA PIN Source: https://docs.smartcomply.com/v3/kyc/kenya/kra_pin POST /api/onboarding/kenya_kyc/kra_pin/ Verify a customer's Kenya Revenue Authority PIN and retrieve their taxpayer details. The KRA PIN endpoint validates a Kenya Revenue Authority (KRA) Personal Identification Number and returns the associated taxpayer details including name, PIN status, iTax status, and tax obligation information. ## Endpoint ``` POST /api/onboarding/kenya_kyc/kra_pin/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------- | | `pin` | string | Yes | The customer's KRA PIN (e.g. `A123456789B`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/kra_pin/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"pin": "A123456789B"}' ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------- | ------ | ------------------------------------------------ | | `data.pin` | string | KRA PIN | | `data.taxpayer_name` | string | Registered taxpayer name | | `data.pin_status` | string | PIN status (e.g. `"Active"`) | | `data.itax_status` | string | iTax system status | | `data.obligation_details` | string | Tax obligation description and registration date | ```json theme={null} { "status": "success", "data": { "pin": "A123456789B", "taxpayer_name": "ABB APP Limited", "pin_status": "Active", "itax_status": "iPage Updated", "obligation_details": "Income Tax - Company Registered 29/01/2013" }, "message": "Pin details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "PIN is required" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # National ID Advanced Source: https://docs.smartcomply.com/v3/kyc/kenya/national_id_advance POST /api/onboarding/kenya_kyc/national_id_advance/ Retrieve extended identity details for a Kenyan national ID, including photo, place of birth, and residence. The National ID Advanced endpoint returns comprehensive identity information for a Kenyan national ID, including the registrant's photo, place of birth, place of residence, and issue details. ## Endpoint ``` POST /api/onboarding/kenya_kyc/national_id_advance/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------- | ------- | -------- | ---------------------------------------- | | `national_id` | integer | Yes | The customer's Kenyan national ID number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/national_id_advance/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"national_id": 1010101010}' ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------ | ----------------------------- | | `data.First_Name` | string | First name | | `data.Surname` | string | Surname | | `data.Other_Name` | string | Other/middle name | | `data.Gender` | string | Gender (`"M"` or `"F"`) | | `data.Date_of_Birth` | string | Date of birth | | `data.Citizenship` | string | Citizenship status | | `data.Date_of_Issue` | string | ID issue date | | `data.Place_of_Birth` | string | Place of birth | | `data.Place_of_Live` | string | Registered place of residence | | `data.Photo` | string | Base64-encoded ID photo | ```json theme={null} { "status": "success", "data": { "Pin": "", "Clan": "", "Photo": "", "Family": "", "Gender": "M", "Surname": "Leo", "RegOffice": "", "First_Name": "Joe", "Occupation": "", "Other_Name": "Doe", "Citizenship": "Kenyan", "Date_of_Birth": "2000-09-20 12:00:00 AM", "Date_of_Death": "", "Date_of_Issue": "1/27/2000 12:00:00 AM", "Place_of_Live": "BOX 12345-00800 NAIROBI\nKAREN\nKAREN\nLOCATION - LANGATA\nDIVISION - KIBERA\nDISTRICT - STAREHE", "Serial_Number": 0, "Place_of_Birth": "NAIROBI\nDISTRICT - STAREHE", "Place_of_Death": "" }, "message": "National ID Advance details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # National ID Basic Source: https://docs.smartcomply.com/v3/kyc/kenya/national_id_basic POST /api/onboarding/kenya_kyc/national_id_basic/ Verify a Kenyan customer's identity using their national ID number. The Kenya National ID Basic endpoint retrieves verified identity data from the Kenyan government's IPRS database, returning the ID holder's full name, gender, citizenship, and photo. ## Endpoint ``` POST /api/onboarding/kenya_kyc/national_id_basic/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------- | ------ | -------- | ---------------------------------------- | | `national_id` | string | Yes | The customer's Kenyan national ID number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/national_id_basic/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"national_id": "00000000"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/national_id_basic/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ national_id: "00000000" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/kenya_kyc/national_id_basic/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"national_id": "00000000"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------- | --------------------------------- | | `data.First_Name` | string | Customer's first name | | `data.Surname` | string | Customer's surname | | `data.Other_Name` | string | Other names | | `data.Gender` | string | `"M"` or `"F"` | | `data.Citizenship` | string | e.g., `"Kenyan"` | | `data.Date_of_Birth` | string | Date of birth | | `data.Date_of_Issue` | string | ID issue date | | `data.Place_of_Birth` | string | Place of birth including district | | `data.Place_of_Live` | string | Registered address | | `data.Photo` | string | Base64-encoded customer photo | | `data.ErrorOcurred` | boolean | `false` on success | ```json theme={null} { "status": "success", "data": { "Gender": "M", "Surname": "Leo", "First_Name": "Joe", "Other_Name": "Doe", "Citizenship": "Kenyan", "ErrorOcurred": false, "Date_of_Birth": "2000-09-20 12:00:00 AM", "Date_of_Issue": "1/27/2000 12:00:00 AM", "Place_of_Live": "BOX 12345-00800 NAIROBI\nKAREN\nLOCATION - LANGATA", "Place_of_Birth": "NAIROBI\nDISTRICT - STAREHE", "Photo": "" }, "message": "National ID Basic details retrieved successfully" } ``` ### 400 Bad Request Returned when the ID number is missing, malformed, or not found. ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Bank Verification Number (BVN) Source: https://docs.smartcomply.com/v3/kyc/nigeria/BVN POST /api/onboarding/nigeria_kyc/bvn/ Verify a customer's identity using their 11-digit Bank Verification Number. The BVN endpoint verifies a customer's Bank Verification Number and returns their registered personal details from the Central Bank of Nigeria's database. Use this for KYC onboarding, identity confirmation, and fraud prevention. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/bvn/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------ | | `bvn` | string | Yes | The customer's 11-digit Bank Verification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22000000001"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ bvn: "22000000001" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"bvn": "22000000001"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | ------------------- | ------ | ---------------------------------------- | | `status` | string | `"success"` on a successful verification | | `data.lastName` | string | Customer's last name as registered | | `data.firstName` | string | Customer's first name as registered | | `data.middleName` | string | Customer's middle name | | `data.dateOfBirth` | string | Date of birth in `YYYY-MM-DD` format | | `data.phoneNumber1` | string | Primary registered phone number | | `message` | string | Human-readable result summary | ```json theme={null} { "status": "success", "data": { "lastName": "OMOLE", "firstName": "ABRAHAM", "middleName": "ISAAC", "dateOfBirth": "1909-09-19", "phoneNumber1": "09011001100" }, "message": "Bank Verification Number details retrieved successfully" } ``` ### 400 Bad Request Returned when the BVN is missing, malformed, or not found in the database. ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized Returned when the `x-access-token` header is missing or invalid. ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` For a full list of error codes, see the [Error Codes](/error_codes) reference. # Bank Verification Number Advanced (BVN) Source: https://docs.smartcomply.com/v3/kyc/nigeria/BVN_Advanced POST /api/onboarding/nigeria_kyc/bvn_advanced/ Retrieve a full verified BVN profile including enrollment data, marital status, and customer photo. The BVN Advanced endpoint provides a comprehensive view of a customer's identity. In addition to standard BVN fields, it returns enrollment details, watchlist status, residential address, and a base64-encoded customer photo. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/bvn_advanced/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------- | ------ | -------- | --------------------------------------------------- | | `bvn` | string | Yes | The customer's 11-digit Bank Verification Number | | `date_of_birth` | string | Yes | The customer's date of birth in `YYYY-MM-DD` format | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn_advanced/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22000000001", "date_of_birth": "1990-01-15"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn_advanced/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ bvn: "22000000001", date_of_birth: "1990-01-15" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn_advanced/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"bvn": "22000000001", "date_of_birth": "1990-01-15"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------- | ------ | ------------------------------------------------------ | | `data.bvn` | string | The BVN that was queried | | `data.image` | string | Base64-encoded JPEG of the customer's registered photo | | `data.title` | string | Honorific (e.g., `"Mr"`, `"Mrs"`) | | `data.gender` | string | `"male"` or `"female"` | | `data.lastName` | string | Customer's last name | | `data.firstName` | string | Customer's first name | | `data.middleName` | string | Customer's middle name | | `data.dateOfBirth` | string | Date of birth in `YYYY-MM-DD` format | | `data.phoneNumber1` | string | Primary registered phone number | | `data.phoneNumber2` | string | Secondary phone number (if available) | | `data.maritalStatus` | string | e.g., `"Single"`, `"Married"` | | `data.lgaOfOrigin` | string | Local government area of origin | | `data.stateOfOrigin` | string | State of origin | | `data.stateOfResidence` | string | State of current residence | | `data.lgaOfResidence` | string | LGA of residence (if available) | | `data.residentialAddress` | string | Residential address (if available) | | `data.enrollmentBank` | string | Bank code where BVN was enrolled | | `data.enrollmentBranch` | string | Branch where BVN was enrolled | | `data.registrationDate` | string | Date of BVN registration | | `data.levelOfAccount` | string | CBN account tier level | | `data.watchListed` | string | `"YES"` if on a watchlist, otherwise `"NO"` | ```json theme={null} { "status": "success", "data": { "bvn": "22000000001", "image": "", "title": "Mr", "gender": "male", "lastName": "OMOLE", "firstName": "ABRAHAM", "middleName": "ISAAC", "nameOnCard": "", "dateOfBirth": "1909-09-19", "lgaOfOrigin": "Ado-Odo/Ota", "watchListed": "NO", "phoneNumber1": "09011001100", "phoneNumber2": "", "maritalStatus": "Single", "stateOfOrigin": "Ogun State", "enrollmentBank": "033", "levelOfAccount": "Level 1 - Low Level Accounts", "lgaOfResidence": "", "enrollmentBranch": "0517-OTA 2", "registrationDate": "2017-09-05", "stateOfResidence": "Ogun State", "residentialAddress": "" }, "message": "Bank Verification Number details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Corporate Affairs Commission (CAC) Source: https://docs.smartcomply.com/v3/kyc/nigeria/CAC POST /api/onboarding/nigeria_kyc/cac/ Verify a registered Nigerian business using its CAC registration number. The CAC endpoint returns verified details of a registered business from the Corporate Affairs Commission database, including address, registration date, and approved name. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/cac/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | -------------------------------------------------------------------------------------------------- | | `registration_number` | string | Yes | The CAC registration number | | `company_name` | string | Yes | Registered company name | | `company_type` | string | Yes | Entity type: `"RC"` (registered company), `"BN"` (business name), or `"IT"` (incorporated trustee) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/cac/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "1261103", "company_name": "JOYCE VENTURES", "company_type": "RC"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/cac/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"registration_number": "1261103", "company_name": "JOYCE VENTURES", "company_type": "RC"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------- | ------- | --------------------------------- | | `data[].id` | integer | Internal record ID | | `data[].rcNumber` | string | CAC registration number | | `data[].approvedName` | string | Government-approved business name | | `data[].address` | string | Registered business address | | `data[].city` | string | City | | `data[].state` | string | State | | `data[].lga` | string | Local government area | | `data[].email` | string | Business email (if available) | | `data[].registrationDate` | string | Date of CAC registration | ```json theme={null} { "status": "success", "data": [ { "id": 8693434, "lga": "Ibadan North West", "city": "Mokola Ibadan", "email": "joyceventures@gmail.com", "state": "OYO", "address": "Okunmade street, Opposite Veterinary Hospital", "rcNumber": "1261103", "approvedName": "JOYCE VENTURES", "registrationDate": "2023-07-11T08:39:54.898+00:00" } ], "message": "Business Registration details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # CAC Advanced Source: https://docs.smartcomply.com/v3/kyc/nigeria/CAC_Advanced POST /api/onboarding/nigeria_kyc/cac_advanced/ Retrieve a comprehensive CAC business profile including directors and shareholding structure. The CAC Advanced endpoint returns a full business profile from the Corporate Affairs Commission, including the complete list of directors, their personal details, shareholding information, and affiliated PSC data. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/cac_advanced/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | -------------------------------------------------------------------------------------------------- | | `registration_number` | string | Yes | The CAC registration number | | `company_name` | string | Yes | Registered company name | | `company_type` | string | Yes | Entity type: `"RC"` (registered company), `"BN"` (business name), or `"IT"` (incorporated trustee) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/cac_advanced/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "10056", "company_name": "JOYCE VENTURES", "company_type": "IT"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/cac_advanced/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"registration_number": "10056", "company_name": "JOYCE VENTURES", "company_type": "IT"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------ | ------- | ------------------------------------------------------------- | | `data.rc_number` | string | Registration number | | `data.company_name` | string | Company name | | `data.company_id` | integer | Internal company ID | | `data.entity_type` | string | Entity type (e.g., `"IT"`, `"RC"`, `"BN"`) | | `data.company_status` | string | e.g., `"ACTIVE"` | | `data.registrationDate` | string | Date of registration | | `data.directors` | array | List of directors with full personal and shareholding details | | `data.directors[].firstname` | string | Director's first name | | `data.directors[].surname` | string | Director's surname | | `data.directors[].gender` | string | Director's gender | | `data.directors[].status` | string | Director status (e.g., `"ACTIVE"`) | | `data.directors[].isChairman` | boolean | `true` if the director is the chairman | | `data.directors[].dateOfAppointment` | string | Date of appointment | ```json theme={null} { "status": "success", "data": { "rc_number": "10056", "company_name": "JOYCE VENTURES", "company_id": 906200, "entity_type": "IT", "company_status": "ACTIVE", "registrationDate": "2007-03-30", "directors": [ { "id": 11234246, "firstname": "SAMSON", "surname": "ADELOLU", "otherName": "DANIEL", "gender": "MALE", "status": "ACTIVE", "occupation": "CLERGY", "isChairman": true, "dateOfAppointment": "2007-03-13T00:00:00.000+00:00", "city": "IBADAN", "state": "OYO", "address": "NO. 4, AGBA ROAD, SANYO" } ] }, "message": "Business Registration details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Driver's License Source: https://docs.smartcomply.com/v3/kyc/nigeria/Drivers_License POST /api/onboarding/nigeria_kyc/driver_license/ Verify a customer's identity using their Nigerian driver's license number. This service is not available at the moment. We're working to restore it — please check back soon. The Driver's License endpoint retrieves verified identity information from the FRSC database, including name, date of birth, license validity dates, state of issue, and a photo. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/driver_license/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | -------------------------------------- | | `license_number` | string | Yes | The customer's driver's license number | | `first_name` | string | Yes | First name as on the license | | `last_name` | string | Yes | Last name as on the license | | `date_of_birth` | string | Yes | Date of birth in `YYYY-MM-DD` format | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/driver_license/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"license_number": "ARR10892UU00", "first_name": "EDIKAN", "last_name": "EFE", "date_of_birth": "1994-08-11"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/driver_license/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"license_number": "ARR10892UU00", "first_name": "EDIKAN", "last_name": "EFE", "date_of_birth": "1994-08-11"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ------------------- | ------ | ------------------------------ | | `data.licenseNo` | string | License number | | `data.lastName` | string | Last name | | `data.firstName` | string | First name | | `data.middleName` | string | Middle name | | `data.gender` | string | Gender | | `data.dateOfBirth` | string | Date of birth | | `data.issuedDate` | string | License issue date | | `data.expiryDate` | string | License expiry date | | `data.stateOfIssue` | string | State where license was issued | | `data.image` | string | Base64-encoded license photo | ```json theme={null} { "status": "success", "data": { "licenseNo": "ARR10892UU00", "lastName": "EDIKAN", "firstName": "EFE", "middleName": "MUNACHI", "gender": "male", "issuedDate": "2013-10-28", "expiryDate": "2018-11-28", "stateOfIssue": "OYO", "dateOfBirth": "1994-08-11", "image": "" }, "message": "Driver License details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Phone Number Advanced Source: https://docs.smartcomply.com/v3/kyc/nigeria/Phone_Number_Advanced POST /api/onboarding/nigeria_kyc/phone_no_advanced/ Retrieve full NIN profile data linked to any phone number registered against an identity. The Phone Number Advanced endpoint returns a full NIN identity profile associated with a given phone number, including numbers beyond the primary registration. Use this when you need to verify additional phone numbers linked to a customer's NIN. For the primary phone number registered to an NIN, use [Phone Number Basic](/v3/kyc/nigeria/phone_number_basic) — it is faster and returns core identity fields. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/phone_no_advanced/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | -------------- | ------ | -------- | ------------------------------------------------------------------ | | `phone_number` | string | Yes | The customer's phone number (Nigerian format, e.g., `09011001100`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/phone_no_advanced/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"phone_number": "09011001100"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/phone_no_advanced/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"phone_number": "09011001100"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------ | ------ | ------------------------------ | | `data.nin` | string | NIN linked to the phone number | | `data.surname` | string | Last name | | `data.firstname` | string | First name | | `data.middlename` | string | Middle name | | `data.gender` | string | Gender (`"M"` or `"F"`) | | `data.birthdate` | string | Date of birth | | `data.telephoneno` | string | Phone number | | `data.residence_address` | string | Residential address | | `data.residence_state` | string | State of residence | | `data.residence_lga` | string | LGA of residence | ```json theme={null} { "status": "success", "data": { "nin": "384748493020", "surname": "JOHN", "firstname": "DOE", "middlename": "MID", "gender": "F", "birthdate": "1 JAN 2000", "telephoneno": "09011001100", "residence_address": "", "residence_state": "", "residence_lga": "" }, "message": "Phone Number details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Virtual NIN (VNIN) Source: https://docs.smartcomply.com/v3/kyc/nigeria/VNIN POST /api/onboarding/nigeria_kyc/vnin/ Verify a customer's identity using their 16-character Virtual National Identification Number. This service is not available at the moment. We're working to restore it — please check back soon. The VNIN endpoint validates a Virtual National Identification Number — a tokenised version of a customer's NIN generated by NIMC — and returns their core identity profile. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/vnin/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------ | | `vnin` | string | Yes | The customer's 16-character Virtual NIN (e.g., `AB012345678910YZ`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/vnin/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"vnin": "AB012345678910YZ"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/vnin/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"vnin": "AB012345678910YZ"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ----------------- | ------ | ------------------------------ | | `data.vnin` | string | The VNIN that was queried | | `data.firstname` | string | First name | | `data.middlename` | string | Middle name | | `data.lastname` | string | Last name | | `data.gender` | string | `"M"` or `"F"` | | `data.mobile` | string | Registered mobile number | | `data.photo` | string | Base64-encoded customer photo | | `data.customer` | string | Unique customer reference UUID | ```json theme={null} { "status": "success", "data": { "vnin": "AB012345678910YZ", "firstname": "John", "middlename": "Doe", "lastname": "Alamutu", "gender": "M", "mobile": "08012345678", "photo": "", "customer": "6bb82c41-e15e-4308-b99d-e9640818eca9" }, "message": "Virtual National Identification Number details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "VNIN is required" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Voter's ID Source: https://docs.smartcomply.com/v3/kyc/nigeria/Voters_ID POST /api/onboarding/nigeria_kyc/voters_id/ Verify a customer's identity using their Nigerian Permanent Voter's Card number. This service is not available at the moment. We're working to restore it — please check back soon. The Voter's ID endpoint validates a Permanent Voter's Card (PVC) number against the INEC database and returns the voter's registered personal details, registration area, and polling unit. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/voters_id/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------- | ------ | -------- | ------------------------------------- | | `voters_id` | string | Yes | The Permanent Voter's Card number | | `first_name` | string | Yes | First name as on the voter's card | | `last_name` | string | Yes | Last name as on the voter's card | | `date_of_birth` | string | Yes | Date of birth in `YYYY-MM-DD` format | | `lga` | string | Yes | Local government area of registration | | `state` | string | Yes | State of registration | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/voters_id/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"voters_id": "91F6B1F5BE295355586", "first_name": "John", "last_name": "Doe", "date_of_birth": "1994-08-11", "lga": "Lagos", "state": "Lagos"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/voters_id/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"voters_id": "91F6B1F5BE295355586", "first_name": "John", "last_name": "Doe", "date_of_birth": "1994-08-11", "lga": "Lagos", "state": "Lagos"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ---------------------------------- | ------ | ----------------------------------- | | `data.full_name` | string | Full name as registered | | `data.voter_identification_number` | string | PVC identification number | | `data.gender` | string | Gender | | `data.occupation` | string | Registered occupation | | `data.time_of_registration` | string | Date and time of voter registration | | `data.state` | string | State of registration | | `data.local_government` | string | LGA of registration | | `data.registration_area_ward` | string | Ward name | | `data.polling_unit` | string | Polling unit description | | `data.polling_unit_code` | string | Polling unit code | ```json theme={null} { "status": "success", "data": { "full_name": "JOHN DOE S", "voter_identification_number": "90F5B1C5B1234567890", "gender": "Male", "occupation": "STUDENT", "time_of_registration": "2011-01-18 13:59:46", "state": "ONDO", "local_government": "IDANRE", "registration_area_ward": "ISALU JIGBOKIN", "polling_unit": "OJAJIGBOKIN, O/S IN FRONT OF ABANA I & II", "polling_unit_code": "28/08/08/005" }, "message": "Voters Identification details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Company Tax ID Source: https://docs.smartcomply.com/v3/kyc/nigeria/company_tax_id POST /api/onboarding/business/company_tax_id/ Verify a Nigerian company's tax records using its CAC registration number. Company/business only. This is a different check from [Company TIN](/v3/kyc/nigeria/tin) — Company Tax ID looks up FIRS tax records using the company's **CAC registration number**, while Company TIN looks up FIRS tax records using the company's **TIN**. Use whichever identifier you already have. The Company Tax ID endpoint validates a Nigerian company's tax records against the FIRS (Federal Inland Revenue Service) database using its CAC registration number, and returns the associated tax identification details. ## Endpoint ``` POST /api/onboarding/business/company_tax_id/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `registration_number` | string | Yes | The company's CAC registration number, including its type prefix (e.g. `RC1234567`, `BN1234567`, `IT1234567`, `LP1234567`, or `LLP1234567`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/business/company_tax_id/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"registration_number": "RC1234567"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/business/company_tax_id/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"registration_number": "RC1234567"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ---------------------------------------------- | ------- | --------------------------------------------------------------------- | | `data.valid` | boolean | Whether a match was found | | `data.business_name` | string | Registered company name | | `data.registration_number` | string | CAC registration number | | `data.id_number` | string | Company's Tax ID | | `data.company_information.name` | string | Registered company name | | `data.company_information.registration_number` | string | CAC registration number | | `data.company_information.tax_id` | string | Company's Tax ID | | `data.company_information.tax_office` | string | Assigned tax office (not returned by Youverify for every company) | | `data.company_information.phone` | string | Registered phone number (not returned by Youverify for every company) | | `data.company_information.email` | string | Registered email (not returned by Youverify for every company) | ```json theme={null} { "status": "success", "data": { "valid": true, "id_number": "2622476055669", "company_information": { "name": "OASIS TASTE & TREAT LTD", "registration_number": "RC9435541", "tin": null, "jtb_tin": null, "tax_id": "2622476055669", "tax_office": null, "phone": null, "email": null }, "business_name": "OASIS TASTE & TREAT LTD", "registration_number": "RC9435541" }, "message": "Company Tax ID details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Registration Number is required." } ``` ```json theme={null} { "status": "failed", "data": {"error_code": "INVALID_INPUT"}, "message": "Company Tax ID check failed: ValidationError: Invalid registration number format. Valid format => RCxxxx, BNxxxxx, ITxxxxx, LPxxxxx or LLPxxxxx" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # National Identity Number (NIN) Source: https://docs.smartcomply.com/v3/kyc/nigeria/nin POST /api/onboarding/nigeria_kyc/nin/ Verify a customer's identity using their 11-digit National Identification Number. The NIN endpoint retrieves a customer's verified identity data from the National Identity Management Commission (NIMC) database. It returns comprehensive personal details including biographic data, next-of-kin information, and a customer photo. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/nin/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ------------------------------------------------------ | | `identification_number` | string | Yes | The customer's 11-digit National Identification Number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nin/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"identification_number": "70123456789"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nin/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ identification_number: "70123456789" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nin/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"identification_number": "70123456789"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | ----------------------- | -------------- | -------------------------------------------- | | `data.nin` | string | The NIN that was queried | | `data.firstName` | string | First name | | `data.middleName` | string | Middle name | | `data.lastName` | string | Surname | | `data.gender` | string | `"male"` or `"female"` | | `data.dateOfBirth` | string | Date of birth in `YYYY-MM-DD` format | | `data.birthState` | string | State of birth | | `data.birthLga` | string | LGA of birth | | `data.telephoneNo` | string | Registered phone number | | `data.email` | string \| null | Email address (if available) | | `data.residenceAddress` | string | Current residential address | | `data.residenceState` | string | State of residence | | `data.residenceLga` | string | LGA of residence | | `data.residenceTown` | string | Town of residence | | `data.maritalStatus` | string | e.g., `"single"`, `"married"`, `"separated"` | | `data.educationalLevel` | string | Highest education level | | `data.employmentStatus` | string | e.g., `"employed"`, `"unemployed"` | | `data.religion` | string | Religion | | `data.spokenLanguage` | string | Primary spoken language | | `data.height` | string | Height in centimetres | | `data.profession` | string | Stated profession | | `data.nokFirstname` | string | Next-of-kin first name | | `data.nokSurname` | string | Next-of-kin surname | | `data.nokAddress1` | string | Next-of-kin address | | `data.nokState` | string | Next-of-kin state | | `data.nokLga` | string | Next-of-kin LGA | | `data.image` | string | Base64-encoded JPEG of the customer's photo | | `data.trackingId` | string | NIMC tracking reference | ```json theme={null} { "status": "success", "data": { "title": "mr", "lastName": "DOE", "firstName": "JOHN", "middleName": "JOSEPH", "gender": "male", "dateOfBirth": "2000-10-21", "birthLga": "Olamaboro", "birthState": "Kogi", "centralID": "", "educationalLevel": "secondary", "email": null, "nin": "12345678901", "employmentStatus": "unemployed", "height": "180", "maritalStatus": "separated", "religion": "christianity", "telephoneNo": "08050003000", "residenceAddress": "MR SNUFUSS'S HOUSE SNUFUSS STREET PHASE 3", "residenceLga": "Gwagwalada", "residenceState": "FCT Abuja", "residenceTown": "GWAGWALADA", "nokFirstname": "JOHN", "nokSurname": "DOE", "nokAddress1": "NO 6 ADUM ROAD OGUGU CENTRE", "nokState": "Kogi", "nokLga": "Olamaboro", "profession": "STUDENT", "spokenLanguage": "IGALA", "trackingId": "S2R0NYFO01113TR", "image": "" }, "message": "National Identification Number details retrieved successfully" } ``` ### 400 Bad Request Returned when the NIN is missing, malformed, or not found. ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # NIN with Face Source: https://docs.smartcomply.com/v3/kyc/nigeria/nin_with_face POST /api/onboarding/nigeria_kyc/nin_with_face/ Verify a customer's NIN combined with a facial image for enhanced identity confirmation. This service is not available at the moment. We're working to restore it — please check back soon. The NIN with Face endpoint verifies a customer's National Identification Number and performs a facial comparison against a provided photo URL. It returns full NIN profile data plus face match results. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/nin_with_face/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ------------------------------------------------------ | | `identification_number` | string | Yes | The customer's 11-digit National Identification Number | | `image_url` | string | Yes | URL of the customer's photo for facial comparison | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nin_with_face/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"identification_number": "70123456789", "image_url": "https://example.com/photo.jpg"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nin_with_face/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"identification_number": "70123456789", "image_url": "https://example.com/photo.jpg"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ----------------------------- | ------ | ------------------------------------------------------------------------- | | `data.nin_data` | object | Full NIN profile (same fields as the [NIN endpoint](/v3/kyc/nigeria/nin)) | | `data.face_data.message` | string | Face match result message | | `data.face_data.confidence` | number | Match confidence percentage (0–100) | | `data.verification.status` | string | `"VERIFIED"` if identity confirmed | | `data.verification.reference` | string | Unique verification reference ID | ```json theme={null} { "status": "success", "data": { "nin_data": { "lastName": "UCHE", "firstName": "KARIM", "middleName": "IKENNA", "gender": "male", "dateOfBirth": "2002-11-09", "nin": "90187493033", "telephoneNo": "09088118811", "residenceAddress": "5, ODEYEMI STREET, ANIMASHAUN", "residenceLga": "Ifo", "residenceState": "Ogun", "image": "" }, "face_data": { "message": "Face Match", "confidence": 99.99 }, "verification": { "status": "VERIFIED", "reference": "8314a5fc-bdb5-40c8-98bd-72aef9f1a868" } }, "message": "National Identification Number details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # NUBAN Verification Source: https://docs.smartcomply.com/v3/kyc/nigeria/nuban POST /api/onboarding/nigeria_kyc/nuban/ Resolve a Nigerian bank account number to its registered account name and bank. The NUBAN endpoint verifies a Nigerian Uniform Bank Account Number (NUBAN) and returns the account name and bank associated with it. Use this for bank account ownership verification during onboarding or payment flows. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/nuban/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | ---------------------------------------- | | `account_number` | string | Yes | The 10-digit NUBAN account number | | `bank_code` | string | Yes | The 3–6 digit bank code (see list below) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nuban/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"account_number": "0768540312", "bank_code": "035"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nuban/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"account_number": "0768540312", "bank_code": "035"}, ) ``` ### Bank Codes Reference | Bank | Code | | ---------------------------- | -------- | | Access Bank | `044` | | Citibank Nigeria | `023` | | ECOBANK | `050` | | FCMB | `214` | | Fidelity Bank | `070` | | First Bank of Nigeria | `011` | | GTBank | `058` | | Heritage Bank | `030` | | JAIZ Bank | `301` | | Kuda Microfinance Bank | `50211` | | Lotus Bank | `303` | | Moniepoint Microfinance Bank | `50563` | | Opay | `999992` | | Palmpay | `999111` | | Polaris Bank | `076` | | Providus Bank | `101` | | Stanbic IBTC Bank | `221` | | Standard Chartered Bank | `068` | | Sterling Bank | `232` | | TAJBank | `302` | | Union Bank of Nigeria | `032` | | United Bank For Africa | `033` | | Unity Bank | `215` | | Wema Bank | `035` | | Zenith Bank | `057` | ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------- | ------------------------------- | | `data.bank_id` | integer | Internal bank identifier | | `data.account_name` | string | Registered account holder name | | `data.account_number` | string | Account number that was queried | ```json theme={null} { "status": "success", "data": { "bank_id": 11, "account_name": "STEPHEN BADMUS", "account_number": "0768540312" }, "message": "Nuban details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # NUBAN Advanced Source: https://docs.smartcomply.com/v3/kyc/nigeria/nuban_advanced POST /api/onboarding/nigeria_kyc/nuban_advanced/ Retrieve enhanced account verification data including account name, bank, and identity details. The NUBAN Advanced endpoint provides a more comprehensive view of a bank account compared to the standard NUBAN check, returning additional identity data linked to the account. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/nuban_advanced/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | ---------------------------------------------------------------------------------- | | `account_number` | string | Yes | The 10-digit NUBAN account number | | `bank_code` | string | Yes | The bank code (see [NUBAN bank codes](/v3/kyc/nigeria/nuban#bank-codes-reference)) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nuban_advanced/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"account_number": "0768540312", "bank_code": "035"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/nuban_advanced/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"account_number": "0768540312", "bank_code": "035"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------- | ------------------------------- | | `data.bank_id` | integer | Internal bank identifier | | `data.account_name` | string | Registered account holder name | | `data.account_number` | string | Account number that was queried | ```json theme={null} { "status": "success", "data": { "bank_id": 11, "account_name": "STEPHEN BADMUS", "account_number": "0768540312" }, "message": "Nuban details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Account Number and Bank Code are required" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Passport Verification Source: https://docs.smartcomply.com/v3/kyc/nigeria/passport_verification POST /api/onboarding/nigeria_kyc/passport/ Verify a customer's identity using their Nigerian international passport number. This service is not available at the moment. We're working to restore it — please check back soon. The Passport Verification endpoint validates a Nigerian passport number against the government database and returns the holder's personal details, passport validity dates, and a photo. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/passport/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------ | | `passport_number` | string | Yes | The customer's passport number | | `surname` | string | Yes | Surname as on the passport | | `date_of_birth` | string | Yes | Date of birth in `YYYY-MM-DD` format | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/passport/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"passport_number": "Z18679232", "surname": "John", "date_of_birth": "1994-08-11"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/passport/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"passport_number": "Z18679232", "surname": "John", "date_of_birth": "1994-08-11"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------ | ------------------------------------------- | | `data.passportNumber` | string | Passport number | | `data.lastName` | string | Last name | | `data.firstName` | string | First name | | `data.middleName` | string | Middle name | | `data.dateOfBirth` | string | Date of birth | | `data.gender` | string | Gender | | `data.dateOfIssue` | string | Passport issue date | | `data.expiryDate` | string | Passport expiry date | | `data.issuePlace` | string | State/location where passport was issued | | `data.documentType` | string | Passport type (e.g., `"Standard Passport"`) | | `data.phoneNumber` | string | Registered phone number | | `data.image` | string | Base64-encoded passport photo | | `data.referenceID` | string | Internal reference ID | ```json theme={null} { "status": "success", "data": { "passportNumber": "Z18679232", "dateOfIssue": "20/09/2023", "expiryDate": "19/09/2028", "documentType": "Standard Passport", "issuePlace": "OGUN STATE", "lastName": "JOHN", "firstName": "EMMANUEL", "middleName": "IFEANYI", "dateOfBirth": "10/04/2000", "gender": "Male", "image": "", "referenceID": "23445", "phoneNumber": "09011002200" }, "message": "International Passport details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Phone Number Basic Source: https://docs.smartcomply.com/v3/kyc/nigeria/phone_number_basic POST /api/onboarding/nigeria_kyc/phone_no_basic/ Retrieve core identity data for the primary phone number registered to a customer's NIN. The Phone Number Basic endpoint returns the name and date of birth associated with the primary phone number registered against a customer's NIN. For other numbers linked to the same NIN, use [Phone Number Advanced](/v3/kyc/nigeria/Phone_Number_Advanced). ## Endpoint ``` POST /api/onboarding/nigeria_kyc/phone_no_basic/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | -------------- | ------ | -------- | ------------------------------------------------------------------ | | `phone_number` | string | Yes | The customer's phone number (Nigerian format, e.g., `09011001100`) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/phone_no_basic/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"phone_number": "09011001100"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/phone_no_basic/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"phone_number": "09011001100"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | ------------------ | ------ | ------------------------------------ | | `data.surname` | string | Last name | | `data.firstName` | string | First name | | `data.middleName` | string | Middle name | | `data.dateOfBirth` | string | Date of birth in `YYYY-MM-DD` format | | `data.phoneNumber` | string | Phone number that was queried | ```json theme={null} { "status": "success", "data": { "surname": "AKINSANYA", "firstName": "TISEOLUWA", "middleName": "JOHN", "dateOfBirth": "1909-09-19", "phoneNumber": "09011001100" }, "message": "Phone Number details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Company TIN Source: https://docs.smartcomply.com/v3/kyc/nigeria/tin POST /api/onboarding/nigeria_kyc/tin/ Verify a Nigerian company's Tax Identification Number. Company/business TIN only. Individual TIN lookups are not supported by any provider behind this endpoint. The Company TIN endpoint validates a business Tax Identification Number against the FIRS (Federal Inland Revenue Service) database and returns the associated taxpayer name, CAC registration number, tax office, and contact details. `/api/onboarding/business/company_tin/` is an alias for this same endpoint and check. If you're already integrated against it, no change is needed — it continues to work. For new integrations, use `/api/onboarding/nigeria_kyc/tin/` above. ## Endpoint ``` POST /api/onboarding/nigeria_kyc/tin/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------------------------- | ------ | -------- | ------------------------------------------------------------------------------- | | `tax_identification_number` | string | Yes | The company's Tax Identification Number (format: `234123456-0001`, 8-14 digits) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/tin/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"tax_identification_number": "234123456-0001"}' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/tin/", headers={"x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json"}, json={"tax_identification_number": "234123456-0001"}, ) ``` ## Response ### 200 OK | Field | Type | Description | | --------------------- | ------ | --------------------------------------- | | `data.taxpayer_name` | string | Registered taxpayer name | | `data.cac_reg_number` | string | CAC registration number (if applicable) | | `data.firstin` | string | First TIN issued | | `data.jittin` | string | Joint income TIN (if applicable) | | `data.tax_office` | string | Assigned tax office | | `data.phone_number` | string | Registered phone number | | `data.email` | string | Registered email (if available) | | `data.search` | string | The search term used | ```json theme={null} { "status": "success", "data": { "search": "07012345678", "taxpayer_name": "FISAYOMI KAYODE NIG LTD", "cac_reg_number": "RC012345", "firstin": "12345678-0001", "jittin": "N/A", "tax_office": "MSTO ALIMOSHO", "phone_number": "08109110099", "email": "" }, "message": "Tax Identification Number details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # National ID Source: https://docs.smartcomply.com/v3/kyc/south_africa/National_ID POST /api/onboarding/south_africa_kyc/national_id/ Verify a customer's identity using their South African ID number (SAID). The South Africa National ID endpoint validates a South African ID number (SAID) and returns the associated personal details from the national registry. ## Endpoint ``` POST /api/onboarding/south_africa_kyc/national_id/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------- | | `national_id` | string | Yes | The customer's South African ID number (SAID) | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/south_africa_kyc/national_id/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"national_id": "0508225709080"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/south_africa_kyc/national_id/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ national_id: "0508225709080" }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/south_africa_kyc/national_id/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"national_id": "0508225709080"}, ) data = response.json() ``` ## Response ### 200 OK | Field | Type | Description | | -------------------- | ------- | ----------------------- | | `data.valid` | boolean | Whether the ID is valid | | `data.first_name` | string | Customer's first name | | `data.last_name` | string | Customer's last name | | `data.middle_name` | string | Middle name, if any | | `data.date_of_birth` | string | Date of birth | | `data.gender` | string | Gender | | `data.nationality` | string | Nationality | | `data.id_number` | string | South African ID number | ```json theme={null} { "status": "success", "data": { "valid": true, "first_name": "IRVEN", "middle_name": "LONDILE", "last_name": "RAMOLETA", "nationality": "ZA", "id_number": "0508225709080" }, "message": "National ID details retrieved successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Business Loan Fraud Check Source: https://docs.smartcomply.com/v3/loan/business_fraud_check POST /api/v1/loan/fraud_check/ Assess the fraud risk of a business loan application using company data and credit history. The Business Loan Fraud Check endpoint evaluates a loan application from a business entity, combining submitted company information with credit bureau data to produce a fraud risk score and financial analysis. ## Endpoint ``` POST /api/v1/loan/fraud_check/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------------------------- | ------- | -------- | ---------------------------------------------------- | | `business_name` | string | Yes | Registered name of the business | | `business_address` | string | Yes | Business address | | `rc_number` | string | Yes | CAC registration number (e.g., `RC-123456`) | | `city` | string | Yes | City of the business | | `country` | string | Yes | Country of the business | | `phone_number` | string | Yes | Business phone number | | `email_address` | string | Yes | Business email address | | `identification_type` | string | Yes | ID type used (e.g., `Passport`, `RC Number`) | | `identification_number` | string | Yes | ID number | | `annual_revenue` | number | Yes | Annual revenue in local currency | | `bank_name` | string | Yes | Business bank name | | `account_number` | string | Yes | Business account number | | `loan_amount_requested` | number | Yes | Requested loan amount | | `purpose_of_loan` | string | No | Purpose of the loan | | `loan_repayment_duration_type` | string | Yes | Repayment period unit: `weeks`, `months`, or `years` | | `loan_repayment_duration_value` | integer | Yes | Number of repayment periods | | `collateral_required` | boolean | Yes | Whether collateral is being offered | | `is_business` | boolean | Yes | Must be `true` for business checks | | `run_aml_check` | boolean | No | Run an AML check. Defaults to `false` | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/loan/fraud_check/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "business_name=Heineken" \ -F "business_address=23 Main Street, Marina" \ -F "rc_number=RC-123456" \ -F "city=Lagos" \ -F "country=Nigeria" \ -F "phone_number=2349012345678" \ -F "email_address=business@example.com" \ -F "identification_type=RC Number" \ -F "identification_number=RC-123456" \ -F "annual_revenue=12345678" \ -F "bank_name=Access Bank" \ -F "account_number=1234567890" \ -F "loan_amount_requested=1000000" \ -F "loan_repayment_duration_type=months" \ -F "loan_repayment_duration_value=5" \ -F "collateral_required=false" \ -F "is_business=true" \ -F "run_aml_check=false" ``` ## Response ### 200 OK | Field | Type | Description | | -------------------------------------------------- | ------ | --------------------------------------------------------------- | | `data.id` | number | Internal record ID | | `data.business_name` | string | Business name from the application | | `data.fraud_risk_score` | number | Overall fraud risk score (0–100; higher = greater risk) | | `data.recommendation` | string | Narrative assessment and guidance for loan decision | | `data.key_financial_analysis.income_stability` | object | Revenue stability with disposable income ratio | | `data.key_financial_analysis.repayment_duration` | object | Repayment timeline assessment | | `data.key_financial_analysis.collateral_coverage` | object | Loan-to-collateral ratio | | `data.key_financial_analysis.debt_serviceability` | object | Ability to service debt from revenue | | `data.key_financial_analysis.debt_to_income_ratio` | object | Debt service ratio vs the 40% threshold | | `data.history` | object | Credit history: total loans, delinquencies, outstanding amounts | | `data.status` | string | Processing status (e.g., `reviewed`) | ```json theme={null} { "status": "Success", "data": { "id": 567, "business_name": "Heineken", "country": "Nigeria", "city": "Lagos", "business_address": "23 Main Street, Apapa", "identification_type": "RC Number", "rc_number": "RC-123456", "phone_number": "2349012345678", "annual_revenue": "12345678.00", "loan_amount_requested": 1000000.00, "purpose_of_loan": "Business Expansion", "fraud_risk_score": 62, "recommendation": "The applicant is requesting a loan of ₦1,000,000.00. The applicant's total fraud risk score is 62, which needs to be evaluated against the lender's risk threshold.", "key_financial_analysis": { "income_stability": { "risk_score": 100, "data_source": "submitted data (estimated)", "monthly_income": "1028806.50", "monthly_expenses": "925925.85", "disposable_income": "102880.65", "observation": "Disposable ratio of 10% indicates limited buffer for unexpected expenses." }, "repayment_duration": { "risk_score": 70, "repayment_duration": "Within 5 months" }, "collateral_coverage": { "risk_score": 80, "loan_amount": "1000000.00", "collateral_value": "0.00", "loan_to_collateral_ratio": "0.00%", "observation": "The loan is entirely unsecured." }, "debt_serviceability": { "risk_score": 30, "loan_amount": "1000000.00", "total_repayment": "1040000.0000", "observation": "Monthly repayment constitutes ~20% of monthly income, indicating manageable serviceability." }, "debt_to_income_ratio": { "risk_score": 30, "debt_service_ratio": "20.22%", "observation": "Debt Service Ratio is below the 40% threshold, indicating low debt burden." } }, "history": { "totalOverdue": 54931635, "totalBorrowed": 135582, "totalNoOfLoans": 9, "totalOutstanding": 54931635, "highestLoanAmount": 45194, "totalNoOfActiveLoans": 3, "totalNoOfClosedLoans": 6, "totalNoOfInstitutions": 2, "totalNoOfPerformingLoans": 6, "totalNoOfDelinquentFacilities": 3 }, "is_individual": false, "is_business": true, "status": "reviewed", "date_created": "2025-03-28T02:42:23.815369Z" }, "message": "Loan fraud check processed successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Individual Loan Fraud Check Source: https://docs.smartcomply.com/v3/loan/individual_fraud_check POST /api/v1/loan/fraud_check/ Assess the fraud risk of an individual loan application using applicant data and real-time credit report information. The Individual Loan Fraud Check endpoint evaluates a loan application by combining submitted applicant data with real-time credit bureau information. The response includes a fraud risk score, a recommendation, and a breakdown of key financial metrics used in the assessment. ## Endpoint ``` POST /api/v1/loan/fraud_check/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | --------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `multipart/form-data` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------ | | `first_name` | string | Yes | Applicant's first name | | `last_name` | string | Yes | Applicant's last name | | `date_of_birth` | string | Yes | Date of birth in `YYYY-MM-DD` format | | `gender` | string | Yes | Gender (e.g., `male`, `female`) | | `country` | string | Yes | Country of residence | | `current_address` | string | Yes | Current residential address | | `duration_of_stay` | string | Yes | Duration at current address (e.g., `5 years`) | | `identification_type` | string | Yes | ID type (e.g., `Passport`, `NIN`) | | `identification_number` | string | Yes | ID number | | `bvn` | string | Yes | 11-digit Bank Verification Number (Nigeria). Use `identifier` + `identifier_type` for other countries | | `identifier` | string | No | Customer identifier for non-Nigeria applicants (e.g. a Kenya national ID number) | | `identifier_type` | string | No | Key of the identifier type (e.g. `bvn`, `national_id`, `ghana_card`). Required when `identifier` is provided | | `phone_number` | string | Yes | Phone number with country code | | `email_address` | string | Yes | Applicant's email address | | `employment_type` | string | Yes | Employment type (e.g., `Full-time`, `Self-employed`) | | `job_role` | string | Yes | Job title or role | | `employer_name` | string | Yes | Name of employer | | `employer_address` | string | Yes | Employer's address | | `annual_income` | number | Yes | Annual income in local currency | | `employment_duration` | string | Yes | Length of current employment | | `loan_amount_requested` | number | Yes | Requested loan amount | | `purpose_of_loan` | string | Yes | Purpose of the loan | | `loan_repayment_duration_type` | string | Yes | Repayment period unit: `weeks`, `months`, or `years` | | `loan_repayment_duration_value` | integer | Yes | Number of repayment periods | | `collateral_required` | boolean | Yes | Whether collateral is being offered | | `collateral` | string | No | Description of collateral if applicable | | `is_individual` | boolean | Yes | Must be `true` for individual checks | | `run_aml_check` | boolean | No | Run an AML check on the applicant. Defaults to `false` | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/loan/fraud_check/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -F "first_name=John" \ -F "last_name=Doe" \ -F "date_of_birth=1980-01-01" \ -F "gender=male" \ -F "country=Nigeria" \ -F "current_address=12 Ojuelegba St" \ -F "duration_of_stay=5 years" \ -F "identification_type=Passport" \ -F "identification_number=A123456789" \ -F "bvn=12345678901" \ -F "phone_number=+2349105678901" \ -F "email_address=john.doe@example.com" \ -F "employment_type=Full-time" \ -F "job_role=Engineer" \ -F "employer_name=Smartcomply" \ -F "employer_address=47 Karimu Ikotun Cl, Yaba, Lagos" \ -F "annual_income=350000" \ -F "employment_duration=2 years" \ -F "loan_amount_requested=100000" \ -F "purpose_of_loan=Personal Development" \ -F "loan_repayment_duration_type=weeks" \ -F "loan_repayment_duration_value=7" \ -F "collateral_required=false" \ -F "is_individual=true" \ -F "run_aml_check=false" ``` For non-Nigeria applicants, omit `bvn` and pass `identifier` (the ID value) and `identifier_type` (the key, e.g. `national_id`, `ghana_card`) instead. This enables multi-country loan fraud assessment. ## Response ### 200 OK | Field | Type | Description | | -------------------------------------------------- | ------ | ---------------------------------------------------------------------- | | `data.id` | number | Internal record ID | | `data.fraud_risk_score` | number | Overall fraud risk score (0–100; higher = greater risk) | | `data.recommendation` | string | Narrative assessment and guidance for loan decision | | `data.key_financial_analysis.income_stability` | object | Income stability assessment with risk score and observation | | `data.key_financial_analysis.repayment_duration` | object | Repayment timeline assessment | | `data.key_financial_analysis.collateral_coverage` | object | Loan-to-collateral ratio and observation | | `data.key_financial_analysis.debt_serviceability` | object | Assessment of whether income can cover repayments | | `data.key_financial_analysis.debt_to_income_ratio` | object | Debt service ratio vs the 40% threshold | | `data.history` | object | Credit bureau history: total loans, delinquencies, outstanding amounts | | `data.status` | string | Processing status (e.g., `reviewed`) | ```json theme={null} { "status": "success", "data": { "id": 101, "first_name": "John", "last_name": "Doe", "date_of_birth": "1980-01-01", "country": "Nigeria", "current_address": "12 Ojuelegba St", "identification_type": "Passport", "bvn": "12345678901", "loan_amount_requested": "15000.00", "fraud_risk_score": 80, "recommendation": "The applicant, John Doe, has applied for a loan of ₦100,000.00. The applicant's total fraud risk score is 80, which is relatively high and warrants further investigation before loan approval.", "key_financial_analysis": { "income_stability": { "risk_score": 100, "data_source": "submitted data (estimated)", "monthly_income": "29166.67", "monthly_expenses": "23333.33", "disposable_income": "5833.33", "observation": "Disposable ratio of 20% indicates a small buffer between income and expenses." }, "repayment_duration": { "risk_score": 70, "repayment_duration": "Within 1.75 months" }, "collateral_coverage": { "risk_score": 80, "loan_amount": "100000.00", "collateral_value": "0.00", "loan_to_collateral_ratio": "0.00%", "observation": "The loan is entirely unsecured." }, "debt_serviceability": { "risk_score": 60, "loan_amount": "100000.00", "total_repayment": "104000.0000", "observation": "Monthly repayment significantly exceeds monthly income." }, "debt_to_income_ratio": { "risk_score": 90, "debt_service_ratio": "203.76%", "observation": "Debt Service Ratio exceeds the 40% threshold significantly." } }, "history": { "totalNoOfLoans": 16, "totalNoOfInstitutions": 5, "totalNoOfActiveLoans": 1, "totalNoOfClosedLoans": 15, "totalNoOfPerformingLoans": 16, "totalNoOfDelinquentFacilities": 0, "highestLoanAmount": 1134330, "totalBorrowed": 3761267, "totalOutstanding": 0, "totalOverdue": 0 }, "is_individual": true, "is_business": false, "status": "reviewed", "date_created": "2025-03-28T03:08:47.170109Z" }, "message": "Loan fraud check processed successfully" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Loan Fraud Check — Overview Source: https://docs.smartcomply.com/v3/loan/introduction Evaluate fraud risk for loan applications using credit report data and applicant financial details. The Loan Fraud Check API assesses the fraud risk of a loan application by combining external credit report data with the applicant's financial profile. It computes a fraud risk score and returns an actionable recommendation — **Approve**, **Review**, or **Reject** — for each application. ## How It Works Send the applicant's BVN (individual) or RC number (business) along with their financial details to the fraud check endpoint. The system fetches the applicant's current credit history from integrated credit bureaus. A rule-based engine evaluates credit history, loan-to-income ratio, applicant age, and other financial factors to compute a fraud risk score. The API returns the computed score alongside a clear recommendation for your loan approval workflow. ## Key Features Fetches up-to-date credit histories for a dynamic risk evaluation basis. Returns clear Approve, Review, or Reject guidance for each application. Supports both individual applicants (BVN) and business applicants (RC number). Strict validation at the model and serializer levels ensures data integrity. ## Endpoints | Endpoint | Description | | --------------------------------------------------------- | ------------------------------------------------ | | [Individual Fraud Check](/v3/loan/individual_fraud_check) | Assess fraud risk for individual loan applicants | | [Business Fraud Check](/v3/loan/business_fraud_check) | Assess fraud risk for business loan applicants | # Get Onboarding Settings Source: https://docs.smartcomply.com/v3/onboarding/get_settings GET /api/onboarding/settings Retrieve the current identity verification and AML screening settings for your branch. ## Endpoint ``` GET /api/onboarding/settings ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------ | -------- | | `x-access-token` | Your API key | Yes | ### Example ```bash cURL theme={null} curl https://adhere-api.smartcomply.com/api/onboarding/settings \ -H "x-access-token: YOUR_API_KEY" ``` ```python Python theme={null} import requests response = requests.get( "https://adhere-api.smartcomply.com/api/onboarding/settings", headers={"x-access-token": "YOUR_API_KEY"}, ) print(response.json()) ``` ```javascript Node.js theme={null} const response = await fetch("https://adhere-api.smartcomply.com/api/onboarding/settings", { headers: { "x-access-token": "YOUR_API_KEY" }, }); const data = await response.json(); ``` ## Response `"success"` on a successful request. `"Settings retrieved"` Whether identity verification is enabled for this branch. Defaults to `true`. Whether AML screening is enabled for this branch. Defaults to `true`. ### 200 OK ```json theme={null} { "status": "success", "message": "Settings retrieved", "data": { "ivs": true, "aml": true } } ``` ### Error Responses | HTTP Status | Message | Cause | | ----------- | ---------------------------------- | ------------------------------- | | `401` | `"Authorization token is missing"` | No `x-access-token` header | | `401` | `"Authorization failed"` | Token not recognised or expired | # Customer Onboarding Source: https://docs.smartcomply.com/v3/onboarding/introduction Verify a customer's identity and screen them for sanctions, PEPs, and adverse media in a single API call. Onboarding a new customer typically requires two separate steps: verify who they are, then check whether they appear on any watchlists. The Customer Onboarding API does both in a single call — you send a country and an ID number, and the API returns a verified identity, AML screening results, and a consolidated decision of `pass`, `review`, or `fail`. Submit a country and identifier to receive a verified identity and AML screening result in one response. Configure which steps — identity verification and AML screening — run for your branch. ## How It Works Send the customer's country and ID number. The API automatically selects the correct document type for that country — no need to specify it unless you want to override the default. The API verifies the identifier against the relevant government or bureau database and extracts the customer's verified name. The verified name is run against global sanctions lists and PEP databases. If identity verification failed and no name was returned, screening is skipped and a `note` is included in the response. Based on the combined IVS and AML result, the API returns a `decision` of `pass`, `review`, or `fail`. The raw identity and screening data are always included so you can build your own logic on top. ## Decision Guide The `decision` field is the primary signal your system should act on: | Decision | Risk level | What it means | Recommended action | | -------- | ------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | | `pass` | Low | Identity verified. No sanctions or PEP matches found. | Proceed with onboarding. | | `review` | Medium | Identity verified, but a PEP or elevated-risk match was found. | Hold onboarding. Route to a compliance officer for manual review before proceeding. | | `fail` | High / unverifiable | Identity could not be verified **or** a high-risk match was found. | Do not onboard. Decline or escalate per your compliance policy. | A `review` decision does **not** mean block the customer. It means onboarding should pause for human review before a final call is made. Automatically declining all `review` cases may exclude legitimate customers who are PEPs but present no actual risk. ## Supported Countries | Country | Default identifier | Supported overrides | | --------- | ------------------ | -------------------- | | `nigeria` | `bvn` | `bvn`, `nin`, `vnin` | | `kenya` | `national_id` | `national_id` | | `ghana` | `ghana_id` | `ghana_id` | | `uganda` | `national_id` | `national_id` | | `rwanda` | `national_id` | `national_id` | # Update Onboarding Settings Source: https://docs.smartcomply.com/v3/onboarding/update_settings POST /api/onboarding/settings Enable or disable identity verification and AML screening for your branch. Use this endpoint to control which steps run during the [Verify Customer](/v3/onboarding/verify_customer) call. Changes apply to all subsequent onboarding requests for your branch. Both `ivs` and `aml` are enabled by default. Disabling `ivs` will also cause AML screening to be skipped, since screening depends on a verified name being returned from the identity check. ## Endpoint ``` POST /api/onboarding/settings ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------ | -------- | | `x-access-token` | Your API key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | --------- | ------- | -------- | --------------------------------------- | | `ivs` | boolean | No | Enable or disable identity verification | | `aml` | boolean | No | Enable or disable AML screening | You can update one or both settings in a single call. Omitted fields retain their current value. ### Example ```bash cURL theme={null} curl -X POST https://adhere-api.smartcomply.com/api/onboarding/settings \ -H "x-access-token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aml": false }' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/settings", headers={"x-access-token": "YOUR_API_KEY"}, json={"aml": False}, ) print(response.json()) ``` ```javascript Node.js theme={null} const response = await fetch("https://adhere-api.smartcomply.com/api/onboarding/settings", { method: "POST", headers: { "x-access-token": "YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ aml: false }), }); const data = await response.json(); ``` ## Response `"success"` on a successful update. `"Settings saved"` The full settings state after the update. Current state of identity verification. Current state of AML screening. ### 200 OK ```json theme={null} { "status": "success", "message": "Settings saved", "data": { "ivs": true, "aml": false } } ``` ### Error Responses | HTTP Status | Message | Cause | | ----------- | ---------------------------------- | ------------------------------- | | `401` | `"Authorization token is missing"` | No `x-access-token` header | | `401` | `"Authorization failed"` | Token not recognised or expired | | `400` | `"Invalid value for ivs"` | Value must be a boolean | | `400` | `"Invalid value for aml"` | Value must be a boolean | # Verify Customer Source: https://docs.smartcomply.com/v3/onboarding/verify_customer POST /api/onboarding/verify_customer Run identity verification and AML screening for a customer in a single call. ## Endpoint ``` POST /api/onboarding/verify_customer ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------ | -------- | | `x-access-token` | Your API key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------ | | `country` | string | Yes | Country of the customer. Supported: `nigeria`, `kenya`, `ghana`, `uganda`, `rwanda` | | `identifier` | string | Yes | The customer's ID number (e.g. BVN, NIN, National ID) | | `identifier_type` | string | No | Overrides the country default. See [supported values](/v3/onboarding/introduction#supported-countries) | ### Example ```bash cURL theme={null} curl -X POST https://adhere-api.smartcomply.com/api/onboarding/verify_customer \ -H "x-access-token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "country": "nigeria", "identifier": "12345678901" }' ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/verify_customer", headers={"x-access-token": "YOUR_API_KEY"}, json={ "country": "nigeria", "identifier": "12345678901", }, ) print(response.json()) ``` ```javascript Node.js theme={null} const response = await fetch("https://adhere-api.smartcomply.com/api/onboarding/verify_customer", { method: "POST", headers: { "x-access-token": "YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ country: "nigeria", identifier: "12345678901", }), }); const data = await response.json(); ``` ## Response All responses return HTTP `200`. Use the `decision` field — not the HTTP status — to determine the onboarding outcome. See the [Decision Guide](/v3/onboarding/introduction#decision-guide) for how to act on each value. Always `"success"` on a `200` response. Always `"Customer onboarding completed"` on success. Unique ID for this onboarding record. Result of the identity verification step. `true` if the identifier was successfully verified against the issuing authority. The document type used, e.g. `"BVN"`, `"NIN"`, `"National ID"`. Present when `verified: true`. Present when `verified: true`. Present when `verified: true` and the provider returns a middle name. ISO-8601 date string. Present when `verified: true`. Present when `verified: true`. Present when `verified: true` and available from the provider. Error message from the verification provider. Only present when `verified: false`. AML screening results. Always returned in a consistent shape, even when screening was skipped. Sanctions matches. Each entry contains `entity_name`, `recorded_date`, `country`, `sanction_body`, `sanction_types`, and `other_information`. PEP matches. Each entry contains `name`, `pep_types`, `gender`, `country`, `source`, and `political_post`. Currently always `[]` — will be enabled as a configurable step in a future release. `"low"`, `"medium"`, or `"high"`. Present only when screening was skipped. Explains why. `"pass"`, `"review"`, or `"fail"`. See the [Decision Guide](/v3/onboarding/introduction#decision-guide). ### Pass — identity verified, no matches ```json theme={null} { "status": "success", "message": "Customer onboarding completed", "data": { "onboarding_id": 1024, "identity": { "verified": true, "identifier_type": "BVN", "first_name": "Amaka", "middle_name": "Chisom", "last_name": "Okafor", "date_of_birth": "1992-04-17", "gender": "Female", "phone": "08031234567" }, "screening": { "sanctions": [], "peps": [], "adverse_media": [], "risk_level": "low" }, "decision": "pass" } } ``` ### Review — identity verified, PEP match found ```json theme={null} { "status": "success", "message": "Customer onboarding completed", "data": { "onboarding_id": 1025, "identity": { "verified": true, "identifier_type": "NIN", "first_name": "Emeka", "last_name": "Nwosu", "date_of_birth": "1985-11-02", "gender": "Male" }, "screening": { "sanctions": [], "peps": [ { "name": "Emeka Nwosu", "pep_types": ["role.pep", "pep-class-2"], "gender": "male", "source": "OpenSanctions", "country": "Nigeria", "political_post": ["Former State Commissioner"] } ], "adverse_media": [], "risk_level": "medium" }, "decision": "review" } } ``` ### Fail — identity verification unsuccessful ```json theme={null} { "status": "success", "message": "Customer onboarding completed", "data": { "onboarding_id": 1026, "identity": { "verified": false, "identifier_type": "BVN", "error": "Bank Verification Number (BVN) check failed: Invalid BVN provided" }, "screening": { "sanctions": [], "peps": [], "adverse_media": [], "risk_level": "low", "note": "AML screening skipped: identity verification did not return a name" }, "decision": "fail" } } ``` ### Error Responses | HTTP Status | Message | Cause | | ----------- | --------------------------------------------------------------------- | ----------------------------------------------- | | `401` | `"Authorization token is missing"` | No `x-access-token` header | | `401` | `"Authorization failed"` | Token not recognised or expired | | `403` | `"Identity Verification suite isn't enabled for this branch"` | Feature not activated — contact support | | `403` | `"Your account hasn't been verified for Identity Verification Suite"` | Admin account pending verification | | `400` | `"country is required"` | Missing `country` field | | `400` | `"identifier is required"` | Missing `identifier` field | | `400` | `"Unsupported country '…'. Supported: …"` | Invalid `country` value | | `400` | `"Unsupported identifier_type '…' for …. Supported: …"` | Invalid `identifier_type` for the given country | # Get All KYC Search Results Source: https://docs.smartcomply.com/v3/transaction/kyc/get_all_search_results GET /api/v1/monitoring/kyc_search/ Retrieve all KYC search results associated with your account, including risk levels and sanction findings. The Get All KYC Search Results endpoint returns a list of every KYC check performed under your account. Each result includes the entity's risk level, PEP status, sanctions matches, and adverse media findings. ## Endpoint ``` GET /api/v1/monitoring/kyc_search/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | ### Example ```bash cURL theme={null} curl -X GET "https://adhere-api.smartcomply.com/api/v1/monitoring/kyc_search/" \ -H "x-access-token: YOUR_SECRET_KEY" ``` ## Response ### 200 OK | Field | Type | Description | | ------------------------------------- | ------ | ----------------------------------------------------- | | `data[].id` | number | Unique identifier for the KYC search result | | `data[].entity_name` | string | Name of the entity that was searched | | `data[].branch_id` | number | Branch associated with this KYC search | | `data[].status` | string | Search status (e.g., `"completed"`) | | `data[].result.risk_level` | string | Risk level assessed: `"low"`, `"medium"`, or `"high"` | | `data[].result.total_hits` | number | Total flagged hits across all categories | | `data[].result.pep_results` | array | Politically Exposed Person matches | | `data[].result.sanction_results` | array | Sanctions list matches | | `data[].result.social_media` | array | Social media profiles found | | `data[].result.adverse_media_results` | array | Adverse media articles | | `data[].result.total_blacklist_hits` | number | Total blacklist flags | ```json theme={null} { "status": "success", "data": [ { "id": 17, "entity_name": "ABDUL MANAN MOHAMMAD ISHAK", "branch_id": 3, "status": "completed", "result": { "risk_level": "low", "total_hits": 1, "pep_results": [], "search_term": "ABDUL MANAN MOHAMMAD ISHAK", "social_media": [], "sanction_results": [ { "name": "Abdul Manan Mohammad Ishak", "types": ["sanction", "warnings", "fitness-probity"], "source": "Smartcomply", "country": "Afghanistan", "recorded_date": "15 Aug. 2012" } ], "total_blacklist_hits": 0, "adverse_media_results": [] } }, { "id": 41, "entity_name": "Heritage Bank", "branch_id": 3, "status": "completed", "result": { "risk_level": "high", "total_hits": 5, "pep_results": [ { "name": "Managing Director/CEO, Heritage Bank Plc", "gender": null, "source": "Smartcomply", "country": "Nigeria", "pep_types": ["pep"] } ], "search_term": "Heritage Bank", "social_media": [], "sanction_results": [], "total_blacklist_hits": 0, "adverse_media_results": [ { "url": "https://thewillnews.com/breaking-cbn-revokes-operational-license-of-heritage-bank-plc/", "date": "June 5, 2024", "title": "CBN revokes operational license of Heritage Bank Plc", "types": ["adverse-media-v2-other-financial"], "snippet": "The Central Bank of Nigeria (CBN) has revoked the banking license of Heritage Bank Plc..." } ] } } ], "message": "Success" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Get KYC Result by ID Source: https://docs.smartcomply.com/v3/transaction/kyc/get_entity_kyc_by_id GET /api/v1/monitoring/kyc_search/{id}/ Retrieve the KYC check result for a specific entity by its search ID. The Get KYC Result by ID endpoint returns the full results of a completed KYC check for a specific entity, including risk level, sanctions matches, PEP findings, and adverse media. ## Endpoint ``` GET /api/v1/monitoring/kyc_search/{id}/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | ### Path Parameters | Parameter | Type | Required | Description | | --------- | ------- | -------- | ------------------------------------------- | | `id` | integer | Yes | Unique identifier for the KYC search result | ### Example ```bash cURL theme={null} curl -X GET "https://adhere-api.smartcomply.com/api/v1/monitoring/kyc_search/17/" \ -H "x-access-token: YOUR_SECRET_KEY" ``` ## Response ### 200 OK | Field | Type | Description | | ----------------------------------- | --------------- | ---------------------------------------------------------------- | | `data.id` | number | Unique identifier for the KYC search result | | `data.entity_name` | string | Name of the entity that was searched | | `data.branch_id` | number | Branch associated with this KYC search | | `data.status` | string | Search status (e.g., `"completed"`) | | `data.result.risk_level` | string | Risk level assessed: `"low"`, `"medium"`, or `"high"` | | `data.result.total_hits` | number | Total flagged hits across all categories | | `data.result.pep_results` | array | Politically Exposed Person matches | | `data.result.sanction_results` | array | Sanctions list matches with country, body, and types | | `data.result.social_media` | array | Social media profiles found | | `data.result.adverse_media_results` | string or array | Adverse media findings, or a pending message if still processing | | `data.result.total_blacklist_hits` | number | Total blacklist flags | ```json theme={null} { "status": "success", "data": { "id": 17, "entity_name": "ABDUL MANAN MOHAMMAD ISHAK", "branch_id": 3, "status": "completed", "result": { "risk_level": "low", "total_hits": 1, "pep_results": [], "search_term": "ABDUL MANAN MOHAMMAD ISHAK", "social_media": [], "sanction_results": [ { "name": "Abdul Manan Mohammad Ishak", "types": ["sanction", "warnings", "fitness-probity"], "source": "Smartcomply", "country": "Afghanistan", "recorded_date": "15 Aug. 2012" } ], "total_blacklist_hits": 0, "adverse_media_results": "Adverse Media Result(s) for ABDUL MANAN MOHAMMAD ISHAK will be available shortly if any are found" } }, "message": "Success" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` ### 404 Not Found ```json theme={null} { "status": "failed", "message": "No KYC result found for the specified ID." } ``` # Run KYC Check Source: https://docs.smartcomply.com/v3/transaction/kyc/post_kyc_check POST /api/v1/monitoring/kyc_search/ Initiate a KYC check for an entity against sanctions lists, PEP databases, and adverse media sources. The Run KYC Check endpoint screens an entity against multiple risk databases including sanctions lists, PEP (Politically Exposed Persons) records, and adverse media sources. Results are returned immediately for completed checks, or asynchronously if adverse media screening is still processing. ## Endpoint ``` POST /api/v1/monitoring/kyc_search/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ----------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `entity_name` | string | Yes | Name of the entity to screen | | `entity_type` | string | No | Entity type: `"person"`, `"company"`, `"business"`, or `"organization"` (defaults to `person` if none provided) | | `sources` | string | No | Comma-separated data sources to query (e.g., `"Sanctions, PEPs, Adverse Media"`) | | `continuous_monitoring` | boolean | No | Enable ongoing monitoring for this entity. Defaults to `false` | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/kyc_search/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "entity_name": "John Doe", "entity_type": "person", "sources": "Sanctions, PEPs, Adverse Media", "continuous_monitoring": false, }' ``` ## Response ### 200 OK — Completed When results are immediately available, the response includes the full KYC result with risk level, PEP findings, sanctions matches, adverse media, and social media profiles. | Field | Type | Description | | ----------------------------------- | ------ | ---------------------------------------------------------- | | `data.id` | number | Unique identifier for this KYC request | | `data.entity_name` | string | Name of the entity screened | | `data.status` | string | Check status: `"completed"` or `"running"` | | `data.result.risk_level` | string | Assessed risk: `"low"`, `"medium"`, or `"high"` | | `data.result.total_hits` | number | Total flagged matches across all sources | | `data.result.total_blacklist_hits` | number | Number of blacklist matches | | `data.result.pep_results` | array | PEP matches with entity name, country, and classification | | `data.result.sanction_results` | array | Sanction matches with body, types, and other information | | `data.result.adverse_media_results` | array | Adverse media articles with URL, date, title, and category | | `data.result.social_media` | array | Social media profiles associated with the entity | ```json theme={null} { "status": "success", "data": { "id": 6036, "entity_name": "Qudratullah Jamal", "status": "completed", "result": { "risk_level": "high", "total_hits": 76, "total_blacklist_hits": 6, "pep_results": [ { "entity_name": "qudratullah jamal", "gender": "Not Available", "country": "Unknown", "pep_types": ["pep-class-1"], "other_names": ["qudratullah jamal"], "other_information": { "recorded_date": "2022-04-27T18:12:14", "political_post": ["sanction"] } } ], "sanction_results": [ { "entity_name": "QUDRATULLAH JAMAL", "recorded_date": "29 Nov. 2011", "country": "Afghanistan", "sanction_body": null, "sanction_types": ["sanction", "warnings"], "other_names": [], "other_information": { "dob": "Approximately 1963", "pob": "Gardez, Paktia Province, Afghanistan", "title": "Maulavi", "designations": "Minister of Information under the Taliban regime" } } ], "adverse_media_results": [ { "url": "https://www.opensanctions.org/entities/NK-a8GaVuetYPU5ZaoT48kMch/", "date": "2026-03-06T12:58:26Z", "title": "Maulavi Qudratullah Jamal - OpenSanctions", "types": ["adverse-media-v2-terrorism"], "provider": "google_cse", "relevance_score": 4 } ], "social_media": [ { "bio": "TOLOnews - X", "url": "https://x.com/TOLOnews/status/1510158383004930052", "platform": "X", "provider": "google_cse", "description": "Addressing a gathering in Kabul, the deputy minister of commerce and industry, Qudratullah Jamal..." } ], "search_term": "Qudratullah Jamal", "date_updated": "2026-03-06 12:58:30" } }, "message": "KYC search completed" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Submit Transaction for Monitoring Source: https://docs.smartcomply.com/v3/transaction/transaction_monitoring/post_transaction_request Submit a transaction for real-time fraud assessment. The payload shape depends on the transaction_type — pick your type below. The Submit Transaction endpoint processes a transaction in real-time against your configured thresholds and limits and returns an activity code indicating whether the transaction is clean, suspicious, or high-risk. The payload shape depends on the `transaction_type` value: **Transfer**, **USSD**, and **Web** use originating and destination account details, while **Card** uses card and merchant details. Pick your type below. ## Endpoint ``` POST /api/v1/monitoring/transaction_monitoring/ ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Common Body Parameters These fields are required for every `transaction_type`. | Parameter | Type | Required | Description | | ----------------------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------- | | `transaction_id` | string | Yes | Unique identifier for the transaction | | `amount` | number | Yes | Transaction amount (e.g. `99.13` or `14000000`) | | `currency` | string | Yes | Currency code (e.g. `NGN`, `USD`) | | `transaction_type` | string | Yes | One of: `transfer`, `ussd`, `web`, `card` | | `account_type` | string | Yes | `individual` or `corporate` | | `customer_details` | object | Yes | Details of the customer initiating the transaction | | `customer_details.customer_name` | string | Yes | Customer's full name | | `customer_details.customer_email` | string | Yes | Customer's email address | | `customer_details.customer_phone` | string | No | Customer's phone number (e.g. `+2347012345678`) | | `customer_details.identifier` | string | No | Customer's identifier value — BVN for Nigeria, national ID for Kenya, Ghana card for Ghana, etc. | | `customer_details.identifier_type` | string | No | Key of the identifier type (`bvn`, `national_id`, `ghana_card`, etc.). Required when `identifier` is provided | | `additional_info` | object | Yes | Additional context for fraud evaluation | | `additional_info.ip_address` | string | Yes | IP address during the transaction | | `additional_info.location` | string | Yes | Location string or lat/lon (e.g. `"Lagos, Nigeria"` or `"lat=-30.66,lon=-65.77"`) | | `additional_info.transaction_description` | string | No | Optional description of the transaction | ### Type-Specific Parameters Account-to-account transfer. In addition to the common fields above, you must include origin and destination accounts. | Parameter | Type | Required | Description | | ------------------------------------ | ------- | -------- | ---------------------------------------------------- | | `origin_account` | object | Yes | Originating account details | | `origin_account.account_number` | string | Yes | Account number of the sender | | `origin_account.bank_code` | string | Yes | Bank code of the sender | | `destination_account` | object | Yes | Destination account details | | `destination_account.account_number` | string | Yes | Account number of the recipient | | `destination_account.bank_code` | string | Yes | Bank code of the recipient | | `run_kyc` | boolean | No | Run a KYC check on the customer. Defaults to `false` | #### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "transaction_id": "12345678", "amount": 14000000, "currency": "NGN", "transaction_type": "transfer", "account_type": "individual", "origin_account": { "account_number": "9876543219", "bank_code": "001" }, "destination_account": { "account_number": "123456789", "bank_code": "002" }, "customer_details": { "customer_name": "Muhammad Ibrahim Isah", "customer_email": "user@example.com", "identifier": "22430372151", "identifier_type": "bvn" }, "additional_info": { "ip_address": "192.168.1.1", "location": "Lagos, Nigeria", "transaction_description": "Payment for order #789" }, "run_kyc": false }' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ transaction_id: "12345678", amount: 14000000, currency: "NGN", transaction_type: "transfer", account_type: "individual", origin_account: { account_number: "9876543219", bank_code: "001", }, destination_account: { account_number: "123456789", bank_code: "002", }, customer_details: { customer_name: "Muhammad Ibrahim Isah", customer_email: "user@example.com", identifier: "22430372151", identifier_type: "bvn", }, additional_info: { ip_address: "192.168.1.1", location: "Lagos, Nigeria", transaction_description: "Payment for order #789", }, run_kyc: false, }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={ "transaction_id": "12345678", "amount": 14000000, "currency": "NGN", "transaction_type": "transfer", "account_type": "individual", "origin_account": { "account_number": "9876543219", "bank_code": "001", }, "destination_account": { "account_number": "123456789", "bank_code": "002", }, "customer_details": { "customer_name": "Muhammad Ibrahim Isah", "customer_email": "user@example.com", "identifier": "22430372151", "identifier_type": "bvn", }, "additional_info": { "ip_address": "192.168.1.1", "location": "Lagos, Nigeria", "transaction_description": "Payment for order #789", }, "run_kyc": False, }, ) data = response.json() ``` Same payload as **Transfer** but with `"transaction_type": "ussd"`. The body still requires `origin_account` and `destination_account`. | Parameter | Type | Required | Description | | ------------------------------------ | ------- | -------- | ---------------------------------------------------- | | `origin_account` | object | Yes | Originating account details | | `origin_account.account_number` | string | Yes | Account number of the sender | | `origin_account.bank_code` | string | Yes | Bank code of the sender | | `destination_account` | object | Yes | Destination account details | | `destination_account.account_number` | string | Yes | Account number of the recipient | | `destination_account.bank_code` | string | Yes | Bank code of the recipient | | `run_kyc` | boolean | No | Run a KYC check on the customer. Defaults to `false` | #### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "transaction_id": "USSD-90001", "amount": 5000, "currency": "NGN", "transaction_type": "ussd", "account_type": "individual", "origin_account": { "account_number": "9876543219", "bank_code": "001" }, "destination_account": { "account_number": "123456789", "bank_code": "002" }, "customer_details": { "customer_name": "Aisha Bello", "customer_email": "aisha@example.com", "identifier": "22430372151", "identifier_type": "bvn" }, "additional_info": { "ip_address": "192.168.1.1", "location": "Lagos, Nigeria", "transaction_description": "USSD airtime top-up" }, "run_kyc": false }' ``` Same payload as **Transfer** but with `"transaction_type": "web"`. The body still requires `origin_account` and `destination_account`. | Parameter | Type | Required | Description | | ------------------------------------ | ------- | -------- | ---------------------------------------------------- | | `origin_account` | object | Yes | Originating account details | | `origin_account.account_number` | string | Yes | Account number of the sender | | `origin_account.bank_code` | string | Yes | Bank code of the sender | | `destination_account` | object | Yes | Destination account details | | `destination_account.account_number` | string | Yes | Account number of the recipient | | `destination_account.bank_code` | string | Yes | Bank code of the recipient | | `run_kyc` | boolean | No | Run a KYC check on the customer. Defaults to `false` | #### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "transaction_id": "WEB-77410", "amount": 250000, "currency": "NGN", "transaction_type": "web", "account_type": "individual", "origin_account": { "account_number": "9876543219", "bank_code": "001" }, "destination_account": { "account_number": "123456789", "bank_code": "002" }, "customer_details": { "customer_name": "Tunde Bakare", "customer_email": "tunde@example.com", "identifier": "22430372151", "identifier_type": "bvn" }, "additional_info": { "ip_address": "192.168.1.1", "location": "Lagos, Nigeria", "transaction_description": "Web checkout payment" }, "run_kyc": false }' ``` In addition to the common fields above, you must include `card_details`. `merchant_details` is optional but recommended. `origin_account` and `destination_account` are not required. | Parameter | Type | Required | Description | | ------------------------------------ | ------- | -------- | ------------------------------------------------------------ | | `timestamp` | string | No | ISO 8601 transaction timestamp (e.g. `2025-08-23T14:30:00Z`) | | `card_details` | object | Yes | Card-specific information | | `card_details.bin` | integer | Yes | First six digits of the card number (BIN) | | `card_details.last4` | integer | Yes | Last four digits of the card number | | `merchant_details` | object | No | Merchant information | | `merchant_details.merchant_name` | string | No | Name of the merchant | | `merchant_details.merchant_location` | string | No | Location of the merchant | | `merchant_details.merchant_mcc` | string | No | Merchant category code (MCC) | | `run_kyc` | boolean | No | Run a KYC check on the customer. Defaults to `false` | #### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "transaction_id": "TXN-CARD-12345678", "amount": 99.13, "currency": "NGN", "transaction_type": "card", "account_type": "corporate", "timestamp": "2025-08-23T14:30:00Z", "card_details": { "bin": 345676, "last4": 9809 }, "merchant_details": { "merchant_name": "ABC Stores", "merchant_location": "Lagos, Nigeria", "merchant_mcc": "5813" }, "customer_details": { "customer_name": "Imagine Dragons", "customer_email": "imaginedragons@gmail.com", "customer_phone": "+2347012345678", "identifier": "98765432109", "identifier_type": "bvn" }, "additional_info": { "ip_address": "102.89.1.1", "location": "Lagos, Nigeria", "transaction_description": "Online purchase" }, "run_kyc": false }' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ transaction_id: "TXN-CARD-12345678", amount: 99.13, currency: "NGN", transaction_type: "card", account_type: "corporate", timestamp: "2025-08-23T14:30:00Z", card_details: { bin: 345676, last4: 9809, }, merchant_details: { merchant_name: "ABC Stores", merchant_location: "Lagos, Nigeria", merchant_mcc: "5813", }, customer_details: { customer_name: "Imagine Dragons", customer_email: "imaginedragons@gmail.com", customer_phone: "+2347012345678", identifier: "98765432109", identifier_type: "bvn", }, additional_info: { ip_address: "102.89.1.1", location: "Lagos, Nigeria", transaction_description: "Online purchase", }, run_kyc: false, }), } ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={ "transaction_id": "TXN-CARD-12345678", "amount": 99.13, "currency": "NGN", "transaction_type": "card", "account_type": "corporate", "timestamp": "2025-08-23T14:30:00Z", "card_details": { "bin": 345676, "last4": 9809, }, "merchant_details": { "merchant_name": "ABC Stores", "merchant_location": "Lagos, Nigeria", "merchant_mcc": "5813", }, "customer_details": { "customer_name": "Imagine Dragons", "customer_email": "imaginedragons@gmail.com", "customer_phone": "+2347012345678", "identifier": "98765432109", "identifier_type": "bvn", }, "additional_info": { "ip_address": "102.89.1.1", "location": "Lagos, Nigeria", "transaction_description": "Online purchase", }, "run_kyc": False, }, ) data = response.json() ``` **Recommended for all new integrations**: pass `identifier` and `identifier_type` inside `customer_details`. This single field pair supports BVN (Nigeria), national ID (Kenya), Ghana card, and other country ID types. **Backward compatible**: integrations that previously sent a `bvn` field can continue to do so. See the [legacy example](#legacy-passing-bvn-directly) below. ### Legacy: passing `bvn` directly The top-level `bvn` field is legacy and only supports BVN (Nigeria). New integrations, both in Nigeria and outside Nigeria, should use `customer_details.identifier` + `customer_details.identifier_type` instead. The legacy field is kept active for backward compatibility and will be removed in a future release. The following payload uses the legacy `bvn` field instead of the new `identifier` pair. It still works. ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_monitoring/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "transaction_id": "LEGACY-001", "amount": 50000, "currency": "NGN", "transaction_type": "transfer", "account_type": "individual", "origin_account": { "account_number": "9876543219", "bank_code": "001" }, "destination_account": { "account_number": "123456789", "bank_code": "002" }, "customer_details": { "customer_name": "Legacy Customer", "customer_email": "legacy@example.com", "bvn": "22430372151", }, "additional_info": { "ip_address": "192.168.1.1", "location": "Lagos, Nigeria" } }' ``` ## Response The response is identical across all `transaction_type` values. ### Activity Codes **Suspicious (flag for review):** | Code | Description | | ----- | ----------------------------------------------------------- | | `450` | Suspicious Transaction Detected — Requires Manual Review | | `451` | High-Risk Transaction — Potential Fraud | | `452` | Unusual Transaction Behavior — Pattern Anomaly | | `453` | Velocity Check Failed — Too Many Transactions in Short Time | | `454` | Geographic Inconsistency — Unusual Location | | `455` | Transaction Amount Too High — Above Threshold | | `456` | Blacklisted Account or Entity | | `457` | Repeated Failed Transactions — Possible Fraud Attempt | **Safe:** | Code | Description | | ----- | -------------------------------------------------------------- | | `200` | Transaction Approved — No Issues | | `201` | Transaction Successfully Processed | | `202` | Transaction Pending Review — Routine Check | | `210` | Trusted Transaction — Verified and Safe | | `211` | Low-Risk Transaction — No Anomalies Detected | | `212` | Recurring Transaction Approved — Previously Authorized Pattern | | `220` | Whitelisted Entity — Pre-approved Account or Business | | `221` | Known Customer — Transaction Aligns with User History | ### 201 Created ```json theme={null} { "status": "Success", "data": { "activity_code": "450", "status": "suspicious", "comment": ["4 rule(s) triggered"] }, "message": "Transaction was successfully processed" } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Transaction Monitoring Source: https://docs.smartcomply.com/v3/transaction/transaction_monitoring/transaction_monitoring_overview Real-time transaction analysis and automated alerting to detect suspicious activity. ## Overview Transaction Monitoring provides real-time analysis of every transaction processed through your Adhere account. It evaluates transactions against a set of configurable rules and automatically triggers alerts when suspicious patterns are detected — helping you comply with AML regulations and prevent fraud proactively. ## How It Works Send transaction data to the [Transaction Monitoring endpoint](/v3/transaction/transaction_monitoring/post_transaction_request) via your backend. The system checks the transaction against your configured rules (amount limits, frequency, geography, merchant category, and more). If one or more rules fire, the transaction is flagged as suspicious and an alert is sent via webhook or email. Investigate the alert in the Adhere dashboard — approve, reject, or escalate the transaction. ## Key Features Configure rules based on transaction amount, frequency, geographic location, merchant category, time of day, and more. Get notified instantly via webhook, email or Slack when a transaction breaches a rule. Review flagged transactions, approve or reject them, and escalate to support from the Adhere dashboard. Optionally screen transactions and counterparties against global watchlists and sanction databases. ## Supported Transaction Types The Submit Transaction endpoint accepts four `transaction_type` values, each with a different payload shape. Pick the type that matches the transaction you're submitting. Account-to-account transfer. Requires `origin_account` and `destination_account`. The most common transaction type. USSD-initiated transaction. Same payload as Transfer — only `transaction_type` changes to `ussd`. Web-initiated transaction. Same payload as Transfer — only `transaction_type` changes to `web`. Card transaction. Requires `card_details` (BIN + last4) and optionally `merchant_details`. No `origin_account` or `destination_account` required. See [Submit Transaction](/v3/transaction/transaction_monitoring/post_transaction_request) for the full request, examples per type, and response codes. ## Rule Criteria Rules can be based on any combination of the following: | Criterion | Example | | --------------------- | --------------------------------------------------------- | | Transaction amount | Flag any transaction over ₦500,000 | | Transaction frequency | Flag more than 10 transactions in 1 hour | | Geographic location | Flag transactions from high-risk countries | | Merchant category | Flag gambling or crypto merchant codes | | Time of day | Flag transactions between 1am–4am | | Account type | Apply different rules to individual vs. business accounts | ## Webhook Notifications When a transaction is flagged, Adhere sends a `suspicious_transaction` event to your configured webhook URL. See [Webhooks](/webhooks) for the full payload structure and signature verification guide. ## Next Steps Send your first transaction for monitoring. Understand the end-to-end flow from submission to resolution. # User Journey Tracking Source: https://docs.smartcomply.com/v3/transaction/transaction_monitoring/user_journey POST /api/v1/journey/event/ Track and validate user transaction events in sequence to detect out-of-order or suspicious behaviour. The User Journey API tracks critical steps in a user's transaction flow through defined checkpoints. It validates that expected events occur in the correct sequence and flags suspicious or out-of-order behaviour in real time. ## Submit Event Submit a user journey event for fraud assessment. ### Endpoint ``` POST /api/v1/journey/event/ ``` ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ---------------------------------------------------------------------------------- | | `user_id` | string | Yes | Unique identifier for the user | | `session_id` | string | Yes | Identifier for the current session | | `event` | string | Yes | Event type: `LOGIN`, `OTP_VERIFY`, `PAYMENT_INIT`, `PAYMENT_COMPLETE`, or `LOGOUT` | | `timestamp` | string | Yes | ISO-8601 datetime of the event | | `device_id` | string | No | Device identifier | | `ip_address` | string | No | IP address during the event | | `metadata.amount` | number | No | Transaction amount if applicable | | `metadata.currency` | string | No | Currency code | ### 201 Created ```json theme={null} { "status": "Success", "data": { "status": "allow", "risk_score": 0.12, "reason": "Normal login pattern", "session_state": "OTP_VERIFY", "alert_triggered": false }, "message": "success" } ``` *** ## Get Session State Retrieve the current state and event history for a session. ### Endpoint ``` GET /api/v1/journey/session/{session_id}/ ``` ### Path Parameters | Parameter | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------- | | `session_id` | string | Yes | Identifier for the session to retrieve | ### 200 OK ```json theme={null} { "status": "success", "data": { "session_id": "abc-123", "user_id": "user-456", "current_state": "PAYMENT_INIT", "events": [], "start_time": "2025-08-01T10:00:00Z" }, "message": "success" } ``` *** ## Clear Session Delete all stored data for a session. ### Endpoint ``` DELETE /api/v1/journey/session/{session_id}/ ``` ### Path Parameters | Parameter | Type | Required | Description | | ------------ | ------ | -------- | ----------------------------------- | | `session_id` | string | Yes | Identifier for the session to clear | ### 204 No Content ```json theme={null} { "message": "Session cleared" } ``` *** ## User Analytics Retrieve fraud and risk statistics for a user across all sessions. ### Endpoint ``` GET /api/v1/journey/analytics/user/{user_id}/ ``` ### Path Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | ----------------------- | | `user_id` | string | Yes | Identifier for the user | ### 200 OK ```json theme={null} { "status": "success", "data": { "user_id": "user-456", "total_events": 42, "average_risk_score": 0.08, "blocked_events": 1, "reviewed_events": 3, "total_sessions": 10, "average_session_risk": 0.07 }, "message": "Success" } ``` *** ## Health Check Check the service health and dependency status. ### Endpoint ``` GET /api/v1/journey/health/ ``` ### 200 OK ```json theme={null} { "status": "healthy", "broker": "connected", "database": "connected", "timestamp": "2025-08-01T10:00:00Z" } ``` *** ## Error Codes | Code | Description | | ----- | ------------------------------------------ | | `200` | Success | | `201` | Event processed successfully | | `400` | Missing, malformed, or invalid fields | | `401` | Authentication failed or API key missing | | `403` | Insufficient permissions for this resource | | `404` | Resource or endpoint not found | | `429` | Rate limit exceeded — retry after cooldown | | `500` | Unexpected server error | # Transaction Screening Source: https://docs.smartcomply.com/v3/transaction/transaction_screening/overview Screen transactions in real time against sanctions lists, high-risk countries, and suspicious keywords. Transaction Screening evaluates each transaction against a set of predefined criteria to identify potentially suspicious or prohibited activity. It cross-checks transactions for sanctions exposure, high-risk geography, and suspicious keyword patterns to help you maintain regulatory compliance and prevent financial crime. ## Screening Criteria | Criteria | Description | | ----------------------- | ---------------------------------------------------------------------------------------------- | | **Sanctioned Entities** | Transactions involving individuals or organisations on international sanction lists | | **High-Risk Countries** | Transactions associated with jurisdictions flagged as high-risk | | **Suspicious Keywords** | Transaction descriptions containing keywords that may indicate fraudulent or illicit behaviour | ## Key Features Transactions are analyzed immediately upon initiation, enabling prompt detection of flagged activity. Tailor screening rules to your business requirements, risk tolerance, and regulatory obligations. Receive alerts when transactions trigger one or more screening criteria for swift review. Every screening decision is logged, providing a full audit trail for compliance reporting. ## Endpoints | Endpoint | Description | | ---------------------------------------------------------------------------------------------- | ---------------------------------- | | [Post Transaction Screening](/v3/transaction/transaction_screening/post_transaction_screening) | Submit a transaction for screening | # Screen a Transaction Source: https://docs.smartcomply.com/v3/transaction/transaction_screening/post_transaction_screening POST /api/v1/monitoring/transaction_screening Screen a transaction against sanctions lists, high-risk countries, and suspicious keyword patterns. The Screen a Transaction endpoint evaluates a transaction against predefined compliance criteria including sanctions lists, high-risk country flags, and suspicious keywords. Transactions matching any criteria are flagged for review. ## Endpoint ``` POST /api/v1/monitoring/transaction_screening ``` ## Request ### Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your API secret key | Yes | | `Content-Type` | `application/json` | Yes | ### Body Parameters | Parameter | Type | Required | Description | | -------------------------- | ------ | ------------ | -------------------------------------------------- | | `transactionId` | string | Recommended | Links repeat calls to the same transaction | | `transactionType` | string | Optional | e.g., `Transfer`, `Payment` | | `amount` | number | **Required** | Transaction amount (e.g., `10000.00`) | | `currency` | string | Optional | Currency code, e.g., `NGN`, `USD` | | `transactionDate` | string | **Required** | ISO-8601 datetime, e.g., `2024-07-06T12:34:56Z` | | `sender.name` | string | **Required** | Sender's full name — screened against risk lists | | `sender.accountNumber` | string | Optional | Sender's account number | | `sender.address` | object | Optional | Sender's address for location-based checks | | `sender.address.country` | string | Recommended | Helps flag high-risk countries | | `sender.identification` | object | Optional | Sender's ID details | | `receiver.name` | string | **Required** | Receiver's full name — screened against risk lists | | `receiver.accountNumber` | string | Optional | Receiver's account number | | `receiver.address` | object | Optional | Receiver's address for location-based checks | | `receiver.address.country` | string | Recommended | Helps flag high-risk countries | | `receiver.identification` | object | Optional | Receiver's ID details | | `details.purpose` | string | Recommended | Transaction purpose — used for keyword screening | | `details.reference` | string | Optional | Your internal reference or invoice number | ### Example ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/v1/monitoring/transaction_screening" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "transactionId": "1234567892", "transactionType": "Transfer", "amount": 10000.00, "currency": "NGN", "transactionDate": "2024-07-06T12:34:56Z", "sender": { "name": "John Doe", "accountNumber": "123456789012", "address": { "street": "123 Main St", "city": "Lagos", "state": "Lagos", "postalCode": "10001", "country": "NIGERIA" }, "identification": { "type": "Passport", "number": "A12345678", "country": "NG" } }, "receiver": { "name": "Jane Smith", "accountNumber": "987654321098", "address": { "street": "456 Elm St", "city": "Abuja", "state": "FCT", "postalCode": "90001", "country": "NIGERIA" } }, "details": { "purpose": "Payment for services", "reference": "INV-2024-001" } }' ``` ## Response ### 201 Created — Flagged When the transaction matches a screening criterion, the response includes the full sanction match details for both sender and receiver. | Field | Type | Description | | --------------------------------------------------- | ------- | --------------------------------------------------------- | | `data.transactionId` | string | Transaction identifier | | `data.amount` | number | Transaction amount | | `data.currency` | string | Currency code | | `data.sender` | object | Sender details echoed back | | `data.receiver` | object | Receiver details echoed back | | `data.sanction.sender_name` | string | Sender name screened | | `data.sanction.sender_record` | array | Sanction matches for the sender | | `data.sanction.receiver_name` | string | Receiver name screened | | `data.sanction.receiver_record` | array | Sanction matches for the receiver | | `data.sanction[].entity_name` | string | Name of the matching sanctioned entity | | `data.sanction[].entity_type` | string | Entity type (e.g., `Person`) | | `data.sanction[].topics` | array | Sanction categories (e.g., `sanction`, `crime.terror`) | | `data.sanction[].match_score` | number | Match confidence score (0 to 1) | | `data.screeningStatus` | string | Outcome: `"flagged"` or `"approved"` | | `data.sender_risk_level` | string | Risk level for sender: `"low"`, `"medium"`, or `"high"` | | `data.receiver_risk_level` | string | Risk level for receiver: `"low"`, `"medium"`, or `"high"` | | `data.comments` | string | Reason for the screening outcome | | `data.additionalActions` | array | Recommended follow-up actions | | `data.additionalActions[].actionType` | string | Type of action (e.g., `"Notify Customer"`) | | `data.additionalActions[].assignedTo` | string | Team or person responsible | | `data.additionalActions[].notes` | string | Instructions for the action | | `data.summary` | object | Summary of screening results | | `data.summary.verdict` | string | Overall screening verdict | | `data.summary.sender_risk_level` | string | Sender risk level | | `data.summary.receiver_risk_level` | string | Receiver risk level | | `data.summary.sender_matches` | object | Sender match details | | `data.summary.sender_matches.matched_status` | boolean | Whether sender had matches | | `data.summary.sender_matches.highest_match_score` | string | Highest match score percentage | | `data.summary.sender_matches.sanctions_count` | number | Number of sanction matches | | `data.summary.sender_matches.peps_count` | number | Number of PEP matches | | `data.summary.sender_matches.on_blacklist` | boolean | Whether sender is on blacklist | | `data.summary.receiver_matches` | object | Receiver match details | | `data.summary.receiver_matches.matched_status` | boolean | Whether receiver had matches | | `data.summary.receiver_matches.highest_match_score` | string | Highest match score percentage | | `data.summary.receiver_matches.sanctions_count` | number | Number of sanction matches | | `data.summary.receiver_matches.peps_count` | number | Number of PEP matches | | `data.summary.receiver_matches.on_blacklist` | boolean | Whether receiver is on blacklist | ```json theme={null} { "status": "success", "data": { "transactionId": "1234567892", "transactionType": "Transfer", "amount": 10000.0, "currency": "NGN", "transactionDate": "2024-07-06T12:34:56Z", "sender": { "name": "QUDRATULLAH JAMAL", "accountNumber": "123456789012", "address": { "street": "123 Main St", "city": "Lagos", "state": "Lagos", "country": "NIGERIA" } }, "receiver": { "name": "Jane Smith", "accountNumber": "987654321098" }, "sanction": { "sender_name": "QUDRATULLAH JAMAL", "sender_record": [ { "entity_name": "Maulavi Qudratullah Jamal", "entity_type": "Person", "topics": ["crime.terror", "export.control", "sanction"], "sanction_types": ["crime.terror", "export.control", "sanction"], "match_score": 1.0, "risk_score": "80%", "matched": "False match" } ], "receiver_name": "Jane Smith", "receiver_record": [ { "entity_name": "JANE A SMITH", "entity_type": "Person", "topics": ["debarment"], "sanction_types": ["debarment"], "match_score": 0.96, "risk_score": "83%", "matched": "True match" } ] }, "screeningStatus": "flagged", "sender_risk_level": "medium", "receiver_risk_level": "high", "comments": "Transaction denied due to high-risk blacklist match, high risk level, or sanctions match.", "additionalActions": [ { "actionType": "Notify Customer", "assignedTo": "Customer Service", "notes": "Inform the customer about the transaction denial." } ], "summary": { "verdict": "flagged", "sender_risk_level": "medium", "receiver_risk_level": "high", "sender_matches": { "matched_status": true, "highest_match_score": "100%", "sanctions_count": 0, "peps_count": 1, "on_blacklist": false }, "receiver_matches": { "matched_status": true, "highest_match_score": "100%", "sanctions_count": 1, "peps_count": 4, "on_blacklist": false } } } } ``` ### 400 Bad Request ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` ### 401 Unauthorized ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` # Webhooks Source: https://docs.smartcomply.com/webhooks Learn how to receive and verify webhook notifications from Adhere. **In a nutshell:** Webhooks allow you to set up a notification system that can be used to receive updates on certain requests made to the Adhere API. Adhere uses webhooks to notify your application when specific events occur. This allows you to build automated workflows and integrate Adhere closely with your system. ## Why use Webhooks? Generally, when you make a request to an API endpoint, you expect to get a near-immediate response. However, some requests may take a long time to process. In order to prevent a timeout error, a pending response is returned. Since your records need to be updated with the final state of the request, you need to either: 1. **Polling**: Make a request for an update at regular intervals. 2. **Webhooks**: Listen to events by using a webhook URL. We recommend using webhooks over polling. Webhooks are more efficient, reduce network overhead, and ensure your system is updated immediately when an event occurs. ## Setup & Integration To start receiving webhook notifications, follow these steps to configure your environment: Provide the endpoint on your server where Adhere will send `POST` requests. This should be a publicly accessible URL. A secret key used to sign the webhook payload. You must keep this secure and use it to verify that requests are coming from Adhere. Save your settings in the Adhere dashboard under the **Integrations** section. ## Security & Verification All webhook requests from Adhere include a `X-Adhere-Signature` header. This header contains the HMAC SHA256 signature of the request body, signed with your Hash Key. ### Verifying Signatures To ensure that a webhook request is genuinely from Adhere, you should verify the signature before processing the payload. ```python Python theme={null} import hmac import hashlib import base64 from flask import request, abort def verify_webhook(request, hash_key): sig_header = request.headers.get("X-Adhere-Signature") if not sig_header: abort(401, "Missing signature") # The header format is "sha256=" _, _, received_sig = sig_header.partition("=") # Compute the HMAC SHA256 digest of the raw request body raw_body = request.get_data() digest = hmac.new( hash_key.encode("utf-8"), raw_body, hashlib.sha256 ).digest() expected_sig = base64.b64encode(digest).decode("utf-8") if not hmac.compare_digest(received_sig, expected_sig): abort(401, "Invalid signature") ``` ```javascript Node.js theme={null} const crypto = require('crypto'); function verifyWebhook(req, hashKey) { const signature = req.headers['x-hub-signature']; if (!signature) { throw new Error('Missing signature'); } const [algo, receivedSig] = signature.split('='); const hmac = crypto.createHmac('sha256', hashKey); const digest = hmac.update(req.rawBody).digest('base64'); if (receivedSig !== digest) { throw new Error('Invalid signature'); } } ``` ```php PHP theme={null} function verify_webhook($request_body, $hash_key, $received_sig) { $expected_sig = base64_encode(hash_hmac('sha256', $request_body, $hash_key, true)); if (!hash_equals($received_sig, $expected_sig)) { http_response_code(401); exit("Invalid signature"); } } ``` ```go Go theme={null} import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "io/ioutil" "net/http" "strings" ) func verifyWebhook(w http.ResponseWriter, r *http.Request, hashKey string) bool { sigHeader := r.Header.Get("X-Adhere-Signature") if sigHeader == "" { return false } // Header format is "sha256=" parts := strings.Split(sigHeader, "=") if len(parts) != 2 { return false } receivedSig := parts[1] body, _ := ioutil.ReadAll(r.Body) h := hmac.New(sha256.New, []byte(hashKey)) h.Write(body) expectedSig := base64.StdEncoding.EncodeToString(h.Sum(nil)) return hmac.Equal([]byte(receivedSig), []byte(expectedSig)) } ``` ```csharp .NET theme={null} using System.Security.Cryptography; using System.Text; public bool VerifyWebhook(string requestBody, string hashKey, string receivedSig) { var keyBytes = Encoding.UTF8.GetBytes(hashKey); var bodyBytes = Encoding.UTF8.GetBytes(requestBody); using (var hmac = new HMACSHA256(keyBytes)) { var hashBytes = hmac.ComputeHash(bodyBytes); var expectedSig = Convert.ToBase64String(hashBytes); return expectedSig == receivedSig; } } ``` Always verify the `X-Adhere-Signature` header to prevent unauthorized requests from interacting with your server. ## Event Payload Structure All webhooks follow a consistent JSON structure: | Parameter | Type | Description | | :-------- | :------ | :---------------------------------------------------------------------------------- | | `success` | boolean | Indicates if the event was processed successfully. | | `module` | string | The Adhere module that triggered the event (e.g., `transaction_monitoring`, `kyc`). | | `event` | string | The specific event type. | | `data` | object | The actual payload data (e.g., transaction details, KYC results). | ## Supported Events ### Transaction Monitoring * **Module**: `transaction_monitoring` * **Events**: * `suspicious_transaction`: Triggered when a transaction is processed and deemed suspicious. ```json theme={null} { "data": { "id": 23, "is_internal_blacklisted": false, "is_blacklisted_by": null, "case_id": "#8N2ZI6", "case_sla": "2025-08-23T09:39:31.551479Z", "case_status": "open", "transaction_id": "9201634916397893719", "amount": 12345.0, "currency": "EUR", "transaction_type": "card", "account_type": "individual", "customer_name": "David Seaman", "customer_email": "davidseaman@example.com", "customer_ip_address": "192.168.0.8", "customer_location": "Yaba, LG", "origin_account_no": "4321567809", "origin_bank_code": "327", "transaction_description": "Payment for order #78901", "destination_account_no": "0123456789", "destination_bank_code": "723", "merchant_name": null, "merchant_location": null, "status": "suspicious", "card_bin": null, "card_last4": null, "bvn": "7890123456", "fraud_percent": null, "tag": [ "1 rule(s) triggered" ], "sender_blacklisted": false, "receiver_blacklisted": false, "rules_flagged": [ "Any transaction by an individual that exceeds an amount {a}" ], "additional_info": {}, "date_created": "2025-08-20T09:39:31.425545Z", "date_updated": "2026-01-16T13:46:07.388489Z", "branch": 2 }, "event": "suspicious_transaction", "module": "transaction_monitoring", "success": true } ``` ## Testing Locally Before deploying to production, we recommend testing your webhook implementation locally. 1. **Use ngrok**: Use [ngrok](https://ngrok.com/) to create a secure tunnel to your local server. 2. **Set Webhook URL**: Update your Adhere dashboard with the ngrok URL (e.g., `https://your-subdomain.ngrok-free.app/webhooks`). 3. **Inspect Requests**: Use the ngrok dashboard or [Webhook.site](https://webhook.site/) to inspect the payloads and headers sent by Adhere. ## Best Practices * **Acknowledge Immediately**: Your server should return a `200 OK` response as quickly as possible. Heavy processing should be handled asynchronously using a task queue. * **Handle Retries**: Adhere will retry failed webhook deliveries (non-2xx responses) up to 3 times with an exponential backoff. * **Use Idempotency**: Ensure your system can handle the same webhook multiple times safely. Use the event's unique ID to track processed events. If your server does not return a 2xx response, Adhere will consider the delivery as failed and will attempt to retry. # Authentication Source: https://docs.smartcomply.com/authentication How to authenticate requests to the Smartcomply API. All requests to the Adhere API must include your secret key in the request headers. Requests without a valid key will return a `401 Unauthorized` error. ## Base URL ``` https://adhere-api.smartcomply.com ``` ## Getting Your API Key After completing your business KYC on the [Adhere dashboard](https://adhere-app.smartcomply.com): 1. Navigate to **Settings → API Keys** 2. Click **Generate Key** 3. Copy and store the key securely — it will not be shown again ## Request Headers | Header | Value | Required | | ---------------- | ------------------- | -------- | | `x-access-token` | Your secret API key | Yes | | `Content-Type` | `application/json` | Yes | ## Example Request ```bash theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22000000001"}' ``` ## Security Best Practices Never expose your secret key in client-side code, public repositories, or logs. * **Use environment variables** — store your key in `.env` files and load it at runtime, never hard-code it * **Use separate keys per environment** — maintain distinct keys for development, staging, and production * **Rotate keys periodically** — regenerate your key from the dashboard if you suspect it has been compromised * **Restrict key usage** — only share keys with services that strictly need them # Error Codes Source: https://docs.smartcomply.com/error_codes HTTP status codes and error responses returned by the Smartcomply API. The Adhere API uses standard HTTP status codes. Codes in the `2xx` range indicate success; `4xx` codes indicate a client error; `5xx` codes indicate a server-side issue. ## HTTP Status Codes | Code | Name | Description | | ----- | --------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `200` | OK | The request succeeded and data is returned in the response body. | | `400` | Bad Request | The request was malformed — a required parameter is missing, the value is invalid, or the request body is not valid JSON. | | `401` | Unauthenticated | The `x-access-token` header is missing or the key is invalid. | | `403` | Forbidden | The API key is valid but does not have permission to access this endpoint. | | `404` | Not Found | The requested resource does not exist. | | `422` | Unprocessable Entity | The request was well-formed but the data failed validation (e.g., an ID number that doesn't match the expected format). | | `500` | Internal Server Error | An unexpected error occurred on Smartcomply's end. | | `502` | Bad Gateway | A dependent upstream service is temporarily unavailable. | | `503` | Service Unavailable | The API is temporarily offline for maintenance. | | `504` | Gateway Timeout | The upstream service did not respond in time. | ## Error Response Format All error responses follow this structure: ```json theme={null} { "status": "failed", "data": [], "message": "A human-readable description of the error" } ``` ## Common Error Scenarios Ensure the `x-access-token` header is present and contains a valid, active secret key. Keys can be regenerated from the Adhere dashboard under **Settings → API Keys**. ```json theme={null} { "status": "failed", "message": "Authentication credentials were not provided." } ``` Check the request body against the endpoint's parameter table. All required fields must be present and non-empty. ```json theme={null} { "status": "failed", "data": [], "message": "This field is required." } ``` The provided ID (BVN, NIN, etc.) could not be matched in the source database. Verify the number is correct and belongs to a real record. ```json theme={null} { "status": "failed", "data": [], "message": "Sorry, your check cannot be processed at the moment. Please try again in a few minutes" } ``` These are rare and typically transient. Implement exponential back-off retry logic in your integration. If a `5xx` error persists for more than a few minutes, contact [support](mailto:adhere@smartcomply.com). ## Retrying Requests For `5xx` errors and network timeouts, retry with exponential back-off: | Attempt | Wait before retry | | --------- | ----------------- | | 1st retry | 1 second | | 2nd retry | 2 seconds | | 3rd retry | 4 seconds | Do **not** retry `4xx` errors — they indicate a problem with the request itself that must be fixed before retrying. # Introduction Source: https://docs.smartcomply.com/introduction Adhere by Smartcomply — identity verification, fraud detection, transaction monitoring, and credit data across Africa. Adhere by Smartcomply ## What is Adhere? **Adhere** is Smartcomply's developer API — a single integration that gives you access to identity verification, fraud detection, transaction monitoring, and credit reporting across Africa. Whether you're onboarding customers, assessing loan applications, or screening transactions in real time, Adhere provides the compliance infrastructure you need to build with confidence. **Currently supported countries:** Nigeria, Ghana, Kenya, Rwanda, and Uganda. ## What You Can Build Verify customer identities using BVN, NIN, national IDs, passports, driver's licenses, and more — across Nigeria, Kenya, Ghana, Rwanda, and Uganda. Score transactions in real time, screen against global sanctions lists, detect card fraud, and monitor user behaviour with AML checks and configurable alert thresholds. Pull individual and business credit histories from CRC, First Central, and Credit Registry — including full reports, scores, and history summaries. Assess individual and business loan applications using AI-driven fraud scoring, real-time credit bureau data, and financial analysis. ## Onboarding Suite The Adhere Onboarding Suite lets you verify customer identities at every step — from document checks and biometric matching to address verification and credit screening — all from a single API. Adhere Onboarding Suite Adhere Onboarding Suite ## Quick Links Make your first API call in under 5 minutes. How to authenticate your requests. Understand API error responses. ## Base URL All API requests use the following base URL: ``` https://adhere-api.smartcomply.com ``` ## Support Reach us at [adhere@smartcomply.com](mailto:adhere@smartcomply.com) or explore the [Postman collection](https://documenter.getpostman.com/view/55164637/2sBXwjxET7). # Android SDK Source: https://docs.smartcomply.com/libraries/android_sdk Integrate SmartComply identity verification and liveness detection into your Android app. # SmartComply Android SDK The SmartComply Android SDK delivers a fully self-contained identity verification flow for Android apps. Launch one Activity and the SDK handles session management, country and ID-type selection, document capture, identity verification, and liveness detection automatically. ## Features * **Single-Activity launch** — start verification with one Intent and receive a typed result back * **Two verification modes** — document photo capture or ID number data entry, configured from your Dashboard * **Guide-box document capture** — frames the ID card precisely so images are always clean and correctly cropped * **Liveness detection** — camera-based face challenge system (blink, turn head) runs automatically after identity verification * **Dynamic ID types** — channels and fields are fetched live from your Dashboard configuration * **Multi-country support** — renders a country picker automatically when more than one country is configured * **Dark and light mode** — theme adapts to the system setting; override via the launch intent *** ## Requirements * **Android API 24** (Android 7.0) or later * **Kotlin 1.9** or later * **Jetpack Compose** enabled in your module *** ## Installation ### 1 — Add Maven Central In `settings.gradle.kts` (already present in most projects): ```kotlin theme={null} dependencyResolutionManagement { repositories { google() mavenCentral() } } ``` ### 2 — Add the dependency In your app or feature module `build.gradle.kts`: ```kotlin theme={null} dependencies { implementation("io.github.386konsult:android-sdk:1.0.0") } ``` ### 3 — Enable Compose ```kotlin theme={null} android { buildFeatures { compose = true } } ``` *** ## Permissions The SDK declares these permissions automatically via manifest merge. You do not need to add them manually unless your project uses a custom manifest merge strategy: ```xml theme={null} ``` The SDK requests the `CAMERA` permission at runtime before the camera is used. Your app does not need to request it separately. *** ## Quick Start ### 1 — Register the result launcher In your `Activity` or `Fragment`: ```kotlin theme={null} import androidx.activity.result.contract.ActivityResultContracts import com.smartcomply.sdk.ui.SmartComplyActivity import com.smartcomply.sdk.types.FlowResult val verificationLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> val data = result.data ?: return@registerForActivityResult when (data.getStringExtra(SmartComplyActivity.RESULT_TYPE)) { SmartComplyActivity.TYPE_SUCCESS -> { val entryId = data.getIntExtra(SmartComplyActivity.RESULT_ENTRY_ID, -1) val status = data.getStringExtra(SmartComplyActivity.RESULT_STATUS) val verifiedName = data.getStringExtra(SmartComplyActivity.RESULT_VERIFIED_NAME) val idTypeName = data.getStringExtra(SmartComplyActivity.RESULT_ID_TYPE_NAME) // handle success } SmartComplyActivity.TYPE_FAILURE -> { val errorMsg = data.getStringExtra(SmartComplyActivity.RESULT_ERROR_MSG) // handle error } SmartComplyActivity.TYPE_CANCELLED -> { // user pressed back } } } ``` ### 2 — Launch verification ```kotlin theme={null} import com.smartcomply.sdk.client.Environment import java.util.UUID val intent = SmartComplyActivity.buildIntent( from = this, apiKey = "pk_live_xxxxxxxxxxxx", // your SmartComply API key clientId = UUID.randomUUID().toString(), // unique per verification attempt environment = Environment.PRODUCTION ) verificationLauncher.launch(intent) ``` ### Jetpack Compose If you are launching from a composable, use `rememberLauncherForActivityResult`: ```kotlin theme={null} import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.runtime.rememberCoroutineScope import com.smartcomply.sdk.ui.SmartComplyActivity import com.smartcomply.sdk.client.Environment import java.util.UUID @Composable fun StartVerificationButton() { val context = LocalContext.current val launcher = rememberLauncherForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> val data = result.data ?: return@rememberLauncherForActivityResult when (data.getStringExtra(SmartComplyActivity.RESULT_TYPE)) { SmartComplyActivity.TYPE_SUCCESS -> { /* handle success */ } SmartComplyActivity.TYPE_FAILURE -> { /* handle error */ } SmartComplyActivity.TYPE_CANCELLED -> { /* user cancelled */ } } } Button(onClick = { val intent = SmartComplyActivity.buildIntent( from = context, apiKey = "pk_live_xxxxxxxxxxxx", clientId = UUID.randomUUID().toString(), environment = Environment.PRODUCTION ) launcher.launch(intent) }) { Text("Verify Identity") } } ``` *** ## buildIntent Parameters ```kotlin theme={null} fun buildIntent( from: Context, apiKey: String, clientId: String, darkTheme: Boolean? = null, // null = follow system environment: Environment = Environment.PRODUCTION ): Intent ``` | Parameter | Default | Description | | ------------- | ------------ | -------------------------------------------------------------------------------- | | `from` | — | The calling `Context` | | `apiKey` | — | Your SmartComply API key — find it in the Dashboard | | `clientId` | — | A unique ID per verification attempt — use `UUID.randomUUID().toString()` | | `darkTheme` | `null` | `true` forces dark mode, `false` forces light, `null` follows the device setting | | `environment` | `PRODUCTION` | `PRODUCTION` for live verification, `SANDBOX` for testing | *** ## Result Extras Read from the `Intent` returned to your activity result callback. | Constant | Type | Present when | | ---------------------- | -------- | ------------------------------------------------------------------- | | `RESULT_TYPE` | `String` | Always — `"success"`, `"failure"`, or `"cancelled"` | | `RESULT_ENTRY_ID` | `Int` | `TYPE_SUCCESS` | | `RESULT_STATUS` | `String` | `TYPE_SUCCESS` — e.g. `"submitted"`, `"verified"` | | `RESULT_SUBMITTED_AT` | `String` | `TYPE_SUCCESS` — ISO 8601 timestamp | | `RESULT_VERIFIED_NAME` | `String` | `TYPE_SUCCESS` — full name from the identity provider, if available | | `RESULT_ID_TYPE_NAME` | `String` | `TYPE_SUCCESS` — e.g. `"National ID"`, `"BVN"` | | `RESULT_ERROR_MSG` | `String` | `TYPE_FAILURE` | *** ## Verification Flow The SDK steps through these states automatically. | Step | Description | | ----------------- | -------------------------------------------------------------------- | | Loading | Session creation and brand config fetch | | Welcome | Brand splash, country picker, and ID type selection | | Camera Permission | Requests camera permission at runtime before any camera is opened | | Document Capture | Camera view for the front (and back, if required) of the ID document | | ID Input | Form fields for data-mode verification (BVN, NIN, etc.) | | Liveness | Live camera challenge — blink, turn head | | Processing | Upload and backend verification in progress | | Success | Verification complete — shows a summary card, then calls back | | Failure | Unrecoverable error — shows the message and a retry button | *** ## SDK Configuration ```kotlin theme={null} data class SDKConfig( val apiKey: String, val clientId: String, val environment: Environment = Environment.PRODUCTION, val requestTimeoutMs: Long = 30_000L, val uploadTimeoutMs: Long = 120_000L, val maxUploadRetries: Int = 3, val debug: Boolean = false ) ``` | Parameter | Default | Description | | ------------------ | ------------ | --------------------------------------------------------- | | `apiKey` | — | Your SmartComply API key (required) | | `clientId` | — | Unique identifier per verification attempt (required) | | `environment` | `PRODUCTION` | `SANDBOX` for testing, `PRODUCTION` for live verification | | `requestTimeoutMs` | `30000` | Timeout in milliseconds for standard API calls | | `uploadTimeoutMs` | `120000` | Timeout in milliseconds for video upload | | `maxUploadRetries` | `3` | Automatic retry attempts on upload failure | | `debug` | `false` | Prints verbose network logs to Logcat when `true` | *** ## Error Handling `SmartComplyActivity` handles and displays all error states automatically. Common scenarios: | Scenario | Cause | Resolution | | -------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------- | | `TYPE_FAILURE` with `"401"` | Invalid or missing API key | Check your key in the SmartComply Dashboard | | `TYPE_FAILURE` — session expired | Session tokens have a 30-minute TTL | Generate a new `clientId` on the next launch | | `TYPE_CANCELLED` | User pressed back | Re-launch when the user is ready to retry | | Upload failed | Network instability | The built-in failure screen offers a retry; if retries are exhausted `TYPE_FAILURE` is returned | *** ## Advanced: Custom Host Activity If you need to embed the verification flow directly inside your own `ComponentActivity` instead of launching a separate screen, you can use `SmartComplyFlowScreen` as a Compose composable: ```kotlin theme={null} import com.smartcomply.sdk.SmartComply import com.smartcomply.sdk.client.SDKConfig import com.smartcomply.sdk.client.Environment import com.smartcomply.sdk.ui.SmartComplyFlowScreen import java.util.UUID val sdk = SmartComply( SDKConfig( apiKey = "pk_live_xxxxxxxxxxxx", clientId = UUID.randomUUID().toString(), environment = Environment.PRODUCTION ) ) // In your composable: SmartComplyFlowScreen( sdk = sdk, darkTheme = null, // null = follow system setting onComplete = { result -> // result.entryId, result.status, result.verifiedName, etc. }, onError = { message -> // unrecoverable error not handled by the built-in failure screen } ) ``` Your host `Activity` must be a `ComponentActivity` and must be in the foreground with an active window. Embedding `SmartComplyFlowScreen` inside a `Dialog` or bottom sheet will cause the camera to fail on some devices. *** ## ProGuard / R8 The SDK ships with its own consumer ProGuard rules. If you see obfuscation-related issues, add to your `proguard-rules.pro`: ``` -keep class com.smartcomply.sdk.** { *; } -keepattributes *Annotation* ``` # iOS SDK Source: https://docs.smartcomply.com/libraries/ios_sdk Integrate SmartComply identity verification and liveness detection into your iOS app with a single drop-in SwiftUI view. # SmartComply iOS SDK The SmartComply iOS SDK is a native Swift library that delivers a fully self-contained identity verification flow for iOS apps. Drop in one SwiftUI view and the SDK handles session management, country and ID-type selection, document capture, identity verification, and liveness detection automatically. ## Features * **Drop-in SwiftUI view** — `SmartComplyFlowView` manages the entire verification flow with no UI code required * **Two verification modes** — document photo capture or ID number data entry, configured from your Dashboard * **Guide-box document capture** — crops exactly what falls inside the ID card frame so the image sent to the backend is always clean * **Liveness detection** — face challenge system (blink, turn head) runs automatically after identity verification * **Dynamic ID types** — channels and fields are fetched live from your Dashboard configuration * **Multi-country support** — renders a country picker automatically when more than one country is configured * **Dark and light mode** — theme adapts to the system colour scheme; override with `preferredColorScheme` * **Automatic retry** — handles upload retries and session errors internally *** ## Requirements * **iOS 16.0** or later * **Swift 5.9** or later * **Xcode 15** or later * **iPhone X or later** — liveness detection requires a front-facing TrueDepth camera *** ## Installation The SDK is distributed via Swift Package Manager. ### Xcode (recommended) 1. Open your project in Xcode 2. Go to **File → Add Package Dependencies** 3. Enter the repository URL: `https://github.com/386konsult/ios-sdk` 4. Select **Exact Version** and enter `1.0.0` 5. Click **Add Package** and select the **SmartComplySDK** library ### Package.swift ```swift theme={null} dependencies: [ .package(url: "https://github.com/386konsult/ios-sdk", exact: "1.0.0") ], targets: [ .target( name: "YourApp", dependencies: [ .product(name: "SmartComplySDK", package: "ios-sdk") ] ) ] ``` *** ## Platform Setup Add the following key to your app's `Info.plist`: ```xml theme={null} NSCameraUsageDescription Camera access is required to photograph your ID document and complete liveness verification. ``` *** ## Quick Start ### 1. Create the SDK instance Create a `SmartComply` instance once — for example in your view model or app entry point. Generate a fresh `clientId` (UUID) for each new verification attempt. ```swift theme={null} import SmartComplySDK let sdk = SmartComply( config: SDKConfig( apiKey: "pk_live_xxxxxxxxxxxx", clientId: UUID().uuidString, // unique per verification attempt environment: .production ) ) ``` ### 2. Present the flow view Embed `SmartComplyFlowView` anywhere in your SwiftUI hierarchy. The SDK loads automatically when the view appears. ```swift theme={null} import SmartComplySDK struct ContentView: View { @State private var showVerification = false let sdk = SmartComply(config: SDKConfig(apiKey: "pk_live_...", clientId: UUID().uuidString)) var body: some View { Button("Verify Identity") { showVerification = true } .fullScreenCover(isPresented: $showVerification) { SmartComplyFlowView(sdk: sdk) { result in showVerification = false print("Entry ID:", result.entryId) print("Status:", result.status) if let name = result.verifiedName { print("Verified name:", name) } } } } } ``` The SDK manages the entire flow automatically. The exact steps depend on the verification mode configured in your Dashboard: **Document mode** (photo capture): 1. Creates a secure session 2. Displays a welcome screen with your brand name and ID type cards 3. Shows a country picker if multiple countries are configured 4. User photographs the front of their ID inside the guide box 5. Photographs the back if required (National ID, Driver's Licence, Voter's Card) 6. Runs liveness face challenges 7. Returns a `FlowResult` to your completion handler **Data mode** (ID number entry): 1. Creates a secure session 2. Displays a welcome screen with ID type selection 3. Shows a country picker if multiple countries are configured 4. User enters their ID number and any required fields 5. Identity is verified against the national database 6. Runs liveness face challenges 7. Returns a `FlowResult` to your completion handler *** ## SDK Configuration ```swift theme={null} public struct SDKConfig { public init( apiKey: String, clientId: String, environment: SDKEnvironment = .sandbox, requestTimeout: TimeInterval = 30, // seconds uploadTimeout: TimeInterval = 120, // seconds maxUploadRetries: Int = 3, debug: Bool = false ) } ``` | Parameter | Default | Description | | ------------------ | ---------- | --------------------------------------------------------------------------------- | | `apiKey` | — | Your SmartComply API key (required) | | `clientId` | — | A unique identifier per verification attempt — use `UUID().uuidString` (required) | | `environment` | `.sandbox` | `.sandbox` for testing; `.production` for live traffic | | `requestTimeout` | `30` | Timeout in seconds for standard API calls | | `uploadTimeout` | `120` | Timeout in seconds for video upload | | `maxUploadRetries` | `3` | Number of automatic retry attempts on upload failure | | `debug` | `false` | Prints verbose network logs to the console when `true` | *** ## FlowResult Delivered to your `onComplete` closure when the user completes the flow in-app. ```swift theme={null} public struct FlowResult { public let entryId: Int // liveness entry ID — use this to query results via the API public let status: String // e.g. "submitted" public let submittedAt: String? // ISO 8601 timestamp public let idTypeName: String? // e.g. "National ID", "BVN" public let verifiedName: String? // name returned by the identity provider (data mode only) } ``` > **Final verification results are delivered via webhook.** Once the backend completes processing, SmartComply sends a webhook event to the URL configured in your Dashboard. Set up your webhook endpoint to receive the final status, extracted fields, and any failure reasons. See the [Webhooks](/webhooks) guide for the full payload reference. *** ## Error Handling `SmartComplyFlowView` handles and displays error states automatically. For the headless API, all SDK methods throw on failure: ```swift theme={null} do { _ = try await sdk.createSession() } catch let error as SDKError { print("API error \(error.statusCode):", error.message) } catch { print("Network error:", error.localizedDescription) } ``` | Scenario | Cause | Resolution | | --------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------- | | `401 Unauthorized` | Invalid or missing API key | Check your key in the SmartComply Dashboard | | Session expired | Sessions expire after 2 hours and are single-use | Generate a new `clientId` and call `createSession()` again | | Camera permission denied | User denied camera access | The flow view shows a Settings deep-link automatically | | Upload failed after retries | Network instability | `maxUploadRetries` exhausted — the failure screen offers a retry | | Identity not found | ID number not found or details mismatched (data mode) | User is shown the reason and prompted to re-enter | # Web SDK Source: https://docs.smartcomply.com/libraries/smartcomply_sdk Integrate Adhere identity verification and liveness detection into your web applications using the SmartComply Web SDK. # Adhere Web SDK The Adhere Web SDK enables you to rapidly and securely verify user identities and perform facial liveness checks directly in your web applications. The SDK mounts a drop-in widget over your application, handling document capture, identity verification, and liveness detection — all in one seamless flow. ## Features * **Drop-in UI Modal** — Responsive, animated widget that overlays your app via `SmartComplyFlow.open()`. * **CDN & npm Support** — Install via npm/yarn or load directly from a CDN with zero build steps. * **Dynamic Routing** — Automatically adapts document and verification requirements from your dashboard configuration. * **Single-Use Sessions** — `clientId` is your permanent integration key (from your SDK Config) and is reused for every session. Each `createSession()` call issues a fresh, single-use session token — that token, not the `clientId`, is what's scoped to one verification. * **Nigeria & Global Identity** — Supports BVN, NIN, passports, driver's licenses, voter's cards, and other document/data channels enabled in your dashboard. * **Two-Sided Document Capture** — Front is always required; back is required, optional, or not offered depending on the document type (e.g. NIN is optional-back, since not every physical NIN document has a usable reverse side). * **Hardware Agnostic Liveness** — Uses native webcam and MediaRecorder API for cross-platform compatibility. A single passive scan (blink + natural head movement) — no discrete step-by-step prompts. *** ## Installation ### Option 1 — CDN (No build step required, recommended) Add the script tag to your HTML: ```html theme={null} ``` The SDK is available globally as `window.SmartComplySDK`: ```javascript theme={null} const { SmartComplyFlow, SmartComply } = window.SmartComplySDK; ``` `@1` always resolves to the latest `1.x.x` release — bug fixes and new features reach your site automatically the moment we publish them, with **no code change on your end, ever**. We commit to never shipping a breaking change as a `1.x` release; if a breaking change is ever needed, it ships as `2.0.0`, and `@1` keeps serving the last safe `1.x` release until you deliberately opt in. This is the same versioning model used by most public JS SDKs (Stripe.js, Google Maps, etc.). Other CDN options: ```html theme={null} ``` `@1`/`@latest` re-resolve on **every page load** — that's what makes them self-updating, with no rebuild or redeploy needed on your side. An exact `@X.Y.Z` pin never moves until you manually change the number in your script tag. See [npmjs.com/package/smartcomply-web-sdk](https://www.npmjs.com/package/smartcomply-web-sdk) for release history. ### Option 2 — npm / yarn ```bash theme={null} npm install smartcomply-web-sdk # or yarn add smartcomply-web-sdk ``` ```javascript theme={null} import { SmartComplyFlow } from 'smartcomply-web-sdk'; ``` Unlike the CDN, npm has no auto-updating option — this is true for every npm package, not specific to ours. `npm install` resolves to the latest version **at the moment you run it**, then locks that exact version in `package-lock.json` (or `yarn.lock`); it will not change again on its own. Run `npm update smartcomply-web-sdk` periodically (or before each deploy) to pick up new fixes — this stays within the `^1.0.x` range already set in your `package.json`, and we commit to never shipping a breaking change within `1.x`, so it's always safe to run. Check [npmjs.com/package/smartcomply-web-sdk](https://www.npmjs.com/package/smartcomply-web-sdk) for the current version number. *** ## Quick Start — Drop-in Widget (Recommended) The easiest way to integrate is the drop-in widget. It handles the complete verification flow automatically. ```javascript theme={null} SmartComplyFlow.open({ apiKey: "your_api_key_here", clientId: "your_client_id_here", environment: "production", // sandbox is not currently available onComplete: (result) => { console.log("Verification complete:", result); // result = { entryId, sessionId, status, submittedAt } }, onError: (error) => { console.error("Verification failed:", error); }, onClose: () => { console.log("Widget closed."); } }); ``` Get your **API Key** and **Client ID** from your [Adhere Dashboard](https://adhere.smartcomply.com) — both come from your SDK Config and are permanent; reuse the same values for every session. What's single-use is the *session token* the SDK obtains internally via `createSession()` (30-minute expiry, revoked after submission) — you never see or manage that token directly through the drop-in widget. ### Configuration Parameters | Parameter | Type | Required | Description | | ------------- | -------- | -------- | -------------------------------------------------------------------------------------------------- | | `apiKey` | string | ✅ Yes | Your API key from the Adhere Dashboard | | `clientId` | string | ✅ Yes | Your permanent client ID from the Adhere Dashboard (SDK Config) — the same value for every session | | `environment` | string | No | `"production"` (default) | | `onComplete` | function | No | Callback fired when verification completes successfully | | `onError` | function | No | Callback fired on error | | `onClose` | function | No | Callback fired when the widget is closed | `sandbox` is not currently available — use `"production"` for all integration and testing today. This section will be updated once sandbox is back. ### Environment URLs | Environment | Base URL | | ------------ | ------------------------------------ | | `production` | `https://adhere-api.smartcomply.com` | *** ## Framework Examples ### React ```jsx theme={null} import { SmartComplyFlow } from 'smartcomply-web-sdk'; export default function VerifyButton() { const handleVerify = () => { SmartComplyFlow.open({ apiKey: process.env.REACT_APP_API_KEY, clientId: process.env.REACT_APP_CLIENT_ID, environment: "production", onComplete: (result) => console.log("Done:", result), onError: (err) => console.error("Error:", err), }); }; return ; } ``` ### Vue ```vue theme={null} ``` ### Plain HTML (CDN) ```html theme={null} ``` *** ## Headless API (Advanced) For full control over the UI, use the `SmartComply` class directly without the modal. ```typescript theme={null} import { SmartComply } from 'smartcomply-web-sdk'; const sdk = new SmartComply({ apiKey: "your_api_key_here", clientId: "your_client_id_here", environment: "production", }); const run = async () => { // 1. Create a session — sessions last 30 minutes and are single-use // (revoked as soon as liveness is submitted) await sdk.createSession(); // 2. Fetch SDK configuration — brand, theme, and available channels per country const config = await sdk.initializeConfig(); console.log("Verification type:", config.verification_type); console.log("Channels:", config.channels); // config.channels["nigeria"] is an array of: // { id, name, code?, requires_back_side?: boolean | "optional", fields: [...] } // 3a. Data verification (BVN/NIN/etc.) — validates against the government database const verifyResult = await sdk.onboarding.verify({ identity_type_id: 1, // channel id from config.channels fields: { bank_verification_number: "12345678901" } }); const identityCheckId = verifyResult.data?.identity_check_id; // 3b. Document verification — capture front (and back, if the channel's // requires_back_side is true or "optional") instead of step 3a. // const documentFront: Blob = /* from a file input or camera capture */; // const documentBack: Blob | undefined = /* only if the channel needs/offers one */; // 4. Run liveness check — requires an HTMLElement container for the camera. // Runs a single passive scan (blink + natural head movement); the // 3rd argument is a descriptive tag for your dashboard, not a live // prompt sequence the UI steps through. const container = document.getElementById("camera-container") as HTMLElement; const liveness = await sdk.liveness.startCheck( container, { identifier: "12345678901", identifier_type: "bvn", country: "NG", identity_check: identityCheckId, // link to the data-verification result above // document: documentFront, // for document verification instead // document_back: documentBack, }, ["BLINK", "TURN_HEAD"] ); console.log("Liveness status:", liveness.status); // "processing" — final // pass/fail result arrives via webhook, not this return value. }; run(); ``` *** ## onComplete Payload `onComplete` fires as soon as the user finishes their part of the flow (the "Verification Submitted" screen renders) — it is a **submission receipt, not a verification verdict**. Backend processing (face match, document read, government DB check) continues after this fires, and `status` is always `"processing"` here regardless of the eventual outcome. The real pass/fail result only ever arrives via [webhook](#receiving-results-webhook). ```json theme={null} { "entryId": 365, "sessionId": "da7623bd-9158-4b56-a9e4-4bccf3c0133f", "status": "processing", "submittedAt": "2026-06-05T23:11:22.873161+00:00", "verificationResult": { "status": "success", "code": "VERIFICATION_COMPLETE", "data": { "first_name": "Amara", "last_name": "Okafor", "identity_check_id": 123 } } } ``` `verificationResult` is only present for **data verification** (BVN/NIN) — it's the immediate government-database lookup result confirming the ID number matched a real record. It says nothing about the face match, which is still pending. It's absent for document verification and liveness-only flows. *** ## Receiving Results (Webhook) The backend delivers exactly one `liveness.completed` webhook per verification, to the URL configured in your SDK Config, once face matching (and OCR / government DB check, depending on the flow) has finished. This is the SDK's own webhook — configured per SDK Config and specific to `liveness.completed`. It's separate from the platform-wide webhook system described in [Webhooks](/webhooks) (transaction monitoring, general KYC module events, `{success, module, event, data}` shape). Both currently sign with HMAC-SHA256 and a `sha256=`-prefixed header, hex-encoded — verify against the raw request body either way. ### Payload shape ```json theme={null} POST https://your-server.com/webhook Content-Type: application/json X-Adhere-Signature: sha256= { "event": "liveness.completed", "verification_id": 42, "verification_type": "data_verification", "status": "passed", "failure_reason": null, "timestamp": "2026-08-08T10:15:00.000Z", "subject": { "identifier": "12345678901", "identifier_type": "National Identity Number (NIN)", "country": "nigeria" }, "biometrics": { "liveness_verified": true, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 70.0 }, "selfie_url": "https://.../autoshot.jpg", "face_analysis": { "gender": "Female", "dominant_emotion": "neutral", "face_quality": { "face_detected": true, "face_confidence": 0.98, "blur_score": 142.3, "is_blurry": false } } }, "activity": { "session_id": "da7623bd-9158-4b56-a9e4-4bccf3c0133f", "started_at": "2026-08-08T10:12:00.000Z", "submitted_at": "2026-08-08T10:14:30.000Z", "completed_at": "2026-08-08T10:15:00.000Z", "duration_seconds": 180 }, "request_context": { "ip": { "address": "102.67.1.66", "city": "Lagos", "country_code": "NG" }, "device": { "user_agent": "Mozilla/5.0 ...", "type": "desktop", "os": "Windows" } }, "customer_profile": { "first_name": "AMARA", "last_name": "OKAFOR", "other_name": null, "date_of_birth": "01-Jan-1997", "age": 29, "gender": "Female", "id_number": "12345678901", "serial_number": null, "occupation": null, "place_of_birth": null, "place_of_live": "...", "date_of_issue": null, "photo_url": null } } ``` For **document verification**, the same top-level shape applies, with `verification_type: "document_verification"` and a `document` block (OCR fields + document-to-selfie face match) instead of `customer_profile`: ```json theme={null} "document": { "status": "verified", "document_type": "passport", "is_expired": false, "first_name": "AMARA", "last_name": "OKAFOR", "date_of_birth": "1997-01-01", "age": 29, "gender": "Female", "nationality": "NGA", "document_number": "A12345678", "expiry_date": "2030-06-15", "issue_date": "2020-06-15", "issuing_authority": "...", "document_url": "https://.../document.jpg", "document_back_url": null, "face_match": { "attempted": true, "verified": true, "confidence_percentage": 55.0, "threshold_percentage": 35.0, "reason": null, "selfie_url": "https://.../autoshot.jpg", "document_face_url": "https://.../document_face.jpg" } } ``` `document` also carries `place_of_birth`, `place_of_issue`, `address`, `district`, `division`, `location`, `sub_location`, `serial_number`, and `barcode_number` — `null` unless the specific document type carries that field (e.g. serial/barcode numbers mainly apply to newer Kenyan ID cards). `face_match.reason` is populated with a user-facing explanation when `verified` is `false` or the match was skipped. `status: "passed"` means **the check ran to completion — not that the person matched**. A face mismatch, low confidence score, or expired document still reports `status: "passed"`, with the real outcome recorded in `biometrics.face_match.verified` (and `document.is_expired` for document verification). `status: "failed"` is reserved for cases where the check itself couldn't run (service error, no selfie captured, government DB rejection). Never gate access on `status` alone — always check `face_match.verified`. `verification_id` matches the `entryId` your `onComplete` callback received. ### Verify the signature The signature header is `X-Adhere-Signature: sha256=` — note the `sha256=` prefix. It's computed over the exact compact-JSON bytes of the request body, so your handler must verify against the **raw body**, not a re-serialized copy of the parsed JSON (re-stringifying can produce different bytes and the signature will never match). ```javascript theme={null} const crypto = require("crypto"); app.post( "/webhook/smartcomply", express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }), (req, res) => { const signature = (req.headers["x-adhere-signature"] || "").replace(/^sha256=/, ""); const secret = process.env.WEBHOOK_SECRET.replace(/-/g, ""); const expected = crypto.createHmac("sha256", secret).update(req.rawBody).digest("hex"); const isValid = signature.length === expected.length && crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex")); if (!isValid) return res.status(401).send("Bad signature"); const { event, verification_id, status, biometrics, document } = req.body; // status === "passed" only means the check ran to completion — check // the real outcome before treating the user as verified: const faceMatched = biometrics?.face_match?.attempted ? biometrics.face_match.verified === true : true; // not attempted (e.g. NIN slip, CAC) — nothing to fail here const documentOk = document ? document.is_expired === false : true; if (event === "liveness.completed" && status === "passed" && faceMatched && documentOk) { markUserAsVerified(verification_id); } else if (event === "liveness.completed") { recordVerificationOutcome(verification_id, req.body); } res.json({ received: true }); } ); ``` *** ## Security Notes * **Client ID** — Permanent, from your SDK Config. Reuse the same `clientId` for every session — there's no per-session ID to generate. * **API Key** — Never expose your API key in client-side code in production. Use environment variables. * **Session Tokens** — The single-use part. Automatically obtained and managed by the SDK per verification via `createSession()`, expire after 30 minutes, and are revoked immediately once liveness is submitted. *** ## Troubleshooting | Error Code | HTTP | Cause | Fix | | ---------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | `INVALID_API_KEY` | 401 | Bad or missing `apiKey` | Check your `apiKey` value in the SDK Config | | `SDK_CONFIG_NOT_FOUND` | 404 | Invalid `clientId` | Check your `clientId` value — it should be the UUID from your SDK Config, not regenerated per session | | `INVALID_SESSION` | 401 | Session token missing, malformed, expired (30 min), or already revoked (a session is single-use — it's consumed once liveness is submitted) | Call `createSession()` again to get a fresh token; `clientId`/`apiKey` stay the same | | `VALIDATION_ERROR` | 400 | Missing or invalid fields in the request | Check `data.errors` in the response for which field failed | | `RETRY_LIMIT_EXCEEDED` | 429 | User exceeded the retry limit for confirmation/liveness attempts | The user must restart with a new session | | `INSUFFICIENT_BALANCE` | 402 | Wallet balance too low | Top up your wallet in the dashboard | | `Camera not available` | — | Browser blocked camera access | Ensure HTTPS and camera permissions are granted | # Account & Identity Verification Source: https://docs.smartcomply.com/pages/account_verification How to use Adhere to verify customer identities and bank accounts at onboarding. Verifying that a customer is who they claim to be — and that the bank account they provide is theirs — is the foundation of safe onboarding. Adhere gives you the tools to do this digitally, in seconds, without asking for paper documents. ## Confirm Identity Before Onboarding Use Nigeria's BVN or NIN to instantly confirm a customer's name, date of birth, and phone number against the central identity database. For Kenya, Ghana, Rwanda, and Uganda, verify against national ID and passport records. Verify an 11-digit Bank Verification Number and return the holder's full name, phone, and date of birth. Confirm identity against Nigeria's National Identity Number database. Verify Kenyan customers using their national ID number. Verify Ghana Card, Passport, Voter ID, SSNIT, or Driver's License numbers. ## Verify the Bank Account Belongs to Them Before disbursing funds or setting up a direct debit, confirm that the account number the customer provided is linked to their identity. Look up any Nigerian bank account number and return the account holder's name — so you can confirm it matches your customer's identity before processing any payment. ## Add a Biometric Layer For higher-risk onboarding flows, add a liveness check or face match to confirm the person presenting the ID is physically present. Compare a selfie against a reference image to confirm the same person. Detect whether the face in a submitted image is live, not a photo or video replay. ## Reduce Drop-Off Without Sacrificing Compliance Because every check returns a result in real time, your onboarding flow stays fast. Customers verify in the same session — no manual review queues, no document uploads, no back-and-forth. A typical verified onboarding flow looks like this: Ask the customer for their BVN, NIN, or national ID number — no document scan needed. Call the relevant Adhere endpoint. The response returns verified name, date of birth, and phone number within seconds. Call NUBAN verification to confirm the account number matches the verified name. For regulated or high-value flows, add a face liveness or comparison check before approval. # Lending & Loan Decisioning Source: https://docs.smartcomply.com/pages/lending How to use Adhere to verify borrowers, pull credit history, and detect fraudulent loan applications. Lending decisions depend on two things: knowing the borrower is real, and knowing they can repay. Adhere gives you both — identity verification, credit bureau data, and AI-driven fraud scoring — through a single API. ## Verify the Borrower's Identity First Before pulling any credit data, confirm the applicant is who they say they are. Use BVN, NIN, or national ID verification to match the submitted details against authoritative government records. Confirm name, phone, and date of birth against the Bank Verification Number registry. Verify the applicant's National Identity Number before processing their application. ## Pull Their Credit History Adhere connects to CRC, First Central, and Credit Registry — Nigeria's major credit bureaus — so you can retrieve a full picture of the applicant's borrowing history before making a decision. Number of loans, active facilities, delinquencies, and total outstanding balance from CRC. Summary-level credit data from First Central Credit Bureau. Detailed credit report including payment history and institution breakdown. Numeric credit score from First Central or CRC to feed directly into your decisioning model. ## Run a Loan Fraud Check The Loan Fraud Check endpoint combines the submitted application data with credit bureau information to produce a fraud risk score (0–100), a repayment assessment, and a recommendation — for both individual and business applicants. Score an individual application using income, employment, collateral, and credit history data. Assess a business loan application using company registration, revenue, and credit data. ## A Complete Lending Due-Diligence Flow Call BVN or NIN verification to confirm the applicant's name and date of birth match what they submitted. Retrieve a credit summary or full report from the bureau of your choice. Check for delinquencies, active loans, and total exposure. Submit the full application to the Loan Fraud Check endpoint. Receive a fraud risk score, key financial ratios, and a plain-language recommendation. Use the score against your risk threshold to approve, review, or decline — with a full audit trail from each API call. # Quickstart Source: https://docs.smartcomply.com/quickstart Make your first Smartcomply API call in under 5 minutes. ## Prerequisites Before you start, make sure you have: * A Smartcomply account — [sign up here](https://adhere-app.smartcomply.com/signup) * Completed your business KYC on the Adhere dashboard * Generated a secret key under **Settings → API Keys** ## Make Your First Request The example below verifies a Nigerian BVN. Replace `YOUR_SECRET_KEY` with your actual key. ```bash cURL theme={null} curl -X POST "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/" \ -H "x-access-token: YOUR_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"bvn": "22000000001"}' ``` ```javascript Node.js theme={null} const response = await fetch( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/", { method: "POST", headers: { "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ bvn: "22000000001" }), } ); const data = await response.json(); console.log(data); ``` ```python Python theme={null} import requests response = requests.post( "https://adhere-api.smartcomply.com/api/onboarding/nigeria_kyc/bvn/", headers={ "x-access-token": "YOUR_SECRET_KEY", "Content-Type": "application/json", }, json={"bvn": "22000000001"}, ) print(response.json()) ``` ## Successful Response ```json theme={null} { "status": "success", "data": { "lastName": "OMOLE", "firstName": "ABRAHAM", "middleName": "ISAAC", "dateOfBirth": "1909-09-19", "phoneNumber1": "09011001100" }, "message": "Bank Verification Number details retrieved successfully" } ``` If you receive a `401`, check that your `x-access-token` header is set correctly. For a full list of error responses, see [Error Codes](/error_codes). ## Next Steps Learn how to secure and manage your API keys. Explore all identity verification endpoints. Understand all possible error responses. Set up real-time event notifications. # Webhooks Source: https://docs.smartcomply.com/webhooks Learn how to receive and verify webhook notifications from Adhere. **In a nutshell:** Webhooks allow you to set up a notification system that can be used to receive updates on certain requests made to the Adhere API. Adhere uses webhooks to notify your application when specific events occur. This allows you to build automated workflows and integrate Adhere closely with your system. ## Why use Webhooks? Generally, when you make a request to an API endpoint, you expect to get a near-immediate response. However, some requests may take a long time to process. In order to prevent a timeout error, a pending response is returned. Since your records need to be updated with the final state of the request, you need to either: 1. **Polling**: Make a request for an update at regular intervals. 2. **Webhooks**: Listen to events by using a webhook URL. We recommend using webhooks over polling. Webhooks are more efficient, reduce network overhead, and ensure your system is updated immediately when an event occurs. ## Setup & Integration To start receiving webhook notifications, follow these steps to configure your environment: Provide the endpoint on your server where Adhere will send `POST` requests. This should be a publicly accessible URL. A secret key used to sign the webhook payload. You must keep this secure and use it to verify that requests are coming from Adhere. Save your settings in the Adhere dashboard under the **Integrations** section. ## Security & Verification All webhook requests from Adhere include a `X-Adhere-Signature` header. This header contains the HMAC SHA256 signature of the request body, signed with your Hash Key. ### Verifying Signatures To ensure that a webhook request is genuinely from Adhere, you should verify the signature before processing the payload. ```python Python theme={null} import hmac import hashlib import base64 from flask import request, abort def verify_webhook(request, hash_key): sig_header = request.headers.get("X-Adhere-Signature") if not sig_header: abort(401, "Missing signature") # The header format is "sha256=" _, _, received_sig = sig_header.partition("=") # Compute the HMAC SHA256 digest of the raw request body raw_body = request.get_data() digest = hmac.new( hash_key.encode("utf-8"), raw_body, hashlib.sha256 ).digest() expected_sig = base64.b64encode(digest).decode("utf-8") if not hmac.compare_digest(received_sig, expected_sig): abort(401, "Invalid signature") ``` ```javascript Node.js theme={null} const crypto = require('crypto'); function verifyWebhook(req, hashKey) { const signature = req.headers['x-hub-signature']; if (!signature) { throw new Error('Missing signature'); } const [algo, receivedSig] = signature.split('='); const hmac = crypto.createHmac('sha256', hashKey); const digest = hmac.update(req.rawBody).digest('base64'); if (receivedSig !== digest) { throw new Error('Invalid signature'); } } ``` ```php PHP theme={null} function verify_webhook($request_body, $hash_key, $received_sig) { $expected_sig = base64_encode(hash_hmac('sha256', $request_body, $hash_key, true)); if (!hash_equals($received_sig, $expected_sig)) { http_response_code(401); exit("Invalid signature"); } } ``` ```go Go theme={null} import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "io/ioutil" "net/http" "strings" ) func verifyWebhook(w http.ResponseWriter, r *http.Request, hashKey string) bool { sigHeader := r.Header.Get("X-Adhere-Signature") if sigHeader == "" { return false } // Header format is "sha256=" parts := strings.Split(sigHeader, "=") if len(parts) != 2 { return false } receivedSig := parts[1] body, _ := ioutil.ReadAll(r.Body) h := hmac.New(sha256.New, []byte(hashKey)) h.Write(body) expectedSig := base64.StdEncoding.EncodeToString(h.Sum(nil)) return hmac.Equal([]byte(receivedSig), []byte(expectedSig)) } ``` ```csharp .NET theme={null} using System.Security.Cryptography; using System.Text; public bool VerifyWebhook(string requestBody, string hashKey, string receivedSig) { var keyBytes = Encoding.UTF8.GetBytes(hashKey); var bodyBytes = Encoding.UTF8.GetBytes(requestBody); using (var hmac = new HMACSHA256(keyBytes)) { var hashBytes = hmac.ComputeHash(bodyBytes); var expectedSig = Convert.ToBase64String(hashBytes); return expectedSig == receivedSig; } } ``` Always verify the `X-Adhere-Signature` header to prevent unauthorized requests from interacting with your server. ## Event Payload Structure All webhooks follow a consistent JSON structure: | Parameter | Type | Description | | :-------- | :------ | :---------------------------------------------------------------------------------- | | `success` | boolean | Indicates if the event was processed successfully. | | `module` | string | The Adhere module that triggered the event (e.g., `transaction_monitoring`, `kyc`). | | `event` | string | The specific event type. | | `data` | object | The actual payload data (e.g., transaction details, KYC results). | ## Supported Events ### Transaction Monitoring * **Module**: `transaction_monitoring` * **Events**: * `suspicious_transaction`: Triggered when a transaction is processed and deemed suspicious. ```json theme={null} { "data": { "id": 23, "is_internal_blacklisted": false, "is_blacklisted_by": null, "case_id": "#8N2ZI6", "case_sla": "2025-08-23T09:39:31.551479Z", "case_status": "open", "transaction_id": "9201634916397893719", "amount": 12345.0, "currency": "EUR", "transaction_type": "card", "account_type": "individual", "customer_name": "David Seaman", "customer_email": "davidseaman@example.com", "customer_ip_address": "192.168.0.8", "customer_location": "Yaba, LG", "origin_account_no": "4321567809", "origin_bank_code": "327", "transaction_description": "Payment for order #78901", "destination_account_no": "0123456789", "destination_bank_code": "723", "merchant_name": null, "merchant_location": null, "status": "suspicious", "card_bin": null, "card_last4": null, "bvn": "7890123456", "fraud_percent": null, "tag": [ "1 rule(s) triggered" ], "sender_blacklisted": false, "receiver_blacklisted": false, "rules_flagged": [ "Any transaction by an individual that exceeds an amount {a}" ], "additional_info": {}, "date_created": "2025-08-20T09:39:31.425545Z", "date_updated": "2026-01-16T13:46:07.388489Z", "branch": 2 }, "event": "suspicious_transaction", "module": "transaction_monitoring", "success": true } ``` ## Testing Locally Before deploying to production, we recommend testing your webhook implementation locally. 1. **Use ngrok**: Use [ngrok](https://ngrok.com/) to create a secure tunnel to your local server. 2. **Set Webhook URL**: Update your Adhere dashboard with the ngrok URL (e.g., `https://your-subdomain.ngrok-free.app/webhooks`). 3. **Inspect Requests**: Use the ngrok dashboard or [Webhook.site](https://webhook.site/) to inspect the payloads and headers sent by Adhere. ## Best Practices * **Acknowledge Immediately**: Your server should return a `200 OK` response as quickly as possible. Heavy processing should be handled asynchronously using a task queue. * **Handle Retries**: Adhere will retry failed webhook deliveries (non-2xx responses) up to 3 times with an exponential backoff. * **Use Idempotency**: Ensure your system can handle the same webhook multiple times safely. Use the event's unique ID to track processed events. If your server does not return a 2xx response, Adhere will consider the delivery as failed and will attempt to retry.