Exports
Exports are asynchronous CSV generation of your shipments. You queue an export, poll it for completion, then download the finished file. Generation streams rows to disk on a worker, so large merchants never block a request. The export covers the same shipments you would see when listing shipments, constrained by the optional filters you pass.
Exports are scoped to your whole account, not to one carrier. A merchant with several licenses gets a single file covering all of them, so license_key is neither required nor accepted — the API ignores it if sent.
Lifecycle
| Status | Meaning |
|---|---|
pending | Created; generation job queued. |
processing | The worker is writing the CSV. |
completed | File is ready. The export is emailed to you. download_url is null while the download route is disabled — see below. |
failed | Generation errored; see error. |
Only one export per license can be in flight at a time. Creating a second while one is still pending/processing returns 409 duplicate_request.
POST /exports
Queue an async shipments export (CSV build). Auth: client credentials. License: required.
Returns 202 Accepted — the file is not ready yet. Poll GET /exports/{export} until status is completed. The finished workbook is emailed to you; the /download route is currently disabled.
Parameters
Body
| Field | Type | Required | Description |
|---|---|---|---|
filter | object | no | Filter set constraining which shipments are exported (mirrors the shipments index). Any unsupplied filter is dropped. |
filter.active | boolean | no | Export only active (true) or inactive (false) shipments. Omit to export both. |
Example request
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 }
}'// Node.js 18+ / browsers — no dependencies
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) // poll GET /exports/{id}<?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; // poll GET /exports/{id}<?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']}");# 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"]) # poll GET /exports/{id}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) // poll GET /exports/{id}
}// 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 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",...}}
}
}// .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()}");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"]}"// [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(())
}Response 202
{
"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"
}
}Errors
| Status | code | When |
|---|---|---|
| 403 | forbidden | No usable license (inactive/expired/not owned). |
| 409 | duplicate_request | An export for this license is already pending/processing (An export is already being prepared for this license.). |
| 422 | validation_failed | filter is not an object, or filter.active is not a boolean. |
GET /exports/
Return a single export owned by the caller's license — the polling endpoint. Auth: client credentials. License: required.
Parameters
Path
| Field | Type | Required | Description |
|---|---|---|---|
export | integer | yes | The export id returned by create. |
Query
| Field | Type | Required | Description |
|---|
Example request
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'// Node.js 18+ / browsers — no dependencies
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()
// Poll until status === 'completed', then GET download_url.
console.log(exportJob.status, exportJob.row_count, exportJob.download_url)<?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'];
// Poll until status is 'completed', then fetch download_url.
echo $export['status'], ' ', $export['download_url'] ?? '-', PHP_EOL;<?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');
// Poll until status is 'completed', then fetch download_url.
logger()->info($export['status'], ['download_url' => $export['download_url']]);# 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"]
# Poll until export["status"] == "completed", then GET download_url.
print(export["status"], export["row_count"], export["download_url"])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)
}
// Poll until Status == "completed", then GET DownloadURL.
fmt.Println(export.Data.Status, export.Data.RowCount)
}// 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 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());
}
// Poll until data.status is "completed", then GET data.download_url.
System.out.println(response.body()); // {"data":{...}} — map with 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>(
"exports/812?license_key={license_key}")
?? throw new InvalidOperationException("Empty response");
var export = payload.RootElement.GetProperty("data");
// Poll until status is "completed", then GET download_url.
Console.WriteLine($"{export.GetProperty("status").GetString()} " +
$"{export.GetProperty("download_url")}");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")
# Poll until export["status"] == "completed", then GET download_url.
puts "#{export["status"]} #{export["row_count"]} #{export["download_url"]}"// [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"];
// Poll until export["status"] == "completed", then GET download_url.
println!("{} {}", export["status"], export["download_url"]);
Ok(())
}Response 200
{
"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"
}
}Response fields
| Field | Type | Description |
|---|---|---|
id | integer | Export id. |
type | string | Export discriminator; always shipments for this endpoint. |
status | string | pending, processing, completed, or failed. |
platform | string | Origin platform; always api_v2. |
row_count | integer | null | Number of data rows written. null until completed. |
filename | string | null | Suggested download filename. null until completed. |
error | string | null | Failure message when status is failed; null otherwise. |
download_url | string | null | Absolute URL to /download. Populated only when status is completed; null otherwise. |
created_at / updated_at | string | ISO-8601 timestamps. |
Errors
| Status | code | When |
|---|---|---|
| 403 | forbidden | No usable license. |
| 404 | not_found | No export with that id belongs to the caller's license (Export not found.). |
| 422 | validation_failed | The request body failed validation. |
GET /exports/{export}/download
Not currently available
This route is disabled in the current release, so download_url comes back null even on a completed export and calling the path returns 404. Retrieve the file through the dashboard, or the email the export sends when it finishes. The reference below is kept for when the route is re-enabled.
Stream the completed export file as a CSV download. Auth: client credentials. License: required.
On success the response is not the JSON envelope — it is the raw file streamed with a Content-Disposition: attachment header (filename = the export's filename). The export must be completed and its file must exist on disk.
Parameters
Path
| Field | Type | Required | Description |
|---|---|---|---|
export | integer | yes | The export id. |
Query
| Field | Type | Required | Description |
|---|
Example request
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// Node.js 18+ — the response is a file stream, not 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
// composer require guzzlehttp/guzzle
$client = new \GuzzleHttp\Client([
'headers' => [
'X-Client-Id' => getenv('SHIPOS_CLIENT_ID'),
'X-Client-Secret' => getenv('SHIPOS_CLIENT_SECRET'),
],
]);
// 'sink' streams straight to disk instead of buffering the body.
$client->get('https://app.shipos.co.il/api/v2/exports/812/download', [
'query' => ['license_key' => getenv('SHIPOS_LICENSE_KEY')],
'sink' => 'shipments.csv',
]);<?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());# 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)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 17+ — BodyHandlers.ofFile writes the stream straight to disk
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());
}
}
}// .NET 8+ — copy the response stream to a file
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);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// [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(())
}Response 200
Streamed CSV file (text/csv) sent as an attachment. There is no JSON body.
Errors
| Status | code | When |
|---|---|---|
| 403 | forbidden | No usable license. |
| 404 | not_found | Export not found for this license (Export not found.), or the export is not yet completed / its file is missing (Export file is not ready.). Poll GET /exports/{export} until status is completed before downloading. |
| 422 | validation_failed | The request body failed validation. |