LEGIT B2B · Developers · XML
XML feed
One permanent link with the whole LEGIT B2B catalogue — your net prices, stock per warehouse, logistics, GPSR data, documents and images — for importers that read a file. Your link is under Account → Export → XML, where you can also preview any product. Stock numbers (total and per warehouse) never go above 51 — 51 means more than 50.
We strongly recommend the API
The XML always carries the whole catalogue, so it is slow to import and stock is only as fresh as your last import. The REST API gives the same data and lets you refresh just prices and stock every few minutes — and you can place orders through it, drop-shipping included. The API page has a step-by-step move from XML.
Your link
It looks like https://b2b.legit.si/xml/<your-token>.xml?lang=sl,en. It is personal (it shows your prices), needs no login and never changes — put it straight into your importer. Keep it private, like a password.
lang— comma-separated languages (sl, en, hr, de, it, sr, bs, es, fr, pl, ro); defaultsl. Each text element is repeated per language with alangattribute.omit— sections to leave out, comma-separated:description,specifications,images,documents,safety,logistics,warehouses. Everything is included by default.ean— optional, comma-separated EANs (up to 50) to get only those products; handy for testing your importer.
Structure
One <product> per sellable variant inside <products>. Elements without a value are left out. Text is in CDATA; numbers use a dot as the decimal separator; prices are net (VAT excluded), the RRP includes VAT.
What each element means
The same fields as the API, so a later move to the API keeps every mapping. In the XML, logistics is the <package> element plus <customsTariff>, <countryOfOrigin> and, for a product shipped in several boxes, <extraPackages><box>…</box></extraPackages>; updatedAt is <updated>. Elements without a value (no restock date, no extra boxes) are left out.
| Field | Type | Meaning |
|---|---|---|
| productId, variantId | string | Our ids. One entry per sellable variant; variants of one product share productId. |
| ean | string | EAN / GTIN — the product identifier, always present. Match products by it. |
| model | string | null | Manufacturer model / MPN. |
| name, url, description | object (lang → string) | Per requested language. name falls back to the store language; description is HTML and may be missing. |
| options | object (lang → string) | Variant options of a several-variant product ("64GB + 2TB"); empty otherwise. |
| brand | { code, name } | null | |
| categories | [{ code, path }] | Deepest categories only; path is per language, e.g. "Computing > Computers > Mini PCs". |
| price | number | null | YOUR regular net price (without VAT), in currency — your partner price, without a special. |
| specialPrice | number | null | A special price that applies to you now (net, lower than price); null = none. You pay specialPrice when it is set, else price. |
| specialValidFrom, specialValidTo | string | null | The special price's first and last day (YYYY-MM-DD, both included); null = no start / no end. |
| specialQtyLimit | number | null | The most units the special price covers in total (since it started); null = no limit. |
| specialQtyLeft | number | null | Units you can still buy at the special price; null = no limit. Beyond it you pay price. |
| currency | string | ISO 4217, EUR. |
| vatRate | number | null | VAT % of the product in Slovenia (VAT is added on the invoice where it applies). |
| rrp | number | null | Recommended retail price, VAT included. |
| inStock | boolean | |
| stock | number | null | Units available now over all warehouses, Always a number, never above 51 (51 = more than 50). For a made-to-order product it is the quantity we can supply (inStock is then always true). |
| warehouses | [{ name, stock, deliveryDays }] | Per warehouse (e.g. "Ljubljana (B13)", "Šentjernej"), stock never above 51; deliveryDays = working days to deliver from that warehouse (null = not set). |
| deliveryDays | number | null | Working days to deliver: the fastest warehouse that has it in stock, else the product’s own delivery time. |
| restockDate | string | null | When an out-of-stock product is expected back (YYYY-MM-DD), set by our staff; null = not known. |
| incoming | { date, quantity, more } | null | More stock on order from our supplier: the earliest expected date (YYYY-MM-DD), the quantity then (at most 50; more = true above 50). null = nothing on order. |
| logistics | object | grossWeightKg, netWeightKg, lengthCm, widthCm, heightCm (package), unitsPerBox, customsTariff (HS / CN code), countryOfOrigin (ISO-2), extraPackages ([{ grossWeightKg, lengthCm, widthCm, heightCm }] — a product shipped in several boxes: every box after the first; empty otherwise). |
| warrantyMonths | number | null | |
| images | string[] | Absolute URLs, main image first. |
| specifications | object (lang → [{ group, name, value }]) | Technical specification rows. |
| attributes | object (lang → [{ group, groupCode, value, valueCode }]) | The product attributes our store filters by (colour, connection, size …). The codes stay the same in every language — map on them. |
| charging | { minPowerW, maxPowerW, powerDelivery, chargerIncluded } | null | Minimum / maximum charging power in watts (a number, may have decimals, e.g. 1.5; null = not entered); powerDelivery (USB Power Delivery) and chargerIncluded are always true or false. null = no charging data. |
| energyLabel | { eprelNumber, labelUrl, classLabelUrl, productSheetUrl } | null | EU energy label: the EPREL registration number and links to the energy label, the energy class label and the product information sheet; any field may be null. null = none. |
| manufacturer, euResponsiblePerson | { name, address, country, contact } | null | GPSR data. |
| safetyImages | string[] | Product safety images (GPSR). |
| documents | [{ title, language, url }] | Manuals, safety instructions, declarations (PDF). |
| updatedAt | string | null | ISO 8601, last change of the product data. |
Freshness and caching
- Product texts, specifications, images and documents refresh hourly.
- Prices and stock are at most 5 minutes old; the same link inside 5 minutes returns the same file.
- Please import the feed at most every 15 minutes (hourly is plenty for most shops).
- Hard limit: 120 requests per minute per account (HTTP 429 above it).
Changelog
- 2026-10-15 — version 1;
eanfilter. Products are identified by<ean>only (no separate SKU).
Questions: [email protected].