מפתחים

SMS נשלח מול נמסר: כשהלקוח אומר שלא קיבל

30 בספטמבר 2026·11 דק' קריאה·מאת ניצן סויסה

הודעת SMS שנשלחה היא הודעה שהרשת הסלולרית קיבלה ויצאה לדרך. הודעה שנמסרה היא הודעה שהרשת אישרה שהגיעה למכשיר. כשלקוח אומר שלא קיבל, התשובה נמצאת בסטטוס המסירה של ההודעה ובשתי חותמות זמן, ובתוך יממה לכל הודעה יש סיווג סופי.

הפנייה הזאת מגיעה לכל מי ששולח SMS מהקוד: "לא קיבלתי את קוד האימות", "לא קיבלתי הודעה שההזמנה יצאה". ברוב המערכות היא נגמרת בניחוש. המאמר הזה עובר על ההבדל בין נשלח לנמסר, על ששת המצבים שהודעה יכולה להיות בהם, ועל סדר התחקור שמוציא מהלוג תשובה מסודרת במקום ניחוש.

למה "נשלח" הוא לא תשובה ללקוח

הבקשה שלך ל-API חזרה עם 202. זה אומר שסנדי קיבלה את ההודעה לשליחה. אחרי רגע ההודעה נמסרת לרשת הסלולרית והסטטוס עובר ל-sent. גם זה עדיין לא אומר כלום על המכשיר של הלקוח. sent הוא הצהרה על הצד שלך: ההודעה יצאה.

delivered הוא הצהרה על הצד של הלקוח: הרשת הסלולרית החזירה אישור מסירה, וההודעה התקבלה במכשיר. זו חותמת הזמן היחידה שאפשר להראות ללקוח ולומר "בשעה הזאת ההודעה הייתה אצלך".

ההבדל נשמע טכני עד הפנייה הראשונה. לקוח שלא קיבל קוד אימות לא יכול להיכנס, ולקוח שלא קיבל עדכון משלוח מתקשר למוקד. בשני המקרים "אצלנו זה נשלח" הוא לא תשובה. "ההודעה התקבלה במכשיר שלך ב-14:32" היא תשובה.

ששת סטטוסי המסירה ומה כל אחד אומר

כל הודעה שיצאה דרך ה-API של Sendy נמצאת באחד משישה מצבים. ההגדרות המלאות נמצאות במדריך השליחה הראשונה; כאן הטבלה מסודרת לפי מה שכל מצב אומר על הפנייה שמולך.

סטטוסמה קרהמה זה אומר על הפנייה
queuedההודעה התקבלה ומחכה לשליחהעדיין מוקדם. חכה רגע ובדוק שוב
sendingההודעה בדרך לרשת הסלולריתכנ"ל
sentהרשת קיבלה את ההודעה, אישור מסירה עדיין לא חזרברוב המקרים האישור מגיע תוך דקות. טלפון כבוי או מחוץ לקליטה מקבל את ההודעה כשהוא חוזר, והרשת מנסה עד יממה
deliveredהרשת אישרה שההודעה התקבלה במכשירההודעה אצל הלקוח. אם הוא לא רואה אותה, הסיבה במכשיר או במספר שרשום אצלך
undeliveredהרשת דיווחה שההודעה לא נמסרה, או שלא התקבל אישור מסירה בתוך יממהמספר מנותק, מכשיר שלא חזר לקליטה, או מספר שגוי שמישהו אחר מחזיק
failedהשליחה נכשלה לפני שההודעה יצאה לרשתהבעיה בצד השליחה: שולח, יעד או תוכן. הקרדיט חוזר

שלושה מצבים הם סופיים: delivered, undelivered ו-failed. הודעה ב-sent היא הודעה שעדיין מחכים לה, ובתוך יממה היא תגיע לאחד משלושת הסופיים. אין הודעה שנשארת "נשלחה" לנצח.

סדר התחקור: חמש בדיקות בסדר קבוע

הפנייה מגיעה עם מספר טלפון ושעה משוערת. ככה הופכים אותה לתשובה.

1. מצא את ההודעה, לא את הלקוח

