Skip to content

ייצוא נתונים (Exports)

ייצוא הוא יצירת CSV אסינכרונית של המשלוחים שלכם. אתם מתזמנים ייצוא, מבצעים עליו polling עד להשלמה, ואז מורידים את הקובץ המוכן. היצירה מזרימה שורות לדיסק על worker, כך שסוחרים גדולים לעולם לא חוסמים בקשה. הייצוא מכסה את אותם משלוחים שהייתם רואים בעת הצגת רשימת משלוחים, בכפוף למסננים האופציונליים שאתם מעבירים.

כל ה-endpoints של ייצוא תחומים לרישיון: בוחרים את חשבון חברת השילוח באמצעות license_key (פרמטר query) = הערך של licenses.key. רישיון פעיל יחיד משמש כברירת מחדל; מספר רישיונות פעילים ללא license_key מחזיר 422; ללא רישיון / לא פעיל / פג תוקף / לא בבעלות מחזיר 403.

מחזור חיים

סטטוסמשמעות
pendingנוצר; משימת היצירה בתור.
processingה-worker כותב את ה-CSV.
completedהקובץ מוכן והייצוא נשלח אליכם במייל. ‏download_url הוא null כל עוד נתיב ההורדה מושבת — ראו להלן.
failedהיצירה נכשלה בשגיאה; ראו error.

רק ייצוא אחד לרישיון יכול להיות בתהליך בכל רגע. יצירת ייצוא שני בזמן שאחד עדיין pending/processing מחזירה 409 duplicate_request.


POST /exports

תזמון ייצוא משלוחים אסינכרוני (בניית CSV). אימות: client credentials. רישיון: חובה.

מחזיר 202 Accepted — הקובץ עדיין לא מוכן. בצעו polling ל-GET /exports/{export} עד ש-status הוא completed. הקובץ המוכן נשלח אליכם במייל; נתיב /download מושבת כרגע.

פרמטרים

Body

שדהסוגחובהתיאור
license_keystringחובה*ה-licenses.key הבוחר את חשבון חברת השילוח. אופציונלי כאשר לקורא יש בדיוק רישיון פעיל אחד.
filterobjectלאסט מסננים המגביל אילו משלוחים מיוצאים (משקף את אינדקס המשלוחים). כל מסנן שלא סופק מושמט.
filter.activebooleanלאייצוא רק משלוחים פעילים (true) או לא-פעילים (false). השמיטו כדי לייצא את שניהם.

דוגמת בקשה

bash
curl --location 'https://app.shipos.co.il/api/v2/exports' \
--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}",
  "filter": { "active": true }
}'
js
// Node.js 18+ / דפדפנים — ללא תלויות
const response = await fetch('https://app.shipos.co.il/api/v2/exports', {
  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: '{license_key}',
    filter: { active: true },
  }),
})

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

const { data: exportJob } = await response.json() // 202 Accepted

console.log(exportJob.id, exportJob.status) // בצעו polling ל-GET /exports/{id}
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->post('exports', [
    'json' => [
        'license_key' => '{license_key}',
        'filter' => ['active' => true],
    ],
]);

$export = json_decode($response->getBody()->getContents(), true)['data'];

echo $export['id'], ' ', $export['status'], PHP_EOL; // בצעו polling ל-GET /exports/{id}
php
<?php

use Illuminate\Support\Facades\Http;

$export = 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/exports', [
        'license_key' => '{license_key}',
        'filter' => ['active' => true],
    ])
    ->throw()
    ->json('data');

logger()->info("export {$export['id']} is {$export['status']}");
python
# pip install httpx
import os

import httpx

response = httpx.post(
    "https://app.shipos.co.il/api/v2/exports",
    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}", "filter": {"active": True}},
)
response.raise_for_status()
export = response.json()["data"]  # 202 Accepted

print(export["id"], export["status"])  # בצעו polling ל-GET /exports/{id}
go
package main

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

func main() {
	body, _ := json.Marshal(map[string]any{
		"license_key": "{license_key}",
		"filter":      map[string]any{"active": true},
	})

	req, _ := http.NewRequest("POST", "https://app.shipos.co.il/api/v2/exports",
		bytes.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("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")

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

	var payload struct {
		Data struct {
			ID     int    `json:"id"`
			Status string `json:"status"`
		} `json:"data"`
	}
	if err := json.NewDecoder(res.Body).Decode(&payload); err != nil {
		panic(err)
	}

	fmt.Println(payload.Data.ID, payload.Data.Status) // בצעו polling ל-GET /exports/{id}
}
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 ShipOsCreateExport {
    public static void main(String[] args) throws Exception {
        String body = """
            {"license_key":"{license_key}","filter":{"active":true}}
            """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.shipos.co.il/api/v2/exports"))
            .header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
            .header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
            .header("Accept", "application/json")
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

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

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

        System.out.println(response.body()); // {"data":{"status":"pending",...}}
    }
}
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 response = await http.PostAsJsonAsync("exports", new
{
    license_key = "{license_key}",
    filter = new { active = true },
});
response.EnsureSuccessStatusCode(); // 202 Accepted

var payload = await response.Content.ReadFromJsonAsync<JsonDocument>()
    ?? throw new InvalidOperationException("Empty response");
var export = payload.RootElement.GetProperty("data");

Console.WriteLine($"{export.GetProperty("id").GetInt32()} " +
    $"{export.GetProperty("status").GetString()}");
ruby
require "net/http"
require "json"

uri = URI("https://app.shipos.co.il/api/v2/exports")
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.dump({ license_key: "{license_key}", filter: { active: true } })

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)

