מעקב
מעקב אחר משלוח לפי קוד המעקב שלו, ללא מידע אישי מזהה (PII). התגובה חושפת בכוונה רק מידע על חברת השילוח והסטטוס, ולעולם לא פרטי נמען.
endpoint זה דורש אימות. הוא היה ציבורי עד שהתברר ש-shipping_code הוא המספר הרץ של חברת השליחויות — כל אחד יכול היה להגדיל אותו ולסרוק משלוחים ותוצאות מסירה של סוחרים אחרים. פרטי ההזדהות מצמצמים את החיפוש לרישיונות שלכם בלבד. עמוד המעקב שהלקוחות שלכם רואים הוא הקישור שנשלח ב-SMS האיסוף, לא ה-endpoint הזה.
GET /tracking/
איתור אחד המשלוחים שלכם לפי קוד המעקב שלו. אימות: client credentials. רישיון: אופציונלי — החיפוש משתרע על כל הרישיונות שבבעלותכם.
פרמטרים
נתיב
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
shipping_code | string | כן | קוד המעקב של חברת השליחויות (shipping_code) או קוד המעקב הקצר. |
בקשה לדוגמה
bash
curl --location 'https://app.shipos.co.il/api/v2/tracking/66747921' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'js
// Node.js 18+ — נדרשים פרטי הזדהות; אין לשלוח אותם לדפדפן
const code = '66747921'
const response = await fetch(`https://app.shipos.co.il/api/v2/tracking/${code}`, {
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: shipment } = await response.json()
console.log(shipment.tracking_code, shipment.carrier.name)
console.log(shipment.status?.description, shipment.status?.is_delivered)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',
],
]);
$shipment = json_decode(
$client->get('tracking/66747921')->getBody()->getContents(),
true,
)['data'];
echo $shipment['tracking_code'], ' ', $shipment['carrier']['name'], PHP_EOL;
echo $shipment['status']['description'] ?? 'no status', PHP_EOL;php
<?php
use Illuminate\Support\Facades\Http;
$shipment = Http::acceptJson()
->get('https://app.shipos.co.il/api/v2/tracking/66747921')
->throw()
->json('data');
logger()->info($shipment['tracking_code'].' '.$shipment['carrier']['name']);
logger()->info($shipment['status']['description'] ?? 'no status');python
# pip install httpx
import httpx
response = httpx.get(
"https://app.shipos.co.il/api/v2/tracking/66747921",
headers={
"X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
"X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
"Accept": "application/json",
},
)
response.raise_for_status()
shipment = response.json()["data"]
print(shipment["tracking_code"], shipment["carrier"]["name"])
print((shipment.get("status") or {}).get("description", "no status"))go
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type trackingResponse struct {
Data struct {
TrackingCode string `json:"tracking_code"`
Carrier struct {
Name string `json:"name"`
} `json:"carrier"`
Status *struct {
Description string `json:"description"`
IsDelivered bool `json:"is_delivered"`
} `json:"status"`
} `json:"data"`
}
func main() {
req, _ := http.NewRequest("GET",
"https://app.shipos.co.il/api/v2/tracking/66747921", nil)
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var payload trackingResponse
if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
panic(err)
}
fmt.Println(payload.Data.TrackingCode, payload.Data.Carrier.Name)
if payload.Data.Status != nil {
fmt.Println(payload.Data.Status.Description)
}
}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 ShipOsTracking {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.shipos.co.il/api/v2/tracking/66747921"))
.header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
.header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
.header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
.header("X-Client-Secret", std::env::var("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/"),
};
var payload = await http.GetFromJsonAsync<JsonDocument>("tracking/66747921")
?? throw new InvalidOperationException("Empty response");
var shipment = payload.RootElement.GetProperty("data");
Console.WriteLine($"{shipment.GetProperty("tracking_code").GetString()} " +
$"{shipment.GetProperty("carrier").GetProperty("name").GetString()}");
if (shipment.TryGetProperty("status", out var status) &&
status.ValueKind == JsonValueKind.Object)
{
Console.WriteLine(status.GetProperty("description").GetString());
}ruby
require "net/http"
require "json"
uri = URI("https://app.shipos.co.il/api/v2/tracking/66747921")
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)
shipment = JSON.parse(response.body).fetch("data")
puts "#{shipment["tracking_code"]} #{shipment.dig("carrier", "name")}"
puts shipment.dig("status", "description") || "no status"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/tracking/66747921")
.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 shipment = &payload["data"];
println!(
"{} {}",
shipment["tracking_code"], shipment["carrier"]["name"]
);
println!("{}", shipment["status"]["description"]);
Ok(())
}תגובה 200
json
{
"data": {
"tracking_code": "66747921",
"carrier": {
"id": 3,
"name": "HFD"
},
"status": {
"code": "delivered",
"description": "נמסר לנמען",
"is_delivered": true
},
"is_active": true,
"updated_at": "2026-07-28T09:14:33.000000Z"
}
}שדות תגובה
| שדה | סוג | תיאור |
|---|---|---|
tracking_code | string | קוד המעקב הציבורי של המשלוח. |
carrier | object | חברת השילוח (Provider): id ו-name. |
status | object | null | הסטטוס הנוכחי: code, description, is_delivered. מפתחות משנה עם ערך null מושמטים; האובייקט כולו הוא null כאשר לא ידוע סטטוס. |
is_active | bool | האם המשלוח פעיל. |
updated_at | string | חותמת זמן ISO-8601 של העדכון האחרון. |
שגיאות
| סטטוס | קוד | מתי |
|---|---|---|
| 404 | not_found | אף משלוח אינו תואם לקוד המעקב שסופק (No shipment found for this tracking code.). |