Query stock
This guide shows you how to get your stock levels from X-Sitter into your own system, for example to keep the stock in your online shop or ERP up to date. All you need is a token and a tool that can send HTTP requests (cURL, Postman, PHP, Python, JavaScript …).
For each article you get how many pieces are in which warehouse. The stock query does not show on which storage location the goods are.
Step 1: Check the requirements
- Your user has the menu entry Settings > API access (German: Einstellungen > API Zugang) in X-Sitter and may open the stock or product overview.
- Clients only: your logistician has made the stock visible to you. This is the same setting that lets you see your stock in X-Sitter itself. Without it, X-Sitter does not even offer you the permission Stock: read for a token. X-Sitter switches this setting ("Show stock", Lagerbestand zeigen) on at your logistician's request, so please talk to your logistician.
Step 2: Create a token
- In X-Sitter, click your name in the top right corner, then Settings.
- Choose API access on the left.
- In the API token section, enter a Name, e.g. "Stock sync shop".
- Optional: set a date under Valid until.
- Under Stock (Bestand), tick only read (lesen). The stock query needs no other permission.
- Click Create token.
- Use copy to take the token that is shown (it starts with
xst_) right away and store it safely in your system. It is shown only this one time.
The token is as valuable as a password. More about this in the overview.
Step 3: Send your first request
In the examples, replace xst_YOUR_TOKEN with your token. The first request fetches the first five articles with their stock:
curl "https://app.x-sitter.com/api/v1/stock?per_page=5" \
-H "Authorization: Bearer xst_YOUR_TOKEN"
<?php
$token = 'xst_YOUR_TOKEN';
$ch = curl_init('https://app.x-sitter.com/api/v1/stock?per_page=5');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($body, true);
print_r($status === 200 ? $result['data'] : $result['error']);
import requests
token = "xst_YOUR_TOKEN"
response = requests.get(
"https://app.x-sitter.com/api/v1/stock",
params={"per_page": 5},
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
result = response.json()
print(result["data"] if response.ok else result["error"])
const token = 'xst_YOUR_TOKEN';
const response = await fetch('https://app.x-sitter.com/api/v1/stock?per_page=5', {
headers: { Authorization: `Bearer ${token}` },
});
const result = await response.json();
console.log(response.ok ? result.data : result.error);
Always send the requests from your server, never from JavaScript in your customers' browsers. Otherwise every visitor can read your token.
If you get an error instead of data, the section
Step 4: Understand the response
A response looks like this:
{
"data": [
{
"article_id": "01999a3c-7e41-7b2a-9d0e-3f6c2a1b4e57",
"sku": "SKU-100",
"owner_company_id": 27,
"quantity": 120,
"quality_assurance": 8,
"warehouses": [
{
"id": "01999a3c-1111-7b2a-9d0e-3f6c2a1b4e57",
"name": "Erfurt",
"quantity": 120,
"quality_assurance": 8
}
]
}
],
"meta": { "page": 1, "per_page": 5, "total": 312, "total_pages": 63 }
}
Sellable stock
For your shop, what usually counts is quantity - quality_assurance, because blocked goods are not shipped. In the example above that is 120 − 8 = 112 pieces.
Good to know:
- The list contains all your articles, including those without stock (then
quantity: 0and emptywarehouses). Within_stock=trueyou only get articles with stock (step 5). - The stock is what lies on the storage locations in the warehouse. Goods for open orders keep counting until they have been booked off their location in the warehouse.
- The articles are sorted by article number.
Step 5: Fetch all pages
The list comes page by page, at most 500 articles per page. For a complete sync, request page after page until you reach total_pages.
<?php
$token = 'xst_YOUR_TOKEN';
$stock = [];
$page = 1;
do {
$url = 'https://app.x-sitter.com/api/v1/stock?' . http_build_query(['page' => $page, 'per_page' => 500]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$result = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException('X-Sitter API: ' . $result['error']['code']);
}
foreach ($result['data'] as $article) {
// Sellable stock = all pieces minus the ones blocked by quality assurance
$stock[$article['sku']] = $article['quantity'] - $article['quality_assurance'];
}
$page++;
} while ($page <= $result['meta']['total_pages']);
print_r($stock);
import requests
token = "xst_YOUR_TOKEN"
stock = {}
page = 1
while True:
response = requests.get(
"https://app.x-sitter.com/api/v1/stock",
params={"page": page, "per_page": 500},
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
result = response.json()
if not response.ok:
raise RuntimeError(f"X-Sitter API: {result['error']['code']}")
for article in result["data"]:
# Sellable stock = all pieces minus the ones blocked by quality assurance
stock[article["sku"]] = article["quantity"] - article["quality_assurance"]
if page >= result["meta"]["total_pages"]:
break
page += 1
print(stock)
const token = 'xst_YOUR_TOKEN';
const stock = {};
let page = 1;
let totalPages = 1;
do {
const url = new URL('https://app.x-sitter.com/api/v1/stock');
url.search = new URLSearchParams({ page, per_page: 500 });
const response = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
const result = await response.json();
if (!response.ok) {
throw new Error(`X-Sitter API: ${result.error.code}`);
}
for (const article of result.data) {
// Sellable stock = all pieces minus the ones blocked by quality assurance
stock[article.sku] = article.quantity - article.quality_assurance;
}
totalPages = result.meta.total_pages;
page++;
} while (page <= totalPages);
console.log(stock);
Narrow down the list
You can combine these parameters as you like:
curl "https://app.x-sitter.com/api/v1/stock?in_stock=true&per_page=100" \
-H "Authorization: Bearer xst_YOUR_TOKEN"
Step 6: Query a single article
If you know the article_id (from an earlier response), you get the stock of exactly this article:
curl "https://app.x-sitter.com/api/v1/stock/01999a3c-7e41-7b2a-9d0e-3f6c2a1b4e57" \
-H "Authorization: Bearer xst_YOUR_TOKEN"
The response has the same structure as one entry of the list, just directly under data and without meta. If you only have the article number, use the list with q=<article number> and pick the entry with the matching sku.
Step 7: Sync regularly
- A complete sync every 15 to 60 minutes is enough for most shops. Do not poll every second; the figures only change when something is booked in the warehouse.
- Use
per_page=500to need as few requests as possible. - Whether your system really uses the token can be seen in X-Sitter under Settings > API access in the column Last used.
- If you set an expiry date, create a new token in good time and swap it in your system.
For logisticians: query a client's stock
As a logistician, your token shows the stock of all articles you manage, including those of your clients (recognisable by owner_company_id). If you only want the articles of one particular client, send its company number in the header X-Company:
curl "https://app.x-sitter.com/api/v1/stock?in_stock=true" \
-H "Authorization: Bearer xst_YOUR_TOKEN" \
-H "X-Company: 27"
The "Show stock" setting plays no role here; it only applies to tokens the client creates itself.
If something does not work
You will find all errors and permissions at a glance in the overview. If you are stuck, contact support via Create ticket in the footer of X-Sitter. Send the time, the address and the response, but never your token.