---
name: manifold-from-spreadsheets
description: Set up Manifold through an agent for a business whose records live in spreadsheets, or in an ERP or inventory system Manifold has no connector for (exports from Unleashed, Katana, inFlow, NetSuite, Xero inventory, a homegrown database). Read each sheet, decide what it is, shape it onto Manifold's import targets, stage, show, commit and reconcile, in dependency order, then walk the rest of setup. Use when someone wants to bring their data across from files or from a system with no migration.
---

# Setting Manifold up from spreadsheets, or an ERP with no connector

**Who this is for:** a merchant whose records are in spreadsheets, or in another system Manifold cannot read directly. `onboarding_list_sources` lists the systems Manifold migrates from (Cin7 today). For any other system, the merchant exports CSV files from it, and you bring them in through imports.

The **manifold-import** skill is the field-level procedure for one import: targets, row shapes, keys, failures. This skill is the whole setup around it.

## What the merchant needs ready

- **The exports**, one file per kind of record:
  - items or products;
  - stock on hand per location, with unit cost;
  - price lists;
  - suppliers and customers;
  - open purchase orders;
  - open sales orders, if they want them.
- **The source system's own ids or document numbers** in each file. They are what make a retried import safe.
- **The Manifold connector** in this client, connected with "Everything I can do" (**manifold-onboarding** skill, step 2).

## Never

- Never ask for, read out or type a password, an API key or any other credential, even one sitting in a column of their export. Leave that column out and tell them it was there.
- Never invent a value to fill a blank: a missing cost stays missing and is asked for.
- Never commit an import the merchant has not seen staged.
- Never re-submit a stock adjustment. It applies again.
- Never decide go-live, billing or who joins the team.

## 1. Account, journey, profile

1. A new business signs up at `https://admin.getmanifold.io/signup?source=agent`; then connect the connector to that organization.
2. `onboarding_get_status`. No journey: `onboarding_start` with `source: "agent"`.
3. `onboarding_set_profile`: what they sell, where, the currency their files are in, the timezone.
4. Check `onboarding_list_sources`: if their system is listed, stop and use that system's skill (the **manifold-from-cin7** skill for Cin7). Otherwise, on their word, `onboarding_skip_step` with step `source` and reason `spreadsheet`.

## 2. Read every file before importing any

For each file, list its headers and a few rows, and decide its target with `imports_list_targets` (the **manifold-import** skill, §2, has the table). Then tell the merchant the plan in one message:

- what each file is;
- what it will become;
- what you will leave out and why;
- what is missing.

Things that usually need a decision:

- **Money in another unit.** Costs and prices are converted to whole cents, never copied.
- **SKUs Manifold refuses.** Letters, digits, `-` and `_` only. A SKU with spaces or `/` needs a rule from them, applied to every file the same way.
- **One sheet holding several kinds of thing** (items and their stock and their price in one row). Split it into several imports from the same file.
- **Duplicates across files** (the same supplier spelled twice). Ask which is right.

## 3. Load in dependency order

One import per target, each finished and reconciled before the next. Each one goes through the same steps:

1. `imports_submit_rows` with `run: false` and a `reference` you mint for that batch;
2. `imports_preview_job`, summarised for the merchant;
3. `imports_commit_job` on their word;
4. `manifold_wait` on `imports_get_job` until `completed` or `failed`;
5. `imports_list_failures` explained and fixed, resubmitting only the corrected rows under a new reference.

The order:

1. `inventory.location`: the sites beyond `Main`.
2. `inventory.item`: the SKU master, **one row per SKU**. A row creates the SKU, so a SKU is created once: a second row for the same SKU (its quantity at another location) is refused as already existing, and that location's stock is lost. Import every SKU at `quantity` 0, or at its quantity in one location only if the file holds just one location.
3. `catalog.product`, then `catalog.composite` (kits).
4. `catalog.price`, into catalogs made first with `catalog_create_catalog` (one per price list), each product listed in it with `catalog_include_product` (a price for an unlisted product is refused).
5. `crm.company`, then `crm.person`. Give every row the source system's id as `reference`.
6. `purchasing.po` for open purchase orders. They arrive as drafts; the merchant approves them.
7. `fulfillment.order` for open sales orders, if they want them live in Manifold.