התחקור מתחיל מההודעה הספציפית, לא מ"כל מה ששלחנו לו". אם השליחה יצאה מהקוד שלך, המזהה חזר לך בתשובה לבקשת השליחה, ואם שמרת אותו ליד האירוע העסקי (ההזמנה, בקשת הקוד) הוא כבר שם. אם לא שמרת, לוג ה-API באזור הדוחות מציג את השליחות לפי מספר וזמן, וכרטיס איש הקשר מציג כל הודעה שיצאה אליו עם סטטוס המסירה שלה.

הלקח לקוד: המזהה שחוזר מהשליחה הוא מפתח התחקור. שמור אותו.

2. קרא את הסטטוס ואת שתי חותמות הזמן

בקשת GET אחת מחזירה את כל מה שצריך:

curl https://sendy.co.il/api/v1/messages/cmqzkdkul0007p20mf0r4tz21 \
  -H "Authorization: Bearer $SENDY_API_TOKEN"
{
  "id": "cmqzkdkul0007p20mf0r4tz21",
  "status": "delivered",
  "to": "+972501234567",
  "from": "MyShop",
  "credits_charged": 1,
  "credits_refunded": 0,
  "refunded": false,
  "error_code": null,
  "created_at": "2026-09-30T11:31:02.114Z",
  "sent_at": "2026-09-30T11:31:04.590Z",
  "delivered_at": "2026-09-30T11:31:09.877Z",
  "idempotency_key": "order-58213-shipped"
}

שלוש חותמות זמן מספרות את הסיפור: created_at היא הרגע שביקשת לשלוח, sent_at הרגע שהרשת קיבלה, delivered_at הרגע שהמכשיר קיבל. to הוא המספר שההודעה יצאה אליו בפועל, וזו הבדיקה השנייה בחשיבותה בתחקור: אם הוא שונה מהמספר שהלקוח נתן לך בטלפון, הבעיה נמצאת בטופס ההרשמה שלך ולא ברשת. המזהה חייב להיות של הודעה שיצאה דרך ה-API של מרחב העבודה שלך; כל מזהה אחר מחזיר 404.

3. אם הסטטוס delivered: הבעיה במכשיר או במספר

ההודעה התקבלה במכשיר בשעה שכתובה ב-delivered_at. זו עובדה שהרשת אישרה, לא הערכה. מה שנשאר לבדוק נמצא אצל הלקוח: המספר הנכון (בדוק את to מול מה שהוא מכתיב לך עכשיו), טלפון עם שני כרטיסי SIM שההודעה נחתה בשני שלהם, אפליקציית הודעות שמסננת שולחים לא מוכרים, או הודעה שנמחקה. השאלה "איזה מספר רשום אצלך" פותרת חלק גדול מהפניות האלה.

מה שהסטטוס לא אומר: אם הלקוח פתח את ההודעה. ל-SMS אין אישור קריאה. delivered פירושו התקבלה במכשיר, ולא יותר מזה, וזה גם מה שאומרים ללקוח.

4. אם הסטטוס sent ועברו פחות מיממה: חכה, אל תשלח שוב

ההודעה אצל הרשת. טלפון כבוי, מחוץ לקליטה או בטיסה מקבל אותה כשהוא חוזר, והרשת ממשיכה לנסות עד יממה. שליחה חוזרת עכשיו מייצרת בדיוק את התרחיש שמפתחים מפחדים ממנו: הלקוח מדליק את הטלפון ומקבל שני קודי אימות, מזין את הראשון, ונכשל. אם בכל זאת צריך לשלוח שוב, Idempotency Key על אותו אירוע עסקי מבטיח שזה יקרה פעם אחת.

בקוד אימות הסיפור קצת שונה: הקוד עצמו פג תוך דקות, אז "חכה" הוא לא תשובה למשתמש שמחכה על המסך. שם הפתרון הוא כפתור "שלח קוד חדש" שיוצר קוד חדש ומזהה חדש, לא שליחה חוזרת של אותה הודעה. המדריך המלא ל-OTP מכסה את המקרה הזה.

5. אם הסטטוס undelivered או failed: קרא את הסיבה

error_code מתמלא כשיש סיבה ידועה. בהודעה שנכשלה לפני שיצאה לרשת הסיבה נמצאת בצד השליחה, והקרדיט חוזר אוטומטית: שולח שלא אושר, מספר לא תקין, תוכן שנדחה. הודעה שיווקית למספר שהסיר את עצמו לא מגיעה בכלל לשלב הזה: הבקשה עצמה נדחית עם 403 ו-RECIPIENT_UNSUBSCRIBED, ואין הודעה לחפש.

