Quick answer

How an SAP BOM upload from Excel works

CS01 in SAP creates a material bill of material: a header for one material, plant, BOM usage and alternative, and one item per component with its item category, quantity and unit. An SAP BOM upload from Excel with PostNow.ai puts one header row per BOM and one detail row per component in a template mapped to BAPI_MATERIAL_BOM_GROUP_CREATE or to a CS01 recording, so a parts list becomes a CS01 mass upload in one run. Validate checks the sheet offline, Simulate lets SAP check every BOM and rolls it back, and Run writes SAP's message back to each header row.

  • Materials come before BOMs. The header material and every component material must exist in the plant before the bill of materials upload starts.
  • Load a multi-level BOM upload level by level. Lowest sub-assemblies first, finished products last, so each level can be exploded and checked as it lands.

This page covers one job: creating SAP bills of material in bulk from Excel, including multi-level structures, and changing them afterwards with CS02. The materials those BOMs name are created first, as described in MM01 mass material creation. The other master data objects and the order to load them in are in SAP master data mass upload.

How PostNow.ai runs an SAP BOM upload from Excel

PostNow.ai treats a CS01 mass upload as a template: a designer builds it once against your SAP system and publishes it, and the engineering or master data team runs its own parts lists through it, each user under their own SAP login on their own computer.

  1. Pick the interface in your own system. Search for BAPI_MATERIAL_BOM_GROUP_CREATE by name in PostNow.ai's BAPI search, or record CS01 in SHDB. The free CS01 bill of material template gives you the column layout and is mapped to CSAP_MAT_BOM_CREATE; use that mapping where SE37 shows the module as remote-enabled in your system (the route section below explains the check).
  2. One H row per BOM, one D row per component. A marker column groups an H row (material, plant, BOM usage, valid-from date, change number, base quantity and unit) with its D rows (item number, item category, component, quantity, unit). A BOM reference column keeps each header and its components together, so a 40-item BOM is one H row and 40 D rows.
  3. Validate the sheet. Validate checks every cell offline: required fields, type, length, date format and allowed values, such as an allow-list of BOM usages and item categories. Whether a component exists in the plant is SAP's answer, and that comes in Simulate.
  4. Simulate. In BAPI mode PostNow.ai calls the interface for every BOM and then BAPI_TRANSACTION_ROLLBACK instead of a commit, so SAP's own messages appear on each H row and no BOM is created. On a recording, Simulate walks the CS01 screens without saving.
  5. Run. In BAPI mode PostNow.ai commits each BOM with BAPI_TRANSACTION_COMMIT only when SAP returned no error, and otherwise rolls it back; a recording saves through CS01 itself. SAP's message lands on the H row, next to its Run Log entry with user, time and system.
  6. Re-run only what failed. Retry Failed re-posts only the BOMs marked ERROR. If someone clicks Run again on the same sheet, PostNow.ai first lists the BOMs whose Run Log already shows a success and offers Skip posted rows before anything is sent to SAP.

Where engineering wants a second pair of eyes on new structures, an approval policy on the template holds the run until an approver has reviewed the rows in the PostNow.ai portal. The approval is tied to that exact data, so a sheet changed after approval needs approval again.

BOM header and items: what each row carries

In a PostNow.ai CS01 template the H row identifies the BOM and the D rows describe its components. CS01 asks for the same split: the initial screen takes the key, the item overview takes the components.

FieldRowWhat it decides
Material, plantHThe product the BOM describes and the plant it is valid in. Both must exist before the run.
BOM usageHWhich areas may use the BOM, such as production or engineering (next section)
Alternative BOMHWhich of several BOMs for the same material, plant and usage this one is: 1, 2, 3 and so on
Valid from, change numberHThe date the structure takes effect, and the engineering change it belongs to where change management is used
Base quantity, base unitHThe quantity of the header material that the component quantities refer to
Item numberDThe item's position: 0010, 0020 and so on, spaced so items can be inserted later
Item categoryDWhat kind of component it is: stock, non-stock, text and others (next section)
Component, quantity, unitDThe component material and how much of it the base quantity needs
Fixed quantity, component scrapDA quantity that does not scale with the lot size, and a planned scrap percentage

