Amazon Add Product to Cart

Site amazon.comTask add-product-to-cartVersion v2Updated Aug 5, 2026Category ecommerce

Find a product matching a natural-language query on Amazon, resolve its ASIN from search results, verify the product page matches the requested criteria, add it to the cart, optionally replace an existing cart item, and confirm the resulting cart state. This skill was captured from a live agent session on amazon.com and publishes here verbatim, exactly as an agent receives it.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Purpose

Find a product satisfying the caller's criteria on Amazon.com, resolve its opaque ASIN from search results, verify the product detail page, add it to the shopping cart, and return confirmation data. When the caller explicitly requests replacement, inspect the active cart after adding the new item and delete the specified old item using Amazon's cart DOM controls.

When to Use

  • Add a product matching a natural-language request to the Amazon.com cart.
  • Requests involving capacity, product type, technology exclusions, brand, price, or similar criteria.
  • Requests to replace an existing cart item with a newly selected product.
  • Any flow where the caller does not already provide an ASIN.

Workflow

  1. Use one stealthed browser session with a US residential proxy on every call:
{ "proxy": { "proxy": "residential", "proxyCountry": "us" } }

Warm https://www.amazon.com/ first in that same session, then navigate directly to the encoded search URL. Use + for spaces and optionally add i=electronics:

https://www.amazon.com/s?k={url-encoded-query}&i=electronics

Use a query containing the requested capacity, product class, and exclusions, such as {query}. Wait for div[data-component-type="s-search-result"], then resolve candidates with this evaluator:

(() => {
  const intnum = (s) => {
    if (!s) return null;
    const m = String(s).replace(/[^0-9]/g, "");
    return m ? parseInt(m, 10) : null;
  };
  const num = (s) => {
    if (!s) return null;
    const m = String(s).replace(/[^0-9.]/g, "");
    return m ? parseFloat(m) : null;
  };
  const out = [],
    seen = new Set();
  for (const c of document.querySelectorAll(
    'div[data-component-type="s-search-result"][data-asin]',
  )) {
    const asin = c.dataset.asin;
    if (
      !asin ||
      seen.has(asin) ||
      c.matches('[data-component-type="sp-sponsored-result"]') ||
      c.querySelector(
        '.puis-sponsored-label-text,.s-sponsored-label-text,[aria-label*="Sponsored"]',
      )
    )
      continue;
    const img = c.querySelector("img.s-image"),
      h2 = c.querySelector("h2"),
      p = c.querySelector(".a-price:not(.a-text-price) .a-offscreen"),
      r = c.querySelector(".a-icon-alt");
    let reviewCount = null;
    for (const e of c.querySelectorAll("[aria-label]")) {
      const a = e.getAttribute("aria-label");
      if (/^[\d,]+\s+ratings?$/i.test(a)) {
        reviewCount = intnum(a);
        break;
      }
    }
    seen.add(asin);
    out.push({
      asin,
      title:
        (img?.alt || "").replace(/^Sponsored Ad\s*-\s*/i, "").trim() ||
        h2?.innerText?.trim() ||
        null,
      price: p?.textContent?.trim() || null,
      priceValue: num(p?.textContent),
      rating: r?.innerText?.trim() || null,
      reviewCount,
      url: `https://www.amazon.com/dp/${asin}`,
    });
  }
  return JSON.stringify({ results: out });
})();

Select a non-sponsored candidate satisfying every constraint. For exclusions such as “not SSD,” reject titles or visible attributes identifying SSD, solid-state, flash, or another excluded technology. Never guess an ASIN; read it from the matching search card.

  1. Navigate directly to https://www.amazon.com/dp/{asin} in the same session. Verify the title, capacity, product type, and exclusions on the detail page before adding. If needed, append ?th=1 to select the default variation. Wait for #add-to-cart-button or input#add-to-cart-button, then click the visible add-to-cart control. Do not click Buy Now.

  2. Confirm the add operation with a compact evaluator on the resulting page:

(() => {
  const body = document.body.innerText || "";
  const count =
    document.querySelector("#nav-cart-count")?.textContent?.trim() || null;
  const confirmation = /added to (your )?cart|added to basket/i.test(body);
  const asin = (location.pathname.match(/\/dp\/([A-Z0-9]{10})/i) || [])[1] || null;
  return JSON.stringify({
    success: confirmation || !!count,
    added: confirmation,
    asin,
    cartCount: count,
    url: location.href,
  });
})();

If there is no confirmation, inspect the add control and retry it once.

  1. If replacement was requested, navigate directly to https://www.amazon.com/gp/cart/view.html, wait for active cart items, and extract them with:
(() => {
  const seen = new Set(),
    items = [];
  for (const el of document.querySelectorAll(
    'div[data-name="Active Items"] div[data-asin],div.sc-list-item[data-asin],[data-itemtype="active"] [data-asin]',
  )) {
    const asin = el.getAttribute("data-asin");
    if (!asin || seen.has(asin)) continue;
    const title = el.querySelector(
        ".sc-product-title,.a-truncate-cut,[class*=item-title],.sc-grid-item-product-title",
      ),
      price = el.querySelector(
        ".sc-product-price,.a-price .a-offscreen,[class*=price]",
      ),
      qty = el.querySelector(
        "input[name=quantity],.sc-quantity-textfield,[data-quantity]",
      );
    if (title || price) {
      seen.add(asin);
      items.push({
        asin,
        title: title?.innerText.trim().replace(/\s+/g, " ") || null,
        price: price?.innerText.trim().replace(/\s+/g, " ") || null,
        qty: qty ? (qty.value || qty.innerText || "").trim() : null,
        container: el.tagName.toLowerCase(),
      });
    }
  }
  const sub = document.querySelector(
    '#sc-subtotal-amount-activecart,#sc-subtotal-amount-buybox,[data-name="Subtotal"]',
  );
  return JSON.stringify({
    subtotal: sub?.innerText.trim() || null,
    itemCount: items.length,
    items,
  });
})();

Identify the old item by the caller's replacement description, title, or ASIN. Within that item's container, use the cart delete control input[data-action="delete-active"] and click it. If the container itself is a nested [data-asin] node, locate its nearest active-item ancestor before searching for the delete input. Wait for the cart to update, then rerun the cart evaluator and verify that the new ASIN remains active and the old item is absent. If no replacement was requested, skip deletion.

  1. Return the selected product, add confirmation, cart count, active items, and any replacement-deletion result. If Amazon blocks the session, stop and report the Robot Check or CAPTCHA.

Site-Specific Gotchas

  • Amazon search and product URLs are frequently bot-walled for cold or datacenter sessions. Warm https://www.amazon.com/ first in the same residential-proxy session.
  • Pass the identical proxy configuration on every follow-up call so cookies and the warmed browser session persist; pin proxyCountry: "us" for the US storefront.
  • Search results contain sponsored placements and repeated cards. Exclude sponsored cards and deduplicate by data-asin.
  • The full product title is often in img.s-image[alt]; <h2> may contain only a shortened brand or label.
  • Product identifiers are opaque. Always read the selected ASIN from a matching search card before constructing /dp/{asin}.
  • Amazon may expose the add control as either #add-to-cart-button or input#add-to-cart-button; never use #buy-now-button.
  • A product can have multiple variations. Verify the selected capacity and type on the detail page; append ?th=1 only when needed.
  • Do not treat the cart icon alone as proof. Verify confirmation text, cart count, or active-cart ASINs.
  • For replacement, add the new item before deleting the old one, then verify both the new item's presence and the old item's absence. The cart delete control observed for active items is input[data-action="delete-active"].
  • Cart pages may expose multiple nested [data-asin] elements. Deduplicate ASINs and only emit records with a title or price element.
  • Avoid snapshot or whole-page dumps on Amazon search/cart pages; use targeted evaluators.
  • If Amazon presents a Robot Check or CAPTCHA, stop and report the block rather than repeatedly navigating.

Expected Output

{
  "success": true,
  "asin": "{resolved-asin}",
  "title": "{selected-product-title}",
  "url": "https://www.amazon.com/dp/{resolved-asin}",
  "added": true,
  "replaced": true,
  "removedAsin": "{old-asin-or-null}",
  "cartCount": "{count}",
  "items": [],
  "error": null
}

For a normal add without replacement, use replaced: false and removedAsin: null. If no matching item is found, return success: false, asin: null, added: false, and an explanatory error. If Amazon blocks the session, return success: false, added: false, and an error identifying the Robot Check or CAPTCHA.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=amazon.com&task=add-product-to-cart