🎉 WIN a Snapmaker U1 Printer! Enter FREE now

The assemble-list JSON format

The complete schema for the file you pass to --load-assemble-list. Every field, every enum value, and the exact rules the slicer enforces while parsing it.

--load-assemble-list <file.json> builds the entire scene from a JSON manifest instead of positional model files. The JSON is the sole geometry source: it enumerates one or more plates, and for each plate it lists the STL or OBJ files to load, how many copies of each, where to place them, which filament slot to assign, how to merge volumes into composite objects, and what per-object or per-plate configuration overrides to apply. Passing this flag and positional model files at the same time is a hard error; the two are mutually exclusive.

This page documents Bambu Studio's parser. Orca Slicer is a fork of the same engine and reads the file identically.

Top-level object

The root is a JSON object with exactly one key that the parser reads. The file must be valid JSON or the run aborts.

FieldTypeReq.Notes
platesarray of plate objectsyesOrdered list of plates to build. Must hold between 1 and 36 entries. No other top-level key is read.

Plate object

Each element of plates is an object with these fields.

FieldTypeReq.Notes
plate_namestringyesName assigned to the plate, used in the output 3MF and logs. May be empty.
need_arrangebooleanyestrue auto-arranges every object on the plate after loading. false locks the plate: objects sit exactly at their pos_x / pos_y / pos_z and are never re-packed.
objectsarray of object entriesyesThe geometry to load onto this plate. Must hold at least one entry.
plate_paramsobject (string to string)noProcess-config key/value overrides applied to the whole plate. Keys are slicer process-config option names; values are their serialized strings. Default: none
assembled_paramsarray of assembled-param entriesnoPost-merge overrides applied to composite objects (entries sharing a positive assemble_index). See sub-schema below. Default: none

Object entry

Each element of a plate's objects array names one geometry file and how to instance it.

FieldTypeReq.Notes
pathstringyesAbsolute path to the geometry file. Must exist at parse time. .stl for any subtype; .obj only when subtype is normal_part. Any other extension is an error.
countintegeryesNumber of instances of this file to place. Must be greater than zero.
filamentsarray of integersyes1-based filament slot for each instance. The key must be present. Length must be 1 (broadcast to all copies) or exactly count. For OBJ files carrying vertex/face colors, this field is ignored and slots come from the color data.
subtypestringnoVolume role. One of the five values in the enum below. Any unrecognized string resolves to normal_part. Default: "normal_part"
assemble_indexarray of integersnoMerge-group per instance. 0 = standalone object; a shared positive N merges all entries with that N into one composite named assemble_N. Length must be 1 or count. Non-normal_part subtypes must use a positive value. Default: [0]
pos_xarray of floatsnoX translation (mm) per instance. Length 1 or count. Honored only when the plate has need_arrange false; otherwise the arranger overrides it. Default: [0.0]
pos_yarray of floatsnoY translation (mm). Same broadcast and arrangement rules as pos_x. Default: [0.0]
pos_zarray of floatsnoZ translation (mm). Same broadcast and arrangement rules as pos_x. Default: [0.0]
print_paramsobject (string to string)noPer-object config overrides, applied to the whole model object before cloning. Default: none
height_rangesarray of height-range entriesnoPer-layer-range overrides. Valid only when subtype is normal_part. See sub-schema below. Default: none

subtype values

The subtype field accepts exactly these five strings. Any other value silently becomes normal_part.

ValueMeaning
normal_partStandard printable mesh. The default when the field is absent or unrecognized.
negative_partNegative volume that subtracts from overlapping normal parts.
modifier_partParameter-modifier volume that applies settings overrides in the region it occupies.
support_enforcerForces support generation in its region.
support_blockerSuppresses support generation in its region.

Sub-schema: height-range entry

Used in an object's height_ranges array and in an assembled_params entry's height_ranges array.

FieldTypeReq.Notes
min_zfloatyesLower bound of the layer range (mm, inclusive).
max_zfloatyesUpper bound of the layer range (mm, inclusive).
range_paramsobject (string to string)yesConfig key/value pairs applied only inside this height range.

Sub-schema: assembled_params entry

Each entry applies extra configuration to a merged composite object after all of its component volumes are combined.

FieldTypeReq.Notes
assemble_indexintegeryesIdentifies the composite object to configure. Must match a positive assemble_index used by at least one object entry on this plate.
print_paramsobject (string to string)noConfig overrides applied to the composite object after merging.
height_rangesarray of height-range entriesnoLayer-range overrides applied to the composite after merging. Same structure as above.

