REST API · v2

תיעוד API

כל ה-endpoints. מתודה GET בלבד. JSON בתשובה. דרוש API key.

פרומפט מהיר ל-LLM

העתק → הדבק ב-Claude / ChatGPT / Gemini → המודל יוכל לכתוב קוד מיידית

💡 הפרומפט כולל את כל ה-endpoints, פורמט הקלט/פלט, וכמה דוגמאות. השלם בסוף את הבקשה שלך ("בנה לי דשבורד...", "כתוב פונקציה...", "תכנן לי...").
אתה עוזר לי לעבוד עם Waze API (https://waze.botomat.co.il) — REST API שמחזיר זמני ומרחקי נסיעה בישראל מבוסס Waze בזמן אמת.

== אימות ==
כל קריאה ל-/api/* (פרט ל-/api/ping ו-/api/auth/*) דורשת API key בכותרת X-API-Key:
  curl -H "X-API-Key: wzk_live_..." https://waze.botomat.co.il/api/route?...

== פורמט קלט (from/to) ==
שני פורמטים נתמכים:
  1. שם בעברית: from=תל אביב | to=ירושלים | from=איתמר | to=אש קודש
  2. קואורדינטות: from=32.0853,34.7818 | to=31.7683,35.2137
תמיד URL-encode עברית עם encodeURIComponent.

== Endpoints ==

GET /api/ping
  בריאות + מטא, לא דורש מפתח. החזרה: {ok, service, placesCount, timestamp}

GET /api/places?limit=N&offset=N
  רשימת 1272 יישובים. החזרה: {total, count, places: [{name, lat, lon}, ...]}

GET /api/places/find?q=
  חיפוש מדויק במאגר מקומי (מהיר). 404 אם לא נמצא.

GET /api/places/search?q=&limit=10
  חיפוש חלקי (substring) במאגר מקומי.

GET /api/autocomplete?q=&limit=8
  השלמה אוטומטית כמו השדה באתר Waze. משלב DB מקומי + Waze.
  החזרה: {results: [{label, name, lat, lon, source: 'local'|'waze'}, ...]}

GET /api/geocode?q=
  המרת שם לקואורדינטות. החזרה: {name, lat, lon, city, type, provider}

GET /api/route?from=&to=[&alternatives=N&departAt=ISO&avoidTolls=1&includeInstructions=1&includeGeometry=1]
  מסלול מלא עם רמת עומס. החזרה:
  {
    from: {name, lat, lon}, to: {name, lat, lon}, region: 'IL',
    durationMinutes, durationSeconds,
    distanceKm, distanceMeters,
    freeFlowMinutes, trafficDelayMinutes,
    trafficLevel: 'free'|'light'|'moderate'|'heavy'|'standstill',
    trafficLevelHe: 'חופשי'|'קל'|'בינוני'|'כבד'|'עצירה',
    congestionRatio: 1.05,         // actual / freeFlow
    averageSpeedKmh: 72.3,
    routeName: '1 מזרח; 443 מזרח',
    departAt: ISO,                 // אם נשלח
    arrivalAt: ISO,                // אם נשלח departAt
    alternatives: [{routeName, durationMinutes, distanceKm, trafficLevel, congestionRatio, ...}],
    requestedAt: ISO
  }

GET /api/distance?from=&to=      → {distanceKm}
GET /api/duration?from=&to=      → {durationMinutes}

GET /api/eta?from=&to=[&departAt=ISO]
  כמו /route + departAt + arrivalAt מחושב.

GET /api/depart-by-arrival?from=&to=&arriveAt=ISO
  "אני רוצה להגיע ב-X, מתי לצאת?" — חישוב הפוך עם חיזוי תנועה.
  החזרה: {arriveAt, recommendedDepartAt, durationMinutes, distanceKm, expectedArrivalAt, overshootMinutes, scenarios: [...]}

GET /api/best-time?from=&to=&start=ISO&end=ISO&stepMinutes=30
  השוואת זמני נסיעה בחלון. מוצא את שעת היציאה הכי טובה.
  סוגרים: start..end ≤ 24 שעות, stepMinutes ≥ 15.
  החזרה: {fastest, slowest, averageMinutes, spreadMinutes, samples: [{departAt, durationMinutes, trafficLevel, arrivalAt}, ...]}

GET /api/matrix?origins=A|B|C&destinations=X|Y[&alternatives=1]
  מטריצת N×M זמני נסיעה (מקסימום 25 תאים). השמות מופרדים ב-|.
  החזרה: {rows: [{from, cells: [{to, durationMinutes, distanceKm, routeName}, ...]}, ...]}

== רמות עומס (trafficLevel) ==
ratio = durationActual / durationFreeFlow
  ratio < 1.10  → 'free'       חופשי
  ratio < 1.25  → 'light'      קל
  ratio < 1.50  → 'moderate'   בינוני
  ratio < 2.00  → 'heavy'      כבד
  ratio ≥ 2.00  → 'standstill' עצירה

== מגבלות ==
- Plan free: 1,000 קריאות/חודש, 60 קריאות/דקה
- Plan pro/enterprise: לפי חוזה
- Header X-RateLimit-Remaining מציג את הנותר בדקה
- Header X-Monthly-Remaining מציג את הנותר החודשי

== קודי שגיאה ==
400 invalid_input          חסר/לא תקין פרמטר
401 missing_api_key        אין X-API-Key
401 invalid_api_key        מפתח לא קיים/בוטל
403 email_not_verified     צריך לאמת מייל לפני שימוש
403 account_blocked        החשבון נחסם
404 not_found              המקום לא נמצא
429 monthly_limit_reached  עברת מכסה חודשית
429 rate_limit_reached     יותר מדי קריאות בדקה
500 internal_error         שגיאה בשרת/Waze upstream

== דוגמאות מהירות ==

# חישוב פשוט (שם)
GET /api/route?from=%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91&to=%D7%99%D7%A8%D7%95%D7%A9%D7%9C%D7%99%D7%9D
# חישוב פשוט (קואורדינטות)
GET /api/route?from=32.0853,34.7818&to=31.7683,35.2137&alternatives=5
# "מתי לצאת בשביל להגיע ב-9 בבוקר?"
GET /api/depart-by-arrival?from=%D7%97%D7%99%D7%A4%D7%94&to=%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91&arriveAt=2026-06-08T07:00:00Z
# "השווה זמני נסיעה בין 7:00 ל-11:00"
GET /api/best-time?from=%D7%9E%D7%95%D7%93%D7%99%D7%A2%D7%99%D7%9F&to=%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91&start=2026-06-08T07:00:00Z&end=2026-06-08T11:00:00Z&stepMinutes=30
# מטריצה: 3 מקורות × 2 יעדים
GET /api/matrix?origins=%D7%97%D7%99%D7%A4%D7%94|%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91|%D7%99%D7%A8%D7%95%D7%A9%D7%9C%D7%99%D7%9D&destinations=%D7%90%D7%99%D7%9C%D7%AA|%D7%91%D7%90%D7%A8%20%D7%A9%D7%91%D7%A2

== קוד JS לדוגמה ==
const API_KEY = 'wzk_live_...';
const BASE = 'https://waze.botomat.co.il';

async function route(from, to, opts = {}) {
  const p = new URLSearchParams({ from, to, ...opts });
  const r = await fetch(`${BASE}/api/route?${p}`, {
    headers: { 'X-API-Key': API_KEY }
  });
  if (!r.ok) throw new Error((await r.json()).error);
  return r.json();
}

const trip = await route('תל אביב', 'ירושלים', { alternatives: 3 });
console.log(`${trip.durationMinutes} דק (${trip.trafficLevelHe}), ${trip.distanceKm} ק"מ`);

== המשימה שלי ==
[כאן כתוב את הבקשה — לדוגמה: "בנה לי React hook useRoute(from, to) שמחזיר זמן ומרחק", או "כתוב לי Node script שמחשב את שעת היציאה הטובה ביותר לפגישה ב-תל אביב ב-09:00 מירושלים".]

🔑 אימות (API Key)

כל קריאה ל-API דורשת מפתח. שלח אותו באחת משלוש דרכים:

מומלץ — Header
X-API-Key: wzk_live_abc123...
Bearer token
Authorization: Bearer wzk_live_abc123...
Query param (לבדיקה מהירה בדפדפן)
?api_key=wzk_live_abc123...
צריך מפתח?

צור חשבון ב-/signup, אמת את המייל, וצור מפתח מהדשבורד.

Base URL

https://waze.botomat.co.il

פורמט קלט (from / to)

1. שם בעברית או אנגלית
from=תל אביב
to=ירושלים
from=איתמר
to=אש קודש
2. קואורדינטות (lat,lon)
from=32.0853,34.7818
to=31.7683,35.2137

מומלץ URL-encode (במיוחד עברית) — encodeURIComponent() ב-JS, --data-urlencode ב-curl.

מגבלות שימוש

תכניתחודשילדקה
free1,00060
proלפי הסכםלפי הסכם
admin6,000

המכסה מתאפסת ב-1 לחודש. Header התשובה כולל X-Monthly-Remaining ו-X-RateLimit-Remaining.

📋 רשימת יישובים

GET/api/places

כל היישובים במאגר (1272). תומך ב-?limit=N&offset=N.

GET /api/places?limit=10
GET/api/places/find?q=...

חיפוש מדויק במאגר מקומי. מהיר, ללא קריאה ל-Waze. 404 אם לא נמצא.

GET /api/places/find?q=תל אביב
GET/api/places/search?q=...&limit=10

חיפוש חלקי (substring) במאגר.

GET /api/places/search?q=בית&limit=10
GET/api/autocomplete?q=...&limit=8

השלמה אוטומטית — DB מקומי + Waze. אידיאלי לטפסי כתובת.

GET /api/autocomplete?q=ירוש&limit=5
{
  "query": "ירוש", "count": 4,
  "results": [
    { "label": "ירושלים", "source": "local", "lat": 31.7819, "lon": 35.2188 },
    { "label": "תירוש",   "source": "local", ... },
    { "label": "תירוש, תל אביב - יפו, Israel", "source": "waze", ... }
  ]
}
GET/api/geocode?q=...

שם → קואורדינטות.

GET /api/geocode?q=איתמר
{
  "name": "איתמר, Israel", "city": "איתמר",
  "lat": 32.16905, "lon": 35.31539,
  "type": "place", "provider": "local"
}
GET/api/route ⭐ הראשי

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

שםחובההסבר
fromמקור
toיעד
alternatives-1-6 (ברירת מחדל 3)
departAt-ISO 8601 — חיזוי תנועה היסטורי
avoidTolls-1/true למניעת אגרה
avoidFerries-0/false לאפשר מעבורות
includeInstructions-1 להוראות נסיעה
includeGeometry-1 לקו מסלול
GET /api/route?from=איתמר&to=אש קודש&alternatives=3
{
  "from": { "name": "איתמר, Israel", "lat": 32.16905, "lon": 35.31539 },
  "to": { "name": "אש קודש, Israel", "lat": 32.06454, "lon": 35.3377 },
  "region": "IL",
  "durationMinutes": 31.5, "durationSeconds": 1890,
  "distanceKm": 33.44, "distanceMeters": 33437,
  "freeFlowMinutes": 30.2, "trafficDelayMinutes": 1.3,
  "trafficLevel": "free",
  "trafficLevelHe": "חופשי",
  "congestionRatio": 1.04,
  "averageSpeedKmh": 63.7,
  "routeName": "505",
  "alternatives": [
    { "routeName": "505", "durationMinutes": 31.5, "distanceKm": 33.44, "trafficLevel": "free", "congestionRatio": 1.04, ... },
    { "routeName": "60 דרום; 60", "durationMinutes": 33.3, "distanceKm": 34.06, ... }
  ],
  "requestedAt": "2026-06-07T15:00:00Z"
}

📏 distance / duration

קיצורי דרך אם צריך רק מספר אחד.

GET /api/distance?from=חיפה&to=אילת   → { "distanceKm": 434 }
GET /api/duration?from=חיפה&to=אילת   → { "durationMinutes": 286.8 }
GET/api/eta

כמו /route + departAt + arrivalAt מחושב.

GET /api/eta?from=פתח תקווה&to=באר שבע&departAt=2026-06-08T08:00:00Z
GET/api/depart-by-arrival🎯 מתקדם

"רוצה להגיע ב-X — מתי לצאת?" — חישוב הפוך עם חיזוי תנועה.

GET /api/depart-by-arrival?from=חיפה&to=תל אביב&arriveAt=2026-06-08T09:00:00Z
{
  "arriveAt": "2026-06-08T09:00:00.000Z",
  "recommendedDepartAt": "2026-06-08T07:42:30.000Z",
  "durationMinutes": 77.5,
  "distanceKm": 94.15,
  "expectedArrivalAt": "2026-06-08T09:00:12.000Z",
  "overshootMinutes": 0.2,
  "scenarios": [ /* iterations */ ]
}
GET/api/best-time📊 השוואה

