Skip to main content

Use shelf data from your own code or agent

Shelf data is the Amazon page as a shopper at a given location sees it: the search results page for a keyword, the Buy Box for an ASIN, the whole offer list, the product page, a seller's storefront. The MixShift plugin's Amazon Shelf skill is one way in; this article is the other two: the REST endpoints for your own code and automations, and the shelf_* tools for AI clients over MCP. Beta, on for every organization. Full reference: mcp.mixshift.io/developers#shelf.

Where the data comes from, and what it is not

Public shelf observations from a licensed third-party shelf-data provider, through MixShift's service on MixShift's own key. No call uses your Amazon authorization, and nothing of yours is sent: an ASIN, a keyword or a seller id is the only input. It is not your account's data (that is the retail surface), not sales estimates ("bought in past month" is the label Amazon puts on its own page), and nothing here writes anywhere.

Access

  • Scope: shelf:read. Interactive sign-ins hold it, and so does a sign-in from a ChatGPT custom app or a Claude, Cursor or Codex connector. A service credential minted at /admin gets it by default; a tenant admin can deny it per person.
  • Organization: your account must belong to a MixShift organization (every customer does). If a call answers shelf_not_enrolled, ask MixShift.
  • Allowance: every data answer counts one against your organization's monthly shelf allowance (a larger discovery allowance in the first month, a monthly one after; no rollover). GET /api/shelf/usage and the zip list are free. See "When you run out" below.

The calls

REST MCP tool Body What comes back in data
POST /api/shelf/search shelf_search { "query", "surface": "desktop" or "mobile", "page": 1 to 5, "zip", "country", "fresh" } every position with rank, absolute_rank, is_sponsored, price, rating, reviews, monthly_sales, badges, coupon, stock text, delivery promise; banners (sponsored brands with brand and headline); related_keywords, total_results, has_more. Desktop is 60 positions a page, mobile 15. One page is one answer.
POST /api/shelf/buybox shelf_get_buybox { "asin", "zip", "country", "fresh" } price, seller and seller_id, ships-from, Prime, stock, free_delivery and fastest_delivery as text and as promise_days_*
POST /api/shelf/offers shelf_get_offers { "asin", "zip", "country", "fresh" } the featured offer plus offers[]: price and price_num, fba, condition, seller_id, promise days
POST /api/shelf/product shelf_get_product { "asin", "zip", "country", "fresh" } title, bullets, details, media, best-seller ranks, rating, badge, the Buy Box block, "customers say"; the answer carries beta: true (a field can be missing)
POST /api/shelf/seller shelf_get_seller { "seller_id", "country", "fresh" } storefront name, rating, description, business details
GET /api/shelf/zips?country=us shelf_list_zips the shopper locations per country (us default; ca uk de fr it es in). Free.
GET /api/shelf/usage shelf_get_usage period, allowance, used, remaining, resets_at. Free.

Only query, asin or seller_id is required. zip is a location from the zip list (omit for the default location; a zip off the list is refused for free). country defaults to us. fresh: true asks for the shelf as of now instead of a recent observation, at the same cost.

A keyword rank call from your own code:

POST https://mcp.mixshift.io/api/shelf/search
Authorization: Bearer <token>
Content-Type: application/json

{ "query": "backpacking meals", "surface": "mobile", "zip": "10001" }

Every data answer has one shape:

{ "ok": true, "kind": "search_mobile", "retailer": "amazon", "country": "us", "zip": "10001",
  "subject": "backpacking meals", "observed_at": "2026-10-20T14:41:13.187Z", "source": "shelf",
  "data": { "surface": "mobile", "page": 1, "page_size": 15, "products": [ ... ], ... } }

observed_at is when the shelf looked like this. MixShift may answer from a recent observation (hours for rank, the Buy Box and offers; a day for the product page; a week for a seller); nothing in the answer says how it was produced. Rank on page n is absolute_rank = (n - 1) * page_size + rank.

From ChatGPT, Claude, Cursor or Codex

Connect the MixShift MCP server as described in Connect AI tools over MCP; the sign-in grants shelf:read with the rest. The seven tools then appear next to the warehouse and Amazon tools, and a question such as "where do we rank for backpacking meals in New York on mobile?" maps to shelf_search. The tool descriptions say what each call costs; the allowance is per organization, so a connector and the plugin draw on the same monthly number.

Tracking rank over time

Every observation MixShift takes is kept and dated, so calling the same keyword at the same zip on a schedule (your own cron, n8n, or a MixShift scheduled task) builds a dated series. A MixShift-run tracked keyword list, with the history on a page and feeding the daily health check and the monthly report, is the next thing being built on this data; to be first on it, send MixShift your keywords, locations and cadence (from the plugin, "track these keywords for me"; or email MixShift). Daily observations count against the allowance like any other answer until history is priced.

When you run out

The call answers 402 shelf_allowance_exhausted with period, allowance, used, resets_at and request_more, which says how to ask for more: from the plugin, "request more shelf requests" sends the request with your organization and period; or reply to any MixShift message. MixShift raises the allowance from your organization's settings, with effect this month.

Errors

The usual envelope, { "ok": false, "kind", "friendly", "source", "retryable", ... }; branch on kind:

kind status meaning
shelf_not_enabled 403 shelf data is switched off for your organization; ask MixShift
shelf_not_enrolled 403 your account has no organization yet; ask MixShift
shelf_allowance_exhausted 402 the month's allowance is used; see above
zip_unavailable 400 not a location on the list (available_count says how many are)
bad_request 400 refused as sent, for example no such ASIN or seller; do not resend unchanged
invalid_request 400 the body did not pass; nothing was sent
throttled 429 retry after retryAfterMs
upstream_unavailable 502 shelf data is temporarily unavailable; retry in a minute

For the general failure contract (who acts, whether to retry), see When a call fails.

Still have questions?
Ask Shifty

Shifty is the MixShift docs assistant. Pick a question or open the chat for anything else.