Agree the base quantity before you build the file. Component quantities are per base quantity, not per piece. A BOM with base quantity 100 and a component quantity of 4 needs 0.04 per piece; the same 4 against base quantity 1 needs 4 per piece. A file that assumes 1 while the BOM says 100 creates a structure that is out by a factor of 100, and SAP accepts it without a message. Engineering tends to think per piece; process industries often state recipes per 100 or per 1,000.

⚠
A wrong quantity raises no error. SAP checks that the component exists in the plant, not whether 3.4 kg of shaft stock is right for one drive shaft. MRP explodes the BOM into component demand and product costing rolls it up into the standard cost, so a wrong quantity shows up later as wrong purchase requisitions and a wrong product cost. A person from engineering checks the D rows against the source parts list before Run.

BOM usage, alternatives and item categories

In PostNow.ai, BOM usage and alternative are two H-row columns, and together with material and plant they form the key of the BOM. Get them wrong and the run either creates a BOM nobody's process reads or stops on a BOM that already exists.

BOM usage

The usage says which areas may use the BOM. The values are defined in Customizing (table T416), so confirm the list in your system; the standard keys most files use are:

UsageMeaning in the standard systemTypical upload
1ProductionStructures that MRP explodes and production orders consume
2Engineering/designThe design structure, kept apart from how the plant builds the product
3UniversalOne BOM that production, costing and other areas may all use
4Plant maintenanceReserved for plant maintenance; production cannot use these

Alternative BOMs are several BOMs for the same material, plant and usage, numbered 1, 2, 3. A plant that can build a pump with two different motors keeps both as alternatives, and planning picks one through production versions or the alternative's lot-size range. In the upload file, the alternative is a column on the H row; leave it out and every BOM in the file claims alternative 1. When the key already has a BOM, SAP rejects the create instead of adding a second one, with messages such as 29 005 "BOM already exists for this material/plant/usage" or 29 003 "Alternative & already exists", so files that add alternatives to existing products need the alternative stated per BOM.

Item categories

The item category on each D row tells SAP what the component is and which fields the row needs. The letters below are the standard keys; Customizing can rename them.

CategoryWhat it isWhat happens in a production order
L Stock itemA component kept in inventoryA reservation is created
N Non-stock itemA component bought for the orderA purchase requisition is created
R Variable-size itemA stock item with size data, such as sheet metal cut to dimensionsReserved like a stock item, with the quantity calculated from the sizes
T Text itemA note with no materialNo component; the text travels with the BOM
D Document itemA drawing or other document from document managementNo material requirement; the document is linked to the BOM for reference

A file that mixes categories has columns that are filled on some rows and empty on others by design: a text item has no component and no quantity, a non-stock item carries purchasing data that a stock item does not. Mark the component column required in the template for the categories that need it, and keep text and document items in their own rows.

Load order for a multi-level BOM upload

PostNow.ai posts the rows in the order of the sheet, so the load order is a property of the file. For a bill of materials upload, two rules decide it: one is enforced by SAP, the other makes the result checkable.

  1. Materials before any BOM. SAP checks that the header material and every component material exist and are extended to the BOM's plant. A component that exists at client level but has no plant data for plant 1010 fails the BOM that uses it. Create and extend the materials first, with a MM01 mass upload where they are new.
  2. Then the BOMs, lowest level first. Sub-assemblies whose components are all purchased parts go first, then the assemblies that use them, then the finished products. SAP does not require a component's own BOM to exist when the parent is created (the item's assembly indicator is set once that BOM exists), but loading bottom-up means each level can be exploded and compared with the source before the next level builds on it.
  3. Alternatives and plant copies after the first structure is proven. A second alternative or the same product in a second plant is the same work again, with fewer surprises once the first structure is right.

Working out the levels is part of the file preparation. In the parts list, a material that appears both as a header and as a component is a sub-assembly; give each header a level number (1 for BOMs with only purchased components, 2 for BOMs that use level-1 sub-assemblies, and so on) and sort the H rows by it. One run per level, or one run with the levels in order, both work.

💡
Look for loops while you assign levels. A material that turns up in its own structure, directly or several levels down, has no level. SAP rejects it with 29 110 "BOM is recursive" unless the item is flagged recursive allowed. Finding the loop in Excel is quicker than finding it from SAP's message.

Posting route: CS01 recording or BAPI