בהודעה שהרשת קיבלה ולא מסרה, הסיבות הן של הרשת: מספר מנותק, מספר שגוי שלא שייך לאף אחד, או מכשיר שלא חזר לקליטה בתוך יממה. הודעה כזאת חויבה, כי הרשת קיבלה אותה. זה הרגע לבדוק מול הלקוח את המספר עצמו, ואם הוא נכון, לשלוח שוב עם מזהה חדש.

מה עונים ללקוח

תשובה טובה לפנייה כזאת היא שלושה משפטים, וכולם מגיעים מהלוג:

  • על הודעה שנמסרה: "ההודעה התקבלה במכשיר שמסתיים ב-4567 ב-30/09 בשעה 14:31. אם היא לא מופיעה, כדאי לבדוק את תיקיית ההודעות המסוננות או לוודא שזה המספר הנכון."
  • על הודעה שעדיין ממתינה: "ההודעה יצאה ב-14:31 ועדיין לא התקבל אישור מהרשת. זה קורה כשהמכשיר כבוי או מחוץ לקליטה, והיא תגיע כשהוא יחזור. אם זה דחוף, נשלח קוד חדש עכשיו."
  • על הודעה שלא נמסרה: "הרשת לא הצליחה למסור את ההודעה למספר שמסתיים ב-4567. האם זה המספר הנכון?"

מה שלא אומרים: "אצלנו זה נשלח", ו"ראינו שקראת". הראשון לא עונה על השאלה, והשני לא נכון, כי אין ל-SMS אישור קריאה.

לבנות את הלוג לפני הפנייה הראשונה

התחקור למעלה עובד גם בדיעבד, אבל הוא קצר בהרבה כשהלוג בצד שלך מוכן מראש. שלושה דברים עושים את ההבדל.

שמור את המזהה ליד האירוע העסקי. שורת ההזמנה, בקשת הקוד או התור מחזיקים את id שחזר מהשליחה. כשהפנייה מגיעה, אתה שולף את ההודעה בבקשה אחת במקום לחפש לפי מספר ושעה. אם שלחת עם Idempotency-Key שנגזר מהאירוע, הוא חוזר גם ב-idempotency_key ומאפשר לך להתאים בכיוון ההפוך.

תן לסטטוס להגיע אליך. במקום לשאול את ה-API כל כמה שניות, webhook שולח לשרת שלך את message.sent, message.delivered, message.undelivered ו-message.failed ברגע שהם קורים, ואובייקט ה-data בכל אירוע הוא בדיוק מה שה-GET מחזיר. שני דברים לזכור: האירועים נשלחים על הודעות שיצאו דרך ה-API, לא על קמפיין מהמחולל, והסדר שלהם לא מובטח, אז הסטטוס הנכון הוא של האירוע האחרון שקיבלת על אותה הודעה, לא הראשון.

תרגם את הסטטוס לתשובה, פעם אחת, בקוד. מפה קטנה שהופכת סטטוס וחותמת זמן למשפט לתמיכה חוסכת את התחקור הידני בכל פנייה:

function supportAnswer(message) {
  const time = (iso) => new Date(iso).toLocaleString("he-IL", { timeZone: "Asia/Jerusalem" });
  switch (message.status) {
    case "delivered":
      return `ההודעה התקבלה במכשיר ב-${time(message.delivered_at)}. לוודא מספר: ${message.to}`;
    case "undelivered":
      return `הרשת לא מסרה את ההודעה למספר ${message.to}. לבדוק את המספר ולשלוח שוב עם מזהה חדש`;
    case "failed":
      return `השליחה נכשלה לפני היציאה לרשת (${message.error_code ?? "ללא סיבה"}). הקרדיט הוחזר`;
    default:
      return `ההודעה יצאה ב-${time(message.sent_at ?? message.created_at)} וממתינה לאישור מסירה. לא לשלוח שוב עדיין`;
  }
}

הפונקציה קוראת רק שדות שה-API מחזיר, ולכן היא עובדת גם על תשובת ה-GET וגם על ה-data של אירוע webhook.

כשזה קמפיין מהמחולל ולא שליחה מהקוד

הודעת אישור הזמנה או עדכון משלוח יוצאת בדרך כלל מהקוד, אבל הפנייה "לא קיבלתי" מגיעה גם על קמפיין שנשלח מהמחולל. שם אין מזהה בקוד, ויש שני מקומות לבדוק בהם.

בעמוד הקמפיין, טבלת הנמענים מציגה לכל נמען את סטטוס המסירה שלו, עם חיפוש לפי מספר וסינון לפי סטטוס. ציר הזמן של הקמפיין מראה מתי השליחה החלה, מתי הסתיימה ומתי אישורי המסירה התקבלו, והשורה "ממתינות לאישור" מתרוקנת בהדרגה עד שכל ההודעות סווגו. בערך יממה אחרי סיום הקמפיין, כשנתוני המסירה סופיים, מגיע סיכום עם המספרים. מדריך תוצאות הקמפיין מסביר את המספרים האלה.

ובכרטיס איש הקשר, ההיסטוריה של הלקוח הספציפי: כל הודעה שיצאה אליו, מקמפיין או מהקוד, עם סטטוס המסירה שלה. זו התשובה למי שמתקשר בלי מספר קמפיין ובלי מזהה, רק עם שם וטלפון.

מה שסטטוס מסירה לא יכול להגיד

שווה לומר את זה בבירור, כי הלקוח ישאל. אישור מסירה אומר שההודעה התקבלה במכשיר. הוא לא אומר שההודעה נפתחה, נקראה או הובנה. ל-SMS אין אישור קריאה, ואף פלטפורמה לא יכולה לספק אותו. מערכת שמציגה לך "נקראה" על SMS מנחשת.

זה גם הגבול של התיעוד: הוא מוכיח מה יצא, לאן, ומתי הגיע. מה שקרה אחר כך נמצא אצל הלקוח, וזה בסדר, כי לרוב הפניות התשובה "ההודעה התקבלה במכשיר בשעה הזאת" היא בדיוק מה שהיה חסר.

שאלות נפוצות

מה ההבדל בין הודעה שנשלחה להודעה שנמסרה? נשלחה (sent) אומר שהרשת הסלולרית קיבלה את ההודעה והיא בדרך. נמסרה (delivered) אומר שהרשת החזירה אישור שההודעה התקבלה במכשיר. רק השני מוכיח שההודעה הגיעה ללקוח.

כמה זמן לוקח עד שמתקבל אישור מסירה? ברוב המקרים דקות. מכשיר כבוי או מחוץ לקליטה מקבל את ההודעה כשהוא חוזר, והרשת מנסה עד יממה. בתוך יממה לכל הודעה יש סיווג סופי: נמסרה, לא נמסרה או נכשלה.

אפשר לדעת אם הלקוח קרא את ההודעה? לא. ל-SMS אין אישור קריאה. סטטוס המסירה מוכיח שההודעה התקבלה במכשיר, וזה הכי רחוק שאפשר לדעת.

הודעה שלא נמסרה, האם חויבתי עליה? הודעה שהרשת קיבלה חויבה, גם אם בסוף לא נמסרה. הודעה שנכשלה לפני שיצאה לרשת לא חויבה, והקרדיט חוזר אוטומטית. בשני המקרים קרדיט אחד הוא הודעה אחת עד 201 תווים.

להתחיל עם לוג שכבר עונה

30 ההודעות הראשונות ב-Sendy יוצאות בלי כרטיס אשראי, וכל אחת מהן מקבלת סטטוס מסירה עם חותמות זמן מהרגע הראשון. פתח חשבון, שלח את ההודעה הראשונה מהקוד, ובדוק בעצמך מה ה-GET מחזיר. התיעוד המלא מחכה כשתצטרך את השאר.

רוצים לראות את זה בפעולה?

30 הודעות חינם בפתיחת חשבון עסקי. בלי כרטיס אשראי, בלי התחייבות.

התחילו בחינם
→ חזרה לבלוג

אתר זה עושה שימוש בעוגיות (Cookies) ובכלים טכנולוגיים נוספים כדי לשפר את חוויית המשתמש, לנתח תנועה ולהתאים פרסומות. המשך הגלישה באתר מהווה את הסכמתך לכך ולמדיניות הפרטיות שלנו.