Read `onboarding_get_status` after each: the `locations`, `products`, `channels` and `parties` steps turn done from what arrived.

**Stock per location** (a SKU at Main and at the Warehouse): the quantities go on the **opening stocktake**, not into `inventory.item`.
- `inventory_start_stocktake`;
- `inventory_record_stocktake_counts` with a count per SKU and location (`locationId` from `inventory_list_locations`) and each SKU's unit cost.

A count sets the figure rather than adding to it, so saving the same counts again changes nothing. Never load other locations' stock as an `inventory.adjustment`: an adjustment adds, and applies again if the file is loaded twice. The stock moves when the stocktake completes (§4): at once for a live organization, at go-live for a read-only one.

**Stock without costs:** if the stock file has no unit cost, give each SKU its cost on the opening stocktake rather than guessing.

**Order history** (orders long since shipped, cancelled or refunded) is the `fulfillment.historical-order` target: one row per line, grouped by the order's `externalNumber`, with `source` naming the old system (two systems' `#1001` are two orders), `placedAt`, `currency`, `outcome`, `totalCents` and `paidCents`. History holds no stock, ships nothing and is never billed or posted to the ledger; the customer is matched by email. It is safe to load again: the same file changes nothing, and a corrected one replaces the order. Read it back with `fulfillment_list_historical_orders`. Load it after the customers (step 5). An order still being worked goes in as `fulfillment.order` (step 7) if it should be live in Manifold, or as history with `outcome: open` to keep it mirrored until go-live.

## 4. The rest of setup

Hand back to the **manifold-onboarding** skill's checklist, step 5:

- order pipeline (`fulfillment_set_workflow`);
- purchasing policy (`purchasing_set_settings`);
- the accounting basis (the merchant, at Settings › Tax);
- the opening stocktake:
  - `inventory_start_stocktake`;
  - `inventory_stocktake_sheet` with `missingCost=true`;
  - `inventory_record_stocktake_counts` with what they confirm (each location's count, from the file or the shelf);
  - `inventory_complete_stocktake`.

  The imported quantities are the expected figures; the count is what is on the shelf.
- books, billing (theirs, at Settings › Billing) and team (theirs, at Settings › Users).

**Keep the old system until go-live.** Nothing follows it: changes made there after the export do not arrive. Agree a cut-over day with the merchant. On that day, re-export what moved (new SKUs, the day's stock) and import only the differences:

- stock as an `inventory.adjustment`, once;
- or recount on the opening stocktake.

## What stays read-only until go-live

The organization starts **read-only**: imports and everything inside Manifold work. What is held is outward:

- mail to their customers and suppliers;
- pushes to a store or a ledger;
- completing the opening stocktake.

Going live is the owner's or an admin's decision, typed in at Settings › General. It needs every stock SKU costed. There is no tool that reads the mode: the badge at the top of the admin shows it.

## Done looks like

- Every file imported or deliberately left out, and the merchant told which.
- `imports_list_jobs`: every job `completed`, every failure explained.
- Spot checks match the source: a few SKUs' quantity and cost (`inventory_get_item`), a supplier, a price.
- `onboarding_get_status`: every applying step done or skipped on their word, billing started.

## When it goes wrong

| What you see | What it means | Next |
|---|---|---|
| `422` on submit | A header is not a field of the target, or a required one is missing | Fix the headers; resubmit under the **same** reference |
| Rows failed: "already exists" | A previous batch created it, or the file holds the SKU twice (once per location) | A re-run: nothing to do. A SKU twice: its other locations' quantities were not loaded — put them on the opening stocktake as counts |
| Rows failed: "not an inventory item" | The product names a SKU no item has | Import the item first, then those product rows under a new reference |
| Companies doubled | A batch went in twice without a `reference` column | Archive the duplicates (`crm_archive_company`); always send `reference` |
| Stock looks doubled | An adjustment file was imported twice | Correct with one opposite adjustment; never import it again |
| A job `failed` with a reason | The job stopped (its access expired after 15 minutes, say) | Split the load into smaller jobs; commit each after the last finished |