export = JSON.parse(response.body).fetch("data") # 202 Accepted
puts "#{export["id"]} #{export["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()
        .post("https://app.shipos.co.il/api/v2/exports")
        .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(&serde_json::json!({
            "license_key": "{license_key}",
            "filter": { "active": true },
        }))
        .send()
        .await?
        .error_for_status()?
        .json()
        .await?;

    let export = &payload["data"];
    println!("{} {}", export["id"], export["status"]);
    Ok(())
}

תשובה 202

json
{
  "data": {
    "id": 812,
    "type": "shipments",
    "status": "pending",
    "platform": "api_v2",
    "row_count": null,
    "filename": null,
    "error": null,
    "download_url": null,
    "created_at": "2026-07-29T08:00:00.000000Z",
    "updated_at": "2026-07-29T08:00:00.000000Z"
  }
}

שגיאות

סטטוסקודמתי
403forbiddenאין רישיון שמיש (לא פעיל / פג תוקף / לא בבעלות).
409duplicate_requestייצוא עבור הרישיון הזה כבר pending/processing (‏An export is already being prepared for this license.).
422validation_failedfilter אינו object,‏ filter.active אינו boolean, או מספר רישיונות פעילים וללא license_key.

GET /exports/

החזרת ייצוא בודד בבעלות הרישיון של הקורא — ה-endpoint ל-polling. אימות: client credentials. רישיון: חובה.

פרמטרים

Path

שדהסוגחובהתיאור
exportintegerכןה-id של הייצוא שהוחזר ביצירה.

Query

שדהסוגחובהתיאור
license_keystringחובה*בוחר את חשבון חברת השילוח. אופציונלי עם רישיון פעיל יחיד.

דוגמת בקשה

bash
curl --location 'https://app.shipos.co.il/api/v2/exports/812?license_key={license_key}' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json'
js
// Node.js 18+ / דפדפנים — ללא תלויות
const url = new URL('https://app.shipos.co.il/api/v2/exports/812')
url.searchParams.set('license_key', '{license_key}')

const response = await fetch(url, {
  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: exportJob } = await response.json()

// בצעו polling עד ש-status === 'completed', ואז בצעו GET ל-download_url.
console.log(exportJob.status, exportJob.row_count, exportJob.download_url)
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('exports/812', [
    'query' => ['license_key' => '{license_key}'],
]);

$export = json_decode($response->getBody()->getContents(), true)['data'];

// בצעו polling עד ש-status הוא 'completed', ואז אחזרו את download_url.
echo $export['status'], ' ', $export['download_url'] ?? '-', PHP_EOL;
php
<?php

use Illuminate\Support\Facades\Http;

$export = 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/exports/812', [
        'license_key' => '{license_key}',
    ])
    ->throw()
    ->json('data');

// בצעו polling עד ש-status הוא 'completed', ואז אחזרו את download_url.
logger()->info($export['status'], ['download_url' => $export['download_url']]);
python
# pip install httpx
import os

import httpx

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

# בצעו polling עד ש-export["status"] == "completed", ואז בצעו GET ל-download_url.
print(export["status"], export["row_count"], export["download_url"])
go
package main

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

type exportResponse struct {
	Data struct {
		ID          int     `json:"id"`
		Status      string  `json:"status"`
		RowCount    *int    `json:"row_count"`
		DownloadURL *string `json:"download_url"`
	} `json:"data"`
}

func main() {
	req, _ := http.NewRequest("GET",
		"https://app.shipos.co.il/api/v2/exports/812?license_key={license_key}", 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 export exportResponse
	if err := json.NewDecoder(res.Body).Decode(&export); err != nil {
		panic(err)
	}

	// בצעו polling עד ש-Status == "completed", ואז בצעו GET ל-DownloadURL.
	fmt.Println(export.Data.Status, export.Data.RowCount)
}
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 ShipOsShowExport {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(
                "https://app.shipos.co.il/api/v2/exports/812?license_key={license_key}"))
            .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());
        }

        // בצעו polling עד ש-data.status הוא "completed", ואז בצעו GET ל-data.download_url.
        System.out.println(response.body()); // {"data":{...}} — מפו עם Jackson/Gson
    }
}
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>(
    "exports/812?license_key={license_key}")
    ?? throw new InvalidOperationException("Empty response");
