Decide the shape first
Ask whether each unit needs its own history.
A hire fleet of 40 bikes needs 40 records: each frame carries a serial number, its own servicing and its own repair costs. A resale listing for 1,000 identical t-shirts needs one record with a quantity of 1,000. Choosing per-unit records for interchangeable stock gives the account 1,000 rows to scroll where one would do, and spreads availability arithmetic across records that never needed separating.
Set the mode with
trackIndividually on the create request. Read Inventory tracking for what each mode reports and what it gives up.
How it works
Four endpoints accept an array:
Each entry creates exactly one record. On
articles/create-many, quantity sets that one record’s capacity: it never multiplies entries, and trackIndividually is read on the single create only.
So there are two ways to create many stock items, and they answer different questions:
- Same item, many tracked units. Call
POST /v1/admin/articlesonce withquantity. Every unit becomes its own record. - Units that differ in name, SKU, location or attributes. Call
POST /v1/admin/articles/create-manywith one entry per record.
Usage
Stock items
Create 40 tracked bikes in one call.codes assigns the first code to the first unit, the second to the second, and generates a code for any unit you leave uncovered.
trackIndividually: false and the same quantity. One record comes back with quantity.total set to 40.
Use create-many when the entries differ from each other:
SKUs
POST /v1/admin/skus/many creates one SKU per entry and returns the id, name and code of each. Omit code and TWICE generates one from the name, adding a numeric suffix until it is unique in the account. Send a code that already exists and the call fails with 400, naming the code. Nothing is created when it fails: the whole array is written in one transaction.
Customers
POST /v1/admin/customers/many returns one id per entry. An entry whose email already exists on the account updates that customer instead of creating a second one, and fields you leave out keep their stored values. Entries without an email are always inserted, so a repeated import without emails builds duplicates.
Order line items
POST /v1/admin/orders/{orderId}/lineItems/create-many adds several lines to one existing order. Each line carries its own quantity, so identical lines do not need one entry each. Prices are computed server-side from the catalog item and pricing row.
Check codes and emails before you send
Run the validation endpoint over the whole list first and resolve the clashes up front. Each returns only the entries that would fail, so an emptyinvalid array means the batch is free to go.
Batch size and rate limits
One call is one request. A loop of 1,000 single creates spends 1,000 requests of the key’s per-second rate and monthly cap; the same import as batch calls spends a handful. See the rate limits section of API keys for the three layers and the response headers that report what is left. The API declares no maximum on array length or onquantity, so nothing rejects a request to create ten million records. Treat a few hundred to around a thousand entries per call as guidance rather than a limit, and split a larger import into several calls.
Splitting also keeps a failure cheap to recover from. SKUs and customers are written in one transaction, so a rejected entry leaves nothing behind. A very large stock item array is committed in parts, so entries early in the array can exist while a later one fails. Send batches you can retry, and record which ones came back 200.
Not every import needs the API. The admin imports stock items and customers from a CSV file, which is usually the faster route for a one-off migration. See Import inventory from CSV and Import customers.
Related articles
Inventory tracking
Serialized and pooled tracking, and what each one reports.
Stock item vs SKU
Which of the two a record should be.
API keys
Authentication, API versions and rate limits.
API: Articles
Every stock item endpoint and its schema.