← חזרה לבדיקת רכב לפי מספר רישוי

API לנתוני רכב בישראל — מדריך למפתחים 2026

עודכן: אוגוסט 2026 • מדריך טכני מאת lior_Ai • רלוונטי ל-JavaScript, Python וכל שפה שיודעת לעשות HTTP GET

נתחיל מהתשובה הלא-נוחה: בישראל אין REST API רשמי לנתוני רכב במובן שמפתחים מצפים לו — אין GET /vehicles/{plate}, אין מפתח API, אין מסמך OpenAPI ואין SLA. מה שיש זה משהו אחר, ולמעשה טוב לא פחות: משרד התחבורה מפרסם את מרשם הרכב כמאגרי נתונים פתוחים בפורטל data.gov.il, שרץ על CKAN. ל-CKAN יש ממשק HTTP לשאילתות על טבלאות — datastore_search — וממנו אפשר לשלוף רשומת רכב לפי מספר רישוי. המדריך הזה מסביר איך לעשות את זה נכון, ומה נשבר בדרך.
תוכן
  1. המודל: מאגרים פתוחים ולא API מוצר
  2. הנקודה היחידה שצריך להכיר — datastore_search
  3. דוגמת curl
  4. דוגמת JavaScript fetch
  5. מבנה התשובה: result.records ו-result.total
  6. עימוד: limit ו-offset
  7. CORS ולמה כמעט תמיד תצטרך פרוקסי
  8. עומסים, אמינות וקאשינג
  9. נרמול מספרי רישוי בישראל
  10. המאגרים הנפרדים ומה יש בכל אחד
  11. עדכניות הנתונים ומה זה אומר למשתמש
  12. רישוי, ייחוס ומה אסור להצהיר
  13. שאלות נפוצות

1. המודל: מאגרים פתוחים ולא API מוצר

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

המשמעויות המעשיות:

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

2. הנקודה היחידה שצריך להכיר — datastore_search

כל השליפות עוברות דרך כתובת אחת:

https://data.gov.il/api/3/action/datastore_search

זו קריאת GET רגילה עם פרמטרים ב-query string, ללא אימות וללא מפתח. הפרמטרים שבאמת חשובים:

פרמטרסוגלמה הוא משמש
resource_idUUIDחובה. מזהה הטבלה שממנה שולפים. מתקבל מעמוד המאגר בפורטל.
qמחרוזת או JSONחיפוש חופשי בכל העמודות, או אובייקט JSON לחיפוש בעמודה מסוימת.
filtersJSONסינון לפי התאמה מדויקת של עמודה לערך. זה מה שכדאי להשתמש בו למספר רישוי.
limitמספרמספר הרשומות המוחזרות. ברירת המחדל נמוכה, אז כדאי לציין במפורש.
offsetמספרדילוג על רשומות — הבסיס לעימוד.
fieldsמחרוזתרשימת עמודות מופרדת בפסיקים, כדי לצמצם את גודל התשובה.
sortמחרוזתמיון, למשל shnat_yitzur desc.

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

איפה משיגים את ה-resource_id

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

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

3. דוגמת curl

חיפוש מספר רישוי עם התאמה מדויקת, באמצעות filters. שים לב לקידוד ה-JSON ב-URL — עם curl נוח להשתמש ב---data-urlencode יחד עם -G, כדי לא לקודד ידנית:

curl -sG "https://data.gov.il/api/3/action/datastore_search" \
  --data-urlencode 'resource_id=RESOURCE_ID' \
  --data-urlencode 'filters={"mispar_rechev":"1234567"}' \
  --data-urlencode 'limit=5' \
  -H 'Accept: application/json'

וגרסת החיפוש החופשי, שימושית כשאינך בטוח בשם העמודה במאגר הספציפי:

curl -sG "https://data.gov.il/api/3/action/datastore_search" \
  --data-urlencode 'resource_id=RESOURCE_ID' \
  --data-urlencode 'q=1234567' \
  --data-urlencode 'limit=5'

