Баримт бичиг

SMS.link нь хэрэглэгчийн илгээсэн SMS-ээр утасны дугаарыг баталгаажуулна. Таны сервер нэг API дуудлагаар 6 оронтой код авч, хэрэглэгч уг кодыг 151586 дугаарт илгээхэд бид webhook болон шалгах API-аар үр дүнг мэдэгдэнэ.

Base URL https://sms.link.mn/api/v1

Хурдан эхлэх

  1. 1
    Бүртгүүлж, хяналтын самбарт Сайт нэмнэ. Нэг хөгжүүлэгч олон сайттай байж болно.
  2. 2
    Сайтын API keys хэсгээс test key (slk_test_…) үүсгэнэ. Бүртгэл батлагдсаны дараа live key (slk_live_…) үүсгэнэ.
  3. 3
    Хэрэглэгч дугаараа оруулахад таны backend POST /verifications дуудаж id, client_secret-ийг frontend рүү дамжуулна.
  4. 4
    Frontend дээр JS widget-ээр "SMS илгээх" товч (утсанд) эсвэл QR код (компьютерт) харуулна.
  5. 5
    Webhook-ээр verification.verified event хүлээн авах эсвэл GET-ээр төлөвийг шалгаад хэрэглэгчийг үргэлжлүүлнэ.

API key

Бүх хүсэлтэд сайтын нууц API key-г Authorization header-ээр илгээнэ (эсвэл X-Api-Key header).

Authorization: Bearer slk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
УгтварГоримТайлбар
slk_live_LiveБодит SMS-ээр баталгаажуулна. Бүртгэл батлагдсаны дараа үүсгэнэ.
slk_test_TestБодит SMS ирэхгүй; simulate-ээр туршина. Бүртгүүлмэгц ашиглаж болно.
API key нь зөвхөн сервер талд хадгалагдана. Browser, мобайл апп, git repository-д хэзээ ч бүү оруулаарай. Key үүсгэхэд зөвхөн нэг удаа харагдах тул найдвартай хадгална уу; алдагдвал хяналтын самбараас цуцалж шинийг үүсгэнэ.

Баталгаажуулалт үүсгэх

POST /api/v1/verifications

Хэрэглэгчийн утасны дугаарт зориулж 6 оронтой код үүсгэнэ. Ижил сайт дээр нэг дугаарт шинэ код үүсгэхэд өмнөх хүлээгдэж буй код автоматаар цуцлагдана.

Параметрүүд (JSON body)

ТалбарТөрөлТайлбар
phone заавалstring8 оронтой Монгол гар утасны дугаар. +976, 976 угтвар, зай, зураасыг хүлээн авч арилгана.
ttlintegerКодын хүчинтэй хугацаа (секунд). 120–1800 хооронд хязгаарлагдана. Анхдагч нь сайтын тохиргоо (10 мин).
metadataobjectТаны өөрийн JSON object (жишээ нь user_id), 2000 тэмдэгт хүртэл. API хариу болон webhook-д буцаж ирнэ.
{
  "phone": "99112233",
  "ttl": 600,
  "metadata": { "user_id": "u_123" }
}

Хүсэлтийн жишээ

curl -X POST https://sms.link.mn/api/v1/verifications \
  -H "Authorization: Bearer $SMSLINK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "99112233"}'

Хариу

HTTP/1.1 201 Created

