Pickup points
Lists the carrier pickup points available to the selected license. The points returned belong to the caller license's carrier: a HFD license returns HFD points, a Cargo license returns Cargo points, and so on. A carrier with no pickup network returns an empty list.
This endpoint is license-scoped: it operates under a single License chosen with the license_key query parameter, whose value is the License's key. With one active license it is used by default; with several, license_key is required (otherwise 422); a key that is missing, inactive, expired, or not owned returns 403.
GET /pickup-points
Return the selected license's carrier pickup points, optionally filtered by city and/or ranked nearest-first around an origin. Auth: client credentials. License: required.
Parameters
Query
| Field | Type | Required | Description |
|---|---|---|---|
license_key | string | conditional | The License key to act under. Required when the account owns more than one active license. |
city | string | no | Case-insensitive substring filter on the point's city (max 255 chars). |
limit | integer | no | Cap the number of points returned (min 1, capped at 500). Applied after ranking, so with an origin it yields the N closest. |
lat | number | no | Origin latitude (-90..90) for nearest-first ranking. Must be sent together with lng. |
lng | number | no | Origin longitude (-180..180) for nearest-first ranking. Must be sent together with lat. |
address | string | no | Free-text origin address (max 500 chars). Geocoded to coordinates for nearest-first ranking. Ignored when explicit lat/lng are supplied. |
How ranking works
By default the list is returned unranked (carrier order) and no distance_km is included.
To rank nearest-first you supply an origin, in one of two ways:
- Explicit coordinates — send both
latandlng. No geocoding, no API key needed. Sending only one of the pair is a validation error. - Address — send
address(and optionallycity, which is passed through to the geocoder). The address is geocoded using the merchant's own key: Google Geocoding when agoogle_api_keyis configured, otherwise Geoapify when ageoapify_api_keyis configured. If neither key is set, no geocoding call is made and the list is returned unranked. (Accounts created before 2025-08-10 fall back to a shared Google key.) Any geocoding failure — no key, provider error, or no match — degrades gracefully to an unranked list rather than erroring.
When an origin is resolved, each point gets a distance_km (great-circle distance from the origin, in kilometres, rounded to 3 decimals) and the list is sorted closest-first. Points that have no coordinates keep distance_km: null and sort last.
distance_km appears only when an origin was supplied (explicit lat/lng, or a successfully geocoded address). On a plain or city-only listing the key is absent.
Example request — plain list
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+ / browsers — no dependencies
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
// 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
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']);
}# 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"])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 17+ — java.net.http, no dependencies (parse with 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":[...]}
}
}// .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()}");
}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// [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(())
}Example request — city filter
curl --location 'https://app.shipos.co.il/api/v2/pickup-points?city=Tel%20Aviv&limit=50' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'// Node.js 18+ / browsers — no dependencies
const query = new URLSearchParams({ city: 'Tel Aviv', 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
// 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' => 'Tel Aviv', 'limit' => 50],
]);
$points = json_decode($response->getBody()->getContents(), true)['data'];
foreach ($points as $point) {
echo $point['id'], ' ', $point['name'], 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' => 'Tel Aviv',
'limit' => 50,
])
->throw()
->json('data');
foreach ($points as $point) {
logger()->info($point['id'].' '.$point['name']);
}# pip install httpx
import os
import httpx
response = httpx.get(
"https://app.shipos.co.il/api/v2/pickup-points",
params={"city": "Tel Aviv", "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"])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": {"Tel Aviv"}, "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 17+ — java.net.http, no dependencies (parse with 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("Tel Aviv", 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":[...]}
}
}// .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"] = "Tel Aviv";
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()}");
}require "net/http"
require "json"
uri = URI("https://app.shipos.co.il/api/v2/pickup-points")
uri.query = URI.encode_www_form(city: "Tel Aviv", 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// [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", "Tel Aviv"), ("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(())
}Example request — nearest by coordinates
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'// Node.js 18+ / browsers — no dependencies
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
// 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
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');
}# 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")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 17+ — java.net.http, no dependencies (parse with 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()); // nearest-first, with distance_km
}
}// .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");
}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// [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(())
}Example request — nearest by address
curl --location 'https://app.shipos.co.il/api/v2/pickup-points?address=Herzl%2010%2C%20Tel%20Aviv&limit=10' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'// Node.js 18+ / browsers — no dependencies
const query = new URLSearchParams({
address: 'Herzl 10, Tel Aviv',
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 is absent when geocoding could not resolve the address
for (const point of points) {
console.log(point.name, point.distance_km ?? 'unranked')
}<?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' => 'Herzl 10, Tel Aviv', 'limit' => 10],
]);
$points = json_decode($response->getBody()->getContents(), true)['data'];
foreach ($points as $point) {
echo $point['name'], ' ', $point['distance_km'] ?? 'unranked', 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', [
'address' => 'Herzl 10, Tel Aviv',
'limit' => 10,
])
->throw()
->json('data');
foreach ($points as $point) {
logger()->info($point['name'].' '.($point['distance_km'] ?? 'unranked'));
}# pip install httpx
import os
import httpx
response = httpx.get(
"https://app.shipos.co.il/api/v2/pickup-points",
params={"address": "Herzl 10, Tel Aviv", "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 is absent when geocoding could not resolve the address
for point in points:
print(point["name"], point.get("distance_km", "unranked"))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": {"Herzl 10, Tel Aviv"},
"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 17+ — java.net.http, no dependencies (parse with 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("Herzl 10, Tel Aviv", 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()); // unranked when geocoding failed
}
}// .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"] = "Herzl 10, Tel Aviv";
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}");
}require "net/http"
require "json"
uri = URI("https://app.shipos.co.il/api/v2/pickup-points")
uri.query = URI.encode_www_form(address: "Herzl 10, Tel Aviv", 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// [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", "Herzl 10, Tel Aviv"), ("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(())
}Response 200
Without an origin (plain / city-filtered list) — no distance_km:
{
"data": [
{
"id": "12345",
"name": "SuperPharm Dizengoff",
"type": "locker",
"address": {
"city": "Tel Aviv",
"street": "Dizengoff",
"house": "50"
},
"coordinates": {
"latitude": 32.0791,
"longitude": 34.7742
}
}
]
}With an origin (lat/lng or geocoded address) — distance_km present, nearest first:
{
"data": [
{
"id": "12345",
"name": "SuperPharm Dizengoff",
"type": "locker",
"address": {
"city": "Tel Aviv",
"street": "Dizengoff",
"house": "50"
},
"coordinates": {
"latitude": 32.0791,
"longitude": 34.7742
},
"distance_km": 0.842
},
{
"id": "67890",
"name": "Point with no geocode",
"type": "store",
"address": {
"city": "Tel Aviv",
"street": "Allenby",
"house": "3"
},
"coordinates": {
"latitude": null,
"longitude": null
},
"distance_km": null
}
]
}Pickup point fields
| Field | Type | Description |
|---|---|---|
id | string | Carrier-agnostic point id. |
name | string | null | Point display name. |
type | string | null | Point type as reported by the carrier (e.g. locker, store), when available. |
address.city | string | null | City. |
address.street | string | null | Street. |
address.house | string | null | House / street number. |
coordinates.latitude | number | null | Latitude, or null when the carrier did not provide one. |
coordinates.longitude | number | null | Longitude, or null when the carrier did not provide one. |
distance_km | number | null | Kilometres from the supplied origin. Present only when an origin was supplied; null for points without coordinates. |
Errors
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | Missing or invalid client credentials. |
| 403 | forbidden | Account has no active license, or the given license_key is inactive / expired / not owned by you. |
| 422 | validation_failed | Invalid query params (e.g. only one of lat/lng, out-of-range coordinates, limit < 1), or multiple active licenses and license_key omitted. |