Verify Mongolian phone numbers with one SMS

Your user sends an SMS from their own phone to 150073 and pays their operator 150₮. 2fa.mn checks it and tells your server the result with a webhook. It costs you nothing.

01 · Products

Two ways, one SMS

02 · Integrate

Connect your server

03 · API

One request creates the code

curl -X POST https://api.2fa.mn/v1/sessions \
  -H "Authorization: Bearer $TWOFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "99112233", "metadata": { "user_id": "u_42" } }'
const res = await fetch('https://api.2fa.mn/v1/sessions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TWOFA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ phone: '99112233', metadata: { user_id: 'u_42' } }),
});
const session = await res.json(); // session.sms_uri, session.code
body := strings.NewReader(`{"phone": "99112233", "metadata": {"user_id": "u_42"}}`)
req, _ := http.NewRequest("POST", "https://api.2fa.mn/v1/sessions", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("TWOFA_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
<?php
$ch = curl_init('https://api.2fa.mn/v1/sessions');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('TWOFA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['phone' => '99112233', 'metadata' => ['user_id' => 'u_42']]),
]);
$session = json_decode(curl_exec($ch), true);
import os, requests

res = requests.post(
    "https://api.2fa.mn/v1/sessions",
    headers={"Authorization": f"Bearer {os.environ['TWOFA_KEY']}"},
    json={"phone": "99112233", "metadata": {"user_id": "u_42"}},
)
session = res.json()  # session["sms_uri"], session["code"]
{
  "id": "ses_8f3k2m",
  "mode": "test",
  "code": "482913",
  "short_code": "150073",
  "sms_uri": "sms:150073?body=482913",
  "status": "pending",
  "expires_at": "2026-12-01T10:05:00Z"
}
  1. 1. Your server → 2fa.mnRequest a code
  2. 2. 2fa.mn → Your serverCode + SMS link
  3. 3. Your server → UserPrice + "Send SMS" button
  4. 4. User → OperatorSMS → 150073
  5. 5. Operator → 2fa.mnSMS (from the user)
  6. 6. 2fa.mn → Your serverVerified (webhook)
04 · Reference

How is it different from regular SMS codes?

Regular SMS code2fa.mn
How the user verifiesTypes in the code they receivedSends an SMS from their own phone (a user-sent SMS, MO SMS)
Who pays for the SMSYour service pays to send itThe user pays their operator 150₮
Your SMS costOne per verificationNone
Fraud cost riskExposed to SMS pumpingYour system sends no paid SMS
IntegrationNeeds a send-SMS and check-code flowAn API and a webhook

What is SMS pumping?

An attack in which someone uses your service to trigger large numbers of SMS codes and run up your costs. 2fa.mn never sends SMS from your system, so it reduces that cost risk. It doesn't fully protect you against other fraud or automated requests.

Who pays?

When the user sends the SMS to 150073, they pay their operator 150₮ (VAT included). You pay nothing to send SMS, and you can earn from every successful verification (Earnings and payouts).

Warning

Show the price clearly before the user taps the SMS button. Guide: the price UI

Data privacy

Phone numbers and message content are processed only to provide the verification service. The production environment runs on servers located in Mongolia. For details, see the privacy policy.

Was this page helpful?