PostNow.ai creates BOMs either way: by calling a function module over RFC in BAPI mode, or by replaying a CS01 recording. BAPI mode calls only remote-enabled modules, so the first question for a BOM template is which of SAP's BOM interfaces your system lets you call remotely.

InterfaceWhat it isHow PostNow.ai uses it
BAPI_MATERIAL_BOM_GROUP_CREATEThe BAPI for material BOMs, an RFC function module. It creates BOMs; it does not change them.BAPI mode: H row and D rows fill its tables (below), committed with BAPI_TRANSACTION_COMMIT
CSAP_MAT_BOM_CREATESAP's BOM API function module: material, plant, usage and valid-from as imports, header in I_STKO, items in T_STPO. It has no RETURN table and raises the exception ERROR.BAPI mode, where SE37 shows it as remote-enabled in your system; the free template is mapped to it
CS01 recordingThe transaction itself, replayed screen by screenRecording mode, with a loop band for the item lines

Check the remote flag before you build on CSAP_MAT_BOM_CREATE. Open the module in SE37, go to the Attributes tab and look at the processing type: Remote-Enabled Module means BAPI mode can call it. If it shows Normal Function Module, use BAPI_MATERIAL_BOM_GROUP_CREATE, a CS01 recording, or a remote-enabled Z wrapper that your developers write around the module. The same check applies to CSAP_MAT_BOM_MAINTAIN for changes.

Mapping BAPI_MATERIAL_BOM_GROUP_CREATE

The BAPI describes a BOM as a small set of linked tables rather than a header and items, so the mapping takes more thought than the sheet does. The BOM_GROUP_IDENTIFICATION on every line ties the tables together; map your BOM reference column to it in each table.

BAPI tableFilled fromFields an upload usually fills
BOMGROUPH rowOBJECT_TYPE BGR, BOM_USAGE, CREATED_IN_PLANT, BOM_TEXT
VARIANTSH rowOBJECT_TYPE BOM, OBJECT_ID, ALTERNATIVE_BOM, BOM_STATUS, BASE_QTY, VALID_FROM_DATE, CHANGE_NO, FUNCTION NEW
MATERIALRELATIONSH rowMATERIAL, PLANT, BOM_USAGE, ALTERNATIVE_BOM
ITEMSEach D rowOBJECT_TYPE ITM, OBJECT_ID, ITEM_NO, ITEM_CAT, COMPONENT, COMP_QTY, VALID_FROM_DATE
ITEMASSIGNMENTSEach D rowSUB_OBJECT_TYPE ITM and SUB_OBJECT_ID (the item), SUPER_OBJECT_TYPE BOM and SUPER_OBJECT_ID (the BOM in VARIANTS), FUNCTION NEW
RETURNRun LogSAP's messages, written to the H row

Fixed values such as the object types go in as a column's Default Value, so the sheet stays readable. The BAPI also has a TESTRUN import; PostNow.ai's Simulate follows the call with BAPI_TRANSACTION_ROLLBACK instead of a commit, so it can stay empty. SAP's program MAT_BOMGROUP_CREATE_SAMPLE writes an existing BOM out in this BAPI's table format, so creating one BOM by hand in CS01 and running the program on it shows a correct set of lines for your release. Compare the fields your BOMs need with the ITEMS structure before you commit to this route: a field CS01 has but the structure lacks is a reason to record instead.

Recording CS01 instead

A recorded CS01 works for any field the screen shows. Record one BOM in SHDB with at least two components, map the screen fields to columns, and turn the item lines into a loop band that repeats once per D row, so one recording takes BOMs of any length. The BDC recording guide covers how to record so the replay holds, and BAPI vs BDC in SAP compares the two methods.

  • Prove the loop on a long BOM. The item overview is a table control that shows a screenful of items at a time. Debug one BOM with more components than fit on the screen before the first full file.
  • Recording mode needs PostNow.ai's ZPOSTNOW_* objects in SAP, installed once per system. The BAPI route needs no add-on objects: RFC access plus the user's normal BOM authorisations.
  • Simulate on a recording walks the CS01 screens without saving, so SAP's save-time checks arrive at Run.
  • SAP GUI stays with the user. PostNow.ai logs in to SAP GUI only on the user's own computer, with the user's own stored login, when the user starts the action (Record, Run, Debug or Call Transaction); never on a server, never unattended, never with someone else's login.

Without an add-in, SAP's own options are the standard batch input program RCSBI010 behind LSMW's BOM object, and on S/4HANA the Migration Cockpit's material BOM object for cutover loads; see SAP Migration Cockpit.

Worked example: a two-level drive shaft family in plant 1010

PostNow.ai handles this with one published CS01 template that the designer mapped to BAPI_MATERIAL_BOM_GROUP_CREATE, and one sheet sorted by level. Engineering releases six drive shaft assemblies (FG-100001 to FG-100006) for plant 1010, built from two frame sub-assemblies (SF-300220, SF-300221) and purchased parts. All BOMs are usage 1, alternative 1, base quantity 1 EA, valid from 01.01.2026. The sheet has 8 H rows and 41 D rows: the two sub-assemblies on top as level 1, the six assemblies below them as level 2.

Excel rowBOM RefColumns filled
HBOM-0001Material SF-300220, plant 1010, usage 1, alternative 1, valid from 01.01.2026, base quantity 1 EA, level 1
DBOM-0001Item 0010, category L, component RM-200015, 1.2 KG
DBOM-0001Item 0020, category L, component CN-500010, 4 EA
HBOM-0003Material FG-100001, plant 1010, usage 1, alternative 1, valid from 01.01.2026, base quantity 1 EA, level 2
DBOM-0003Item 0010, category L, component SF-300220, 1 EA
DBOM-0003Item 0020, category L, component CP-410090, 2 EA
DBOM-0003Item 0030, category L, component RM-200015, 3.4 KG
  1. Validate. Two cells are flagged: an item category Z that is not in the template's allow-list, and a quantity typed as text with a unit inside the cell ("4 EA"). Both are fixed in the sheet.
  2. Simulate. Six of the eight BOMs pass. FG-100004 fails because its component CP-410095 exists but has no plant data for 1010; the materials team extends it to the plant with an MM01 run before the level-2 run. FG-100006 returns SAP's message that a BOM already exists for this material, plant and usage: a test BOM from the prototype phase. Engineering confirms it is obsolete and deletes it in CS02 before the run.
  3. Run, level 1. The two sub-assembly BOMs are created. A CS11 explosion of each matches the parts list.
  4. Run, level 2. The six assemblies are created, and each H row shows a success entry in its Run Log.
  5. Check. A CS12 multi-level explosion of FG-100001 shows the frame sub-assembly with its own components underneath, and the quantities per level match the source. One assembly from each sub-assembly family is checked this way before the BOMs are released to planning.

Every BOM can be traced from its Excel rows and its Run Log entry to the structure in SAP.

Changing BOMs in bulk: CS02, change numbers and validity

PostNow.ai changes existing BOMs through a recorded CS02, or in BAPI mode through CSAP_MAT_BOM_MAINTAIN where SE37 shows it as remote-enabled in your system; the free CS02 BOM change template is mapped to that module. BAPI_MATERIAL_BOM_GROUP_CREATE creates only, so a change file always has its own template.

  • Keep creates and changes in separate files. A CS01 create stops on a BOM that already exists (for example 29 005), and a CS02 change needs the BOM to exist. Mixing them in one sheet turns every re-run into a sorting exercise.
  • Change numbers carry the history. Where engineering change management is active, a change is posted under a change number with a valid-from date, so the structure before that date stays as it was and the new one applies from the date. If your configuration requires a change number for the BOM, a file without one is rejected however good the structure is.
  • Future dates do nothing until the date. A change valid from 01.03.2026 is correct for a planned engineering change and confusing for a correction that should apply today. Agree the valid-from per file.
  • Quantities and dates are batch-input fields in the CSAP modules. In CSAP_MAT_BOM_CREATE and CSAP_MAT_BOM_MAINTAIN, the component quantity, base quantity and valid-from date are character fields (data elements ending in _BI), read in the SAP user's own notation: 12,5 or 12.5, 24.09.2026 or 09/24/2026. Format those columns as text in Excel and type the values in the notation of the user who runs the template, then prove one BOM in Simulate before the full file.
  • Check where-used before a change wave. CS15 lists every BOM that contains a component, which is the list of BOMs a component replacement touches.

