Inventory CSV import API

inventory_v1

low6 fields · 3 required · 0 validatedPack · E-commerce

Import this template via API. Import per-SKU per-location inventory levels from CSV. Multilingual warehouse and stock-level hints.

30-second curl

curl -X POST https://api.adaptivmapr.com/v1/uploads \
  -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
  -F "template=inventory_v1" \
  -F "file=@your_data.csv"

At a glance

Pack
E-commerce
FHIR resource
Risk level
low
Fields
6 (3 required, 0 validated)

Why it exists

Why this template?

The Inventory template is the per-SKU per-location stock-level row. Each row carries a SKU (required), a location_id (required — multi-warehouse is the common case), on_hand (the physical count), an optional reserved (committed but not yet shipped), an optional last_counted_at timestamp, and an optional reorder_point. E-commerce and warehousing teams use this template for daily stock-sync jobs, for cycle-count reconciliation, and for migrations between warehouse-management systems. The composite key is (sku, location_id) — the cascade does not enforce it because primary-key constraints belong downstream, but the dry-run report flags duplicate composites so you can decide whether to sum, take the latest, or reject. The location_id field picks up Lager / entrepôt / magazzino / almacén / warehouse at zero cost.

on_hand is the only required numeric field — reserved and reorder_point are optional because not every warehouse tracks them. last_counted_at is a date, not a datetime, in most sources; the parser accepts both. The template does not derive available_to_promise (on_hand - reserved); that lives downstream so the formula can be customised per workspace.

Migration scenarios & common foreign headers

Migration scenarios for the Inventory template: daily stock-sync jobs from a WMS into a storefront, cycle-count reconciliation against the source of truth, WMS-to-WMS migrations during a fulfilment-provider swap, and multi-warehouse consolidation where regional stock files need to reconcile into one cross-region view. Foreign headers we see often: "SKU / Artikelnummer / Référence / Codice / Location / Lager / Entrepôt / Magazzino / Almacén / Warehouse / Bestand / Stock / Giacenza / Existencias / Reserved / Reserviert / Réservé / Riservato / Reservado / Last Counted / Letzte Zählung / Reorder Point / Nachbestellpunkt / Point de réapprovisionnement / Punto di riordino". The composite-key dry-run report flags duplicate (sku, location_id) pairs — the most common cause of mysterious stock overcounts in homegrown sync jobs.

Canonical columns

Schema

The canonical column set, with the type each row carries, whether it is required, the field-level validators that fire on commit, and the multilingual header hints the cascade resolves against.

ColumnTypeRequiredValidatorsHints
skustringyes
location_idstringyeslager · entrepôt · magazzino · almacén · warehouse
on_handnumberyesbestand · stock · giacenza · existencias
reservednumberreserviert · réservé · riservato · reservado
last_counted_atdate
reorder_pointnumbernachbestellpunkt · point de réapprovisionnement · punto di riordino

The cascade

How AdaptivMapr maps your headers to this template

Five layers run in order, cheapest first. Layer 1 (Statistics) auto-accepts headers that have been mapped the same way across past uploads. Layer 2 (Heuristic) compares your header to the column name, the optional label, and every registered hint (DE / FR / IT / EN / ES) after a Unicode-and-punctuation-normalising pass. Layer 3 (Fuzzy) catches typos and reordered words. Layer 4 (Semantic) uses cached embeddings to catch the long tail of paraphrases. Layer 5 (LLM) only fires on genuinely ambiguous columns, constrained to the template’s allowed column set so it cannot invent a field. When a layer auto-accepts, the lower-cost layers below it never run — that is the cost lever.

REST · POST /v1/uploads

Pass the template_id; the cascade picks up the rest.

curl -X POST https://api.adaptivmapr.com/v1/uploads \
  -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
  -F "template=inventory_v1" \
  -F "file=@your_data.csv"

The canonical template definition is read-only at GET /v1/templates/inventory_v1.

MCP · Cursor / Claude Desktop

Drop AdaptivMapr into your IDE. Schema-only calls need no key and draw only the small flat per-map fee.

// In Cursor or Claude Desktop with the AdaptivMapr MCP server installed:
adaptivmapr.match_headers({
  template: "inventory_v1",
  headers: ["sku", "location_id", "on_hand", "reserved"]
})
MCP install instructions →

Questions

FAQ — Inventory CSV import

How do I model lot or serial numbers?

Lot-level inventory needs a separate template — one row per lot per location. The canonical row is SKU-level because most catalogues are non-lotted.

Can on_hand be negative?

The validator does not reject negatives. Negative on_hand usually means an over-shipped or mis-counted SKU; flagging that is downstream business logic.

What about in-transit stock?

Model it as a separate location_id (e.g., "transit_seattle") or fork the template to add an `in_transit` field. The canonical row is per-physical-location.

How fresh is the last_counted_at field expected to be?

The template does not enforce freshness. Downstream business logic decides whether a stale count means "trust on_hand" or "block sale until recounted". The canonical row carries the timestamp; interpretation is per workspace.

Keep exploring

Browse other templates in the E-commerce pack

Inventory CSV import API — AdaptivMapr — AdaptivMapr