A sandbox where you pick the outcome.
Send an identifier ending 2222 and the upstream hangs, then fails — every time, on every machine. Not found, malformed and declined work the same way, so the paths that break in production are the paths you can put in a test suite. No bank, registry or SMS gateway is contacted in the sandbox, and nothing is metered.
Authentication
One key, two environments
Every request carries your API key as a bearer token. The older x-api-key header is still accepted and will not be removed — existing integrations do not need to change.
divp_test_…
Sandbox. Nothing real is contacted, nothing is billed, and connector behaviour is chosen by what you send.
divp_live_…
Production. Real registries, real banks, real money, metered against your plan.
curl -X POST https://verifia.anybanq.lk/v1/verifications/nic \
-H "Authorization: Bearer divp_test_…" \
-H "Content-Type: application/json" \
-d '{
"nicNumber": "199012340000",
"fullName": "Nimal Perera",
"consentGiven": true
}'Amounts are in minor units wherever a field says so, and every amount carries an explicit currency. Nothing is assumed to be LKR.
Sandbox
The last four digits choose the outcome
The scenario is keyed on the last four digits of an NIC or account number, not a magic prefix — a Sri Lankan NIC carries a birth year up front and an account number carries a branch, so a prefix scheme would force you to use structurally invalid identifiers. Punctuation and a trailing letter are ignored; only digits count. Anything that is not one of these codes succeeds, so your own realistic test data gives you a working flow.
| Send | You get | What it exercises |
|---|---|---|
| …0000 | Verified | The registry or bank returns a matching record. |
| …1111 | Not found | Well-formed input, nothing upstream to match it against. |
| …2222 | Timeout | The upstream hangs for a full 5 seconds, then fails. Test your own timeout. |
| …3333 | Validation error | The upstream rejects the request as malformed. |
| 999.99 | Declined | Any payment for this amount is refused by the issuing bank. |
A sandbox key works while your account is still onboarding or awaiting review, so you can build the integration before the paperwork is finished. It stops working only if the account is suspended.
Webhooks
Signed, retried, de-duplicable
Results are posted to your endpoint as JSON. A failed delivery is retried with exponential backoff — 10s, 30s, 2m, 10m, 30m, then 2h — for six attempts by default, after which it sits in the dead-letter list for you to replay from the dashboard.
POST https://your-app.lk/hooks/verifia
x-divp-event: verification.completed
x-divp-signature: sha256=<hex hmac of the raw body>
x-divp-delivery-id: 0f2c…
x-divp-attempt: 1
{
"event": "verification.completed",
"data": {
"verificationId": "…",
"type": "NIC",
"status": "APPROVED",
"outcome": "PASS",
"score": 100
},
"sentAt": "2026-09-16T04:21:08.114Z"
}const expected = crypto
.createHmac("sha256", process.env.VERIFIA_WEBHOOK_SECRET)
.update(rawBody) // the exact bytes we sent, not a re-serialised object
.digest("hex");
// Retries resend an identical body, so the signature never changes.
// Dedupe on x-divp-delivery-id.Getting keys
Sandbox first, live after approval
- 1
Register
Create the account at /register. We review it — you are told when sign-in opens.
- 2
Take the sandbox key
A divp_test_ key comes back on the registration screen itself, before any review, so you can call the sandbox the same minute. It is shown once; we store only an Argon2id hash of it and cannot recover it for you. Lost it, or signed up earlier? Settings → API keys mints another.
- 3
Finish onboarding
Business registration number, BR certificate, at least one director and a settlement account. Submitting runs a business (KYB) verification.
- 4
Request live access
Once it is granted, live keys unlock. Ask for one before then and the API says so plainly: this account is not approved for live keys yet.
Keys can be scoped and revoked individually, and every live key can be revoked at once if you ever need to. Each key records when it was last used.
What we deliberately do not publish
There is no public OpenAPI document.
Stop looking for one — it is not hidden behind a URL you have yet to guess. A complete route inventory tells an attacker exactly which doors exist and what shape the keys are, so the spec is served only to signed-in merchants, and /docs and /openapi.json are refused at the edge on every host.
The same content is in the dashboard the moment you can sign in: the full reference, per workflow, with your own keys already filled in. Everything on this page is true of the sandbox before you have an account at all.