For reading existing structures into Excel before a change, the routes are described in how to export SAP data to Excel.

BOM upload in S/4HANA

PostNow.ai uses the same CS01 template on S/4HANA: CS01, CS02 and CS03 are still the BOM transactions, and the BOM interfaces described above keep their names. What changes around them:

  • Longer material numbers. Once the extended material number is switched on, header and component numbers can have up to 40 characters (SAP Note 2267140). A file built with 18-character numbers still loads; check the column lengths in the template if your numbers grow.
  • The Migration Cockpit has a material BOM object. For a cutover load, the S/4HANA Migration Cockpit's material BOM object loads BOMs from a file or staging tables; in S/4HANA 2025 it is called Material BOM (new) (SAP KBA 3739860). Day-to-day BOM work after go-live stays with CS01/CS02 and an Excel template.
  • Variant configuration is a separate job. Super BOMs with object dependencies are maintained with the configuration model, and S/4HANA offers advanced variant configuration for it. Keep them out of a plain BOM upload file.

CS01 upload errors and the fix

PostNow.ai writes SAP's message to each failed BOM's H row, so the fix starts from the message text. These are the ones a bulk CS01 run meets most, plus one problem that raises no message at all:

MessageWhat it meansFix
29 005 BOM already exists for this material/plant/usageA create for a key that already has a BOMLook at it in CS03. Either it is a duplicate to skip, an alternative that needs its own number, or a change that belongs in the CS02 file
29 003 Alternative … already existsThe alternative number in the file is takenUse the next free alternative, after checking which ones exist in CS03
29 110 BOM is recursiveA component contains the header material somewhere in its own structureFind the loop in the level assignment of the file. Set the item's recursive-allowed flag only where engineering intends the loop
29 001 BOM not found for this material/plant/usageA change file names a BOM that does not exist with that usageCheck the usage and alternative columns, or move the row to the create file
Component not maintained in the plantThe component material exists but has no plant data for the BOM's plantExtend the material to the plant (MM01 for the plant views), then Retry Failed
No message: quantities out by a factorThe file assumed a different base quantity from the BOM headerCorrect the base quantity or the component quantities, check with a CS12 explosion, and change the BOMs in CS02
Run Log: UNKNOWN (PostNow.ai)SAP's answer was lost after the BOM was sent, so it may have been createdLook for the BOM in CS03 before anyone posts the row again; Retry Failed leaves UNKNOWN rows alone

Checklist before a CS01 mass upload

PostNow.ai checks formats and allowed values and keeps operators on the published template; this list covers the decisions that stay with engineering and master data.

  1. The file holds new BOMs only; changes to existing BOMs are in a separate CS02 file.
  2. Every header and component material exists and is extended to the BOM's plant.
  3. BOM usage and alternative are filled on every H row, and the usages exist in your system.
  4. Base quantity is stated per BOM and agreed with engineering, and component quantities refer to it.
  5. Item categories are in the allow-list, and text items carry no component.
  6. Each H row has a level, the sheet is sorted by level, and no material sits in its own structure.
  7. Valid-from dates and change numbers follow the engineering change rules of the plant.
  8. Where the template calls a CSAP module, SE37 shows it as remote-enabled, and quantity and date cells use the running user's notation.
  9. Simulate has run clean on the whole file, and the first created BOM has been exploded in CS12.

What to plan for in a CS01 mass upload

PostNow.ai creates BOMs through SAP's BOM interfaces or the CS01 screens, so SAP's own material, plant and recursion checks decide every result.

  • Run SAP's checks in Simulate. Validate checks formats, lengths and allowed values in Excel; component, plant and recursion checks start when SAP sees the BOM in Simulate.
  • Review quantities as a person. A wrong base quantity or component quantity passes every check, so someone from engineering compares an explosion with the parts list.
  • Load materials before BOMs. The BOM file depends on the material file; run them in that order, with the BOM run after the materials are confirmed in SAP.
  • Plan one run per level. Exploding each level before the next keeps a wrong sub-assembly from spreading into every assembly above it.
  • Pick the interface once per system. Check the remote flags in SE37 in development, quality and production alike, and keep the CS01 recording ready as the alternative.
  • Keep re-runs in the same workbook. The re-post check reads this sheet's Run Log, and UNKNOWN rows are checked in SAP before anyone creates them again.

