Skip to content

shraga100/israelpost-zip-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

איתור מיקוד · דואר ישראל

ממשק מינימליסטי ל-API איתור המיקוד של דואר ישראל. שרת Node קטן (ללא תלויות) מגיש דף חיפוש חי + משמש פרוקסי שעוקף את חסימת ה-CORS, וכולל תיעוד ודוגמאות קוד (cURL, Python, PHP, Node.js, Ruby).

⚠️ זהו API פנימי לא מתועד של דואר ישראל. אין SLA; המבנה/המפתח עלולים להשתנות. לשימוש אישי/חינוכי. לשימוש מסחרי בהיקף — מומלץ פתרון רשמי מול דואר ישראל.

הרצה

git clone https://github.com/shraga100/israelpost-zip-api
cd israelpost-zip-api
npm start

פתח את http://localhost:3000

דורש Node 18+ (משתמש ב-fetch המובנה). אין npm install — אפס תלויות.

מבנה

israelpost-zip/
├── server.js          # שרת + פרוקסי (Node, ללא תלויות)
├── package.json
├── public/
│   └── index.html     # UI חיפוש + תיעוד + דוגמאות קוד
└── README.md

תיעוד ה-API

בסיס ואימות

Base URL https://apimftprd.israelpost.co.il/mypost-zip/
שיטה GET (כל הקריאות)
פורמט JSON
Header חובה Ocp-Apim-Subscription-Key: 5ccb5b137e7444d885be752eda7f767a
Header נוסף שהאתר שולח Authorization: Bearer null (מיותר — null מילולי, לא נדרש בפועל)

הערות:

  • ה-Subscription Key הוא של Azure API Management ומוטמע בקוד הפרונטאנד (סטטי, גלוי לכל). בלעדיו מתקבל 401 Access Denied.
  • אין צורך ב-cookies, session, או פתרון reCAPTCHA. ה-reCAPTCHA שבדף הוא קישוט שאינו חוסם את ה-XHR.
  • מפתח כזה עלול להתחלף מתישהו; אם תקבל 401 — שלוף אותו מחדש מקוד ה-JS של הדף, או הזרק דרך IL_POST_KEY=xxxx npm start.

מעטפת תגובה אחידה

{ "ReturnCode": 0, "ErrorMessage": null, "Result": ... }

ReturnCode: 0 = הצלחה. שגיאות יופיעו ב-ErrorMessage.


1. חיפוש יישובים (Autocomplete)

GET /mypost-zip/getcities-lang?CityStartsWith={טקסט}&Lang=he
פרמטר תיאור
CityStartsWith תחילת שם היישוב (URL-encoded, עברית)
Lang he / en

תגובה:

{"ReturnCode":0,"ErrorMessage":null,"Result":[
  {"id":"1212","sym":"5000","n":"תל אביב - יפו","syn":"תל אביב יפו","divided":true,"zip":"0000000"}
]}
  • id — מזהה היישוב (משמש בקריאות הבאות כ-CityID).
  • n — שם תצוגה, syn — מילת חיפוש, sym — סמל יישוב (קוד למ"ס).
  • zip — מיקוד אחיד ליישוב אם קיים (0000000 = אין; יש לחפש לפי רחוב).

2. חיפוש רחובות ביישוב (Autocomplete)

GET /mypost-zip/GetStreets-lang?CityID={id}&CityName=&SearchMode=ID-StartsWith&StartsWith={טקסט}&Lang=he
פרמטר תיאור
CityID ה-id שהתקבל משלב 1
StartsWith תחילת שם הרחוב (URL-encoded)
SearchMode ID-StartsWith
CityName נשאר ריק כש-CityID מסופק

תגובה:

{"ReturnCode":0,"ErrorMessage":null,"Result":[
  {"id":"91992","sym":"0404","n":"דיזנגוף","syn":"דיזנגוף","cityID":"1212"}
]}
  • id — מזהה הרחוב (משמש כ-StreetID בשלב 3).

3. איתור המיקוד הסופי

נקודת קצה אחת לשני המצבים (כתובת / ת.ד), משתנה לפי הפרמטרים.

א. לפי כתובת (רחוב + בית)

GET /mypost-zip/SearchZip-Lang?CityID={id}&StreetID={id}&House={מספר}&Entry={כניסה}&Lang=he&ByMaanimID=true
פרמטר תיאור
CityID מזהה יישוב (שלב 1)
StreetID מזהה רחוב (שלב 2)
House מספר בית
Entry כניסה (אופציונלי; רלוונטי כש-divided=true)
ByMaanimID true

תגובה:

{"ReturnCode":0,"ErrorMessage":null,"Result":{
  "zip":"6439612",
  "msgtype":"address",
  "messageResult":"המיקוד לכתובת הינו: 6439612"
}}

ב. לפי תיבת דואר (ת.ד)

GET /mypost-zip/SearchZip-Lang?CityID={id}&POB={מספר תיבה}&Lang=he&ByMaanimID=true

תגובה:

{"ReturnCode":0,"ErrorMessage":null,"Result":{
  "zip":"4081002",
  "msgtype":"POB",
  "cityname":"אלעד",
  "messageResult":"המיקוד עבור ת.ד 100 ב... הינו:"
}}

המיקוד הסופי תמיד בשדה Result.zip (7 ספרות).


זרימה מלאה

טקסט עיר  → getcities-lang   → CityID
טקסט רחוב → GetStreets-lang  → StreetID
CityID + StreetID + House → SearchZip-Lang → zip

ה-endpoints של השרת המקומי (פרוקסי)

השרת ב-server.js עוטף את ה-API ומגיש מאותו origin (פותר CORS):

נתיב מקומי קורא ל
/api/cities?q=&lang=he getcities-lang
/api/streets?cityId=&q=&lang=he GetStreets-lang
/api/zip?cityId=&streetId=&house=&entry= SearchZip-Lang (כתובת)
/api/zip-pob?cityId=&pob= SearchZip-Lang (ת.ד)

דוגמאות קוד

כל דוגמה היא פונקציה שלמה find_zip(city, street, house) שמבצעת את כל הזרימה (יישוב → רחוב → מיקוד).

cURL

KEY="5ccb5b137e7444d885be752eda7f767a"

# 1) יישוב -> CityID
curl -G "https://apimftprd.israelpost.co.il/mypost-zip/getcities-lang" \
  -H "Ocp-Apim-Subscription-Key: $KEY" \
  --data-urlencode "CityStartsWith=תל א" \
  --data-urlencode "Lang=he"

# 2) רחוב -> StreetID
curl -G "https://apimftprd.israelpost.co.il/mypost-zip/GetStreets-lang" \
  -H "Ocp-Apim-Subscription-Key: $KEY" \
  --data-urlencode "CityID=1212" \
  --data-urlencode "SearchMode=ID-StartsWith" \
  --data-urlencode "StartsWith=דיזנגוף" \
  --data-urlencode "Lang=he"

# 3) מיקוד
curl -G "https://apimftprd.israelpost.co.il/mypost-zip/SearchZip-Lang" \
  -H "Ocp-Apim-Subscription-Key: $KEY" \
  --data-urlencode "CityID=1212" \
  --data-urlencode "StreetID=91992" \
  --data-urlencode "House=100" \
  --data-urlencode "Lang=he" \
  --data-urlencode "ByMaanimID=true"
# => {"ReturnCode":0,...,"Result":{"zip":"6439612",...}}

Python

import requests

BASE = "https://apimftprd.israelpost.co.il/mypost-zip"
HEADERS = {"Ocp-Apim-Subscription-Key": "5ccb5b137e7444d885be752eda7f767a"}

def get(endpoint, **params):
    r = requests.get(f"{BASE}/{endpoint}", params=params, headers=HEADERS)
    return r.json()["Result"]

def find_zip(city, street, house, entry=""):
    city_id   = get("getcities-lang", CityStartsWith=city, Lang="he")[0]["id"]
    street_id = get("GetStreets-lang", CityID=city_id, SearchMode="ID-StartsWith",
                    StartsWith=street, Lang="he")[0]["id"]
    res = get("SearchZip-Lang", CityID=city_id, StreetID=street_id,
              House=house, Entry=entry, Lang="he", ByMaanimID="true")
    return res["zip"]

print(find_zip("תל אביב", "דיזנגוף", 100))   # 6439612

PHP

<?php
const BASE = "https://apimftprd.israelpost.co.il/mypost-zip";
const KEY  = "5ccb5b137e7444d885be752eda7f767a";

function ilpost_get($endpoint, $params) {
    $url = BASE . "/$endpoint?" . http_build_query($params);
    $ctx = stream_context_create(["http" => [
        "header" => "Ocp-Apim-Subscription-Key: " . KEY,
    ]]);
    $json = json_decode(file_get_contents($url, false, $ctx), true);
    return $json["Result"];
}

function find_zip($city, $street, $house, $entry = "") {
    $cityId   = ilpost_get("getcities-lang",
                  ["CityStartsWith" => $city, "Lang" => "he"])[0]["id"];
    $streetId = ilpost_get("GetStreets-lang",
                  ["CityID" => $cityId, "SearchMode" => "ID-StartsWith",
                   "StartsWith" => $street, "Lang" => "he"])[0]["id"];
    $res = ilpost_get("SearchZip-Lang",
              ["CityID" => $cityId, "StreetID" => $streetId, "House" => $house,
               "Entry" => $entry, "Lang" => "he", "ByMaanimID" => "true"]);
    return $res["zip"];
}

echo find_zip("תל אביב", "דיזנגוף", 100);   // 6439612

Node.js

// Node 18+ (fetch מובנה) — ללא תלויות
const BASE = "https://apimftprd.israelpost.co.il/mypost-zip";
const HEADERS = { "Ocp-Apim-Subscription-Key": "5ccb5b137e7444d885be752eda7f767a" };

async function get(endpoint, params) {
  const url = new URL(`${BASE}/${endpoint}`);
  Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
  const r = await fetch(url, { headers: HEADERS });
  return (await r.json()).Result;
}

async function findZip(city, street, house, entry = "") {
  const cityId   = (await get("getcities-lang", { CityStartsWith: city, Lang: "he" }))[0].id;
  const streetId = (await get("GetStreets-lang", { CityID: cityId,
                    SearchMode: "ID-StartsWith", StartsWith: street, Lang: "he" }))[0].id;
  const res = await get("SearchZip-Lang", { CityID: cityId, StreetID: streetId,
                House: house, Entry: entry, Lang: "he", ByMaanimID: "true" });
  return res.zip;
}

findZip("תל אביב", "דיזנגוף", 100).then(console.log);   // 6439612

Ruby

require "net/http"
require "json"
require "uri"

BASE = "https://apimftprd.israelpost.co.il/mypost-zip"
KEY  = "5ccb5b137e7444d885be752eda7f767a"

def ilpost_get(endpoint, params)
  uri = URI("#{BASE}/#{endpoint}")
  uri.query = URI.encode_www_form(params)
  req = Net::HTTP::Get.new(uri)
  req["Ocp-Apim-Subscription-Key"] = KEY
  res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
  JSON.parse(res.body)["Result"]
end

def find_zip(city, street, house, entry = "")
  city_id   = ilpost_get("getcities-lang", CityStartsWith: city, Lang: "he")[0]["id"]
  street_id = ilpost_get("GetStreets-lang", CityID: city_id,
                SearchMode: "ID-StartsWith", StartsWith: street, Lang: "he")[0]["id"]
  ilpost_get("SearchZip-Lang", CityID: city_id, StreetID: street_id,
    House: house, Entry: entry, Lang: "he", ByMaanimID: "true")["zip"]
end

puts find_zip("תל אביב", "דיזנגוף", 100)   # 6439612

הערות

  • CORS: ל-API אין כותרות CORS, לכן דפדפן מ-origin אחר לא יכול לקרוא לו ישירות — השרת המקומי פותר זאת בכך שהוא קורא בצד-שרת.
  • אפשר להחליף את המפתח דרך משתנה סביבה: IL_POST_KEY=xxxx npm start.
  • divided=true: ביישובים/רחובות מסוימים נדרשת Entry (כניסה) להבחנה בין מיקודים.
  • קידוד: כל טקסט בעברית חייב URL-encoding (UTF-8).

רישיון

MIT

About

ממשק מינימליסטי ל-API איתור מיקוד של דואר ישראל — שרת Node ללא תלויות + UI חיפוש חי + תיעוד ודוגמאות קוד

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors