Skip to content

KYC review

Queues → KYC review is who has been verified, to what level, and “whether that verification is still worth anything.”

Needs kyc.read to open and kyc.review to decide. The Retention tab needs gdpr.process and does not appear without it.

Tab What it is
Review queue The daily job: submitted profiles awaiting a decision.
Expiring and lapsed Verification that has run out or is about to.
Levels What each tier demands and how long an approval stands.
Retention Documents held past their retention date. Destructive.

Each tab reads when you first open it rather than on arrival, so the estate-wide sweeps do not run for people who never look at them.

When a merchant sends a submission for review, staff holding kyc.review are emailed “KYC to review: {merchant}”, by the live deployment only. The email names the KYC queue rather than linking to it.

Control Values
Risk rating High risk first, Medium risk, Low risk.
Column What it holds
Merchant Who.
Status Where the profile stands.
Level “Held, and the level being asked for. A submission always asks for more.”
Risk The rating.
Waiting “Days since the merchant was created. The queue is ordered by it.”
Submission The case — or a red Orphaned — nothing to decide pill.
Business type, Country, Last touched —

A row opens the dossier. An orphaned row does not, because there is nothing to open: it is a merchant awaiting review with no open case behind it.

Orphaned rows, and opening a case for a merchant

Section titled “Orphaned rows, and opening a case for a merchant”

An orphaned row is fixable from here. Open a case creates the submission on the merchant’s behalf — assisted onboarding, which is the norm in this market where a field agent sits with a merchant and fills the form in.

Field Notes
Level being applied for Which level the case is for.
Why you are opening it for them e.g. “Field visit in Kumasi; the merchant has no portal access yet and the documents were collected in person.”

The case opens in progress and is not yet before a reviewer — the dialog says “case opened, not yet filed”. It still has to be filed from the dossier. One open submission per merchant is enforced, so a second attempt is refused rather than producing a duplicate.

The Retention tab is the destructive one, and the single field on it is the record of why:

Field Notes
Why this document is being destroyed Required. The retention policy it is being destroyed under is the useful answer, because the document itself will not be there to re-examine.

Two results are worth telling apart. A purge that destroyed the file is the normal one. A purge reporting “the file was already gone” succeeded on the row and deleted nothing — the record now says destroyed, and something removed the object outside this console. That needs looking at rather than filing.

Purging a Ghana Card row deletes the sealed number; there is no file to destroy, and no file storage is involved. The erasure log records document_number_sealed as erased, with the number’s keyed digest. That proves which number was erased without the log holding it.

Opening a submission gives you the whole case in one page: the gate, the submission, the documents, the checks and the owners.

The platform evaluates whether this submission can be decided, against the level being asked for, and that verdict is rendered before anything else — with the approve action disabled behind it.

Kind Meaning
Blockers The submission cannot be approved until these are resolved.
Advisories Styled apart deliberately. Not blockers.

The gate also summarises ownership: Ownership complete, Declared total, Undisclosed, UBOs (“holding 25 per cent or more”), PEPs, and Owner KYC required.

“As it was attested, and what has happened to it.” Status, level requested, created, submitted, reviewed, filed by, the reason given to the merchant, and reviewer notes where there are any.

An in-progress case shows “this case has not been filed yet — nobody can approve or reject it until it has been submitted.” The action offered is File this case for review, with a reason. A submission is filed once.

Each document on the case, with its type: Ghana Card, passport, driver’s licence, voter’s ID, selfie, proof of address, certificate of incorporation, business certificate (Form A / Form 3), tax certificate, bank statement, utility bill, board resolution, or something else.

Reading a Ghana Card number. Instead of View, the row has Read number. It needs kyc.review and a reason — “Why are you viewing it”, recorded against your account — and is logged as kyc.document.number_reveal. It shows the full number: “Check it on the NIA verification service, then close this. Do not copy it anywhere else.” Everywhere else it is shown masked, as GHA-*****6789-0.

Face match on a case with a Ghana Card is the selfie against the photo NIA holds for that number, not against an image of the card.

A Ghana Card counts as evidence when its sealed number is on file. The gate checks the number, not storage, and so does Approve on the document. A row with neither a file nor a sealed number is reported as “The row carries neither a file nor a sealed number. This is OUR data fault, not a missing submission.” It can’t be approved. From the API, the gate’s document finding carries number_only: true for a Ghana Card.

Opening one is a PII access. The dialog says so — “opening it is a PII access, and the reason is part of the record” — and asks:

Field Notes
Why are you opening it Recorded against your name in the audit log.

Write something real. “Checking” is not a reason; “verifying the registration number against the submission” is.

Duplicate findings. Where the same document appears on another record, the panel says so and shows what it can: the other record, the type, how long it has been held, and who it belongs to. The same Ghana Card number on another account is flagged the same way, matched on the number’s keyed digest, and it blocks the level just as an identical file does. A national ID on two unrelated merchants is either a data error or a finding, and it is not for you to assume which.

Uploading for a merchant — “three steps: sign, upload, record. All three have to finish or the file is orphaned in the bucket.”

Field Notes
What kind of document From the list above — except the Ghana Card, which is not offered.
The file —
Document number, masked Masked, deliberately.
Issuing country —
Expires on —
Why you are uploading this for them Audited.

A submission with no documents cannot satisfy a level that requires them, and the empty state says exactly that.

The eight check types:

Check What it tests
ID verification The document against an issuer registry.
Liveness The selfie is a live person.
Face match Selfie against the ID photo — for a Ghana Card, the photo NIA holds.
Name enquiry The bank or mobile money account name.
Sanctions screening —
PEP screening Politically exposed person.
Adverse media —
Business registry Company lookup at the registrar.

“A level requiring checks cannot be granted until they have been run.”

Recording a vendor check — “what a vendor said, stored verbatim. This re-evaluates the gate.”

Field Notes
Which check One of the eight.
Result Pass — satisfies the requirement. Fail — a finding against the subject. Manual review — NOT satisfied. Error — the vendor could not be reached.
Which vendor answered —
Their reference —
Score Where the vendor gives one.
What the vendor gave as the reason —
The full vendor payload Stored verbatim.
Why this is being recorded by hand Audited.

A vendor response can be read back in full — “verbatim, as the vendor sent it. This is the most personal data in the API.” Treat opening it the way you treat opening a document.

Overriding a check is dual controlled: “the check stays as it is until another person approves this.”

Field Notes
Justification stored on the check Travels with the check forever.
Why the request is being raised For the approval record.

The panel shows the request’s status, approvers needed, expiry, and the permission an approver must hold. See Approvals.

“As declared. The gate’s figures are computed from these.” If nobody is named, the panel says “no owners are declared, so the whole entity is an undisclosed share” — which is a finding, not an empty list.

“The decision is recorded against the case. It does not itself grant a level.”

Field Notes
Reason For the record.
Next review due When this verification should be revisited.
Reviewer notes “Internal. The merchant never sees this.”

“The merchant is told, and has to submit again.” Three separate reason fields, because there are three audiences:

Field Who reads it
Reason the merchant sees The merchant. Required.
Reason for the audit log Auditors, and whoever reviews your decision.
Reviewer notes Internal only.

They are deliberately not one box. The merchant-facing one is the one that must never accidentally contain an internal note, and a single field is how that happens.

Write the merchant-facing reason as an instruction: “the certificate of incorporation is cropped — resubmit with all four corners visible” tells them what to do. “Documents insufficient” generates a support ticket and a second rejection.

The merchant is emailed when a single document is rejected (“Your {document} needs replacing”), with the document type and your rejection reason. They can replace it without waiting for the whole submission to be refused, so write that reason for them too.

Approving the submission records the decision on the case. Granting the level is what changes what the merchant may do.

The gate is re-evaluated against the level you name, so granting a higher level than the submission asked for is checked against that level’s requirements, not these. Granting is what moves the merchant’s current_level, and nothing else does — not the merchant, not the submission, not an approval.

A direct grant (POST /v1/kyc/merchants/{id}/level) emits merchant.kyc_approved, the same event a submission approval emits. So the merchant gets the verification-approved email and, if subscribed, the webhook. A direct grant used to tell them nothing.

The days-remaining figure goes negative, and the tab treats the sign as the whole story: lapsed rows are listed first, counted separately, and pilled as overdue, with the figure rendered as “34 days ago” rather than as “-34 days remaining” — which is a sentence nobody parses correctly at speed.

The default window deliberately includes the past, so opening the tab shows you what has already gone wrong before what is about to.

Work it before the review queue. A merchant in the queue is at least one who cannot trade yet.

The rate card for verification: which documents and checks each tier demands, whether owner KYC is required, whether it may be auto-approved, and how long an approval stands. It is the reference every other tab’s numbers are judged against — and it is what the merchant sees their own side of in the merchant docs.

Levels 0 and 1 may be auto-approved when every check passes. Levels 2 and 3 always need a human.

Documents held past their retention date, with a permanent delete.

This tab is gdpr.process, not kyc.review, and it is only shown to accounts holding it — so a reviewer is never shown a destructive tab they cannot use and must not be tempted by.

It lives here rather than under Data requests on purpose: filed under GDPR it reads as a data-subject chore, and filed here it is visibly the other end of the same document’s life.