var export = payload.RootElement.GetProperty("data");

// בצעו polling עד ש-status הוא "completed", ואז בצעו GET ל-download_url.
Console.WriteLine($"{export.GetProperty("status").GetString()} " +
    $"{export.GetProperty("download_url")}");
ruby
require "net/http"
require "json"

uri = URI("https://app.shipos.co.il/api/v2/exports/812")
uri.query = URI.encode_www_form(license_key: "{license_key}")

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)

export = JSON.parse(response.body).fetch("data")

# בצעו polling עד ש-export["status"] == "completed", ואז בצעו GET ל-download_url.
puts "#{export["status"]} #{export["row_count"]} #{export["download_url"]}"
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/exports/812")
        .query(&[("license_key", "{license_key}")])
        .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 export = &payload["data"];
    // בצעו polling עד ש-export["status"] == "completed", ואז בצעו GET ל-download_url.
    println!("{} {}", export["status"], export["download_url"]);
    Ok(())
}

תשובה 200

json
{
  "data": {
    "id": 812,
    "type": "shipments",
    "status": "completed",
    "platform": "api_v2",
    "row_count": 1436,
    "filename": "shipments-20260729080000.csv",
    "error": null,
    "download_url": "https://app.shipos.co.il/api/v2/exports/812/download",
    "created_at": "2026-07-29T08:00:00.000000Z",
    "updated_at": "2026-07-29T08:00:12.000000Z"
  }
}

שדות התשובה

שדהסוגתיאור
idintegerמזהה הייצוא.
typestringמבחין סוג הייצוא; תמיד shipments עבור ה-endpoint הזה.
statusstringpending,‏ processing,‏ completed או failed.
platformstringפלטפורמת המקור; תמיד api_v2.
row_countinteger | nullמספר שורות הנתונים שנכתבו. null עד completed.
filenamestring | nullשם קובץ מוצע להורדה. null עד completed.
errorstring | nullהודעת כשל כאשר status הוא failed; אחרת null.
download_urlstring | nullכתובת URL מוחלטת ל-/download. מאוכלס רק כאשר status הוא completed; אחרת null.
created_at / updated_atstringחותמות זמן ISO-8601.

שגיאות

סטטוסקודמתי
403forbiddenאין רישיון שמיש.
404not_foundאף ייצוא עם המזהה הזה אינו שייך לרישיון של הקורא (Export not found.).
422validation_failedמספר רישיונות פעילים וללא license_key.

GET /exports/{export}/download

אינו זמין כרגע

הנתיב הזה מושבת בגרסה הנוכחית, ולכן download_url חוזר כ-null גם עבור ייצוא שהושלם, וקריאה לנתיב מחזירה 404. אפשר להוריד את הקובץ דרך לוח הבקרה, או מהמייל שנשלח בסיום הייצוא. התיעוד שלהלן נשמר לקראת החזרת הנתיב.

הזרמת קובץ הייצוא המושלם כהורדת CSV. אימות: client credentials. רישיון: חובה.

בהצלחה התשובה היא לא מעטפת ה-JSON — זהו הקובץ הגולמי המוזרם עם כותרת Content-Disposition: attachment (שם הקובץ = ה-filename של הייצוא). הייצוא חייב להיות completed והקובץ שלו חייב להתקיים על הדיסק.

פרמטרים

Path

שדהסוגחובהתיאור
exportintegerכןה-id של הייצוא.

Query

שדהסוגחובהתיאור
license_keystringחובה*בוחר את חשבון חברת השילוח. אופציונלי עם רישיון פעיל יחיד.

דוגמת בקשה

bash
curl --location 'https://app.shipos.co.il/api/v2/exports/812/download?license_key={license_key}' \
--header 'X-Client-Id: {client_id}' \
--header 'X-Client-Secret: {client_secret}' \
--header 'Accept: application/json' \
--output shipments.csv
js
// Node.js 18+ — התשובה היא זרם קובץ, לא JSON
import { writeFile } from 'node:fs/promises'

const url = new URL('https://app.shipos.co.il/api/v2/exports/812/download')
url.searchParams.set('license_key', process.env.SHIPOS_LICENSE_KEY)

const response = await fetch(url, {
  headers: {
    'X-Client-Id': process.env.SHIPOS_CLIENT_ID,
    'X-Client-Secret': process.env.SHIPOS_CLIENT_SECRET,
  },
})

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

