Risk & compliance
Prove control of a phone or email
Send a six-digit code by SMS or email and record a verified code as a check with its own reference_id and audit trail.
What it does
OTP Ownership, in detail.
SMS and email
Fixed limits
Device and IP signals
Billed only on success
Templates in five languages
How it works
From request to decision.
- 1
POST /v1/otp/send
Choose the channel and destination; you receive an otp_ id, masked destination, expiry, retry_after and max_attempts.
- 2
The customer enters the code
Show the masked destination and a resend button that respects retry_after.
- 3
POST /v1/otp/verify
Send the id and code to receive a verification, or attempts_remaining on failure.
Routing and providers
SMS goes through Speedmap’s SMS partner and email through Speedmap’s mailer. Destinations and codes are stored hashed and masked.
Use it
One request. One normalized response.
Call POST /v1/otp/verify through @speedmap/node, speedmap for Python.
curl -X POST http://localhost:4000/v1/otp/verify \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"id": "otp_1a5dabfcfba052dd",
"code": "123456"
}'{
"reference_id": "spm_33b168aac3f7166171247ed8",
"object": "verification",
"product": "otp",
"method": "otp_sms",
"status": "verified",
"match": true,
"mode": "sandbox",
"summary": {
"otp_id": "otp_1a5dabfcfba052dd",
"channel": "sms",
"destination_masked": "**********4567",
"verified": true,
"attempts": 1,
"purpose": "account opening",
"sent_at": "2026-10-20T12:53:14.965Z",
"verified_at": "2026-10-20T12:53:15.054Z",
"risk_signals": {
"score": 0,
"level": "low",
"factors": [],
"phone": {
"network": "MTN",
"is_virtual": false,
"nigerian": true
}
}
},
"consent": {
"mechanism": "subject_otp",
"consent_id": null
}
}Use cases
Where Nigerian teams use it.
Signup
Prove the phone before the NIN or BVN check, binding the verified identity to a phone the customer holds.
Payout destination changes
Require an OTP to the registered number before a settlement account changes.
Hosted pages
The same OTP engine confirms the subject on Speedmap-hosted consent and verification pages.
Candidate onboarding
Confirm a candidate’s email before sending a document capture link.
Part of:Lending
What you get back
The fields you will read.
| Field | Meaning |
|---|---|
| summary.verified | true on a correct code |
| summary.channel / destination_masked | Where the code went |
| summary.attempts | How many tries it took |
| summary.risk_signals | Score, level and factors from the destination and any client_ip and user_agent hints |
| error.code | otp_invalid, otp_expired, otp_too_many_attempts, otp_already_used, otp_resend_too_soon, otp_destination_limited |
summary.verified
- Meaning
- true on a correct code
summary.channel / destination_masked
- Meaning
- Where the code went
summary.attempts
- Meaning
- How many tries it took
summary.risk_signals
- Meaning
- Score, level and factors from the destination and any client_ip and user_agent hints
error.code
- Meaning
- otp_invalid, otp_expired, otp_too_many_attempts, otp_already_used, otp_resend_too_soon, otp_destination_limited
Assertion tier
Identical on every tier: the destination is always masked.
Full tier
Adds data: the full device and IP risk assessment (factor weights and details). Destinations stay masked.
Pricing
Billed per live check on the Scale up plan. Failed calls and idempotent retries are never billed.
- Does an OTP prove identity?
- No. It proves possession at that moment; add Phone Identity, Fraud Signals or a NIN or BVN check to know who holds it.
- Can I use my own SMS sender name?
- Sender IDs are configured per workspace during the compliance review.
Start verifying in minutes. Go live when you’re ready.
Create your account in under a minute and explore the full dashboard. We switch your workspace live after a short compliance review.