Carrier-grade phone verification across mobile operator networks. Silent-first, with an SMS one-time code as the automatic backstop when a silent check cannot run.
Pick a scenario. It runs against the live API in sandbox mode - nothing reaches a real operator or sends a real SMS.
npm install mxlabs-number-verifypip install mxlabs-number-verifyThe SDK manages the session and polling. You open the auth URL on the user device; that request over the cellular network is what proves the number.
import { MXNumberVerify } from 'mxlabs-number-verify';
const nv = new MXNumberVerify({ apiKey: process.env.MXLABS_API_KEY });
const result = await nv.verifyNumber('+60123456789', {
onAuthUrl: url => redirectUserToUrl(url) // device opens it over cellular
});
if (result.status === 'verified') grantAccess(result.phone);
else await nv.smsSend(result.sessionId); // backstop: one-time code by SMS
Python is identical: nv.verify_number(...).
Drive the session, redirect and fallback yourself:
const { sessionId, authUrl } = await nv.start('+60123456789');
// device opens authUrl over cellular, then:
const result = await nv.pollVerify(sessionId);
if (result.status !== 'verified') {
const { masked } = await nv.smsSend(sessionId);
await nv.smsVerify(sessionId, codeFromUser);
}
verify() runs one check and returns a
status. Poll until you get a terminal status (the SDK does this for you).
| status | Meaning | What to do |
|---|---|---|
| pending | The silent check is still running, waiting on the operator. Not final. | Keep polling verify() until a terminal status (or timeout). |
| verified | The number is confirmed. method shows how (number_verification or sms_otp); phone echoes it back. |
Grant access. |
| not_verified | The operator checked and the number is not active on this device. | Do not grant access. Offer the SMS fallback (fallback: sms_otp). |
| nv_unavailable | The silent check could not run (e.g. Wi-Fi, timeout, or sandbox). Not the number's fault. reason says why. |
Fall back to an SMS one-time code (fallback: sms_otp). |
Other responses
| started | start() succeeded. Returns session_id and auth_url (open on the user's device over cellular). |
| sms_sent | sms_send() dispatched the code. Returns masked (masked number) and expires_in (seconds). |
| invalid / expired | sms_verify() — the code was wrong (invalid) or has expired (expired). Ask the user to retry or resend. |
| ok | ping() — the API and your key are healthy. |
| error | A request-level failure. error is one of invalid_api_key, invalid_phone, rate_limited (with retry_after), session_not_found_or_expired, missing_session_id, unknown_action. |
Try it against the sandbox in five minutes, no signup. Sandbox calls never reach a real operator or send a real SMS.
sbx_demo_9f3b7c1e0a2d4856b1c9e7f2a6d40b83
| +10000000001 | Silent success → verified |
| +10000000002 | Silent unavailable → SMS backstop (code 000000) |
| +10000000003 | Wrong number → not verified |
pip install mxlabs-number-verify
from mxlabs_number_verify import MXNumberVerify
nv = MXNumberVerify(api_key="sbx_demo_9f3b7c1e0a2d4856b1c9e7f2a6d40b83")
print(nv.verify_number("+10000000001")) # {'status': 'verified', ...}
curl -s https://api.mxlab.sg/sdk.php \
-H "X-API-Key: sbx_demo_9f3b7c1e0a2d4856b1c9e7f2a6d40b83" \
-d action=start -d phone=+10000000001
Full API reference: Node / Python READMEs. Machine-readable contract: OpenAPI spec.
Tell us where to send your sandbox and live keys. We'll reply by email.