返回资讯中心
外部精选
软件工程
#开发者实时流

Building a universal e-commerce catalog for agents

On September 20th, Amazon started blocking agents from shopping on their website. Users report that xAI's Grok and OpenAI's new agents can't get through either.

Hacker News 最新pencildiver2026/10/22 · 23 天前30 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

On September 20th, Amazon started blocking agents from shopping on their website. Users report that xAI's Grok and OpenAI's new agents can't get through either.

Yesterday, Walmart went the other way. They announced agent profiles, an MCP-based agent gateway, and a written set of rules for agents that shop on a customer's behalf.

We believe that agents are going to shop for humans no matter what. The question will become how they get in and what they find. We think the answer is an open door, and results that nobody can manipulate.

For context, Agora is a universal catalog for agents. An agent can search, buy, and track orders across more than 1 million online stores through one schema, one cart, and one checkout. Today we serve about 15 million agent requests a month, through distribution partners including Glance and Samsung TV Shopping.

This post explains how it works and why we built it this way.

Websites are built for people. Agents that shop through a browser are slow and break easily. That is true for one big retailer, and much worse across a million small ones.

We built one catalog for all of them. Agora ingests products from Shopify, WooCommerce, and custom stores into one data model. The catalog refreshes daily, and we check price and stock live when an agent interacts with a product.

There are two ways in. Browser agents get a dedicated /agent interface with stable selectors and machine-readable JSON. Programmatic agents get a REST API for search, cart, checkout, and order tracking.

The agent never handles card numbers. Payment goes through Stripe. The agent passes payment tokens, and by default it stops before payment so a person can confirm.

Ranking is not for sale. Agora holds no inventory, sells no products of its own, and takes no money for ranking. For an agent, the ranking is the whole product, so this matters more than it does for people.

Businesses pay us, not for placement. We make money from subscriptions and usage credits that we charge the businesses building on Agora. Merchants pay 0% commission.

It is not finished. We cover about 1 million of an estimated 25 million online stores. Daily data goes stale. Our permission model is simpler than Walmart's. We cover those gaps below.

Walmart said it in its announcement: agents that shop through a web browser follow "steps designed for people," which "can be slow and error-prone, and agents may get stuck along the way".

Now multiply that by a million stores. Each one has its own theme, its own checkout, and its own idea of what a "variant" is. A person asking an agent for "a quiet dishwasher under $800" doesn't want the agent to visit a few sites it happens to know. They want the best answer from all of them. No agent can open a million websites per query, and no team wants a million agents learning its DOM by trial and error.

Walmart's answer is a gateway for Walmart. That is a good answer for Walmart. It is not an answer for the independent shoe brand on Shopify, the kitchen store on WooCommerce, or the specialty retailer running its own stack. Most of them will never build an MCP server or write terms for agents. They still want to sell to people who shop through agents.

A universal catalog is one index of products from many stores, behind one interface. In practice it has four parts.

Ingestion. We bring stores into the catalog in three ways: platform-specific connectors for the big commerce systems such as Shopify and WooCommerce, custom connectors for selected merchants with their own stacks, and live data partnerships with larger retailers and marketplaces.

Normalization. Every product lands in the same data model, no matter where it came from. A product has an _id, a slug, a name, a brand, a price, an availability status, a store, and a list of variants, each with its own id, title, price, and availability. An agent learns this shape once and uses it everywhere.

Freshness. The catalog refreshes daily. Daily is good enough for search and ranking. It is not good enough for a purchase, because prices and stock change during the day. So when an agent opens a product or adds it to a cart, we check the live price and stock with the store. This is a deliberate tradeoff. A full real-time index of a million stores would be expensive and fragile. A daily index with live checks at the point of decision gives the agent fresh numbers where they matter.

Transactions. Search is only half the job. One cart can hold products from different stores, and one checkout places the order for all of them. Afterwards, one endpoint reports order status and tracking.

Agents today come in two broad types, and they want different things. So Agora has two interfaces over the same catalog.

Perplexity, OpenAI Operator, Claude Computer Use, Browser-Use

/agent/search → /agent/product/[slug] → #agent-add-to-cart → /agent/cart → /agent/checkout

Custom LLM tools, MCP servers, backend scripts

/api/search → product JSON → /api/agent/cart → /api/agent/checkout

Both start in the same place. An agent can fetch a JSON manifest at GET /api/agent-routes that lists the live routes, the DOM selectors, and the schema contracts. The same protocol is published in Markdown at /agents.md and /llms.txt, because many agents read Markdown more reliably than they read HTML. The full contract is on our agent routes page.

We could have told browser agents to use the API. Most of them can't. Browser agents are general-purpose. They don't read our docs before they arrive, and they don't carry API keys. They land on a page and try to make sense of it. So we built pages that are easy to make sense of.

The /agent routes are a separate interface from our consumer site. They render the same catalog with a few rules.

Everything is addressable by URL. An agent doesn't need to find a search box and type into it. It can open /agent/search?q=quiet%20dishwasher&page=1 directly. Fewer steps means fewer chances to fail.