Making a template like this repeatable for a team (designers who build, operators who only run, a published template in the central library) is covered in Excel to SAP automation. Where BOMs are part of a legacy cutover rather than day-to-day engineering, the sequence around them is in SAP master data migration.

Free CS01 bill of material upload template

PostNow.ai publishes a free CS01 bill of material template: an H row per BOM and a D row per component, two sample BOMs (a drive shaft assembly and its frame sub-assembly), a field guide for every column and a mapping sheet for CSAP_MAT_BOM_CREATE. Check that module in SE37 before you use the mapping in BAPI mode; to post through BAPI_MATERIAL_BOM_GROUP_CREATE or a CS01 recording instead, keep the column layout and build that mapping in your own template. It sits with the other master data templates in the SAP master data template library, next to the CS02 change template.

Frequently asked questions

How do I upload a BOM into SAP from Excel?
With PostNow.ai, put one header row per BOM (material, plant, BOM usage, alternative, valid-from date, base quantity) and one detail row per component (item number, item category, component, quantity, unit) in a template mapped to BAPI_MATERIAL_BOM_GROUP_CREATE or to a CS01 recording. Validate checks the sheet offline, Simulate lets SAP check every BOM and rolls it back, and Run creates the BOMs and writes SAP's message back to each header row.
In which order do I load a multi-level BOM?
Materials first: the header material and every component material must exist and be extended to the plant. Then the BOMs from the lowest level up: sub-assemblies with only purchased components, then the assemblies that use them, then finished products. SAP accepts a parent before its sub-assembly's BOM exists, but loading level by level lets you explode and check each level before the next one builds on it.
Which BAPI creates a material BOM?
BAPI_MATERIAL_BOM_GROUP_CREATE. It describes the BOM in linked tables: BOMGROUP, VARIANTS and MATERIALRELATIONS for the header, ITEMS and ITEMASSIGNMENTS for the components, and RETURN for SAP's messages. It creates BOMs but does not change them, and the call is committed with BAPI_TRANSACTION_COMMIT. SAP's program MAT_BOMGROUP_CREATE_SAMPLE writes an existing BOM out in these tables, which shows a correct set of lines.
Is CSAP_MAT_BOM_CREATE remote-enabled?
Check it in your own system: open CSAP_MAT_BOM_CREATE in SE37 and look at the processing type on the Attributes tab. Remote-Enabled Module means an RFC client such as PostNow.ai's BAPI mode can call it; Normal Function Module means it can only be called inside SAP, so use BAPI_MATERIAL_BOM_GROUP_CREATE, a CS01 recording, or a remote-enabled Z wrapper. The same check applies to CSAP_MAT_BOM_MAINTAIN for changes.
What do BOM usage and alternative BOM mean?
BOM usage says which areas may use a BOM: in the standard system 1 is production, 2 engineering/design, 3 universal and 4 plant maintenance, defined in table T416. An alternative BOM is a second or third BOM for the same material, plant and usage, such as a different way of building the same product. Material, plant, usage and alternative together identify the BOM.
Which item category do I use for stock and non-stock items?
L for stock items, which create a reservation in the production order, and N for non-stock items, which create a purchase requisition. R is a variable-size item, T a text item with no material, and D a document item. These are the standard keys; Customizing can change the letters, so check your system's list before you fill the allow-list.
How do I change BOMs in bulk with CS02?
Keep changes in their own file. PostNow.ai changes BOMs through a recorded CS02 or through CSAP_MAT_BOM_MAINTAIN where SE37 shows it as remote-enabled. Where engineering change management is active, each change carries a change number and a valid-from date, so the old structure stays valid until that date. CS15 lists every BOM that uses a component before a change wave.
Which SAP tables hold a BOM?
MAST links a material and plant to a BOM, STKO holds the BOM header (base quantity, status), STPO holds the items, and STAS holds the item selection per alternative. For reading BOMs, an explosion such as CS12 handles alternatives and validity dates more reliably than a join of the raw tables.
Your parts list. SAP's BOM rules.

Run your next SAP BOM upload from Excel

Map CS01 once, simulate every BOM, then create them level by level and see SAP's answer on every header row.

Start free trial
  • 14-day free trial
  • Works with ECC and S/4HANA
  • Posts under your own SAP login