משלוח לנקודת איסוף
המדריך הזה עובר על תהליך נקודות האיסוף המלא: עיון בנקודות של המוביל, איתור הנקודה הקרובה ביותר ללקוח שלכם, ויצירת משלוח שמגיע אליה. לטבלאות הפרמטרים המלאות ראו את מדריך העזר לנקודות איסוף ואת מדריך העזר למשלוחים.
כל הבקשות נושאות את פרטי הלקוח שלכם, וכאשר לחשבון יש יותר מרישיון פעיל אחד — גם license_key (פרמטר שאילתה ב-GET, שדה בגוף הבקשה ב-POST). הנקודות שתקבלו שייכות למוביל של הרישיון שנבחר — רישיון HFD מציג נקודות HFD, רישיון Cargo מציג נקודות Cargo.
שלב 1 — עיון בנקודות של המוביל
התחילו ברשימה פשוטה כדי לראות מה רשת המוביל מציעה:
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'// 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()
console.log(`${points.length} pickup points in the carrier network`)<?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'];
echo count($points), ' pickup points', PHP_EOL;<?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');
logger()->info(count($points).' pickup points');# 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"]
print(len(points), "pickup points")package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type pickupPointsResponse struct {
Data []struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
} `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)
}
fmt.Println(len(payload.Data), "pickup points")
}// 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":[...]} — מפו עם Jackson/Gson
}
}// .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");
var points = payload.RootElement.GetProperty("data");
Console.WriteLine($"{points.GetArrayLength()} pickup points");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)
points = JSON.parse(response.body).fetch("data")
puts "#{points.size} pickup points"// [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?;
let total = payload["data"].as_array().map_or(0, |points| points.len());
println!("{total} pickup points");
Ok(())
}צמצמו את התוצאות עם פילטר תת-מחרוזת city (ללא תלות ברישיות) ועם limit (מוגבל ל-500):
# 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'// Node.js 18+ / דפדפנים — ללא תלויות
const params = new URLSearchParams({ city: 'תל אביב', limit: '50' })
const response = await fetch(
`https://app.shipos.co.il/api/v2/pickup-points?${params}`,
{
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.type)
}<?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'], ' ', $point['type'], PHP_EOL;
}<?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'].' '.$point['type']);
}# 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()
for point in response.json()["data"]:
print(point["id"], point["name"], point["type"])package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
type pickupPointsResponse struct {
Data []struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
} `json:"data"`
}
func main() {
query := url.Values{"city": {"תל אביב"}, "limit": {"50"}}
endpoint := "https://app.shipos.co.il/api/v2/pickup-points?" + query.Encode()
req, _ := http.NewRequest("GET", endpoint, 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.Type)
}
}// 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 city = URLEncoder.encode("תל אביב", StandardCharsets.UTF_8);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points"
+ "?city=" + city + "&limit=50"))
.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":[...]} — מפו עם Jackson/Gson
}
}// .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 query = $"?city={Uri.EscapeDataString("תל אביב")}&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()} " +
$"{point.GetProperty("type").GetString()}");
}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"]} #{point["type"]}"
end// [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"], point["type"]);
}
}
Ok(())
}מובילים ללא רשת נקודות איסוף
מוביל שאין לו רשת נקודות איסוף (או שנתוני הנקודות שלו טרם סונכרנו) מחזיר רשימה ריקה — זו אינה שגיאה. לרישיונות של איסוף עצמי או שליחים בלבד פשוט אין מה להציג כאן.
שלב 2 — איתור הנקודה הקרובה ביותר
כדי לדרג נקודות מהקרובה לרחוקה, ספקו ל-API נקודת מוצא. יש שתי דרכים:
- קואורדינטות מפורשות — העבירו
latו-lng(שניהם נדרשים יחד). לא נדרש שום מפתח API. - כתובת בטקסט חופשי — העבירו
address(אפשר גם עםcity). הכתובת עוברת geocoding עם המפתח של הסוחר עצמו:google_api_keyאם הוגדר, ואחרתgeoapify_api_key. אם אף אחד מהמפתחות לא הוגדר, לא מתבצעת קריאת geocoding ותקבלו בחזרה את הרשימה הלא-מדורגת — כמו בשלב 1, ללאdistance_km.
עם נקודת מוצא, כל נקודה מקבלת שדה distance_km והרשימה ממוינת מהקרובה לרחוקה; limit ייתן לכם את N הקרובות ביותר.
curl --location 'https://app.shipos.co.il/api/v2/pickup-points?lat=32.0853&lng=34.7818&limit=5' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'// Node.js 18+ / דפדפנים — ללא תלויות
const params = new URLSearchParams({ lat: '32.0853', lng: '34.7818', limit: '5' })
const res = await fetch(`https://app.shipos.co.il/api/v2/pickup-points?${params}`, {
headers: {
'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
'Accept': 'application/json',
},
})
const { data: points } = await res.json()
const nearest = points[0]
console.log(nearest.id, nearest.name, nearest.distance_km)<?php
// composer require guzzlehttp/guzzle
$client = new \GuzzleHttp\Client(['base_uri' => 'https://app.shipos.co.il/api/v2/']);
$response = $client->get('pickup-points', [
'headers' => [
'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
'Accept' => 'application/json',
],
'query' => [
'lat' => 32.0853,
'lng' => 34.7818,
'limit' => 5,
],
]);
$points = json_decode((string) $response->getBody(), true)['data'];
$nearest = $points[0] ?? null;<?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' => 5,
])
->throw()
->json('data');
$nearest = $points[0] ?? null;# 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": 5},
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"]
nearest = points[0] if points else None
print(nearest["id"], nearest["name"], nearest["distance_km"])package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
type nearestResponse struct {
Data []struct {
ID string `json:"id"`
Name string `json:"name"`
DistanceKm *float64 `json:"distance_km"`
} `json:"data"`
}
func main() {
query := url.Values{"lat": {"32.0853"}, "lng": {"34.7818"}, "limit": {"5"}}
endpoint := "https://app.shipos.co.il/api/v2/pickup-points?" + query.Encode()
req, _ := http.NewRequest("GET", endpoint, 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 nearestResponse
if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
panic(err)
}
nearest := payload.Data[0]
fmt.Println(nearest.ID, nearest.Name, *nearest.DistanceKm)
}// 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 ShipOsNearestPoint {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points"
+ "?lat=32.0853&lng=34.7818&limit=5"))
.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());
}
// data[0] היא הנקודה הקרובה ביותר — מפו עם Jackson/Gson
System.out.println(response.body());
}
}// .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?lat=32.0853&lng=34.7818&limit=5")
?? throw new InvalidOperationException("Empty response");
var nearest = payload.RootElement.GetProperty("data")[0];
Console.WriteLine($"{nearest.GetProperty("id").GetString()} " +
$"{nearest.GetProperty("name").GetString()} " +
$"{nearest.GetProperty("distance_km").GetDouble()} km");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: 5)
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)
nearest = JSON.parse(response.body).fetch("data").first
puts "#{nearest["id"]} #{nearest["name"]} #{nearest["distance_km"]}"// [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", "5")])
.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?;
let nearest = &payload["data"][0];
println!(
"{} {} {}",
nearest["id"], nearest["name"], nearest["distance_km"]
);
Ok(())
}אותה בקשה לפי כתובת במקום קואורדינטות:
# 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=5' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'// Node.js 18+ / דפדפנים — ללא תלויות
const params = new URLSearchParams({ address: 'הרצל 10, תל אביב', limit: '5' })
const res = await fetch(`https://app.shipos.co.il/api/v2/pickup-points?${params}`, {
headers: {
'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
'Accept': 'application/json',
},
})
const { data: points } = await res.json()
// distance_km נעדר כאשר לא הוגדר מפתח geocoding של הסוחר
const nearest = points[0]<?php
// composer require guzzlehttp/guzzle
$client = new \GuzzleHttp\Client(['base_uri' => 'https://app.shipos.co.il/api/v2/']);
$response = $client->get('pickup-points', [
'headers' => [
'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
'Accept' => 'application/json',
],
'query' => [
'address' => 'הרצל 10, תל אביב',
'limit' => 5,
],
]);
$points = json_decode((string) $response->getBody(), true)['data'];
$nearest = $points[0] ?? null;<?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' => 5,
])
->throw()
->json('data');
$nearest = $points[0] ?? null;# pip install httpx
import os
import httpx
response = httpx.get(
"https://app.shipos.co.il/api/v2/pickup-points",
params={"address": "הרצל 10, תל אביב", "limit": 5},
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"]
nearest = points[0] if points else None
print(nearest["id"], nearest.get("distance_km"))package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
type geocodedResponse struct {
Data []struct {
ID string `json:"id"`
Name string `json:"name"`
DistanceKm *float64 `json:"distance_km"`
} `json:"data"`
}
func main() {
query := url.Values{"address": {"הרצל 10, תל אביב"}, "limit": {"5"}}
endpoint := "https://app.shipos.co.il/api/v2/pickup-points?" + query.Encode()
req, _ := http.NewRequest("GET", endpoint, 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 geocodedResponse
if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
panic(err)
}
nearest := payload.Data[0]
fmt.Println(nearest.ID, nearest.Name, nearest.DistanceKm)
}// 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 ShipOsNearestByAddress {
public static void main(String[] args) throws Exception {
String address = URLEncoder.encode("הרצל 10, תל אביב", StandardCharsets.UTF_8);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.shipos.co.il/api/v2/pickup-points"
+ "?address=" + address + "&limit=5"))
.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":[...]} — מפו עם Jackson/Gson
}
}// .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 address = Uri.EscapeDataString("הרצל 10, תל אביב");
var payload = await http.GetFromJsonAsync<JsonDocument>(
$"pickup-points?address={address}&limit=5")
?? throw new InvalidOperationException("Empty response");
var nearest = payload.RootElement.GetProperty("data")[0];
Console.WriteLine($"{nearest.GetProperty("id").GetString()} " +
$"{nearest.GetProperty("name").GetString()}");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: 5)
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)
nearest = JSON.parse(response.body).fetch("data").first
puts "#{nearest["id"]} #{nearest["name"]} #{nearest["distance_km"]}"// [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", "5")])
.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?;
let nearest = &payload["data"][0];
println!("{} {}", nearest["id"], nearest["name"]);
Ok(())
}התגובה — הקרובה ביותר תחילה, distance_km בקילומטרים מנקודת המוצא שלכם:
{
"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": "קופיקס אלנבי",
"type": "store",
"address": {
"city": "תל אביב",
"street": "אלנבי",
"house": "3"
},
"coordinates": {
"latitude": 32.0737,
"longitude": 34.7688
},
"distance_km": 1.735
}
]
}שמרו את ה-id של הנקודה — זה מה שהמשלוח יפנה אליו.
טיפ
distance_km קיים רק כאשר סיפקתם נקודת מוצא (lat/lng מפורשים, או address שעבר geocoding בהצלחה). נקודות שאין להן קואורדינטות משלהן מקבלות distance_km: null וממוינות אחרונות. כשלי geocoding אף פעם לא מחזירים שגיאה — הם מתדרדרים לרשימה הלא-מדורגת.
שלב 3 — יצירת משלוח לנקודת איסוף
משלוח לנקודת איסוף הוא POST /shipments רגיל שבו ship_data.pickup נושא את ה-id של הנקודה משלב 2. שני דברים משתנים ביחס למשלוח עד הבית:
ship_data.pickup(מחרוזת, עד 64 תווים) — מזהה נקודת האיסוף. זה מה שמנתב את החבילה לנקודה.ship_data.pickup_address(מחרוזת, אופציונלי) — תווית קריאה לאדם של הנקודה, שנשמרת לצד המשלוח.ship_data.streetו-ship_data.cityאינם חובה כאשרship_data.pickupקיים (הם מוגדריםrequired_without:ship_data.pickup).
כל השאר נשאר לפי גוף היצירה הסטנדרטי: ship_data.type (1 = משלוח רגיל, 2 = איסוף), ship_data.return (1 = כיוון אחד, 2 = הלוך ושוב), ship_data.packages, שדות איש הקשר הנדרשים, ומעטפת order הנדרשת עם תמונת הנמען order.shipping שלה.
curl --location 'https://app.shipos.co.il/api/v2/shipments' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"license_key": "{license_key}",
"ship_data": {
"contact_name": "ישראל ישראלי",
"contact_phone": "0521234567",
"contact_mail": "israel@example.co.il",
"type": "1",
"return": "1",
"packages": 1,
"pickup": "12345",
"pickup_address": "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
"note": "שביר"
},
"order": {
"id": "1042",
"number": "1042",
"currency": "ILS",
"total": 249.90,
"shipping": {
"first_name": "ישראל",
"last_name": "ישראלי",
"phone": "0521234567",
"email": "israel@example.co.il",
"city": "תל אביב",
"country": "IL"
}
}
}'// Node.js 18+ / דפדפנים — ללא תלויות
const res = await fetch('https://app.shipos.co.il/api/v2/shipments', {
method: 'POST',
headers: {
'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
license_key: licenseKey,
ship_data: {
contact_name: 'ישראל ישראלי',
contact_phone: '0521234567',
contact_mail: 'israel@example.co.il',
type: '1',
return: '1',
packages: 1,
pickup: '12345',
pickup_address: 'סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב',
note: 'שביר',
},
order: {
id: '1042',
number: '1042',
currency: 'ILS',
total: 249.9,
shipping: {
first_name: 'ישראל',
last_name: 'ישראלי',
phone: '0521234567',
email: 'israel@example.co.il',
city: 'תל אביב',
country: 'IL',
},
},
}),
})
const { data: shipment } = await res.json()<?php
// composer require guzzlehttp/guzzle
$client = new \GuzzleHttp\Client(['base_uri' => 'https://app.shipos.co.il/api/v2/']);
$response = $client->post('shipments', [
'headers' => [
'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
'Accept' => 'application/json',
],
'json' => [
'license_key' => $licenseKey,
'ship_data' => [
'contact_name' => 'ישראל ישראלי',
'contact_phone' => '0521234567',
'contact_mail' => 'israel@example.co.il',
'type' => '1',
'return' => '1',
'packages' => 1,
'pickup' => '12345',
'pickup_address' => 'סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב',
'note' => 'שביר',
],
'order' => [
'id' => '1042',
'number' => '1042',
'currency' => 'ILS',
'total' => 249.90,
'shipping' => [
'first_name' => 'ישראל',
'last_name' => 'ישראלי',
'phone' => '0521234567',
'email' => 'israel@example.co.il',
'city' => 'תל אביב',
'country' => 'IL',
],
],
],
]);
$shipment = json_decode((string) $response->getBody(), true)['data'];<?php
use Illuminate\Support\Facades\Http;
$shipment = Http::withHeaders([
'X-Client-Id' => config('services.shipos.client_id'),
'X-Client-Secret' => config('services.shipos.client_secret'),
])
->acceptJson()
->post('https://app.shipos.co.il/api/v2/shipments', [
'license_key' => $licenseKey,
'ship_data' => [
'contact_name' => 'ישראל ישראלי',
'contact_phone' => '0521234567',
'contact_mail' => 'israel@example.co.il',
'type' => '1',
'return' => '1',
'packages' => 1,
'pickup' => '12345',
'pickup_address' => 'סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב',
'note' => 'שביר',
],
'order' => [
'id' => '1042',
'number' => '1042',
'currency' => 'ILS',
'total' => 249.90,
'shipping' => [
'first_name' => 'ישראל',
'last_name' => 'ישראלי',
'phone' => '0521234567',
'email' => 'israel@example.co.il',
'city' => 'תל אביב',
'country' => 'IL',
],
],
])
->throw()
->json('data');# pip install httpx
import os
import httpx
response = httpx.post(
"https://app.shipos.co.il/api/v2/shipments",
headers={
"X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
"X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
"Accept": "application/json",
},
json={
"license_key": license_key,
"ship_data": {
"contact_name": "ישראל ישראלי",
"contact_phone": "0521234567",
"contact_mail": "israel@example.co.il",
"type": "1",
"return": "1",
"packages": 1,
"pickup": "12345",
"pickup_address": "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
"note": "שביר",
},
"order": {
"id": "1042",
"number": "1042",
"currency": "ILS",
"total": 249.90,
"shipping": {
"first_name": "ישראל",
"last_name": "ישראלי",
"phone": "0521234567",
"email": "israel@example.co.il",
"city": "תל אביב",
"country": "IL",
},
},
},
)
response.raise_for_status()
shipment = response.json()["data"]package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
body := fmt.Sprintf(`{
"license_key": %q,
"ship_data": {
"contact_name": "ישראל ישראלי",
"contact_phone": "0521234567",
"contact_mail": "israel@example.co.il",
"type": "1",
"return": "1",
"packages": 1,
"pickup": "12345",
"pickup_address": "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
"note": "שביר"
},
"order": {
"id": "1042",
"number": "1042",
"currency": "ILS",
"total": 249.90,
"shipping": {
"first_name": "ישראל",
"last_name": "ישראלי",
"phone": "0521234567",
"email": "israel@example.co.il",
"city": "תל אביב",
"country": "IL"
}
}
}`, os.Getenv("SHIPOS_LICENSE_KEY"))
req, _ := http.NewRequest("POST",
"https://app.shipos.co.il/api/v2/shipments", strings.NewReader(body))
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("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
shipment, _ := io.ReadAll(res.Body)
fmt.Println(res.StatusCode, string(shipment))
}// 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 ShipOsCreatePickupShipment {
public static void main(String[] args) throws Exception {
String body = """
{
"license_key": "%s",
"ship_data": {
"contact_name": "ישראל ישראלי",
"contact_phone": "0521234567",
"contact_mail": "israel@example.co.il",
"type": "1",
"return": "1",
"packages": 1,
"pickup": "12345",
"pickup_address": "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
"note": "שביר"
},
"order": {
"id": "1042",
"number": "1042",
"currency": "ILS",
"total": 249.90,
"shipping": {
"first_name": "ישראל",
"last_name": "ישראלי",
"phone": "0521234567",
"email": "israel@example.co.il",
"city": "תל אביב",
"country": "IL"
}
}
}""".formatted(System.getenv("SHIPOS_LICENSE_KEY"));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.shipos.co.il/api/v2/shipments"))
.header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
.header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 201) {
throw new RuntimeException("ShipOS error: " + response.body());
}
System.out.println(response.body()); // {"data":{...}}
}
}// .NET 8+ — System.Net.Http.Json
using System.Net.Http.Json;
using System.Text;
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 licenseKey = Environment.GetEnvironmentVariable("SHIPOS_LICENSE_KEY");
var body = $$"""
{
"license_key": "{{licenseKey}}",
"ship_data": {
"contact_name": "ישראל ישראלי",
"contact_phone": "0521234567",
"contact_mail": "israel@example.co.il",
"type": "1",
"return": "1",
"packages": 1,
"pickup": "12345",
"pickup_address": "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
"note": "שביר"
},
"order": {
"id": "1042",
"number": "1042",
"currency": "ILS",
"total": 249.90,
"shipping": {
"first_name": "ישראל",
"last_name": "ישראלי",
"phone": "0521234567",
"email": "israel@example.co.il",
"city": "תל אביב",
"country": "IL"
}
}
}
""";
var response = await http.PostAsync("shipments",
new StringContent(body, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var payload = await response.Content.ReadFromJsonAsync<JsonDocument>()
?? throw new InvalidOperationException("Empty response");
var shipment = payload.RootElement.GetProperty("data");
Console.WriteLine(shipment.GetProperty("tracking_code").GetString());require "net/http"
require "json"
uri = URI("https://app.shipos.co.il/api/v2/shipments")
request = Net::HTTP::Post.new(uri)
request["X-Client-Id"] = ENV.fetch("SHIPOS_CLIENT_ID")
request["X-Client-Secret"] = ENV.fetch("SHIPOS_CLIENT_SECRET")
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
request.body = JSON.generate({
license_key: ENV.fetch("SHIPOS_LICENSE_KEY"),
ship_data: {
contact_name: "ישראל ישראלי",
contact_phone: "0521234567",
contact_mail: "israel@example.co.il",
type: "1",
return: "1",
packages: 1,
pickup: "12345",
pickup_address: "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
note: "שביר",
},
order: {
id: "1042",
number: "1042",
currency: "ILS",
total: 249.90,
shipping: {
first_name: "ישראל",
last_name: "ישראלי",
phone: "0521234567",
email: "israel@example.co.il",
city: "תל אביב",
country: "IL",
},
},
})
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)
shipment = JSON.parse(response.body).fetch("data")// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let body = json!({
"license_key": std::env::var("SHIPOS_LICENSE_KEY")?,
"ship_data": {
"contact_name": "ישראל ישראלי",
"contact_phone": "0521234567",
"contact_mail": "israel@example.co.il",
"type": "1",
"return": "1",
"packages": 1,
"pickup": "12345",
"pickup_address": "סופר-פארם דיזנגוף, דיזנגוף 50, תל אביב",
"note": "שביר"
},
"order": {
"id": "1042",
"number": "1042",
"currency": "ILS",
"total": 249.90,
"shipping": {
"first_name": "ישראל",
"last_name": "ישראלי",
"phone": "0521234567",
"email": "israel@example.co.il",
"city": "תל אביב",
"country": "IL"
}
}
});
let payload: Value = reqwest::Client::new()
.post("https://app.shipos.co.il/api/v2/shipments")
.header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
.header("X-Client-Secret", std::env::var("SHIPOS_CLIENT_SECRET")?)
.header("Accept", "application/json")
.json(&body)
.send()
.await?
.error_for_status()?
.json()
.await?;
println!("{}", payload["data"]["tracking_code"]);
Ok(())
}תגובת 201 — שימו לב ש-pickup_point_id מהדהד את הנקודה שבחרתם:
{
"data": {
"uuid": "9b2c7f1e-3a4d-4c88-9f21-2f0d5a6b7c88",
"tracking_code": "66747921",
"carrier": { "id": 3, "name": "HFD" },
"status": null,
"service_type": "1",
"is_active": true,
"recipient": {
"name": "ישראל ישראלי",
"phone": "0521234567",
"company": null,
"address": {
"street": null,
"number": null,
"city": "תל אביב",
"state": null,
"zip": null,
"country": "IL"
}
},
"pickup_point_id": "12345",
"packages": 1,
"cod": null,
"order": { "id": "1042", "number": "1042" },
"references": { "external_id": null },
"short_tracking_code": null,
"label_generated": false,
"collection_status": null,
"collected_at": null,
"ready_at": null,
"created_at": "2026-07-29T09:14:00.000000Z",
"updated_at": "2026-07-29T09:14:00.000000Z"
}
}הפכו את היצירה לבטוחה לניסיונות חוזרים
הוסיפו כותרת Idempotency-Key לבקשת היצירה כדי שניסיון חוזר ברשת לעולם לא ייצור חבילה שנייה. ראו אידמפוטנטיות.
שלב 4 — מעקב
השתמשו ב-uuid שהוחזר לקריאות מאומתות — GET /shipments/{shipment}, GET /shipments/{shipment}/status (מרענן מהמוביל), GET /shipments/{shipment}/label — או ב-GET /tracking/{code} הציבורי עם ה-tracking_code. פרטים במדריך העזר למשלוחים.
שגיאות נפוצות
| סטטוס | קוד | מתי |
|---|---|---|
| 403 | forbidden | ה-license_key אינו פעיל / פג תוקף / אינו בבעלותכם, או שלחשבון אין רישיון פעיל. |
| 409 | duplicate_request | יצירה של אותו משלוח לוגי כבר בתהליך — נסו שוב בעוד רגע. |
| 422 | validation_failed | הגוף נכשל בוולידציה (למשל חסרים street/city וגם אין pickup), או כמה רישיונות פעילים ללא license_key. |
| 424 | carrier_error | המוביל דחה את המשלוח (למשל מזהה של נקודה שכבר אינה קיימת). |