Import products
Bring a connected channel's catalog, or a CSV, into Nembol from your app or agent: only new items, linking by SKU, one-import filters, live progress, and undo.
POST /imports runs the same import as the Nembol dashboard, in the
background, with the same rules. Your key needs products:write.
Import a channel's catalog
curl -X POST https://api.nembol.com/rest/v1/imports \
-H "Authorization: Bearer $NEMBOL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"channel_account_id": "chac_66f0a1",
"filters": {"status": "Active", "quantity": {"operator": "gt", "value": 0}}}'{
"id": "op_8fd2c1",
"object": "operation",
"type": "import.channel",
"status": "processing",
"import": {
"source": "channel",
"channel_account_id": "chac_66f0a1",
"filters": { "status": "Active", "quantity": { "operator": "gt", "value": 0 } },
"warnings": [],
"processed": 0
}
}What comes in, exactly like a dashboard import:
- Only new items. Items already imported from that channel account are skipped (channel imports; for a CSV see below), so running an import again only brings what's new.
- No duplicates by SKU. An item whose SKU matches exactly one product
already in Nembol (with the same number of variants) is linked to it, and
the product isn't overwritten. Ambiguous matches aren't imported and are
counted in
not_imported. - The plan's product limit stops creation; items over the limit are
counted in
not_imported.GET /billingtells you the headroom first.
Filters for one import
Without filters the import uses the channel account's import settings (the
same ones as in the dashboard). filters override them for this import
only; the saved settings don't change.
| Filter | Channels | Values |
|---|---|---|
quantity | all except Faire, Temu, Wix | {"operator": "gt" | "lt" | "eq", "value": 0}, total stock across variants |
status | most channels | each channel's own values, e.g. eBay Active / Unsold / All, Etsy active / draft / expired / inactive, Shopify any / published / unpublished |
listing_type | eBay | All, FixedPriceItem (Buy It Now), Chinese (auction) |
shop_section_id | Etsy | a shop section id |
collection_id | Shopify | a collection id (GET /channel_accounts/{id}/collections) |
category_id | WooCommerce, Wix, Square | a category id |
availability | Google Merchant Center | all, in_stock, out_of_stock |
sku_contains | Amazon | text the SKU must contain |
The full list of values is in the API reference.
Read the warnings
import.warnings holds plain-language notes to pass on to the person before
they rely on the result. For example, on some plans some filters are
ignored, or the store is already at its product limit. Linking by SKU works
on every plan.
Import a CSV
Send the file content as text:
curl -X POST https://api.nembol.com/rest/v1/imports \
-H "Authorization: Bearer $NEMBOL_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{"csv": "id,title,description,quantity,price,sku\nMUG-1,Blue mug,A blue mug,5,12.50,MUG-BLUE\n"}
JSONRequired columns: price and quantity (or sku-code alone, to update
existing variants by SKU: only the columns you send change). They're checked
before anything starts: a file without them answers 422 validation_failed
with error.details.missing_columns. id, title, description and the
rest are optional; without id a row gets one derived from its content, so
re-uploading the same file finds the same products. Shopify, eBay and inkFrog
exports are recognized too; columns that aren't recognized are listed in
import.warnings.
Re-imported rows, one rule: a row whose id matches a product in the
store (its prod_… id from an export, or the id of
the row that created it) updates it (updated), never a duplicate; a row
with nothing new is counted as unchanged. For a CSV, import.total is known
from the start.
Follow the progress
Poll GET /operations/{id}, or subscribe to operation.completed:
{
"id": "op_8fd2c1",
"type": "import.channel",
"status": "succeeded",
"import": {
"processed": 342,
"created": 310,
"linked": 32,
"requires_attention": 3,
"not_imported": 4,
"error": null
}
}processed grows while the import runs. For a channel import it counts the
products created so far (items linked to an existing product are counted at
the end), for a CSV the rows processed. created, updated, linked and
not_imported are set when it finishes. One import per channel account (and
one CSV) runs at a time: a second request answers 409 import_already_running.
requires_attention counts the items that may already exist in Nembol but
not with certainty: they come in paused (to_verify) until someone decides
(see Duplicates).
Undo an import
Undoing removes products from Nembol, so it asks for the same two-step
confirmation as every irreversible action. The first call answers
409 confirmation_required with a confirmation.token; show its summary to
the person and, if they agree, repeat the same request with the token:
curl -X POST https://api.nembol.com/rest/v1/imports/op_8fd2c1/undo \
-H "Authorization: Bearer $NEMBOL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Nembol-Confirmation: cfm_3kTq9Xb2"Send {"include_modified": true} as the body to also remove created products
edited after the import.
{
"import": {
"undone_at": "2026-10-08T10:12:00.000Z",
"undo": {
"removed": 309,
"unlinked": 32,
"kept": { "live_on_a_channel": 1, "modified_after_import": 0 }
}
}
}The undo removes from Nembol what the import added (the products it created
and the links it added to existing products) and never touches anything on
the channel: your eBay or Etsy listings stay exactly as they are. In the
API, the removed products' listings go with them: they leave
GET /listings and answer 404 by id.
- Products that are now live on a channel are always kept.
- Products edited after the import are kept, unless you pass
"include_modified": true. - Each import can be undone once, after it has finished.
After an undo, importing again brings the same items back.
Good practice for agents
- Check
GET /billing(plan headroom) before a big import, and say how many products the store can still add. - Tell the person what the import will do (only new items, linking by SKU,
the filters you set) and read
import.warningsback to them. - Keep the operation id: it's what you need to undo.
Last updated on October 20, 2026
Need help?
Email us and a human replies, usually within one business day.