Duplicates: Requires attention and Same product
How imports handle products that may already exist, how to resolve them, and how to merge two products into one.
When a channel import finds an item that could be a product already in
Nembol (but not with certainty), it doesn't guess and it doesn't discard
it: the item comes in paused, with status to_verify ("Requires
attention" in the dashboard). It is not published, synced or linked until
someone decides.
Find what needs attention
curl "https://api.nembol.com/rest/v1/products?status=to_verify" \
-H "Authorization: Bearer $NEMBOL_API_KEY"Each product explains why in requires_attention:
{
"id": "prod_7c1e",
"status": "to_verify",
"requires_attention": {
"reason": "ambiguous_match",
"message": "The SKU matches more than one product in Nembol",
"channel": "etsy",
"conflicting_product_ids": ["prod_51aa", "prod_51ab"],
"detected_at": "2026-10-13T10:00:00.000Z"
}
}Imports report how many items came in this way (import.requires_attention
in the operation). While a product is to_verify, listing writes answer
409 product_requires_attention and SKU-matched inventory writes skip it.
Resolve it
Two ways out:
- It's the same item as an existing product → merge them with
POST /products/merge(below). This also resolves it. - Otherwise →
POST /products/{id}/resolve:
resolution | When |
|---|---|
keep_independent (+ with) | It's a different product from those in with. Remembered: never proposed again. If with leaves out some conflicting products, it stays to_verify with the others. Check resolved_ids. |
made_to_order | Etsy listing with one quantity for all variants, made to order: every variant keeps that quantity. |
recheck | The seller fixed the Etsy setting: Nembol reads the listing again (409 still_requires_attention if not fixed yet). |
ignore | Not wanted in Nembol: the product is deleted and future imports skip that channel listing. Nothing changes on the channel. |
The Etsy reasons (etsy_shared_quantity, etsy_processing_profiles) are
channel settings, not duplicates: keep_independent answers
409 resolution_not_applicable for them.
Ignored listings are listed by GET /ignored_listings;
DELETE /ignored_listings/{id} stops ignoring one, and the next import of
that channel brings it in again.
Merge two products (Same product)
curl -X POST https://api.nembol.com/rest/v1/products/merge \
-H "Authorization: Bearer $NEMBOL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product_ids": ["prod_51aa", "prod_7c1e"], "survivor_id": "prod_51aa", "dry_run": true}'- The survivor keeps its id; the others are archived with
merged_intoand their listings move to the survivor. One stock per variant is then shared by every channel. - Always send
dry_run: truefirst and show the preview:title,variantsand what each channel will show (listings). choicespicks, per field, which product a value comes from (default: the survivor):title,description,sku,barcode,price,quantity,photos,tags,category. For example:"choices": {"photos": {"from": "prod_7c1e"}, "quantity": {"values": {"var_1": 5}}}. Takingphotosbrings that product's variant images too. The channels keep their own titles and descriptions.- Products that don't look alike are listed in
looks_different: merging them needsconfirm_different: true. - Refused when two products are live on the same channel account
(
422 same_channel_account). - Undoable for 30 days with
POST /actions/{id}/undo(the id is in theNembol-Action-Idheader).
Variants that don't correspond
Variants are matched by SKU, then by option values. When that fails the merge
answers 422 variants_differ with error.details.matching: both variant
lists and a suggestion. If manual_allowed is true (the absorbed product
is live only on Etsy, Shopify or WooCommerce, with the same number of
variants), match them yourself and send the merge again:
{
"product_ids": ["prod_51aa", "prod_7c1e"],
"survivor_id": "prod_51aa",
"variant_maps": { "prod_7c1e": { "var_e1": "var_a1", "var_e2": "var_a2" } }
}The map must be complete and one to one. After the merge the channel's variants take Nembol's names (and SKUs where the channel allows).
Events
A merge emits product.updated for the survivor (data.merged) and
product.deleted for each absorbed product (data.merged_into). A
resolution emits product.updated (product.deleted for ignore).
Good practice for agents
- Never resolve or merge on your own: show the person the conflicting products side by side and let them choose.
- Use
dry_runbefore every merge, and keep the action id to undo.
Last updated on October 15, 2026
Need help?
Email us and a human replies, usually within one business day.