Verify anyone. Any channel. One API.

Verify users over SMS, Voice, Email, USSD and WhatsApp through one API. One session model, one integration, every phone your users carry.

Verification session01J8XQ4M
Verifying
+233 24 ••• 4567
Verification code
SMS pending
transaction_idorder_8841

Verification made simple.

Connect through the channels your users already use, while you get the tools and visibility to manage verification with confidence.

A woman outdoors checking a verification code on her phone.

Never lose a customer because a code didn't arrive.

SMS, Voice, Email, USSD and WhatsApp, whichever device and network your customer actually has. No separate integration per channel.

Pay for what you use.

Nothing expires, nothing auto-renews. Top up when you need to, the balance is still yours next quarter.

Test mode · $0 charged

Try it with zero risk.

Every app gets live and test credentials. Build and test the whole flow before you spend a cedi.

Truefaktor console: an application overview showing total verification requests, credit usage per channel and verification trends.
Truefaktor Console

See exactly what you're spending, and whether it's working.

Requests, success rate, and credits used per channel, per application, in the console. No end-of-month surprises.

One vendor, not four contracts.

We hold the telecom, WhatsApp and email delivery relationships so you don't have to manage four separate vendors to reach one customer.

One API. Five ways to verify.

Reach users on whichever channel fits their device and connectivity. Integrate once and choose per request.

SMS

A one-time code delivered by text message.

any phone with a SIM

Voice

The code read aloud over an automated call.

when a text can't land

Email

A one-time code, or a magic link for passwordless sign-in.

otp or magic_link

USSD

The user dials a code we return. No smartphone, no data plan.

feature phones welcome

WhatsApp

Verification delivered inside the app your users already open every day.

rich, familiar, fast
Same session, same statuses, same callback on every channel. Pick one per request with "channel", or set a default per application.

Two requests. That's the integration.

Authenticate with your product key and secret, create a session, then confirm the code your user enters. Poll for status or receive it at your callback URL.

1. Create a session
# product key as username, secret as password
curl -u API_KEY:API_SECRET \
  -X POST https://api.truefaktor.com/v2/generate \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "sms",
    "client_msisdn": "233241234567",
    "transaction_id": "order_8841",
    "description": "Confirm your order"
  }'

# 200
{
  "session_id": "01J8XQ4M...",
  "channel": "sms",
  "expires_at": "2026-09-24T10:05:00Z"
}

# WhatsApp instead? same client_msisdn, just change the channel
#   "channel": "whatsapp"

# email instead? swap two fields
#   "channel": "email", "client_email": "ama@example.com",
#   "config": { "method": "magic_link" }
2. Confirm the code
curl -u API_KEY:API_SECRET \
  -X POST https://api.truefaktor.com/v2/verify \
  -H "x-auth-session-id: 01J8XQ4M..." \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "order_8841",
    "otp_code": "482913"
  }'

# 200
{
  "session_id": "01J8XQ4M...",
  "status": "completed"
}

# wrong code -> invalid_otp, too many tries -> max_attempts
# USSD sessions need no code: the user dials, you poll /v2/status
HTTP Basic auth

Your product key is the username, your secret the password. Keys are per application and revocable from the console.

6-digit codes, 5-minute expiry

Codes expire after 300 seconds by default, with a 30-second resend cooldown and attempt limits.

Poll or callback

Read a session with POST /v2/status, or receive the same result at the callback URL set on your application.

Built for the moments when identity matters.

A verification is often the last step before money moves or an account changes hands. The flow around the code is as important as the code.

Codes expire

Every session carries an expires_at. Nothing stays pending forever.

Attempts are limited

Too many wrong codes ends the session with max_attempts. Resends wait 30 seconds.

States are explicit

pending, verified, completed, expired, declined, cancelled: your app always knows exactly where a session stands.

Tied to your transaction

Sessions are keyed by your own transaction_id, so a result can never be confused with another request.

Rate-limited and monitored

Every channel is rate-limited and watched for abuse at the account level.

Registered data controller

Mobiverse Solutions Limited is registered with Ghana's Data Protection Commission.

Wherever you need to know it's really them.

Different products, the same question. Pick the channel that reaches your users.

Fintech

Step-up before money moves

Confirm a transfer or a new payee with a code the account holder can answer from any phone.

Marketplaces

Verify both sides of a trade

Confirm a buyer's number at signup and a seller's at payout, before anyone is trusted with the other's goods or money.

SaaS

Passwordless sign-in

Send a magic link or a code instead of managing yet another password, and drop it into your existing login.

E-commerce

Confirm orders and deliveries

Check the number behind a cash-on-delivery order, or confirm a handover with a code the recipient reads out.

Public services

Reach citizens without smartphones

USSD and voice verify people on feature phones and patchy networks, so access doesn't depend on a data plan.

Logistics

Prove the handover happened

Verify the driver at pickup and the recipient at drop-off, with a channel that works in the field.

Build verification into your product.

One API. SMS, Voice, Email, USSD and WhatsApp.

Contact us

Tell us about your integration and we'll get back to you.