Undo and confirmations

Every change your app or agent makes is logged with before/after values and can be undone for 30 days; irreversible actions ask for a two-step confirmation first.

Two rules keep a store safe when an app (or an AI agent) operates it:

  1. Everything can be traced and most things can be undone. Each change is recorded in the action log with who made it and the exact values before and after. For 30 days you can undo it.
  2. What can't be undone asks first. Delisting, disconnecting a channel, removing variants, refunding a storefront order, undoing an import and closing a company all use the same two-step confirmation.

Find what was done

Every write answers with a Nembol-Action-Id header, irreversible ones included (shipping an order, delisting, disconnecting). A replay of the same Idempotency-Key (Idempotent-Replayed: true) isn't a new write: it records no action and has no header. The full log:

curl "https://api.nembol.com/rest/v1/actions?product_id=prod_66f0a1" \
  -H "Authorization: Bearer $NEMBOL_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "act_66f0b2",
      "object": "action",
      "type": "product.update",
      "summary": "Edited product \"Blue mug\"",
      "actor": { "type": "api_key", "name": "Inventory agent", "via": "mcp" },
      "reversibility": "reversible",
      "undoable": true,
      "undoable_until": "2026-11-07T10:00:00.000Z",
      "items": [
        {
          "product_id": "prod_66f0a1",
          "changes": [
            { "path": "fields.title", "before": "Blue mug", "after": "Big blue mug" },
            { "path": "variants.66f0a2.price", "before": "10.00", "after": "12.00" }
          ]
        }
      ],
      "created_at": "2026-10-08T10:00:00.000Z"
    }
  ]
}

Logged: product create/edit/delete/restore, variant and inventory changes, price adjustments, product batches, imports, channel-account settings (also when changed in the dashboard), publishes, delists, shipments and connect/disconnect. Kept 90 days. Reading needs events:read or products:read.

Undo

Preview first:

curl -X POST https://api.nembol.com/rest/v1/actions/act_66f0b2/undo \
  -H "Authorization: Bearer $NEMBOL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run": true}'
{
  "object": "undo_preview",
  "status": "simulated",
  "outcome": "partial",
  "items": [
    {
      "product_id": "prod_66f0a1",
      "restored": ["variants.var_66f0a2.price"],
      "unchanged": [],
      "conflicts": [{ "path": "fields.title", "reason": "changed_since", "current": "Mug v3" }]
    }
  ]
}

A dry run never undoes anything: status is always simulated and outcome says what the real undo would answer (undone, partial, conflict, nothing_to_undo). A merge undo lists every product: the survivor (role: "survivor": fields, variants and listings that go back) and each absorbed one (role: "absorbed": it comes back with its listings).

Then the same call without dry_run. How each value is treated:

The value nowWhat the undo does
Still what the action wrotePuts the old value back
Already the old valueNothing (unchanged)
Changed again since, by someone or by a channelLeaves it and reports a conflict
A quantityReverses the change as a delta: if the action set 5 → 8 and 2 sold since (6), the undo makes it 3. Sold stock is never re-added. Below zero → conflict

Restored products are re-sent to their channels. The undo is itself an action (undo_of points to the original) and an action can be undone once.

ActionUndo
Product edit, variant/inventory change, price adjustment, batchValues restored (re-synced to channels)
Product deleteProduct and its images back (also POST /products/{id}/restore)
Product createDeleted again, unless it's live on a channel
Channel-account settingsSettings restored
ImportCreated products removed and links undone (nothing on the channel)
PublishNot automatic. Delist it (DELETE /listings/{id}); channel fees aren't refunded
Delist, shipment notice, disconnectIrreversible (see below)

Deleted products and their images

A deleted product keeps its images for 30 days, so restoring it within that time brings them back. After 30 days the images are removed; the product data can still be restored, without them.

Two-step confirmation

Irreversible actions (DELETE /listings/{id}, POST /listings/batch with action: "delist", disconnecting a channel account…) first answer 409. Shipping an order (POST /orders/{id}/fulfillment) doesn't ask: it's the automated step of a fulfillment system, and the marketplace is notified at most once per order.

{
  "error": {
    "type": "invalid_request_error",
    "code": "confirmation_required",
    "message": "Delisting ends this listing on its channel. Publishing it again later creates a NEW listing … repeat the SAME request with header \"Nembol-Confirmation: cfm_3kTq9Xb2\" within 10 minutes."
  },
  "confirmation": {
    "token": "cfm_3kTq9Xb2",
    "summary": "Delisting ends this listing on its channel. …",
    "expires_at": "2026-10-08T10:10:00.000Z"
  }
}

Show confirmation.summary to the person. If they agree, send the same request again with the header:

curl -X DELETE https://api.nembol.com/rest/v1/listings/list_cHJvZF8x \
  -H "Authorization: Bearer $NEMBOL_API_KEY" \
  -H "Nembol-Confirmation: cfm_3kTq9Xb2"

Nembol asks for the confirmation only once the request is valid and the action is possible, so your app never asks a person to confirm something that can't happen:

  • an unknown company, import, listing or order answers 404 straight away;
  • an import already undone or a listing that can't be delisted answers its own error straight away;
  • closing a company that is already closed answers 200 with the company as it is: closing is idempotent, nothing to confirm;
  • a batch delist counts in its summary only the listings that would really end; when none would (unknown, already delisted, not delistable), it answers the per-item outcomes without a confirmation.

The summary names what the action is about (the product and the shop for a delist, the shop for a disconnect, the company for a close), so you can show it to the person as is.

The token works once, for that exact request, for 10 minutes. It's asked for keys created from 2026-10-08 and for every call made through the Nembol MCP server (Nembol-Client: mcp).

Good practice for agents

  • Keep the Nembol-Action-Id of what you did, so you can undo it precisely. Never "undo the last thing" blindly.
  • Preview with dry_run and tell the person about conflicts instead of forcing values.
  • Never confirm on the person's behalf: a confirmation_required answer is the moment to ask them.

Last updated on October 18, 2026

Need help?

Email us and a human replies, usually within one business day.

On this page