Selectors are a contract, not an accident. Every element an agent needs has a stable id or a data-agent-* attribute: #agent-product-list, .agent-product-item, #agent-add-to-cart, #agent-submit-order. These don't change when we change the design. Each product card carries its id, slug, name, and price as attributes, so an agent can read a results page without parsing any visible text:

<li class="agent-product-item" data-agent-product-id="..." data-agent-product-slug="..." data-agent-product-name="..." data-agent-product-price="$499.00">

The full object is on the page. Every product page includes the complete product as JSON in pre#agent-product-raw-json. The agent reads it with .textContent and calls JSON.parse(). (Not .innerHTML, which escapes & as & and breaks the parse. We learned that from watching agents fail.)

State is explicit. After a click, an agent has to guess whether anything happened. We tell it. The add-to-cart button sets data-agent-cart-status to idle, adding, added, or error. Checkout sets data-agent-checkout-status to idle, invalid, or awaiting-payment. The agent waits for a value, not for a spinner to disappear.

There is a clear place to stop. The checkout form is plain and labelled. If the agent's policy requires a person to confirm payment, it fills the shipping form, submits, and hands off to the person to finish.

None of this is new technology. It is the kind of discipline you'd apply to a public API, applied to HTML.

For agents that run headless, such as backend tools, MCP servers, and partner integrations, there is a REST API. Search needs no key:

GET /api/search?q=quiet%20dishwasher&page=1&count=20

The authenticated v1 API lives at https://zues.searchagora.com/api/v1:

const res = await fetch( 'https://zues.searchagora.com/api/v1/search?q=quiet%20dishwasher&count=5', { headers: { Authorization: Bearer ${process.env.AGORA_API_KEY} } }, ) const data = await res.json() // data.Products[] — use ._id for cart and checkout

A purchase takes three calls. First, set the cart:

POST /api/agent/cart { "items": [{ "product": "<_id>", "quantity": 1, "variantId": "<variantId>" }] }

Second, create a Stripe PaymentIntent with POST /api/agent/payment-intent. This returns a clientSecret and a publishableKey. The payment is confirmed with Stripe, using Stripe.js, Elements, or the Stripe API. The result is a payment method id (pm_…) and a PaymentIntent id (pi_…).

Third, place the order with POST /api/agent/checkout, passing the two ids and a shipping address. Checkout can also accept items directly, so the cart and order can happen in one call.

The agent never sees a card number. It handles Stripe tokens, not payment details. This is the same principle Walmart wrote into its agent terms: agents "don't receive customers' payment-card information and can't add or change a customer's payment methods". It is also at the heart of Amazon's complaint about Muse, which Amazon says "appears to capture and store customer credentials". Meta disputes that. Either way, the safest design is one where the agent never has the credential to begin with.

Defaults are forgiving, errors are precise. Many products have only one variant. If an agent leaves out variantId, we default it to the product's _id rather than failing. But a malformed id returns 400 and an unknown product returns 404, so the agent can tell "you sent garbage" from "that product is gone".

Buying is not the end of a shopping task. People ask "where's my order?" and agents need to answer. GET /api/agent/orders/[orderId] returns the status, a carrier tracking link, and an estimated delivery date:

{ "orderId": "12345", "status": "SHIPPED", "trackingUrl": "https://tools.usps.com/go/TrackConfirmAction?tLabels=...", "estimatedDelivery": "2026-10-24" }

An API key can only read its own orders.

When a person shops on Amazon, they scroll past the ads. Consumers' Checkbook searched Amazon for 50 products and found that, on average, 54% of the first 25 results were paid placements, and the top two to five results were always ads.

An agent doesn't scroll. It reads the results it's given and picks from them. If the ranking is for sale, the agent's answer is for sale too, and the person on the other end never sees the label that says "Sponsored".

This is part of why the agent question is hard for big retailers. Bank of America analysts, writing about Walmart's agent strategy, noted that if "screenless computers are the ones checking out, it remains unclear what happens to the advertising landscape". A retailer with a large ad business has a reason to want people on its pages, not agents.

Agora doesn't have that conflict. We hold no inventory. We sell no products of our own. We take no money for ranking, and we charge merchants 0% commission. Results are ordered by how well they match what the person asked for, and nothing else. When an agent asks Agora for the best quiet dishwasher, the answer isn't shaped by who paid.

So how do we make money? Businesses that build on Agora, such as agent developers and distribution partners, pay a subscription and buy credits for usage. That's the whole model. Shoppers don't pay us, merchants don't pay us, and nobody pays us for position. Our incentive is to return the best result, because that's what our customers are paying for.

It would be easy to cast Amazon as the villain here. That would not be fair.

Amazon's stated concerns are real. Its position is that agents "should operate openly and respect service provider decisions about whether or not to participate". Its terms ask agents to identify themselves, not pose as humans, and not get around its limits. Those are reasonable rules. An agent that logs in as a person, holds their password, and clicks around undisclosed is a security problem, whatever its intentions.

Walmart's rules are reasonable too. Agents get their own profile. Purchases need approval by default, or must stay under a spending limit the customer sets. Agents can't take actions beyond what the shopp

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →