Skip to main content

UVerify for Python

The official Python library for UVerify: BVN, NIN, driver’s licence and voter’s card checks, liveness and face match, ID documents, AML screening and CAC, for Nigerian businesses.

pip install uverify

Python 3.8 or later. No dependencies.

Quick start

from uverify import UVerify

uverify = UVerify("uvk_test_...")  # or set UVERIFY_API_KEY; uvk_test_ is the free sandbox

v = uverify.identity.nin(id_number="12345678901", first_name="Adaeze", last_name="Okafor")
if v["status"] == "verified":
    print(v["data"], v["field_matches"])

In the sandbox the last two digits of the ID number choose the result: 00 not found, 99 registry error, 98 face mismatch, anything else verified.

A live customer, end to end

session = uverify.liveness.create_session(redirect_url="https://yourapp.com/kyc/done")
# send the person to session["url"]; when they come back:
v = uverify.identity.bvn_face_match(
    id_number="22212345678", first_name="Adaeze", last_name="Okafor",
    liveness_session_id=session["id"],
    aml_screening=True,
)
if v["status"] == "verified" and v["face_match"]["status"] == "matched" and v["aml_screening"]["status"] == "clear":
    ...  # approve

Everything else

uverify.identity.bvn(id_number=..., first_name=..., last_name=...)       # also drivers_license, voters_card, tin
uverify.identity.nin_face_match(id_number=..., selfie_image=open("me.jpg", "rb").read())
uverify.business.cac(id_number="RC123456", aml_screening=True)

uverify.documents.verify(front_image=open("nin.jpg", "rb").read(), document_type="nin_card")
uverify.aml.screen(name="Adaeze Okafor", date_of_birth="1990-01-15")
uverify.aml.monitors.create(name="Adaeze Okafor")
link = uverify.kyc.create_link(customer_name="Ada", require_document=True)   # send link["url"]

uverify.verifications.list(status="verified")
uverify.account.balance()

Responses are plain dicts, exactly as in the API reference.

Errors

from uverify import UVerifyError

try:
    uverify.identity.nin(id_number=id_number)
except UVerifyError as e:
    if e.code == "insufficient_balance":
        ...
    print(e.code, e.message, e.request_id, e.details)

A check that finds nothing isn’t an error: it returns status: "not_found" (and you aren’t charged).

Retries

Timeouts, connection errors, 5xx and rate limits are retried twice with backoff (max_retries, timeout). Every check carries a reference (generated if you don’t pass one), so a retry never charges twice, and if the first attempt went through you get that result.

Webhooks

from uverify import construct_event, UVerifySignatureError

@app.post("/webhooks/uverify")          # Flask/FastAPI/Django: use the raw body
def hook():
    try:
        event = construct_event(request.get_data(), request.headers.get("UVerify-Signature"), WEBHOOK_SECRET)
    except UVerifySignatureError:
        return "", 400
    if event["type"] == "verification.completed":
        ...
    return "", 200

Deliveries can repeat: dedupe on event["id"].

Tests

python -m unittest discover -s tests                       # offline
UVERIFY_TEST_KEY=uvk_test_... python -m unittest tests.test_sandbox

MIT licence.

Metadata

Release files for uverify 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for uverify 0.1.0
File Size Uploaded
uverify-0.1.0.tar.gz 10.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for uverify 0.1.0
File Interpreter ABI Platform
uverify-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.7 kB

Release files / uverify-0.1.0.tar.gz

Download URL uverify-0.1.0.tar.gz
Size 10.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bad65c3d4e170f2463eabfa93c84588a630924337f65683dc252031dd871353e
BLAKE2b-256 checksum
How to use checksums
b5ae3146e0ac93c951afd91fc3d87741d02d051da367322bf21c59a05f6b6635
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Release files / uverify-0.1.0-py3-none-any.whl

Download URL uverify-0.1.0-py3-none-any.whl
Size 8.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e50ab559134b04f61fb7783b12ff8fbc358eec07e3288c13fa047214ebb3490a
BLAKE2b-256 checksum
How to use checksums
6288fa6568029425a2fc70f574f6b9e830d9b2c088cbc696a7c528a83d5df995
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page