Sync stock levels from another system
Your other system knows how many there should be. Post the difference as one logbook line per item, safe to re-run.
Say a supplier portal or your web shop says you have 72 AA batteries, and you want ItemTally to agree. You can’t set a quantity, but you can post the difference: read what ItemTally has, subtract, and adjust by the gap. The logbook then shows exactly when and why the number moved.
You need a read and write key.
1. Match the item
Match on a code both systems share. A barcode you’ve attached, or the ItemTally QR you stored on your side, works best:
curl "https://api.itemtally.com/v1/items/lookup?value=IT-000016" \
-H "Authorization: Bearer $ITEMTALLY_KEY"
{ "folderId": null, "itemId": "7f1c2a4e-0b7d-4c55-9a51-2f0e8d3c6b10" }
2. Read the quantity and post the gap
curl https://api.itemtally.com/v1/items/7f1c2a4e-0b7d-4c55-9a51-2f0e8d3c6b10 \
-H "Authorization: Bearer $ITEMTALLY_KEY"
# … "quantity": 48 …
curl -X POST https://api.itemtally.com/v1/items/7f1c2a4e-0b7d-4c55-9a51-2f0e8d3c6b10/adjust \
-H "Authorization: Bearer $ITEMTALLY_KEY" \
-H "Content-Type: application/json" \
-d '{"delta": 24, "reason": "Sync from supplier portal", "movementId": "c8f5e2a1-7d4b-4f3e-9a6c-1b2d3e4f5a61"}'
{ "quantity": 72 }
Skip the call when the gap is zero: a delta of 0 is refused.
The whole sync, in JavaScript
const API = "https://api.itemtally.com/v1";
const headers = {
Authorization: `Bearer ${process.env.ITEMTALLY_KEY}`,
"Content-Type": "application/json",
};
async function api(path, init = {}) {
const res = await fetch(`${API}${path}`, { ...init, headers });
const body = await res.json();
if (!res.ok) throw new Error(`${res.status} ${body.code}: ${body.message}`);
return body;
}
// What the other system says: code → how many there should be.
const target = { "IT-000016": 72, "IT-000007": 21 };
for (const [code, wanted] of Object.entries(target)) {
const { itemId } = await api(`/items/lookup?value=${encodeURIComponent(code)}`);
if (!itemId) {
console.warn(`No item for ${code}`);
continue;
}
const item = await api(`/items/${itemId}`);
const delta = wanted - item.quantity;
if (delta === 0) continue;
const { quantity } = await api(`/items/${itemId}/adjust`, {
method: "POST",
body: JSON.stringify({
delta,
reason: "Sync from supplier portal",
movementId: crypto.randomUUID(),
}),
});
console.log(`${item.name}: ${item.quantity} → ${quantity}`);
}
Make it safe to re-run
- Retries. If a request times out, you can’t tell whether it landed. Reuse the same
movementIdfor the retry and it’s applied once. Generate the id when you decide on the change, and keep it until the call succeeds. - Someone changes stock mid-sync. The read and the adjust are two calls, so a hand-over in between makes your gap slightly off. Run the sync when the floor is quiet, or re-run it: the second pass posts the small remainder.
- Which side wins. This recipe makes the other system the truth. If people also count stock in ItemTally, decide who wins per item, or sync the other way with webhooks on
movement.posted. - Volume. Each item is two reads and one write, well inside 600 reads and 120 writes a minute for a few hundred items. For thousands, space the writes out or watch
RateLimit-Remaining.
Stuck on an integration? Email [email protected] with the request you sent and the response you got. The person who built the API answers, usually within a business day.