Skip to content

נקודות איסוף

מחזיר את רשימת נקודות האיסוף של חברת השילוח הזמינות לרישיון שנבחר. הנקודות המוחזרות שייכות לחברת השילוח של רישיון הקורא: רישיון HFD מחזיר נקודות HFD, רישיון Cargo מחזיר נקודות Cargo, וכן הלאה. חברת שילוח ללא רשת נקודות איסוף מחזירה רשימה ריקה.

ה-endpoint הזה הוא ברמת רישיון (license-scoped): הוא פועל תחת רישיון (License) יחיד שנבחר באמצעות פרמטר השאילתה license_key, שערכו הוא ה-key של הרישיון. עם רישיון פעיל אחד הוא נבחר כברירת מחדל; עם כמה רישיונות, license_key הוא חובה (אחרת 422); מפתח חסר, לא פעיל, שפג תוקפו או שאינו בבעלותכם מחזיר 403.


GET /pickup-points

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

פרמטרים

Query

שדהסוגחובהתיאור
license_keystringמותנהה-key של הרישיון לפעול תחתיו. חובה כאשר לחשבון יש יותר מרישיון פעיל אחד.
citystringלאסינון תת-מחרוזת (ללא תלות ברישיות) על עיר הנקודה (עד 255 תווים).
limitintegerלאהגבלת מספר הנקודות המוחזרות (מינימום 1, מקסימום 500). מוחל לאחר הדירוג, כך שעם נקודת מוצא הוא מחזיר את N הקרובות ביותר.
latnumberלאקו רוחב של נקודת המוצא (-90..90) לדירוג מהקרוב לרחוק. חייב להישלח יחד עם lng.
lngnumberלאקו אורך של נקודת המוצא (-180..180) לדירוג מהקרוב לרחוק. חייב להישלח יחד עם lat.
addressstringלאכתובת מוצא בטקסט חופשי (עד 500 תווים). עוברת geocoding לקואורדינטות לצורך דירוג מהקרוב לרחוק. מתעלמים ממנה כאשר נשלחים lat/lng מפורשים.

איך הדירוג עובד

כברירת מחדל הרשימה מוחזרת ללא דירוג (בסדר של חברת השילוח) וללא distance_km.

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

  1. קואורדינטות מפורשות — שלחו גם lat וגם lng. ללא geocoding, ללא צורך במפתח API. שליחת אחד בלבד מהזוג היא שגיאת ולידציה.
  2. כתובת — שלחו address (ואופציונלית city, שמועבר הלאה ל-geocoder). הכתובת עוברת geocoding באמצעות המפתח של הסוחר עצמו: Google Geocoding כאשר מוגדר google_api_key, אחרת Geoapify כאשר מוגדר geoapify_api_key. אם אף אחד מהמפתחות לא מוגדר, לא מתבצעת קריאת geocoding והרשימה מוחזרת ללא דירוג. (חשבונות שנוצרו לפני 2025-08-10 נופלים חזרה למפתח Google משותף.) כל כשל geocoding — היעדר מפתח, שגיאת ספק, או היעדר התאמה — מתדרדר בצורה מבוקרת לרשימה לא מדורגת במקום להחזיר שגיאה.

כאשר נקודת מוצא נקבעת, כל נקודה מקבלת distance_km (מרחק מעגל גדול מנקודת המוצא, בקילומטרים, מעוגל ל-3 ספרות אחרי הנקודה) והרשימה ממוינת מהקרובה ביותר. נקודות ללא קואורדינטות נשארות עם distance_km: null וממוינות אחרונות.

distance_km מופיע רק כאשר סופקה נקודת מוצא (lat/lng מפורשים, או address שעבר geocoding בהצלחה). ברשימה רגילה או מסוננת-עיר בלבד המפתח נעדר.

בקשה לדוגמה — רשימה רגילה

bash
curl --location 'https://app.shipos.co.il/api/v2/pickup-points' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'
js
// Node.js 18+ / דפדפנים — בלי תלויות
const response = await fetch('https://app.shipos.co.il/api/v2/pickup-points', {
  headers: {
    'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
    'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
    Accept: 'application/json',
  },
})

