CSV Import Wizard
Import a product catalog from a CSV file: SegOps reads your columns, uses Claude to suggest a schema and column mapping, and runs the import as a background job you can track to completion.
Before you start#
The file must be a UTF-8 encoded .csv (a UTF-8 BOM is handled automatically). The wizard handles up to 100k rows. Two fields are reserved and always live on the product itself rather than in your schema:
sku— the product's unique identifier (one product perskuper workspace)name— the product's display name
Every other column is mapped to a field in your tenant ProductSchema.
Step 1 — Upload#
Open /pim/import and drag a CSV onto the drop zone, or click to browse. On upload SegOps:
- parses the header row and the first 5 rows as a preview sample
- counts the total rows
- asks Claude Haiku to infer a schema and a column-to-field mapping for any columns it has not seen before
- reuses the workspace's learned mapping (confirmed mappings from prior imports) for known columns — learned memory wins over AI
This creates an ImportJob in the mapping state and returns job_id, headers, sample_rows, suggested_schema, and suggested_mapping.
The draft is saved to your browser and the URL becomes /pim/import?job=<id>, so a refresh — or resuming later from Import history — restores your progress.
Step 2 — Map columns#
The wizard shows three panels:
| Panel | What it does |
|---|---|
| Preview | The first sample rows, exactly as parsed |
| Column mapping | Each CSV column → a schema field, sku, name, or — skip — |
| Schema fields | The fields that will be saved as your product schema |
AI suggestions are pre-filled — review and adjust. For each schema field you can change the Type (Text, Number, Boolean, List, URL, Price, Multi-price, Datetime) and toggle Required, or remove the field entirely. Removing a field also clears any column mapped to it. Columns mapped to sku/name are stripped from the schema automatically since they are not stored in data.
Step 3 — Confirm and import#
Click Import N rows. This calls:
This persists (or updates) your ProductSchema, merges every confirmed non-null mapping into the workspace's learned memory, sets the job back to pending, and enqueues the background run_csv_import task. You are returned to /pim immediately — the import runs asynchronously.
Tracking the job#
Import jobs move through five states:
| State | Meaning |
|---|---|
pending | Confirmed; queued for the worker |
mapping | Awaiting your column mapping (resume from Import history) |
importing | Rows being upserted |
done | Finished; imported_count rows in the catalog |
failed | Aborted; see error_message |
The Import history page (/pim/imports) lists the 20 most recent jobs with a live progress bar and polls every 3 seconds while any job is pending or importing. You can also poll a single job:
A job stuck in mapping shows a Resume mapping button that reopens the wizard at Step 2.
Re-imports and upserts#
Imports are idempotent on (workspace, sku). Each row is upserted with update_or_create: a new sku is inserted, an existing one is overwritten with the new name and mapped data. The original row is kept in raw_data. To refresh a catalog, re-import a CSV with the same SKUs — there is no separate "update" mode. After a successful import the stored CSV content is cleared, products are synced to ClickHouse, and AI-search embeddings are regenerated.
For programmatic upserts, POST /api/pim/products/bulk/ accepts {"products": [{sku, name, ...fields}]} and auto-merges any new field keys into the schema. See the API reference.