שליחת קוד אימות במייל מהכתובת otp@ivr.top. הקוד נוצר אצלנו ומוחזר בתשובה, ואתם אחראים לשמור אותו ולאמת אותו מול המשתמש.
POST https://otp-verify-mmf.ivr.top/api/v1/otp/send
כותרות:
Content-Type: application/jsonX-API-Token: <הטוקן שקיבלתם> (אפשר גם Authorization: Bearer <הטוקן>)הקריאה חייבת להגיע מהשרת שלכם, מכתובת ה-IP שאושרה מראש.
גוף הבקשה:
| שדה | חובה | ברירת מחדל | תיאור |
|---|---|---|---|
to |
כן | כתובת המייל של המשתמש | |
appName |
לא | IVR |
שם המותג. הנושא יהיה: Your <appName> verification code |
action |
לא | sign in |
הפעולה שבמייל: Use this code to <action>. |
origin |
לא | https://ivr.top |
כתובת האתר שלכם (https בלבד). מיועדת לקשירת הקוד לדומיין, וחשוב שתהיה הכתובת שבה המשתמש מזין את הקוד |
expiryMinutes |
לא | 10 |
תוקף הקוד בדקות (1 עד 60), מופיע בטקסט המייל |
תשובה (200):
{
"challengeId": "5d0ea1b1-01cd-40b2-ac62-d1660584ac5b",
"code": "048291",
"messageId": "<5d0ea1b1-...@ivr.top>",
"expiresAt": "2026-10-28T12:41:25.802Z"
}
code הוא מחרוזת של 6 ספרות. אפשר לקבל אפסים מובילים, ולכן לא להמיר למספר.expiresAt הוא זמן התפוגה לפי expiryMinutes. הוא לא נאכף אצלנו, אתם אוכפים אותו.שגיאות:
| קוד | משמעות |
|---|---|
| 400 | קלט לא תקין (error אומר איזה שדה) |
| 401 | טוקן חסר או שגוי |
| 403 | הקריאה לא מגיעה מ-IP מורשה |
| 502 | השליחה נכשלה. אין קוד בתשובה, אפשר לנסות שוב |
const res = await fetch('https://otp-verify-mmf.ivr.top/api/v1/otp/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Token': process.env.OTP_API_TOKEN },
body: JSON.stringify({ to: email, appName: 'Acme', action: 'sign in to Acme', origin: 'https://app.acme.com' }),
});
if (!res.ok) throw new Error(`otp send failed: ${res.status}`);
const { challengeId, code, expiresAt } = await res.json();
השירות רק שולח את הקוד, ולכן האימות עצמו נעשה בשרת שלכם:
challengeId, hash של code (למשל SHA-256), expiresAt ומונה ניסיונות.challengeId, לעולם לא את code. הקוד שחוזר מהשירות מיועד לשרת שלכם בלבד, ואם תעבירו אותו לדפדפן כל אחד יוכל לעקוף את האימות.challengeId ואת הקוד שהמשתמש הקליד.crypto.timingSafeEqual). בהצלחה מוחקים את הרשומה, כך שקוד עובד פעם אחת בלבד.challengeId ואת הקוד שולחים ב-body של בקשת POST, לא ב-URL.שדה הקלט בלקוח. התכונה autocomplete="one-time-code" גורמת ל-iOS, ל-Safari, ל-Chrome ולמנהלי סיסמאות להציע את הקוד מהמייל בלחיצה:
<input
type="text"
inputmode="numeric"
autocomplete="one-time-code"
maxlength="6"
pattern="\d{6}"
name="otp_code"
required
/>
באפליקציית iOS נייטיב משתמשים ב-textContentType = .oneTimeCode, ובאנדרואיד נייטיב ב-autofillHints="smsOTP".
מייל באנגלית מ-otp@ivr.top: הקוד בשורה הראשונה, אחריו משפט הפעולה, התוקף והערת אבטחה. אפשר לבקש קוד חדש בכל עת, וכל קריאה יוצרת קוד חדש ו-challengeId חדש. כדאי להגביל בצד שלכם את קצב הבקשות לכל משתמש, כי השירות לא מגביל קצב.