Semantics that trip people up

need_arrange: true vs false

true submits the plate to the auto-arranger after loading; it ignores pos_x/y/z and repacks to minimize footprint. false locks the plate: each object stays exactly at its specified translation and nothing is re-arranged for the whole run.

assemble_index: 0 is standalone, positive merges

An index of 0 (or an omitted field, which defaults to [0]) makes the geometry its own model object. A positive N merges every entry on the plate that shares that N into one composite object named assemble_N; the first entry with that index creates it and later ones append as volumes. A single entry's assemble_index array may mix 0 and positive values across its copies. Non-normal_part subtypes cannot stand alone, so they must carry a positive index.

Loaded IDs and --skip-objects

Objects loaded this way get their loaded ID from list order. There is no stable identify_id as in a saved 3MF, so targeting assemble-list objects with --skip-objects means counting the order they appear in the JSON.

OBJ color overrides filaments

When an OBJ file carries per-face or per-vertex colors (via MTL or vertex data), the slicer clusters those colors into filament slots and the filaments field is ignored for slot selection. An OBJ with a UV+PNG texture, or no color data, uses filaments normally. OBJ is only allowed for normal_part.

Validation and errors

Any of these aborts the CLI rather than producing partial output.

Constraint violatedResult
--load-assemble-list passed alongside positional model filesAborts before any processing. The two input methods are mutually exclusive.
JSON file path does not existFile-not-found error.
JSON cannot be parsedConfig-file error.
plates is absent, empty, or has more than 36 entriesConfig-file error.
A plate's objects array is absent or emptyConfig-file error.
count is zero or negativeConfig-file error.
filaments key is absentConfig-file error.
filaments / assemble_index / pos_* length is neither 1 nor countConfig-file error.
An object path does not exist on diskFile-not-found error.
File extension is not .stl or .objInvalid-params error.
.obj paired with any subtype other than normal_partInvalid-params error.
height_ranges supplied for a non-normal_part subtypeInvalid-params error.
Non-normal_part subtype with assemble_index omitted or 0Invalid-params error.
Constructed plate count does not match the JSON plate countInvalid-params error.

Worked examples

Auto-arranged multi-object plate

body.stl loads once on filament 1. lid.stl loads three times: copies 1 and 3 on filament 1, copy 2 on filament 2, all sharing the print_params. need_arrange: true lets the slicer place all four objects.

{
  "plates": [
    {
      "plate_name": "Top Plate",
      "need_arrange": true,
      "objects": [
        { "path": "/models/body.stl", "count": 1, "filaments": [1] },
        {
          "path": "/models/lid.stl",
          "count": 3,
          "filaments": [1, 2, 1],
          "print_params": { "layer_height": "0.1", "support_type": "normal(auto)" }
        }
      ]
    }
  ]
}

Locked layout with a merged object and layer ranges

base.stl and top_modifier.stl share assemble_index: [7], so they merge into one object called assemble_7. The plate is locked, so both volumes stay at their coordinates. After merging, assembled_params adds a support override and a 0.3 mm layer-height band for the bottom 5 mm, and plate_params disables timelapse for this plate only.

{
  "plates": [
    {
      "plate_name": "Assembly Plate",
      "need_arrange": false,
      "plate_params": { "timelapse_type": "0" },
      "objects": [
        {
          "path": "/models/base.stl",
          "count": 1, "filaments": [1],
          "subtype": "normal_part", "assemble_index": [7],
          "pos_x": [50.0], "pos_y": [60.0], "pos_z": [0.0]
        },
        {
          "path": "/models/top_modifier.stl",
          "count": 1, "filaments": [2],
          "subtype": "modifier_part", "assemble_index": [7],
          "pos_x": [50.0], "pos_y": [60.0], "pos_z": [10.0],
          "print_params": { "infill_density": "80%" }
        }
      ],
      "assembled_params": [
        {
          "assemble_index": 7,
          "print_params": { "support_type": "normal(auto)" },
          "height_ranges": [
            { "min_z": 0.0, "max_z": 5.0, "range_params": { "layer_height": "0.3" } }
          ]
        }
      ]
    }
  ]
}

Sign up for free today

No credit card required. Connect unlimited printers and get production automation running in minutes.