Stockkeeping Unit Table in Business Central: API & Schema

Complete reference for the Stockkeeping Unit (SKU) table in Microsoft Dynamics 365 Business Central: schema, relationships, API access, and query examples.

By Skuno Engineering Last reviewed Verified on BC26, BC27

At a glance

Table number5700
Object typeTable
Table classificationMaster
Data classificationCustomerContent
Primary key (clustered)Location Code, Item No., Variant Code
Secondary keysReplenishment System, Vendor No., Transfer-from Code; Item No., Location Code, Variant Code; Item No., Transfer-Level Code
Field count~80 (standard fields)
Microsoft REST APINot exposed in API v2.0
OData web servicePage-based OData (Page 5701) is being deprecated
Skuno BIGET /api/v2.0/odata/bc/Stockkeeping_Unit_5700
Versions coveredBC14 onwards

The Stockkeeping Unit table (table 5700) in Microsoft Dynamics 365 Business Central stores location- and variant-specific planning parameters for an item. Each row represents one combination of Item, Location, and Variant, and acts as a per-warehouse override of the planning, vendor, and replenishment settings on the underlying Item card. Stockkeeping Units are how Business Central models the reality that the same product can have a different reorder point in Auckland than it does in Wellington, or a different preferred vendor at a transit depot than at a retail store.

Microsoft API status