await writeFile('shipments.csv', Buffer.from(await response.arrayBuffer()))
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'headers' => [
        'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
        'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
    ],
]);

// 'sink' מזרים ישירות לדיסק במקום לאגור את הגוף.
$client->get('https://app.shipos.co.il/api/v2/exports/812/download', [
    'query' => ['license_key' => getenv('SHIPOS_LICENSE_KEY')],
    'sink' => 'shipments.csv',
]);
php
<?php

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

$response = Http::withHeaders([
    'X-Client-Id' => config('services.shipos.client_id'),
    'X-Client-Secret' => config('services.shipos.client_secret'),
])
    ->get('https://app.shipos.co.il/api/v2/exports/812/download', [
        'license_key' => config('services.shipos.license_key'),
    ])
    ->throw();

Storage::put('exports/shipments.csv', $response->body());
python
# pip install httpx
import os

import httpx

with httpx.stream(
    "GET",
    "https://app.shipos.co.il/api/v2/exports/812/download",
    params={"license_key": os.environ["SHIPOS_LICENSE_KEY"]},
    headers={
        "X-Client-Id": os.environ["SHIPOS_CLIENT_ID"],
        "X-Client-Secret": os.environ["SHIPOS_CLIENT_SECRET"],
    },
) as response:
    response.raise_for_status()
    with open("shipments.csv", "wb") as file:
        for chunk in response.iter_bytes():
            file.write(chunk)
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
)

func main() {
	query := url.Values{"license_key": {os.Getenv("SHIPOS_LICENSE_KEY")}}
	endpoint := "https://app.shipos.co.il/api/v2/exports/812/download?" + 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"))

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

	if res.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("ShipOS error: HTTP %d", res.StatusCode))
	}

	file, err := os.Create("shipments.csv")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	io.Copy(file, res.Body)
}
java
// Java 17+ — BodyHandlers.ofFile כותב את הזרם ישירות לדיסק
import java.net.URI;
import java.nio.file.Path;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ShipOsExportDownload {
    public static void main(String[] args) throws Exception {
        String url = "https://app.shipos.co.il/api/v2/exports/812/download"
            + "?license_key=" + System.getenv("SHIPOS_LICENSE_KEY");

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("X-Client-Id", System.getenv("SHIPOS_CLIENT_ID"))
            .header("X-Client-Secret", System.getenv("SHIPOS_CLIENT_SECRET"))
            .build();

        HttpResponse<Path> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofFile(Path.of("shipments.csv")));

        if (response.statusCode() != 200) {
            throw new RuntimeException("ShipOS error: HTTP " + response.statusCode());
        }
    }
}
csharp
// .NET 8+ — העתקת זרם התשובה לקובץ
using var http = new HttpClient();
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");
using var response = await http.GetAsync(
    $"https://app.shipos.co.il/api/v2/exports/812/download?license_key={licenseKey}",
    HttpCompletionOption.ResponseHeadersRead);

response.EnsureSuccessStatusCode();

await using var file = File.Create("shipments.csv");
await response.Content.CopyToAsync(file);
ruby
require "net/http"
require "uri"

uri = URI("https://app.shipos.co.il/api/v2/exports/812/download")
uri.query = URI.encode_www_form(license_key: ENV.fetch("SHIPOS_LICENSE_KEY"))

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

Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request) do |response|
    raise "ShipOS error: #{response.code}" unless response.is_a?(Net::HTTPSuccess)

    File.open("shipments.csv", "wb") do |file|
      response.read_body { |chunk| file.write(chunk) }
    end
  end
end
rust
// [dependencies]
// reqwest = { version = "0.12" }
// tokio = { version = "1", features = ["full"] }
use std::fs::File;
use std::io::Write;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let bytes = reqwest::Client::new()
        .get("https://app.shipos.co.il/api/v2/exports/812/download")
        .query(&[("license_key", std::env::var("SHIPOS_LICENSE_KEY")?)])
        .header("X-Client-Id", std::env::var("SHIPOS_CLIENT_ID")?)
        .header("X-Client-Secret", std::env::var("SHIPOS_CLIENT_SECRET")?)
        .send()
        .await?
        .error_for_status()?
        .bytes()
        .await?;

    File::create("shipments.csv")?.write_all(&bytes)?;
    Ok(())
}

תשובה 200

קובץ CSV מוזרם (text/csv) הנשלח כקובץ מצורף. אין גוף JSON.

שגיאות

סטטוסקודמתי
403forbiddenאין רישיון שמיש.
404not_foundהייצוא לא נמצא עבור הרישיון הזה (Export not found.), או שהייצוא עדיין לא completed / הקובץ שלו חסר (Export file is not ready.). בצעו polling ל-GET /exports/{export} עד ש-status הוא completed לפני ההורדה.
422validation_failedמספר רישיונות פעילים וללא license_key.