Skip to content

מעקב

מעקב אחר משלוח לפי קוד המעקב שלו, ללא מידע אישי מזהה (PII). התגובה חושפת בכוונה רק מידע על חברת השילוח והסטטוס, ולעולם לא פרטי נמען.

endpoint זה דורש אימות. הוא היה ציבורי עד שהתברר ש-shipping_code הוא המספר הרץ של חברת השליחויות — כל אחד יכול היה להגדיל אותו ולסרוק משלוחים ותוצאות מסירה של סוחרים אחרים. פרטי ההזדהות מצמצמים את החיפוש לרישיונות שלכם בלבד. עמוד המעקב שהלקוחות שלכם רואים הוא הקישור שנשלח ב-SMS האיסוף, לא ה-endpoint הזה.

GET /tracking/

איתור אחד המשלוחים שלכם לפי קוד המעקב שלו. אימות: client credentials. רישיון: אופציונלי — החיפוש משתרע על כל הרישיונות שבבעלותכם.

פרמטרים

נתיב

שדהסוגחובהתיאור
shipping_codestringכןקוד המעקב של חברת השליחויות (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_codestringקוד המעקב הציבורי של המשלוח.
carrierobjectחברת השילוח (Provider): id ו-name.
statusobject | nullהסטטוס הנוכחי: code, description, is_delivered. מפתחות משנה עם ערך null מושמטים; האובייקט כולו הוא null כאשר לא ידוע סטטוס.
is_activeboolהאם המשלוח פעיל.
updated_atstringחותמת זמן ISO-8601 של העדכון האחרון.

שגיאות

סטטוסקודמתי
404not_foundאף משלוח אינו תואם לקוד המעקב שסופק (No shipment found for this tracking code.).