{
  "id": "ver_7k2mq9xa4d1fz8c3rb6ph0tn",
  "object": "verification",
  "status": "pending",
  "livemode": true,
  "phone": "99112233",
  "code": "482915",
  "short_number": "151586",
  "sms_uri": "sms:151586?&body=482915",
  "sms_uri_ios": "sms:151586&body=482915",
  "sms_uri_android": "sms:151586?body=482915",
  "qr_data": "SMSTO:151586:482915",
  "client_secret": "vcs_Q3d9XkP2mN7vB4cR8tY1wZ6hL0sJ5fGa",
  "created_at": "2026-10-28T10:00:00Z",
  "expires_at": "2026-10-28T10:10:00Z",
  "verified_at": null,
  "sender_phone": null,
  "operator": null,
  "metadata": { "user_id": "u_123" }
}
ТалбарТайлбар
idБаталгаажуулалтын ID (ver_…). Төлөв шалгах, webhook-ийг тулгахад ашиглана.
statuspending, verified, expired, cancelled, failed — дэлгэрэнгүй.
livemodeLive key-ээр үүссэн бол true, test key бол false.
code, short_numberХэрэглэгч short_number руу илгээх 6 оронтой код.
sms_uri, sms_uri_ios, sms_uri_androidSMS апп-ыг бөглөөд нээх холбоос — нэг товчоор SMS.
qr_dataКомпьютер дээр QR болгон харуулах текст (SMSTO: формат).
client_secretЗөвхөн үүсгэх хариунд нэг удаа ирнэ. Frontend widget-д энэ баталгаажуулалтын төлөвийг уншихад ашиглана.
verified_at, sender_phone, operatorБаталгаажсаны дараа бөглөгдөнө: хэзээ, ямар дугаараас, аль оператороор (unitel, skytel, …).
expires_atКодын хүчинтэй хугацаа дуусах цаг (UTC).

Нэг товчоор SMS илгээх

sms: холбоос дарахад утасны SMS апп нээгдэж, хүлээн авагч (151586) болон текст (код) автоматаар бөглөгдөнө. Хэрэглэгч зөвхөн Send дарна. iOS болон Android-ийн формат бага зэрэг ялгаатай тул API гурван хувилбарыг буцаана:

ТалбарФорматХэзээ
sms_urisms:151586?&body=482915iOS болон Android аль алинд ажиллах ерөнхий хувилбар
sms_uri_iossms:151586&body=482915iPhone, iPad
sms_uri_androidsms:151586?body=482915Android
qr_dataSMSTO:151586:482915Компьютер: QR код уншуулахад утсанд SMS апп бөглөгдөнө
<!-- Утсан дээр: SMS апп нээгдэж хүлээн авагч, текст бөглөгдөнө -->
<a href="sms:151586?&body=482915" class="btn">SMS илгээх</a>

<!-- Платформоор нь сонгох (sms_uri_ios / sms_uri_android) -->
<script>
  const isIOS = /iPhone|iPad|iPod/.test(navigator.userAgent);
  link.href = isIOS ? verification.sms_uri_ios : verification.sms_uri_android;
</script>

Компьютер дээр sms: холбоос ажиллахгүй тул QR код харуулна. Бэлэн widget эдгээрийг бүгдийг автоматаар шийднэ. Ямар ч тохиолдолд кодыг текстээр нь харуулж, гараар илгээх боломж үлдээгээрэй.

JS widget

Хамгийн хялбар арга: backend-ийн буцаасан id, client_secret-ийг widget-д өгнө. Widget нь утсан дээр "SMS илгээх" товч, компьютер дээр QR код, кодыг том үсгээр, хугацааны тоолуурыг харуулж, төлөвийг 2 секунд тутам шалгана. Баталгаажмагц onVerified дуудагдана.

<div id="smslink"></div>
<script src="https://sms.link.mn/js/smslink.js"></script>
<script>
  SmsLink.mount("#smslink", {
    id: "ver_...",            // API-ийн хариунаас
    clientSecret: "vcs_...",  // API-ийн хариунаас
    onVerified: () => {
      // Зөвхөн UX дохио. Баталгаажсаныг backend-ээрээ (webhook эсвэл GET) заавал шалгана.
      location.assign("/signup/next");
    },
    onExpired: () => alert("Кодын хугацаа дууслаа. Дахин оролдоно уу."),
  });
</script>

Тохиргоо