if (!response.ok) {
  const { error } = await response.json()
  throw new Error(`${error.code}: ${error.message}`)
}

const { data: points } = await response.json()

for (const point of points) {
  console.log(point.id, point.name, point.address.city)
}
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.shipos.co.il/api/v2/',
    'headers' => [
        'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
        'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
        'Accept' => 'application/json',
    ],
]);

$points = json_decode(
    $client->get('pickup-points')->getBody()->getContents(),
    true,
)['data'];

foreach ($points as $point) {
    echo $point['id'], ' ', $point['name'], ' ', $point['address']['city'], PHP_EOL;
}
php
<?php

use Illuminate\Support\Facades\Http;

$points = Http::withHeaders([
    'X-Client-Id' => config('services.shipos.client_id'),
    'X-Client-Secret' => config('services.shipos.client_secret'),
])
    ->acceptJson()
    ->get('https://app.shipos.co.il/api/v2/pickup-points')
    ->throw()
    ->json('data');

foreach ($points as $point) {
    logger()->info($point['id'].' '.$point['name'].' '.$point['address']['city']);
}
python
# pip install httpx
import os

import httpx

response = httpx.get(
    "https://app.shipos.co.il/api/v2/pickup-points",
    headers={
        "X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
        "X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
        "Accept": "application/json",
    },
)
response.raise_for_status()
points = response.json()["data"]

for point in points:
    print(point["id"], point["name"], point["address"]["city"])
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

type pickupPointsResponse struct {
	Data []struct {
		ID      string `json:"id"`
		Name    string `json:"name"`
		Address struct {
			City string `json:"city"`
		} `json:"address"`
	} `json:"data"`
}

func main() {
	req, _ := http.NewRequest("GET",
		"https://app.shipos.co.il/api/v2/pickup-points", nil)
	req.Header.Set("X-Client-Id", os.Getenv("SHIPOS_CLIENT_ID"))
	req.Header.Set("X-Client-Secret", os.Getenv("SHIPOS_CLIENT_SECRET"))
	req.Header.Set("Accept", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var payload pickupPointsResponse
	if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
		panic(err)
	}

	for _, point := range payload.Data {
		fmt.Println(point.ID, point.Name, point.Address.City)
	}
}
java
// Java 17+ — java.net.http, בלי תלויות (פרסור עם Jackson/Gson)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ShipOsPickupPoints {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points"))
            .header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
            .header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
            .header("Accept", "application/json")
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            throw new RuntimeException("ShipOS error: " + response.body());
        }

        System.out.println(response.body()); // {"data":[...]}
    }
}
csharp
// .NET 8+ — System.Net.Http.Json
using System.Net.Http.Json;
using System.Text.Json;

using var http = new HttpClient
{
    BaseAddress = new Uri("https://app.shipos.co.il/api/v2/"),
};
http.DefaultRequestHeaders.Add("X-Client-Id",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_ID"));
http.DefaultRequestHeaders.Add("X-Client-Secret",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_SECRET"));

var payload = await http.GetFromJsonAsync<JsonDocument>("pickup-points")
    ?? throw new InvalidOperationException("Empty response");

foreach (var point in payload.RootElement.GetProperty("data").EnumerateArray())
{
    Console.WriteLine($"{point.GetProperty("id").GetString()} " +
        $"{point.GetProperty("name").GetString()}");
}
ruby
require "net/http"
require "json"

uri = URI("https://app.shipos.co.il/api/v2/pickup-points")
request = Net::HTTP::Get.new(uri)
request["X-Client-Id"] = ENV.fetch("SHIPOS_CLIENT_ID")
request["X-Client-Secret"] = ENV.fetch("SHIPOS_CLIENT_SECRET")
request["Accept"] = "application/json"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

raise "ShipOS error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)

JSON.parse(response.body).fetch("data").each do |point|
  puts "#{point["id"]} #{point["name"]} #{point.dig("address", "city")}"
end
rust
// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let payload: Value = reqwest::Client::new()
        .get("https://app.shipos.co.il/api/v2/pickup-points")
        .header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
        .header("X-Client-Secret", std::env::var("SHIPOS_CLIENT_SECRET")?)
        .header("Accept", "application/json")
        .send()
        .await?
        .error_for_status()?
        .json()
        .await?;

    if let Some(points) = payload["data"].as_array() {
        for point in points {
            println!("{} {}", point["id"], point["name"]);
        }
    }
    Ok(())
}

בקשה לדוגמה — סינון לפי עיר

bash
# city=תל אביב (מקודד באחוזים)
curl --location 'https://app.shipos.co.il/api/v2/pickup-points?city=%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91&limit=50' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'
js
// Node.js 18+ / דפדפנים — בלי תלויות
const query = new URLSearchParams({ city: 'תל אביב', limit: '50' })

const response = await fetch(
  `https://app.shipos.co.il/api/v2/pickup-points?${query}`,
  {
    headers: {
      'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
      'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
      Accept: 'application/json',
    },
  },
)

if (!response.ok) {
  const { error } = await response.json()
  throw new Error(`${error.code}: ${error.message}`)
}

const { data: points } = await response.json()

for (const point of points) {
  console.log(point.id, point.name, point.address.street, point.address.house)
}
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.shipos.co.il/api/v2/',
    'headers' => [
        'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
        'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
        'Accept' => 'application/json',
    ],
]);