The Stockkeeping Unit table is not exposed in the Business Central REST API v2.0. There is no standard stockkeepingUnits endpoint. Historically the workaround was to publish Page 5701 (Stockkeeping Unit Card) as an OData web service, but Microsoft is deprecating the practice of exposing standard pages as APIs, so that path is no longer recommended for new integrations. The remaining options are to write a custom API page in AL and deploy it as an extension to every tenant, or to use Skuno BI, which exposes the table as a full OData v4 endpoint (https://<tenant>.skuno.app/api/v2.0/odata/bc/Stockkeeping_Unit_5700) without per-environment AL development.

That gap is bigger than it looks. Replenishment automation and planner-facing dashboards lean directly on SKU parameters, and most BC integrations work around the missing endpoint by pulling Items, joining against Inventory by Location, and re-deriving the SKU rules at runtime. The re-derivation is brittle: every time a planner edits an SKU directly in BC, the integration’s view of the world diverges from what planning actually uses.

When to use the Stockkeeping Unit table

Use Stockkeeping Unit when you need location- or variant-specific planning behaviour: a different reorder point, vendor, or lead time per location, transfer routing between warehouses, or per-location costing parameters. Use the Item table directly when those parameters are uniform across your operation. Use Item Variant alone when you have product variants (colour, size) that share planning settings across locations.

A useful rule of thumb: if your inventory planner ever says “we order more of X for the Auckland warehouse than for Wellington,” you should be using SKUs.

Query examples

The underlying schema is the same in every example below. What changes between them is the naming convention (AL field names vs. SQL bracketed names vs. OData-safe names), the filter syntax, and how much of the table you can actually see from the endpoint.

AL

var
    SKU: Record "Stockkeeping Unit";
begin
    SKU.SetRange("Location Code", 'BLUE');
    SKU.SetFilter("Reorder Point", '>0');
    if SKU.FindSet() then
        repeat
            // process each SKU
        until SKU.Next() = 0;
end;

SQL (on-prem only)

SELECT TOP 100
    [Location Code], [Item No_], [Variant Code],
    [Reorder Point], [Reorder Quantity], [Vendor No_]
FROM [CRONUS$Stockkeeping Unit$00000000-0000-0000-0000-000000000000]
WHERE [Location Code] = 'BLUE'
  AND [Reorder Point] > 0;

Direct SQL access is only supported on Business Central on-prem deployments; SaaS environments lock down the database.

Custom API page (AL)

page 50100 "Stockkeeping Unit API"
{
    PageType = API;
    SourceTable = "Stockkeeping Unit";
    APIPublisher = 'contoso';
    APIGroup = 'inventory';
    APIVersion = 'v1.0';
    EntityName = 'stockkeepingUnit';
    EntitySetName = 'stockkeepingUnits';
    DelayedInsert = true;
    ODataKeyFields = SystemId;

    layout
    {
        area(content)
        {
            repeater(Group)
            {
                field(itemNo; Rec."Item No.") { }
                field(variantCode; Rec."Variant Code") { }
                field(locationCode; Rec."Location Code") { }
                field(reorderPoint; Rec."Reorder Point") { }
                field(reorderQuantity; Rec."Reorder Quantity") { }
                field(vendorNo; Rec."Vendor No.") { }
            }
        }
    }
}

A custom API page is now the only Microsoft-supported way to expose the SKU table over HTTP from a SaaS tenant. It must be deployed as part of an AL extension to each environment that needs it.

Skuno BI (OData v4)

Skuno BI exposes Stockkeeping Unit as a full OData v4 endpoint. The path is tenant-scoped and table-numbered, so the table is addressable without any per-environment AL deployment.

The response is a superset of the base schema documented above: in addition to every base-table field, Skuno BI surfaces FlowFields evaluated server-side and any columns added by table extensions installed on the tenant. Microsoft’s Manufacturing module, for example, adds Production_BOM_No, Routing_No, Qty_on_Prod_Order, and the planned / firm-planned / released order receipt quantities; Warehouse, Service, and third-party apps add their own fields on the same record. The $metadata document at the endpoint root reflects whichever extensions are actually deployed on that tenant. If a field appears in your response that isn’t in the schema table above, it almost always came from a table extension rather than from the base SKU table.

GET https://mycompany.skuno.app/api/v2.0/odata/bc/Stockkeeping_Unit_5700
    ?$filter=Location_Code eq 'BLUE' and Reorder_Point gt 0
    &$select=Item_No,Variant_Code,Location_Code,Reorder_Point,Reorder_Quantity,Vendor_No
    &$top=100

A trimmed response:

{
	"@odata.context": "https://mycompany.skuno.app/api/v2.0/odata/bc/$metadata#Stockkeeping_Unit_5700",
	"value": [
		{
			"Item_No": "1000",
			"Variant_Code": "GREEN / L",
			"Location_Code": "",
			"Replenishment_System": "Purchase_0",
			"Reordering_Policy": "0",
			"Reorder_Point": "0",
			"Reorder_Quantity": "0",
			"Maximum_Inventory": "0",
			"Safety_Stock_Quantity": "0",
			"Lead_Time_Calculation": "",
			"Vendor_No": "",
			"Assembly_Policy": "Assemble_to_Stock_0",
			"Manufacturing_Policy": "Make_to_Stock_0",
			"Flushing_Method": "Manual_0",
			"Inventory": "0",
			"Qty_on_Purch_Order": "0",
			"Qty_on_Sales_Order": "0",
			"Qty_in_Transit": "0",
			"Last_Date_Modified": "2026-04-18",
			"Use_Cross_Docking": 1,
			"systemId": "{520273F8-E43A-F111-BEC2-6045BDC3ECAB}",
			"SystemCreatedAt": "2026-04-18T05:10:56.417Z",
			"SystemModifiedAt": "2026-04-18T05:10:56.417Z"
		}
	]
}

Standard OData query options apply: $filter, $select, $top, $skip, $orderby, and $count.

Gotchas

Field-number order vs. primary-key order. The fields are declared on the table in the order Item No. (1), Variant Code (2), Location Code (3). The clustered primary key, however, is Location Code, Item No., Variant Code (Key1). Integrations that build keys from fields[0..2] will get the order wrong; use the key definition, not the declaration order.

At least one of Location Code or Variant Code must be set. The OnInsert and OnRename triggers reject any SKU where both Location Code and Variant Code are blank. That’s just an Item, not an SKU. The error message refers to Text000 in the AL source.

Composite key, not a surrogate. There is no SKU No. integer column. Every join from another table needs all three columns, and a blank Variant Code counts as a distinct value, not “any variant.”

SKUs are optional and the absence of one matters. Business Central uses SKU planning parameters only when a row exists for the exact Item/Location/Variant combination being planned. If a planner deletes an SKU row, planning silently falls back to Item-level parameters, which is rarely what was intended. The OnInsert trigger calls PlanningAssignment.AssignOne to keep the requisition worksheet aware of new SKUs.

Quantity-on-hand is a FlowField, not a column. Inventory (field 68) is computed on demand from Item Ledger Entry; it doesn’t exist on the SKU row. SQL and OData consumers that select it without a CalcFields (or equivalent OData expansion) get zero. For warehouse-level on-hand, prefer Item Ledger Entry filtered by Item No., Location Code, and Variant Code directly.

Replenishment System change doesn’t backfill. Changing an SKU from Purchase to Transfer doesn’t reroute existing open purchase orders. The change only affects requisition-worksheet runs after the edit. It also recomputes Transfer-Level Code (field 5400) and rejects circular transfer graphs.

No base UoM override. The SKU table has no Unit of Measure Code field. Base UoM lives on the Item and applies across all SKUs. Field 7307 (Put-away Unit of Measure Code) is warehouse-only and doesn’t change costing or ledger units.

Transfer routes are required, not optional. Setting Transfer-from Code triggers CheckTransferRoute, which errors if no Transfer Route record exists between the two locations. SKUs cannot silently route around missing routes.

Published-page OData is being deprecated. Publishing Page 5701 (or any standard page) as an OData web service was the historical workaround for the missing API. Microsoft is winding that pattern down, and the page-based property names were always unstable, as they’re derived from the AL caption and can break when the page is edited. New integrations should use a custom API page in AL or a sync-based product like Skuno BI rather than starting on page-based OData today.

How Skuno BI exposes Stockkeeping Unit

Skuno BI surfaces the full Stockkeeping Unit table, including FlowFields and any columns added by Manufacturing, Warehouse, or other Microsoft (and third-party) table extensions installed on the tenant, as a queryable OData v4 endpoint at https://<tenant>.skuno.app/api/v2.0/odata/bc/Stockkeeping_Unit_5700. Item, Location, Item Ledger Entry, and the rest of the planning-relevant tables are exposed on the same convention, with the BC table number suffixed onto the resource name. Standard OData query options ($filter, $select, $top, $orderby, $count) work against any column, including FlowFields like Inventory and Qty_on_Purch_Order, which are evaluated server-side so consumers don’t have to mimic CalcFields. The endpoint is backed by an analytical column store, so filter performance doesn’t depend on the underlying BC SQL keys.

SKU data drives planning across every location in your business, and reading it out of your own database shouldn’t require an AL extension deployed to every tenant just to get an API page.

See how Skuno BI surfaces Business Central data →

Schema reference

#FieldTypeLengthDescriptionNotes
1Item No.Code20FK to Item (where Type = Inventory). NotBlank.Part of the composite primary key. Validating this field calls CopyFromItem, which seeds most planning fields from the Item card.
2Variant CodeCode10FK to Item Variant on (Item No., Variant Code).Part of the composite primary key. Blank counts as a distinct SKU, not “any variant.”
3Location CodeCode10FK to Location where Use As In-Transit = false.Part of the composite primary key. SKUs cannot be created at in-transit locations.
4DescriptionText (FlowField)100Lookup of Item.Description.FlowField, not stored on the SKU row. Empty until CalcFields runs.
12Shelf No.Code10Free-text shelf identifier for the SKU at this location.Not validated against the Bin or Warehouse Bin tables; purely informational.
22Unit CostDecimalPer-SKU unit cost. MinValue 0.For Standard-costed items, validating this also writes to Standard Cost. For other costing methods, errors if item ledger entries exist.
24Standard CostDecimalPer-SKU standard cost (Standard costing method only).Validation triggers ItemCostMgt.UpdateUnitCostSKU; changes are gated by a confirmation dialog when interactive.
25Last Direct CostDecimalMost recent direct purchase cost recorded for this SKU.Set by purchase posting; not a user-edited planning input.
31Vendor No.Code20Preferred vendor when replenishment is Purchase. FK to Vendor.On change, copies the vendor’s Lead Time Calculation into the SKU. Overrides the vendor on the Item card for this Location/Variant.
32Vendor Item No.Text50Vendor’s part number for this SKU.OptimizeForTextSearch is set; useful for vendor-facing exports.
33Lead Time CalculationDateFormulaLead time used by planning for purchase orders from the SKU vendor.Validated as non-negative via LeadTimeMgt. Falls back to vendor lead time, then item lead time, if blank.
34Reorder PointDecimalInventory level at which a replenishment is suggested.Per-location, per-variant; the main reason to use SKUs instead of an Item-only setup.
35Maximum InventoryDecimalTarget inventory level for Maximum Qty. policy.AccessByPermission Req. Wksh. Template = R. Order quantity = Maximum Inventory − Projected Inventory at order date.
36Reorder QuantityDecimalQuantity to order when reorder point is hit (Fixed Reorder Qty. policy).Ignored if the reordering policy is Maximum Qty. or Lot-for-Lot.
62Last Date ModifiedDateDate of last insert, modify, or rename.System-maintained from the OnInsert/OnModify/OnRename triggers. Read-only.
68InventoryDecimal (FlowField)Sum of Item Ledger Entry quantity for this Item/Location/Variant.FlowField; requires CalcFields. Honours Date Filter, Global Dimension 1/2 Filter, and Drop Shipment Filter.
84Qty. on Purch. OrderDecimal (FlowField)Outstanding base quantity on open purchase orders for this SKU.FlowField. AccessByPermission Purch. Rcpt. Header = R.
85Qty. on Sales OrderDecimal (FlowField)Outstanding base quantity on open sales orders for this SKU.FlowField. AccessByPermission Sales Shipment Header = R.
910Assembly PolicyEnum "Assembly Policy"Assemble-to-Stock or Assemble-to-Order.Assemble-to-Order requires Replenishment System = Assembly. AccessByPermission BOM Component = R.
5400Transfer-Level CodeIntegerDepth of this SKU in the transfer hierarchy (system-maintained).Editable = false. Recomputed by UpdateTransferLevels when Replenishment System or Transfer-from Code change. Used by the planning engine to order transfer suggestions.
5401Lot SizeDecimalStandard lot size for the SKU (manufacturing/assembly).Used in routing cost rollups; not the same as Reorder Quantity.
5410Discrete Order QuantityIntegerNumber of forecasted periods to combine into a single order.Lot-for-Lot policy only.
5411Minimum Order QuantityDecimalLower bound applied to planning-suggested order quantities.MinValue 0.
5412Maximum Order QuantityDecimalUpper bound applied to planning-suggested order quantities.AccessByPermission Req. Wksh. Template = R.
5413Safety Stock QuantityDecimalBuffer inventory added to projected demand.AccessByPermission Req. Wksh. Template = R. Treated as a hard floor by planning, not just a forecasting hint.
5414Order MultipleDecimalRounding multiple for planning-suggested order quantities.AccessByPermission Req. Wksh. Template = R.
5415Safety Lead TimeDateFormulaExtra lead time added to planning calculations beyond Lead Time Calculation.AccessByPermission Req. Wksh. Template = R. Validated as non-negative.
5416Components at LocationCode10Where components are consumed for assembly/production orders. FK to Location.When blank, falls back to the Inventory Setup default.
5417Flushing MethodEnum (Manufacturing "Flushing Method")Manual, Forward, Backward, Pick + Forward, Pick + Backward.Drives how component consumption is posted on production orders.
5419Replenishment SystemEnum "Replenishment System"Purchase, Prod. Order, Transfer, or Assembly.Drives planning behaviour. Switching to Transfer requires a non-blank Location Code; switching to Assembly forces Assembly Policy = Assemble-to-Stock unless Assemble-to-Order is intentional. OnValidate recomputes Transfer-Level Code.
5428Time BucketDateFormulaGranularity of planning periods for this SKU.Validated as non-negative.
5440Reordering PolicyEnum "Reordering Policy"Blank, Fixed Reorder Qty., Maximum Qty., Order, or Lot-for-Lot.Combines with Replenishment System to determine planning logic. OnValidate auto-toggles Include Inventory for Lot-for-Lot / Maximum Qty. / Fixed Reorder Qty.
5441Include InventoryBooleanWhether projected inventory is netted against demand by planning.Auto-set by Reordering Policy validation; can be overridden manually for custom policies.
5442Manufacturing PolicyEnum (Manufacturing "Manufacturing Policy")Make-to-Order or Make-to-Stock.Relevant only when Replenishment System = Prod. Order.
5443Rescheduling PeriodDateFormulaWindow within which planning will reschedule an existing supply rather than create a new one.Validated as non-negative.
5444Lot Accumulation PeriodDateFormulaWindow over which demand is consolidated into a single supply (Lot-for-Lot).Validated as non-negative.
5445Dampener PeriodDateFormulaMinimum time gap before planning suggests rescheduling forward.Validated as non-negative. Suppresses small reschedule-forward churn.
5446Dampener QuantityDecimalMinimum quantity change before planning suggests a quantity adjustment.MinValue 0. Suppresses small qty-change churn.
5447Overflow LevelDecimalInventory level above which planning suggests reducing supply.MinValue 0.
5448Plan Minimal SupplyBooleanWhen true, planning prefers smaller, more-frequent supply suggestions.Interacts with Reorder Quantity and Order Multiple.
5700Transfer-from CodeCode10Source location for Transfer replenishment. FK to Location where Use As In-Transit = false.Required when Replenishment System = Transfer. OnValidate walks the transfer graph to refresh Transfer-Level Code and rejects circular routes; must have a Transfer Route record between the two locations.
5701Qty. in TransitDecimal (FlowField)Sum of base quantity in transit toward this Location.FlowField over Transfer Line where Derived From Line No. = 0.
7302Put-away Template CodeCode10Default put-away template at this Location.FK to Put-away Template Header.
7307Put-away Unit of Measure CodeCode10Default unit of measure used during warehouse put-away.FK to Item Unit of Measure on (Item No., Code). This is the only UoM field on the SKU. There is no base-UoM override per SKU; base UoM lives on the Item.
7380Phys Invt Counting Period CodeCode10Counting frequency for cycle counts on this SKU.Validation recomputes Next Counting Start Date and Next Counting End Date.
7384Use Cross-DockingBooleanWhether cross-docking is enabled for this SKU.InitValue = true. AccessByPermission Bin Content = R.

Relationships

Related tableRelationshipForeign keyNotes
Itemmany-to-oneItem No.Every SKU rolls up to one item; the item record holds defaults the SKU overrides. Restricted to items with Type = Inventory.
Locationmany-to-oneLocation CodeSKUs exist per physical or logical inventory location. In-transit locations are excluded.
Item Variantmany-to-oneItem No., Variant CodeOptional; a blank Variant Code is a valid (and distinct) SKU.
Vendormany-to-oneVendor No.Optional. Overrides the Item card vendor for this Location/Variant.
Location (Transfer-from)many-to-oneTransfer-from CodeSource location for transfer replenishment. Must have a Transfer Route to Location Code.
Item Ledger Entryone-to-manyItem No., Location Code, Variant CodeNot a true FK: joined on the composite key, not on a ‘SKU No.’ column.
Stockkeeping Unit Comment Lineone-to-manyItem No., Variant Code, Location CodeOptional free-form comment lines per SKU. Deleted by the SKU OnDelete trigger.
Planning Assignmentone-to-manyItem No., Variant Code, Location CodeAuto-maintained by OnInsert (AssignOne) and OnModify (SKUChange). Drives which Item/Location/Variant combinations the requisition worksheet evaluates.

Frequently asked questions

What is the Stockkeeping Unit table in Business Central?

The Stockkeeping Unit (SKU) table (table 5700) in Microsoft Dynamics 365 Business Central stores location- and variant-specific planning and replenishment parameters for an item. Each row represents one combination of Item, Location, and Variant. SKUs let you set different reorder points, vendors, lead times, and replenishment systems per warehouse without duplicating items.

Is the Stockkeeping Unit table exposed via the Business Central API?

No. Stockkeeping Unit is not part of the Business Central REST API v2.0 surface. Microsoft is also deprecating the practice of publishing standard pages (like Page 5701) as OData web services, so that workaround is no longer a durable option. To access SKU data programmatically, the supported paths are to build a custom API page in AL and deploy it as an extension to each tenant, or to use Skuno BI, which exposes the table as a full OData v4 endpoint at https://<tenant>.skuno.app/api/v2.0/odata/bc/Stockkeeping_Unit_5700.

What's the difference between an Item and a Stockkeeping Unit?

An Item is global: it defines the product itself, its base UoM, costing method, and item category. A Stockkeeping Unit is per-location and per-variant and overrides planning, vendor, and (where applicable) cost settings for that specific combination. If you only operate from one location and don’t use variants, you don’t need SKUs at all. If you have multiple warehouses with different lead times or vendors, SKUs are how you express that.

How do I create Stockkeeping Units in bulk?

Business Central includes a Create Stockkeeping Unit batch job (report 5706) that generates SKUs for combinations of items, locations, and variants based on filters you supply. The batch can copy default values from the Item card and from a chosen ’template’ SKU. For programmatic bulk creation, write an AL codeunit that constructs records and calls CopyFromItem, or use a custom API page.

Why doesn't my Stockkeeping Unit's reorder point trigger a planning suggestion?

The most common causes are: (1) the SKU’s Reordering Policy is blank, (2) Stockkeeping Unit Exists is false at the item-location combination being planned, or (3) the requisition worksheet is being run against the Item rather than the SKU. Business Central uses the SKU’s parameters only when an SKU row exists for the exact Item/Location/Variant triple.

Can a Stockkeeping Unit override the base unit of measure?

No. The SKU table has no base-UoM field, base UoM is set on the Item card and applies across all SKUs for that item. The only UoM-related field on the SKU is Put-away Unit of Measure Code (field 7307), which controls warehouse put-away behaviour, not the base unit of measure used in costing or ledger entries.

Which Business Central versions include the Stockkeeping Unit table?

Stockkeeping Unit has existed since NAV 4.0 and is present in every supported Business Central version, including BC14 through BC27. The schema has been stable; recent additions are around item tracking and warehouse classification rather than the core planning columns. Replenishment System and Reordering Policy migrated from Option to Enum types but kept the same field numbers and values.