СонголтТайлбар
id заавалБаталгаажуулалтын ID
clientSecret заавалҮүсгэх хариуны client_secret
baseUrlАнхдагчаар script-ийн домэйн (https://sms.link.mn)
onVerified(v)Баталгаажсан үед
onExpired(v)Кодын хугацаа дууссан үед
onStatus(v)Төлөв өөрчлөгдөх бүрт (pending, verified, expired, failed, cancelled)

SmsLink.mount() нь { destroy() } буцаана. HTML attribute-аар автоматаар суулгаж ч болно:

<div data-smslink data-id="ver_..." data-client-secret="vcs_..."></div>
<script src="https://sms.link.mn/js/smslink.js" defer></script>
onVerified бол зөвхөн хэрэглэгчийн интерфейсийн дохио. Хэрэглэгчийг баталгаажсан гэж тооцохын өмнө backend-ээрээ webhook эсвэл GET хүсэлтээр заавал шалгана уу.

Төлөв шалгах

GET /api/v1/verifications/{id}
curl https://sms.link.mn/api/v1/verifications/ver_7k2mq9xa4d1fz8c3rb6ph0tn \
  -H "Authorization: Bearer $SMSLINK_KEY"
{
  "id": "ver_7k2mq9xa4d1fz8c3rb6ph0tn",
  "object": "verification",
  "status": "verified",
  "livemode": true,
  "phone": "99112233",
  "code": "482915",
  "short_number": "151586",
  ...
  "verified_at": "2026-10-28T10:01:12Z",
  "sender_phone": "99112233",
  "operator": "unitel",
  "metadata": { "user_id": "u_123" }
}

Хүчинтэй хугацаа нь дууссан pending баталгаажуулалт expired гэж буцна. Өөр сайт эсвэл өөр горимын (live/test) ID-д 404 not_found буцна.

Жагсаалт

GET /api/v1/verifications
QueryТайлбар
statuspending, verified, expired, cancelled, failed
phoneУтасны дугаараар шүүх
limit1–100, анхдагч 20
starting_afterХуудаслалт: өмнөх хуудасны сүүлийн id. Шинээс хуучин руу эрэмбэлэгдэнэ.
curl "https://sms.link.mn/api/v1/verifications?status=verified&limit=20" \
  -H "Authorization: Bearer $SMSLINK_KEY"
{
  "object": "list",
  "data": [ { "id": "ver_...", "status": "verified", ... } ],
  "has_more": true
}

Цуцлах

POST /api/v1/verifications/{id}/cancel

Зөвхөн pending төлөвтэйг цуцална; бусад үед 409 not_pending буцна.

curl -X POST https://sms.link.mn/api/v1/verifications/ver_7k2mq9xa4d1fz8c3rb6ph0tn/cancel \
  -H "Authorization: Bearer $SMSLINK_KEY"

Webhook

Хяналтын самбарт сайтын Webhook хэсэгт HTTPS URL болон хүлээн авах event-үүдээ тохируулна. Баталгаажуулалтын төлөв өөрчлөгдөхөд бид таны URL руу POST хүсэлт илгээнэ.

EventХэзээ
verification.verifiedЗөв дугаараас зөв код ирж баталгаажсан (анхдагчаар идэвхтэй)
verification.expiredКодын хугацаа SMS ирэхээс өмнө дууссан
verification.failedКод буруу дугаараас 3 удаа ирсэн
webhook.testХяналтын самбарын "Туршилт илгээх" товч

Хүсэлт

POST /webhooks/smslink HTTP/1.1
Content-Type: application/json
User-Agent: SmsLink-Webhooks/1.0
SmsLink-Event: verification.verified
SmsLink-Delivery: evt_3h8k2m9q4x7z1c5v0b6n2p4r
SmsLink-Signature: t=1761645672,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

{
  "id": "evt_3h8k2m9q4x7z1c5v0b6n2p4r",
  "type": "verification.verified",
  "created_at": "2026-10-28T10:01:12Z",
  "livemode": true,
  "data": {
    "verification": {
      "id": "ver_7k2mq9xa4d1fz8c3rb6ph0tn",
      "object": "verification",
      "status": "verified",
      "phone": "99112233",
      "short_number": "151586",
      "verified_at": "2026-10-28T10:01:12Z",
      "sender_phone": "99112233",
      "operator": "unitel",
      "metadata": { "user_id": "u_123" },
      ...
    }
  }
}
HeaderТайлбар
SmsLink-EventEvent-ийн төрөл
SmsLink-DeliveryEvent-ийн давтагдашгүй ID (evt_…), body-ийн id-тай ижил. Давтан ирсэн event-ийг ялгахад ашиглана.
SmsLink-Signaturet=<unix timestamp>,v1=<hex> — доорх гарын үсэг

Гарын үсэг шалгах

v1 = hex(HMAC_SHA256(webhook_secret, t + "." + raw_body)). Webhook secret (whsec_…)-ийг хяналтын самбарын Webhook хэсгээс авна. Body-г JSON болгон задлахаас өмнө түүхий (raw) хэлбэрээр нь шалгах, мөн t 5 минутаас хуучин бол татгалзахыг зөвлөж байна.

import crypto from "node:crypto";
import express from "express";

function verifySignature(rawBody, header, secret) {
  const parts = Object.fromEntries((header || "").split(",").map((p) => p.split("=")));
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  const given = parts.v1 || "";
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  return fresh && given.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}

const app = express();
app.post("/webhooks/smslink", express.raw({ type: "application/json" }), (req, res) => {
  const raw = req.body.toString("utf8");
  if (!verifySignature(raw, req.get("SmsLink-Signature"), process.env.SMSLINK_WEBHOOK_SECRET)) {
    return res.sendStatus(400);
  }
  const event = JSON.parse(raw);
  if (event.type === "verification.verified") {
    const { phone, metadata } = event.data.verification;
    // хэрэглэгчийн дугаарыг баталгаажсан гэж тэмдэглэнэ
  }
  res.sendStatus(200);
});

Хариу ба давтан илгээлт

  • 2xx хариуг амжилттай гэж тооцно. Redirect (3xx) дагахгүй тул эцсийн URL-аа шууд тохируулна уу.
  • Хариу 10 секунд-ээс удаан бол timeout болно. Хүнд ажлаа queue руу шилжүүлээд шууд 200 буцаахыг зөвлөнө.
  • Амжилтгүй бол 1 мин → 5 мин → 30 мин → 2 цаг → 6 цаг → 24 цаг-ийн дараа давтана (нийт 7 оролдлого). Давталт бүр шинэ t-тэй гарын үсэгтэй.
  • Хүргэлт бүрийн хүсэлт/хариуг хяналтын самбарын Webhook лог-оос харж, гараар дахин илгээх боломжтой.
  • Ижил event давтагдаж ирж болзошгүй тул id-аар нь idempotent боловсруулна уу.

Төлөв ба тулгах дүрэм

ТөлөвУтга
pendingКод үүссэн, SMS хүлээж байна
verifiedОруулсан дугаараас зөв код ирж баталгаажсан
expiredХүчинтэй хугацаанд SMS ирээгүй
cancelledAPI-аар цуцалсан, эсвэл ижил дугаарт шинэ код үүссэн
failedКод буруу дугаараас 3 удаа ирсэн

Тулгах дүрэм

  • SMS-ийн текстээс 6 оронтой кодыг ялгана. 482915, 482 915, Kod: 482915 гэх мэт бичлэгийг хүлээн авна.
  • Кодоор pending баталгаажуулалтыг олж, SMS илгээсэн дугаар нь оруулсан дугаартай яг таарвал verified болно.
  • Өөр дугаараас ирвэл баталгаажихгүй (жишээ нь хоёр SIM-тэй хэрэглэгч өөр SIM-ээс илгээсэн). 3 дахь удаагаас failed болно.
  • Нэг код нэг л удаа хүчинтэй. Нэг сайт дээр ижил дугаарт шинэ код үүсгэхэд өмнөх pending код cancelled болно.
  • Тусгай дугаар бүх операторт ижил: 151586.

Test горим

slk_test_ key-ээр үүсгэсэн баталгаажуулалт бодит SMS-ээр баталгаажихгүй. Оронд нь SMS ирсэн мэт simulate хийнэ — webhook, төлөв, widget бүгд бодит урсгалтай яг адил ажиллана. Test горим бүртгэл батлагдахаас өмнө ч ажилладаг. Хяналтын самбарын Test горимд баталгаажуулалт бүрийн хажууд "Simulate" товч бий.

POST /api/v1/verifications/{id}/simulate

Body-гүй бол баталгаажуулалтын дугаараас ирсэн мэт (verified). {"from": "…"} өгвөл тухайн дугаараас ирсэн мэт — mismatch-ийг турших боломжтой. Live key-ээр дуудвал 403 test_mode_only.

# Зөв дугаараас ирсэн мэт (verified болно)
curl -X POST https://sms.link.mn/api/v1/verifications/ver_.../simulate \
  -H "Authorization: Bearer $SMSLINK_TEST_KEY"

# Өөр дугаараас ирсэн мэт (mismatch-ийг турших)
curl -X POST https://sms.link.mn/api/v1/verifications/ver_.../simulate \
  -H "Authorization: Bearer $SMSLINK_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from": "88001122"}'