$response = $client->get('pickup-points', [
    'query' => ['city' => 'תל אביב', 'limit' => 50],
]);
$points = json_decode($response->getBody()->getContents(), true)['data'];

foreach ($points as $point) {
    echo $point['id'], ' ', $point['name'], PHP_EOL;
}
php
<?php

use Illuminate\Support\Facades\Http;

$points = Http::withHeaders([
    'X-Client-Id' => config('services.shipos.client_id'),
    'X-Client-Secret' => config('services.shipos.client_secret'),
])
    ->acceptJson()
    ->get('https://app.shipos.co.il/api/v2/pickup-points', [
        'city' => 'תל אביב',
        'limit' => 50,
    ])
    ->throw()
    ->json('data');

foreach ($points as $point) {
    logger()->info($point['id'].' '.$point['name']);
}
python
# pip install httpx
import os

import httpx

response = httpx.get(
    "https://app.shipos.co.il/api/v2/pickup-points",
    params={"city": "תל אביב", "limit": 50},
    headers={
        "X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
        "X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
        "Accept": "application/json",
    },
)
response.raise_for_status()
points = response.json()["data"]

for point in points:
    print(point["id"], point["name"], point["address"]["street"])
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

type pickupPointsResponse struct {
	Data []struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	} `json:"data"`
}

func main() {
	query := url.Values{"city": {"תל אביב"}, "limit": {"50"}}
	req, _ := http.NewRequest("GET",
		"https://app.shipos.co.il/api/v2/pickup-points?"+query.Encode(), nil)
	req.Header.Set("X-Client-Id", os.Getenv("SHIPOS_CLIENT_ID"))
	req.Header.Set("X-Client-Secret", os.Getenv("SHIPOS_CLIENT_SECRET"))
	req.Header.Set("Accept", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var payload pickupPointsResponse
	if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
		panic(err)
	}

	for _, point := range payload.Data {
		fmt.Println(point.ID, point.Name)
	}
}
java
// Java 17+ — java.net.http, בלי תלויות (פרסור עם Jackson/Gson)
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class ShipOsPickupPointsByCity {
    public static void main(String[] args) throws Exception {
        String query = "city=" + URLEncoder.encode("תל אביב", StandardCharsets.UTF_8)
            + "&limit=50";

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points?" + query))
            .header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
            .header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
            .header("Accept", "application/json")
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            throw new RuntimeException("ShipOS error: " + response.body());
        }

        System.out.println(response.body()); // {"data":[...]}
    }
}
csharp
// .NET 8+ — System.Net.Http.Json
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;

