Reference

Marketplace (bring your own provider)

Connect your own verification and core-banking providers in Build → Marketplace and use their capabilities as workflow steps.

Build → Marketplace lists every provider you can plug into ThirdFactor. ThirdFactor Native is the built-in suite (nothing to connect). The other providers are BYOK — bring your own key: you connect them with the credentials the provider issued to your organisation, and the provider bills its own usage fee to you directly.

Once a provider is connected, each of its workflow capabilities appears in the workflow builder as a step type — grouped under its category (for example CBS Integration or Compliance). Provider steps run on ThirdFactor's servers when the verification completes; the applicant never sees a screen for them.

Permissions

PermissionAllows
View marketplaceBrowse the Marketplace tabs and open provider details, pricing and setup requirements.
Manage marketplace integrationsConnect a provider (Test and save), delete its credentials, and send an integration request.
Use marketplace lookupsRun a connected provider's lookup from a verification's Marketplace tab or the Live Video Call panel (for example Get details from Pumori).
Update applicant dataEdit the data a lookup returned, Save as draft and Send it back to the provider.

Workflow editors (Create & edit KYC workflows) can add connected provider steps to a workflow and configure them.

Lookups on a verification (Marketplace tab)

While a provider that offers lookups is connected, every verification page has a Marketplace tab (after Access log), and the Live Video Call panel has the same tab next to Info, Signature and Notes — both show the same case and the same history. Anyone who can open the verification sees the tab; running a lookup needs Use marketplace lookups.

  • Get details from Pumori runs Account Validation with the account number (MainCode), then Customer Information Lookup with the client code it returned. The account number is pre-filled from the case — an account the verification opened or validated, the applicant's answer, or your metadata — and can be edited to look up a different account.
  • Each successful lookup is saved as a snapshot, timestamped and attributed ("fetched by …"). Fetching again always adds a new snapshot; history is shown newest first, and each snapshot expands to its fields. A lookup that finds nothing is not saved.
  • With Update applicant data you can edit a snapshot's returned data and Save as draft (drafts persist until sent or discarded) or Send it through the provider's update call — for Pumori, Update Client Information. Before sending, ThirdFactor re-reads the record: if someone changed an edited field in the CBS since the lookup, nothing is sent and you are asked to fetch again. The write is sent once and never retried automatically; afterwards the record is read back and compared, and any difference holds the update for compliance review (the verification is tagged and the team that manages Marketplace is notified).
  • Lookups, drafts and sends appear in the verification's timeline and Access log. Personal identifiers stay masked for operators without View unmasked personal data. Lookup and update calls are billed at the capability's Third Factor Fee Credit (free unless your plan sets a rate).

Connecting a provider

Open the provider → Setup, fill in the credentials (required fields are marked, and every field explains itself on hover) and press Test and save. ThirdFactor runs one read-only capability with the credentials — you pick which from the button's menu; a provider with a single capability runs it directly — and saves the credentials only if that check passes. Secrets are encrypted at rest and never shown again; leave a secret blank to keep the saved one.

Delete credentials disconnects the provider. Workflow steps that use it then land on their failure outcome (see below) until you connect again.

What happens when a provider call fails

Every provider step has an If the provider call fails setting — Approved, In review (the default) or Declined. A failed call — network error, timeout, a 5xx, an unreadable answer, rejected credentials, a missing input, or a disconnected provider — lands the step on that outcome instead of leaving it pending. The reason is recorded on the step.

Pumori (CBS)

Pumori is the core banking system built by InfoDevelopers Pvt. Ltd.

  • Credentials: Base URL (the host root before /api/pumori), Username and Password, plus the CBS user ID that write calls are booked under (at most 6 characters: Pumori's models refuse a longer one, and Test and save says so). The password is exchanged for a token that ThirdFactor refreshes every 15 minutes, and again immediately if Pumori ever answers 401.
  • Private network: Pumori runs inside your banking network. Your network team must allowlist ThirdFactor's egress IP range on the Pumori host — otherwise calls time out — and ThirdFactor approves outbound access to your specific host. The first Test and save against a new private host sends that request automatically.
  • Workflow steps: Account Validation, Client Code Creation, Account Creation, Customer Information Lookup, Update Client Information, Turnover Details (read and update).
  • Dates: Pumori returns dates as timestamps (2015-09-18T00:00:00) but its update call accepts only the date part, so every date is sent as YYYY-MM-DD — the values read from the CBS as well as the ones you edit. Nepali (BS) dates are sent exactly as read (DD/MM/YYYY).
  • Update call method: the Pumori document does not say whether Update Client Information and Update Turnover Details are POST or PUT, so it is an Advanced setting (POST by default). If Pumori answers 405 to the configured method, nothing was processed, so the update is sent once more with the method Pumori's Allow header names (or the other of POST / PUT), the accepted method is saved on the connection, and the result says so. A 405 to both methods lists them and the Allow header for your CBS team.
  • Update Client Information sends the client's BranchCode (read from the record, where Pumori calls it Branch) because the update model requires it, and every value read back from the CBS is trimmed before it is sent again (Pumori pads fixed-width columns such as the country code and then refuses the padded value). A value longer than Pumori's documented limit (CBS user ID 6, country codes 2) is reported before anything is sent.
  • A refused call quotes Pumori: when Pumori answers a 4xx to a lookup or an update, the result, the draft's note and the Activity tab carry Pumori's own reply — for a 400 that is the field its model rejected and why (for example DateOfBirth: Could not convert string to DateTime) — so your CBS team gets the exact objection rather than a bare "HTTP 400".
  • Client Code Creation sends the complete documented request. Map each field to verification data, a questionnaire answer or a fixed value with {{ variable }} templates. Address codes follow the CBS's own lists: DistrictCode is the old district code from Get District; CProvince (and CState on updates) is the New District Code from Get Local Authorities by District (filtered by the province from Get Province); CVDCMDC is the LocalAuthoCode from Get Local Authorities Address. The step editor offers these as cascading pickers, and a name (for example Jhapa) mapped into a code field is resolved to its code at run time.
  • Safety: writes run only for an approved verification (configurable per step); client and account creation are never retried blindly — after an unclear answer ThirdFactor looks the record up first and re-submits only if nothing was created; every client creation or update is read back and its address fields compared, and a mismatch holds the verification for manual compliance review.
  • Manual approvals: a verification that finishes In review defers its writes (the step shows as skipped). When a reviewer approves it — from the verification page, a maker/checker case, a confirmed four-eyes proposal, or the API's status update — the deferred writes run once, with the same safeguards. A decline never writes. If a write fails at that point the approval stands: the failure is recorded on the step, the team is notified in the console, and anyone with Manage marketplace integrations can press Retry provider step on the verification. After an unclear earlier attempt, a retry checks the CBS for the record before sending anything.
  • Pumori has no photograph field, so it can't be a Reference Image source for Face Match.

KSKL NID Check

  • Credentials: Partner Identifier, Partner Key and Partner Signature — the three KSKL issues to your organisation — plus the access token. KSKL's token endpoint (POST /api/create/token) sits on KSKL's internal network and is reachable only from inside your bank's network or VPN, so ThirdFactor cannot generate or renew the token: generate it there (the Setup tab shows the exact curl), paste the Bearer JWT into Access token, and Test and save runs one alphaAuthWithAddress check with it. The token is stored encrypted, masked after save and never returned by any API, log or export — not even its last characters. Every check sends it as Authorization: Bearer together with a Hash header over the request body — an HMAC-SHA512 keyed by the Partner Key by default (KSKL names SHA-512). KSKL documents the header only as "a SHA-based hash of the request payload" and refuses a wrong one with Invalid HMAC, so the construction (HMAC-SHA512 / SHA256 / SHA1 / MD5 keyed by the Partner Key or the Partner Signature, hex or base64, or a plain SHA-256 / SHA-512) is an Advanced setting on the connection — and Test and save finds it for you: when KSKL answers Invalid HMAC, the test tries the other constructions in turn (one call each) and saves the one KSKL accepts, naming it in the result. If KSKL refuses them all, the message lists what was tried — ask KSKL for the exact HMAC recipe (e.g. the pre-request script of their Postman collection). Turning off TLS certificate verification for KSKL's internal endpoint is the other Advanced setting. Nothing is cached or re-minted at runtime.

  • Expiry: on save, the token's exp claim is read (without verifying the signature) and shown beside the field; a token that is not a JWT, or has no exp, asks for Token expires on. The KSKL card and the Setup tab show Active, Expires in N days (within 30), Expires today or Token expired; tenants connected before the token field existed see Token required until one is added. Administrators are emailed and notified in the console 30 days and 7 days before expiry, on the day, and once when it has expired. Replace token on the Setup tab takes the new token with one test check and never asks for the partner credentials again; checks started after the save use the new token. Token changes (who, when, the new expiry — never the token) appear in the integration's Activity tab and in Audit Logs.

  • NID Verification calls KSKL's alphaAuthWithAddress service with the national ID number, full name, date of birth and permanent address — province, district, municipality and ward, as KSKL's own integer codes (KSKL retired the earlier number + name + date-of-birth check in October 2026). The step's address inputs default to what the ID document read; a blank level falls back to a questionnaire answer with the usual field id (province, district, municipality, ward), and finally to the document's address line. Names are matched to KSKL's codes automatically (English or Nepali, with or without Municipality / Rural Municipality; the province is worked out from the district). A name that matches nothing — or more than one place — is never guessed: the step lands on its failure outcome with the reason (address_problems) and no call is made.

  • Answers: KSKL replies synchronously with HIT, MISS or PROCESSING. Only HIT is a match (the registry's values, including the address it holds, are kept for reconciliation). MISS — or any other status — is a no-hit, handled by the step's When the registry says no hit outcome. A PROCESSING answer is asked again after 3 seconds, then every 5 seconds up to 30 seconds, then every 15 seconds up to 2 minutes, then the step's failure outcome applies. The Setup tab also shows a callback URL you can give KSKL; a pushed result short-circuits the re-asking.

  • Token expired or rejected: when the stored token is missing or past its expiry (no call is made) or KSKL answers a check with 401/403, the step fails with KSKL_AUTH_FAILED and the reason KSKL access token expired or invalid — never a no-hit, and never retried (no re-mint, no re-asking; an early background run settles the step rather than handing it back). The kskl.nid.failed event carries the same reason, and the Setup tab shows KSKL rejected the access token (401/403) after a live rejection until a new token is pasted. The partner secrets are stored encrypted; the console shows only their last 4 characters.

  • Any other answer: a 2xx reply that is not the documented alphaAuthWithAddress shape fails the step with unreadable_response, and KSKL's own error envelope ({"error": "true", "message": …}, a validation reply, or a status of error / failed) fails it with provider_error — never a no-hit, and never retried. Both reasons quote KSKL's reply (its message, else the first 200 characters of the body, secrets redacted) in the step's failure, in the Setup tab's test result and on the Activity tab, so a wrong Hash construction or an inactive partner account is named rather than guessed. A message that mentions the hash points at the Hash algorithm choice under Advanced in Setup (which a Setup-tab test probes automatically, see above). Every call's trail records the construction it used.

  • Network: KSKL's endpoint sits on its internal network — your server must reach dhruv.kskl.org.np over the link or VPN KSKL agreed with you, and KSKL must allow-list your server's public IP for your partner account. A 403 IP whitelist validation failed is reported as KSKL_IP_NOT_ALLOWED with the IP(s) to send KSKL — it is not a token problem and does not raise the token banner. The Base URL is the host only (https://dhruv.kskl.org.np); an endpoint pasted there is trimmed to the host, and a 404 answer names the Base URL as the thing to check.

  • Reaching KSKL through your own KSKL VPN (on-prem): when KSKL only accepts your bank's NAT addresses, have your network team present dhruv.kskl.org.np at an internal address on your firewall (a transparent forward, so KSKL's own certificate is served). On the server, map the hostname to that address in the app's compose override (extra_hosts) and approve a private-network grant for the KSKL host, since a public hostname that resolves to a private address is otherwise refused. The request then leaves through your KSKL tunnel with your NAT address.

Pricing

The Pricing tab shows, per capability, the Third Factor Fee Credit (debited from your credit balance for each call a workflow step makes — free unless your plan sets a rate) and the provider's own usage fee in NPR, which the provider bills to you directly.

Requesting a provider

+ Request integration sends ThirdFactor the provider's name, an optional category and a note about your use case. The team reviews every request.