Алдааны кодууд

Алдааны үед HTTP статус код болон нэг төрлийн JSON хариу буцна. Асуудал шалгуулахдаа request_id-г хавсаргана уу.

HTTP/1.1 400 Bad Request

{
  "error": {
    "code": "invalid_phone",
    "message": "Утасны дугаар буруу байна. 8 оронтой Монгол дугаар оруулна уу.",
    "request_id": "0HN7J2K4L5M6:00000001"
  }
}
HTTPcodeТайлбар
400invalid_requestBody JSON биш, талбар дутуу эсвэл metadata буруу
400invalid_phoneУтасны дугаар 8 оронтой Монгол гар утасны дугаар биш
401invalid_api_keyAPI key буруу, байхгүй эсвэл цуцлагдсан
403account_pendingБүртгэл батлагдаагүй байхад live key ашигласан — test key ашиглана уу
403account_suspendedХөгжүүлэгчийн бүртгэл татгалзагдсан эсвэл түр хаагдсан
403site_disabledСайтын API хандалт хаагдсан
403test_mode_onlySimulate-ийг live key-ээр дуудсан
404not_foundБаталгаажуулалт олдсонгүй (өөр сайт эсвэл өөр горим)
409not_pendingЗөвхөн pending төлөвтэйг цуцлах боломжтой
429rate_limitedХүсэлтийн хязгаар хэтэрсэн — Retry-After header-ийг харна уу

Хязгаар

ХязгаарУтга
API хүсэлтНэг API key-д минутад 120 хүсэлт
Нэг дугаартНэг сайт дээр нэг дугаарт цагт 10 баталгаажуулалт
Кодын хугацаа120–1800 секунд (анхдагч 600)
Буруу дугаараас3 оролдлогын дараа failed
metadata2000 тэмдэгт хүртэл JSON object
Webhook timeout10 секунд, 7 оролдлого

Асуулт байвал info@sms.link.mn хаягаар холбогдоно уу.

Сервертэй дахин холбогдож байна…

Холбогдож чадсангүй. секундын дараа дахин оролдоно.

Холболт тасарлаа.
Хуудсаа дахин ачаална уу.

Сесс түр зогслоо.

Сессийг сэргээж чадсангүй.
Хуудсаа дахин ачаална уу.

Алдаа гарлаа. Дахин ачаалах ✕