using var http = new HttpClient
{
    BaseAddress = new Uri("https://app.shipos.co.il/api/v2/"),
};
http.DefaultRequestHeaders.Add("X-Client-Id",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_ID"));
http.DefaultRequestHeaders.Add("X-Client-Secret",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_SECRET"));

var query = HttpUtility.ParseQueryString(string.Empty);
query["city"] = "תל אביב";
query["limit"] = "50";

var payload = await http.GetFromJsonAsync<JsonDocument>($"pickup-points?{query}")
    ?? throw new InvalidOperationException("Empty response");

foreach (var point in payload.RootElement.GetProperty("data").EnumerateArray())
{
    Console.WriteLine($"{point.GetProperty("id").GetString()} " +
        $"{point.GetProperty("name").GetString()}");
}
ruby
require "net/http"
require "json"

uri = URI("https://app.shipos.co.il/api/v2/pickup-points")
uri.query = URI.encode_www_form(city: "תל אביב", limit: 50)

request = Net::HTTP::Get.new(uri)
request["X-Client-Id"] = ENV.fetch("SHIPOS_CLIENT_ID")
request["X-Client-Secret"] = ENV.fetch("SHIPOS_CLIENT_SECRET")
request["Accept"] = "application/json"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

raise "ShipOS error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)

JSON.parse(response.body).fetch("data").each do |point|
  puts "#{point["id"]} #{point["name"]}"
end
rust
// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let payload: Value = reqwest::Client::new()
        .get("https://app.shipos.co.il/api/v2/pickup-points")
        .query(&[("city", "תל אביב"), ("limit", "50")])
        .header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
        .header("X-Client-Secret", std::env::var("SHIPOS_CLIENT_SECRET")?)
        .header("Accept", "application/json")
        .send()
        .await?
        .error_for_status()?
        .json()
        .await?;

    if let Some(points) = payload["data"].as_array() {
        for point in points {
            println!("{} {}", point["id"], point["name"]);
        }
    }
    Ok(())
}

בקשה לדוגמה — הקרובות ביותר לפי קואורדינטות

bash
curl --location 'https://app.shipos.co.il/api/v2/pickup-points?lat=32.0853&lng=34.7818&limit=10' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'
js
// Node.js 18+ / דפדפנים — בלי תלויות
const query = new URLSearchParams({
  lat: '32.0853',
  lng: '34.7818',
  limit: '10',
})

const response = await fetch(
  `https://app.shipos.co.il/api/v2/pickup-points?${query}`,
  {
    headers: {
      'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
      'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
      Accept: 'application/json',
    },
  },
)

if (!response.ok) {
  const { error } = await response.json()
  throw new Error(`${error.code}: ${error.message}`)
}

const { data: points } = await response.json()

for (const point of points) {
  console.log(point.name, `${point.distance_km ?? '?'} km`)
}
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.shipos.co.il/api/v2/',
    'headers' => [
        'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
        'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
        'Accept' => 'application/json',
    ],
]);

$response = $client->get('pickup-points', [
    'query' => ['lat' => 32.0853, 'lng' => 34.7818, 'limit' => 10],
]);
$points = json_decode($response->getBody()->getContents(), true)['data'];

foreach ($points as $point) {
    echo $point['name'], ' ', $point['distance_km'] ?? '?', ' km', PHP_EOL;
}
php
<?php

use Illuminate\Support\Facades\Http;

$points = Http::withHeaders([
    'X-Client-Id' => config('services.shipos.client_id'),
    'X-Client-Secret' => config('services.shipos.client_secret'),
])
    ->acceptJson()
    ->get('https://app.shipos.co.il/api/v2/pickup-points', [
        'lat' => 32.0853,
        'lng' => 34.7818,
        'limit' => 10,
    ])
    ->throw()
    ->json('data');

foreach ($points as $point) {
    logger()->info($point['name'].' '.($point['distance_km'] ?? '?').' km');
}
python
# pip install httpx
import os

import httpx

response = httpx.get(
    "https://app.shipos.co.il/api/v2/pickup-points",
    params={"lat": 32.0853, "lng": 34.7818, "limit": 10},
    headers={
        "X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
        "X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
        "Accept": "application/json",
    },
)
response.raise_for_status()
points = response.json()["data"]

for point in points:
    print(point["name"], point.get("distance_km"), "km")
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

type nearestPointsResponse struct {
	Data []struct {
		Name       string   `json:"name"`
		DistanceKm *float64 `json:"distance_km"`
	} `json:"data"`
}