השווה זמני נסיעה בחלון של עד 24 שעות. מוצא את שעת היציאה המהירה ביותר.

GET /api/best-time?from=מודיעין&to=תל אביב&start=2026-06-08T07:00:00Z&end=2026-06-08T11:00:00Z&stepMinutes=30
{
  "windowStart": "...", "windowEnd": "...",
  "sampleCount": 9,
  "fastest": { "departAt": "...", "durationMinutes": 42.1, "trafficLevel": "light", ... },
  "slowest": { "departAt": "...", "durationMinutes": 71.5, "trafficLevel": "heavy", ... },
  "averageMinutes": 56.2,
  "spreadMinutes": 29.4,
  "samples": [ /* כל הנדגמים */ ]
}

⚠️ פעולה כבדה (קריאה אחת לכל sample). עדיף stepMinutes ≥ 30.

GET/api/matrix🔢 מסיבי

מטריצת N×M זמני נסיעה. הפרד בין מקומות ב-|. מקסימום 25 תאים.

GET /api/matrix?origins=חיפה|תל אביב|ירושלים&destinations=אילת|באר שבע
{
  "origins": ["חיפה", "תל אביב", "ירושלים"],
  "destinations": ["אילת", "באר שבע"],
  "rows": [
    { "from": "חיפה", "cells": [
      { "to": "אילת", "durationMinutes": 286, "distanceKm": 434, "routeName": "..." },
      { "to": "באר שבע", "durationMinutes": 152, "distanceKm": 218, "routeName": "..." }
    ]},
    ...
  ]
}

🚦 רמות עומס תנועה

החישוב מבוסס על congestionRatio = duration / freeFlow:

free / חופשיratio < 1.10 — אין פקקים
light / קלratio < 1.25 — האטה קלה
moderate / בינוניratio < 1.50 — צפיפות
heavy / כבדratio < 2.00 — פקק רציני
standstill / עצירהratio ≥ 2.00 — תנועה עומדת

⚠️ קודי שגיאה

קודerrorמתי
400invalid_inputפרמטר חסר / לא תקין
401missing_api_keyחסר X-API-Key
401invalid_or_revoked_api_keyהמפתח לא חוקי / בוטל
403email_not_verifiedצריך לאמת מייל לפני שימוש ב-API
403account_blockedהחשבון נחסם
404not_foundהמקום לא נמצא
429monthly_limit_reachedעברת מכסה חודשית
429rate_limit_reachedיותר מדי קריאות בדקה
500internal_errorתקלה ב-Waze upstream

💻 דוגמאות בקוד

JavaScript (fetch)
const API_KEY = 'wzk_live_...';
const params = new URLSearchParams({ from: 'תל אביב', to: 'ירושלים' });
const res = await fetch(`https://waze.botomat.co.il/api/route?${params}`, {
  headers: { 'X-API-Key': API_KEY }
});
const trip = await res.json();
console.log(`${trip.durationMinutes} דק (${trip.trafficLevelHe}), ${trip.distanceKm} ק"מ`);
Node.js (axios)
import axios from 'axios';
const client = axios.create({
  baseURL: 'https://waze.botomat.co.il',
  headers: { 'X-API-Key': process.env.WAZE_API_KEY }
});
const { data } = await client.get('/api/route', {
  params: { from: 'איתמר', to: 'אש קודש', alternatives: 3 }
});
Python (requests)
import requests
r = requests.get(
  'https://waze.botomat.co.il/api/route',
  params={'from': 'תל אביב', 'to': 'ירושלים', 'alternatives': 3},
  headers={'X-API-Key': 'wzk_live_...'}
)
trip = r.json()
print(trip['durationMinutes'], 'min,', trip['trafficLevelHe'])
curl
curl -G "https://waze.botomat.co.il/api/route" \
  -H "X-API-Key: wzk_live_..." \
  --data-urlencode "from=תל אביב" \
  --data-urlencode "to=ירושלים"
PHP
$ch = curl_init('https://waze.botomat.co.il/api/route?' . http_build_query([
  'from' => 'תל אביב', 'to' => 'ירושלים'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-API-Key: wzk_live_...']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$trip = json_decode(curl_exec($ch), true);