אם אתה מעדיף לבנות את ה-URL בעצמך, זכור שסימני {, } ו-" חייבים להיות מקודדים. שאילתת filters שנשלחת בלי קידוד תקין תחזור עם שגיאת ולידציה, ולא עם תוצאה ריקה — מה שדווקא נוח לדיבוג.

לגלות אילו עמודות קיימות במשאב לפני שמסננים לפיהן — פשוט שלוף רשומה אחת וקרא את המפתחות:

curl -sG "https://data.gov.il/api/3/action/datastore_search" \
  --data-urlencode 'resource_id=RESOURCE_ID' \
  --data-urlencode 'limit=1' | python3 -m json.tool | head -60

4. דוגמת JavaScript fetch

אותה שליפה מצד לקוח או מ-Node. שים לב ל-URLSearchParams, שמטפל בקידוד עבורך, ולטיפול בשגיאות שמפריד בין כשל HTTP לכשל לוגי:

const BASE = 'https://data.gov.il/api/3/action/datastore_search';

async function lookupVehicle(resourceId, plate, { column = null, limit = 5 } = {}) {
  const params = new URLSearchParams({
    resource_id: resourceId,
    limit: String(limit),
  });

  if (column) {
    params.set('filters', JSON.stringify({ [column]: plate }));
  } else {
    params.set('q', plate);
  }

  const res = await fetch(BASE + '?' + params.toString(), {
    headers: { Accept: 'application/json' },
  });

  if (!res.ok) {
    throw new Error('datastore_search HTTP ' + res.status);
  }

  const json = await res.json();

  // CKAN מחזיר success:false עם קוד 200 בחלק מהמקרים
  if (!json.success) {
    throw new Error('datastore_search failed: ' + JSON.stringify(json.error));
  }

  return {
    records: json.result.records,
    total: json.result.total,
    fields: json.result.fields,
  };
}

// שימוש
const { records, total } = await lookupVehicle('RESOURCE_ID', '1234567', {
  column: 'mispar_rechev',
});

if (total === 0) {
  console.log('לא נמצאה רשומה');
} else {
  console.log(records[0]);
}
מלכודת נפוצה: CKAN יכול להחזיר HTTP 200 עם success: false בגוף התשובה. בדיקה של res.ok לבדה אינה מספיקה — חייבים לבדוק גם את json.success, אחרת תקבל חריגה מוזרה בשלב שבו אתה נוגע ב-result.records.

5. מבנה התשובה: result.records ו-result.total

התשובה עוטפת את התוצאה באובייקט קבוע. המפתחות שאתה צריך:

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

6. עימוד: limit ו-offset

לשליפה של רשומת רכב בודדת אין צורך בעימוד — limit=1 או limit=5 מספיק. עימוד נדרש כשמורידים חתיכות גדולות, למשל בניית קאש מקומי או ניתוח סטטיסטי.

async function* iterateAll(resourceId, pageSize = 1000) {
  let offset = 0;
  let total = Infinity;

  while (offset < total) {
    const params = new URLSearchParams({
      resource_id: resourceId,
      limit: String(pageSize),
      offset: String(offset),
    });

    const res = await fetch(BASE + '?' + params.toString());
    const json = await res.json();
    if (!json.success) throw new Error('page failed at offset ' + offset);

    total = json.result.total;
    const batch = json.result.records;
    if (batch.length === 0) break;

    yield batch;
    offset += batch.length;

    // נשימה בין עמודים — לא להציף שירות ציבורי
    await new Promise((r) => setTimeout(r, 250));
  }
}

כמה כללי אצבע: השרת עשוי לכפות תקרה על limit, ולכן קדם על בסיס batch.length בפועל ולא על בסיס pageSize שביקשת. הוסף השהיה קצרה בין עמודים. תמיד קבע תנאי עצירה על מערך ריק, כי הסתמכות על total לבדה תיכשל אם המאגר מתעדכן בזמן הסריקה. ואם אתה באמת צריך את כל המאגר — עדיף להוריד את קובץ ה-CSV המלא מעמוד המאגר במקום לעמד מאות אלפי רשומות דרך ה-API.

7. CORS ולמה כמעט תמיד תצטרך פרוקסי

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

הפתרון הנכון הוא שכבת ביניים משלך: פונקציית edge, serverless function או שרת קטן שמבצע את הקריאה מצד השרת ומחזיר JSON נקי ללקוח. היתרונות מצטברים במהירות:

אם אתה עובד עם Netlify Functions, Cloudflare Workers, Vercel או Supabase Edge Functions — כל אחת מהן מספיקה בהחלט לתפקיד. שים לב שהמדריך הזה מוגש מאתר עם מדיניות CSP קפדנית, ולכן כל דומיין חיצוני שאתה קורא אליו צריך להיות מוצהר במפורש ב-connect-src.

8. עומסים, אמינות וקאשינג

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

9. נרמול מספרי רישוי בישראל

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

10. המאגרים הנפרדים ומה יש בכל אחד

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

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

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

11. עדכניות הנתונים ומה זה אומר למשתמש

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

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

12. רישוי, ייחוס ומה אסור להצהיר

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

🔧 מימוש עובד להתייחסות

car.lior-ai.com הוא מימוש חי של כל מה שכתוב כאן: שליפה מכמה מאגרים במקביל, נרמול מספרי רישוי, מיפוי שמות עמודות בתעתיק לשדות בעברית, נתיבי כשל למשתמש, וקישור החוצה לרשם המשכונות למה שאינו קיים בנתונים הפתוחים. אפשר להזין מספר רישוי ולראות אילו שדות בפועל חוזרים ואילו לא.

🚗 לבדיקה חיה לפי מספר רישוי

רשימת המאגרים בשימוש: מקורות המידע • המדריך לצד הצרכן: בדיקת רכב לפני קנייה 2026 • עוד שירותי AI: lior-ai.com/tools

❓ שאלות נפוצות
יש API רשמי לבדיקת רכב לפי מספר רישוי בישראל?

לא במובן הקלאסי. אין endpoint מוצרי מתועד עם גרסאות ו-SLA. מה שקיים הוא מאגרי נתונים פתוחים בפורטל data.gov.il, שרץ על CKAN, וממשק שאילתות גנרי בשם datastore_search. דרכו אפשר לשלוף רשומת רכב לפי מספר רישוי בקריאת GET רגילה, בלי אימות ובלי מפתח.

צריך מפתח API או הרשמה?

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

איפה מוצאים את ה-resource_id הנכון?

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

אפשר לקרוא ישירות מהדפדפן, בלי שרת?

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

מה מבנה התשובה?

JSON עם success בוליאני, ומתחת ל-result: records (מערך הרשומות), total (סך ההתאמות לשאילתה, ולא מספר הרשומות שהוחזרו), fields (תיאור העמודות), ו-limit/offset. שים לב ש-CKAN יכול להחזיר HTTP 200 עם success: false, ולכן חייבים לבדוק את שני הדברים.

איך עושים עימוד על מאגר גדול?

בעזרת limit ו-offset, כשקידום ה-offset מבוסס על מספר הרשומות שהוחזרו בפועל ולא על מה שביקשת — השרת עשוי לכפות תקרה. הוסף השהיה קצרה בין עמודים ותנאי עצירה על מערך ריק. אם אתה צריך את כל המאגר, עדיף להוריד את קובץ ה-CSV המלא מעמוד המאגר.

האם הנתונים מתעדכנים בזמן אמת?

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

אפשר לקבל מהמאגרים מידע על תאונות או שעבודים?

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

איך מנרמלים מספר רישוי שהמשתמש הקליד?

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

מה קורה כששם עמודה או מזהה משאב משתנה?

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

⚠️ הבהרה: car.lior-ai.com הוא שירות פרטי של lior_Ai ואינו משויך, מאושר או קשור לממשלת ישראל, למשרד התחבורה או לכל גוף ממשלתי אחר. המדריך הזה הוא תיעוד קהילתי בלתי רשמי של עבודה עם נתונים ציבוריים פתוחים, ואינו תיעוד רשמי של data.gov.il או של משרד התחבורה. שמות שדות, מזהי משאבים ומבנה תשובה עשויים להשתנות ללא הודעה. תנאי השימוש המחייבים בנתונים הם אלה המפורסמים בפורטל ובעמוד המאגר עצמו.