func main() {
	query := url.Values{
		"lat":   {"32.0853"},
		"lng":   {"34.7818"},
		"limit": {"10"},
	}
	req, _ := http.NewRequest("GET",
		"https://app.shipos.co.il/api/v2/pickup-points?"+query.Encode(), nil)
	req.Header.Set("X-Client-Id", os.Getenv("SHIPOS_CLIENT_ID"))
	req.Header.Set("X-Client-Secret", os.Getenv("SHIPOS_CLIENT_SECRET"))
	req.Header.Set("Accept", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var payload nearestPointsResponse
	if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
		panic(err)
	}

	for _, point := range payload.Data {
		fmt.Println(point.Name, point.DistanceKm)
	}
}
java
// Java 17+ — java.net.http, בלי תלויות (פרסור עם Jackson/Gson)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ShipOsNearestPickupPoints {
    public static void main(String[] args) throws Exception {
        String query = "lat=32.0853&lng=34.7818&limit=10";

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points?" + query))
            .header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
            .header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
            .header("Accept", "application/json")
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            throw new RuntimeException("ShipOS error: " + response.body());
        }

        System.out.println(response.body()); // הקרובות ביותר ראשונות, עם distance_km
    }
}
csharp
// .NET 8+ — System.Net.Http.Json
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;

using var http = new HttpClient
{
    BaseAddress = new Uri("https://app.shipos.co.il/api/v2/"),
};
http.DefaultRequestHeaders.Add("X-Client-Id",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_ID"));
http.DefaultRequestHeaders.Add("X-Client-Secret",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_SECRET"));

var query = HttpUtility.ParseQueryString(string.Empty);
query["lat"] = "32.0853";
query["lng"] = "34.7818";
query["limit"] = "10";

var payload = await http.GetFromJsonAsync<JsonDocument>($"pickup-points?{query}")
    ?? throw new InvalidOperationException("Empty response");

foreach (var point in payload.RootElement.GetProperty("data").EnumerateArray())
{
    Console.WriteLine($"{point.GetProperty("name").GetString()} " +
        $"{point.GetProperty("distance_km")} km");
}
ruby
require "net/http"
require "json"

uri = URI("https://app.shipos.co.il/api/v2/pickup-points")
uri.query = URI.encode_www_form(lat: 32.0853, lng: 34.7818, limit: 10)

request = Net::HTTP::Get.new(uri)
request["X-Client-Id"] = ENV.fetch("SHIPOS_CLIENT_ID")
request["X-Client-Secret"] = ENV.fetch("SHIPOS_CLIENT_SECRET")
request["Accept"] = "application/json"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

raise "ShipOS error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)

JSON.parse(response.body).fetch("data").each do |point|
  puts "#{point["name"]} #{point["distance_km"]} km"
end
rust
// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let payload: Value = reqwest::Client::new()
        .get("https://app.shipos.co.il/api/v2/pickup-points")
        .query(&[("lat", "32.0853"), ("lng", "34.7818"), ("limit", "10")])
        .header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
        .header("X-Client-Secret", std::env::var("SHIPOS_CLIENT_SECRET")?)
        .header("Accept", "application/json")
        .send()
        .await?
        .error_for_status()?
        .json()
        .await?;

    if let Some(points) = payload["data"].as_array() {
        for point in points {
            println!("{} {} km", point["name"], point["distance_km"]);
        }
    }
    Ok(())
}

בקשה לדוגמה — הקרובות ביותר לפי כתובת

bash
# address=הרצל 10, תל אביב (מקודד באחוזים)
curl --location 'https://app.shipos.co.il/api/v2/pickup-points?address=%D7%94%D7%A8%D7%A6%D7%9C%2010%2C%20%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91&limit=10' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'
js
// Node.js 18+ / דפדפנים — בלי תלויות
const query = new URLSearchParams({
  address: 'הרצל 10, תל אביב',
  limit: '10',
})

const response = await fetch(
  `https://app.shipos.co.il/api/v2/pickup-points?${query}`,
  {
    headers: {
      'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
      'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
      Accept: 'application/json',
    },
  },
)

if (!response.ok) {
  const { error } = await response.json()
  throw new Error(`${error.code}: ${error.message}`)
}

const { data: points } = await response.json()

// distance_km נעדר כאשר ה-geocoding לא הצליח לפענח את הכתובת
for (const point of points) {
  console.log(point.name, point.distance_km ?? 'unranked')
}
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.shipos.co.il/api/v2/',
    'headers' => [
        'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
        'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
        'Accept' => 'application/json',
    ],
]);

$response = $client->get('pickup-points', [
    'query' => ['address' => 'הרצל 10, תל אביב', 'limit' => 10],
]);
$points = json_decode($response->getBody()->getContents(), true)['data'];

foreach ($points as $point) {
    echo $point['name'], ' ', $point['distance_km'] ?? 'unranked', PHP_EOL;
}
php
<?php

use Illuminate\Support\Facades\Http;

$points = Http::withHeaders([
    'X-Client-Id' => config('services.shipos.client_id'),
    'X-Client-Secret' => config('services.shipos.client_secret'),
])
    ->acceptJson()
    ->get('https://app.shipos.co.il/api/v2/pickup-points', [
        'address' => 'הרצל 10, תל אביב',
        'limit' => 10,
    ])
    ->throw()
    ->json('data');

foreach ($points as $point) {
    logger()->info($point['name'].' '.($point['distance_km'] ?? 'unranked'));
}
python
# pip install httpx
import os

import httpx

response = httpx.get(
    "https://app.shipos.co.il/api/v2/pickup-points",
    params={"address": "הרצל 10, תל אביב", "limit": 10},
    headers={
        "X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
        "X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
        "Accept": "application/json",
    },
)
response.raise_for_status()
points = response.json()["data"]

# distance_km נעדר כאשר ה-geocoding לא הצליח לפענח את הכתובת
for point in points:
    print(point["name"], point.get("distance_km", "unranked"))
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

type addressPointsResponse struct {
	Data []struct {
		Name       string   `json:"name"`
		DistanceKm *float64 `json:"distance_km"`
	} `json:"data"`
}

func main() {
	query := url.Values{
		"address": {"הרצל 10, תל אביב"},
		"limit":   {"10"},
	}
	req, _ := http.NewRequest("GET",
		"https://app.shipos.co.il/api/v2/pickup-points?"+query.Encode(), nil)
	req.Header.Set("X-Client-Id", os.Getenv("SHIPOS_CLIENT_ID"))
	req.Header.Set("X-Client-Secret", os.Getenv("SHIPOS_CLIENT_SECRET"))
	req.Header.Set("Accept", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var payload addressPointsResponse
	if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
		panic(err)
	}

	for _, point := range payload.Data {
		fmt.Println(point.Name, point.DistanceKm)
	}
}
java
// Java 17+ — java.net.http, בלי תלויות (פרסור עם Jackson/Gson)
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class ShipOsPickupPointsByAddress {
    public static void main(String[] args) throws Exception {
        String query = "address="
            + URLEncoder.encode("הרצל 10, תל אביב", StandardCharsets.UTF_8)
            + "&limit=10";

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points?" + query))
            .header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
            .header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
            .header("Accept", "application/json")
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            throw new RuntimeException("ShipOS error: " + response.body());
        }

        System.out.println(response.body()); // לא מדורג כאשר ה-geocoding נכשל
    }
}
csharp
// .NET 8+ — System.Net.Http.Json
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;

using var http = new HttpClient
{
    BaseAddress = new Uri("https://app.shipos.co.il/api/v2/"),
};
http.DefaultRequestHeaders.Add("X-Client-Id",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_ID"));
http.DefaultRequestHeaders.Add("X-Client-Secret",
    Environment.GetEnvironmentVariable("SHIPOS_CLIENT_SECRET"));

var query = HttpUtility.ParseQueryString(string.Empty);
query["address"] = "הרצל 10, תל אביב";
query["limit"] = "10";

var payload = await http.GetFromJsonAsync<JsonDocument>($"pickup-points?{query}")
    ?? throw new InvalidOperationException("Empty response");

foreach (var point in payload.RootElement.GetProperty("data").EnumerateArray())
{
    point.TryGetProperty("distance_km", out var distance);
    Console.WriteLine($"{point.GetProperty("name").GetString()} {distance}");
}
ruby
require "net/http"
require "json"

uri = URI("https://app.shipos.co.il/api/v2/pickup-points")
uri.query = URI.encode_www_form(address: "הרצל 10, תל אביב", limit: 10)

request = Net::HTTP::Get.new(uri)
request["X-Client-Id"] = ENV.fetch("SHIPOS_CLIENT_ID")
request["X-Client-Secret"] = ENV.fetch("SHIPOS_CLIENT_SECRET")
request["Accept"] = "application/json"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

raise "ShipOS error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)

JSON.parse(response.body).fetch("data").each do |point|
  puts "#{point["name"]} #{point.fetch("distance_km", "unranked")}"
end
rust
// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let payload: Value = reqwest::Client::new()
        .get("https://app.shipos.co.il/api/v2/pickup-points")
        .query(&[("address", "הרצל 10, תל אביב"), ("limit", "10")])
        .header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
        .header("X-Client-Secret", std::env::var("SHIPOS_CLIENT_SECRET")?)
        .header("Accept", "application/json")
        .send()
        .await?
        .error_for_status()?
        .json()
        .await?;

    if let Some(points) = payload["data"].as_array() {
        for point in points {
            println!("{} {}", point["name"], point["distance_km"]);
        }
    }
    Ok(())
}

תגובה 200

ללא נקודת מוצא (רשימה רגילה / מסוננת לפי עיר) — ללא distance_km:

json
{
  "data": [
    {
      "id": "12345",
      "name": "סופר-פארם דיזנגוף",
      "type": "locker",
      "address": {
        "city": "תל אביב",
        "street": "דיזנגוף",
        "house": "50"
      },
      "coordinates": {
        "latitude": 32.0791,
        "longitude": 34.7742
      }
    }
  ]
}

עם נקודת מוצא (lat/lng או address שעבר geocoding) — distance_km קיים, הקרובה ביותר ראשונה:

json
{
  "data": [
    {
      "id": "12345",
      "name": "סופר-פארם דיזנגוף",
      "type": "locker",
      "address": {
        "city": "תל אביב",
        "street": "דיזנגוף",
        "house": "50"
      },
      "coordinates": {
        "latitude": 32.0791,
        "longitude": 34.7742
      },
      "distance_km": 0.842
    },
    {
      "id": "67890",
      "name": "נקודה ללא geocode",
      "type": "store",
      "address": {
        "city": "תל אביב",
        "street": "אלנבי",
        "house": "3"
      },
      "coordinates": {
        "latitude": null,
        "longitude": null
      },
      "distance_km": null
    }
  ]
}

שדות נקודת איסוף

שדהסוגתיאור
idstringמזהה נקודה אחיד לכל חברות השילוח.
namestring | nullשם התצוגה של הנקודה.
typestring | nullסוג הנקודה כפי שמדווח על ידי חברת השילוח (למשל locker, store), כאשר זמין.
address.citystring | nullעיר.
address.streetstring | nullרחוב.
address.housestring | nullמספר בית / רחוב.
coordinates.latitudenumber | nullקו רוחב, או null כאשר חברת השילוח לא סיפקה אותו.
coordinates.longitudenumber | nullקו אורך, או null כאשר חברת השילוח לא סיפקה אותו.
distance_kmnumber | nullקילומטרים מנקודת המוצא שסופקה. קיים רק כאשר סופקה נקודת מוצא; null עבור נקודות ללא קואורדינטות.

שגיאות

סטטוסקודמתי
401unauthenticatedclient credentials חסרים או שגויים.
403forbiddenלחשבון אין רישיון פעיל, או שה-license_key שסופק אינו פעיל / פג תוקף / אינו בבעלותכם.
422validation_failedפרמטרי שאילתה שגויים (למשל רק אחד מ-lat/lng, קואורדינטות מחוץ לטווח, limit < 1), או כמה רישיונות פעילים ו-license_key הושמט.