# BuyWise

> BuyWise gives AI shopping agents trust signals about brands and product listings: what kind of brand it is, and how a brand or a listing looks on white-label products, quality, price, discounts, reviews and sellers. Every answer is a set of findings, each with a confidence. There is never a buy or avoid verdict: the agent weighs the signals for its user.

Use it when a user is looking at a product or a brand and wants to know whether it's trustworthy, a generic white-label item, fairly priced, or really discounted. Answers come back in a fraction of a second. The same checks are available over MCP and REST.

## What it answers

- **Brands**: what kind of brand it is (established, independent maker, store brand, generic white-label, little-known), its build-quality reputation, and its price positioning (budget, value, mid-range, premium, luxury). A product check reports on the brand its `brand` field names.
- **Product listings**: whether it's a generic white-label product, its quality signals, its price against what's typical, whether a "was" price is a fake discount, whether the reviews look credible, and whether the seller looks legitimate. A check runs only when you send the evidence it judges: price for the price check; price plus listPrice, or a "was" price in the title or details, for fake discounts; rating or reviewCount for reviews; seller or url for the seller.
- **Findings**: each has a tone (good, warn or bad), a confidence from 0 to 1 and a certainty (very likely, likely, unsure). Cautions and red flags carry a one-line "why". Every report has a one-line summary an agent can quote.
- **Unavailable findings**: a brand whose findings couldn't be produced (service busy, or a failed check) still comes back, with its name, empty `instincts` and an `error` field.
- **Where the text comes from**: apart from the names and ids you send, which are echoed back as given, response text is BuyWise's own fixed wording. Nothing is fetched from or copied out of the listing's page.

## Connect over MCP

MCP endpoint: https://api.buywise.fyi/mcp

Streamable HTTP, stateless, JSON responses. Protocol versions 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05. No sign-up needed for the free checks; to use an API key, send it as an `Authorization: Bearer <API key>` header. Assistants can sign each person in with OAuth 2.1 (authorization code with PKCE; metadata at https://api.buywise.fyi/.well-known/oauth-authorization-server), with Google, an emailed code or a BuyWise Pro license key. A signed-in person's checks are their own, wherever their assistant calls from. Tools: `check_brands`, `check_product` and `check_products`, all read-only, taking the same fields as the REST API below.

- ChatGPT: in developer mode, add a custom MCP app (plugin) with this URL and no authentication.
- Claude Code: `claude mcp add --transport http buywise https://api.buywise.fyi/mcp --header "Authorization: Bearer <API key>"`. Leave out the header to use the free checks.
- Claude's apps (claude.ai, desktop and mobile) need a BuyWise account connected before the first check. Add a custom connector with this URL, and Claude asks you to sign in when you connect it.
- Meta Muse: add BuyWise from Muse's connectors, or a custom connector for this URL, and sign in when Muse asks.
- Gemini, Perplexity, Cursor and other MCP clients: add this URL as a remote (Streamable HTTP) MCP server.
- OpenAI Responses API and Agents SDK: `{"type": "mcp", "server_label": "buywise", "server_url": "https://api.buywise.fyi/mcp", "require_approval": "never"}`. Perplexity's Agent API takes the same `mcp` tool without `require_approval`. For an API key add `"authorization": "<API key>"`, sent with every request.
- Gemini API managed agents: `{"type": "mcp_server", "name": "buywise", "url": "https://api.buywise.fyi/mcp"}`.
- [MCP server card](https://api.buywise.fyi/mcp/server-card): name, version and connection details as JSON.

## REST API

JSON in, JSON out, base URL https://api.buywise.fyi.

- [OpenAPI 3.1](https://api.buywise.fyi/agent/v1/openapi.json): every endpoint and schema.
- [API index](https://api.buywise.fyi/agent/v1): endpoints, auth, limits and error codes as JSON.
- `GET /agent/v1/brand?name=&detail=`: check a brand.
- `POST /agent/v1/brands` `{"brands": [...]}`: check several brands, up to 50.
- `POST /agent/v1/product` `{"product": {...}}`: check a product listing.
- `POST /agent/v1/products` `{"products": [...]}`: check several product listings, up to 20.

```sh
curl 'https://api.buywise.fyi/agent/v1/brand?name=Anker'

curl -X POST https://api.buywise.fyi/agent/v1/brands -H 'Content-Type: application/json' \
  -d '{"brands":["Anker","Amazon Basics","ZXQVLM"]}'

curl -X POST https://api.buywise.fyi/agent/v1/product -H 'Content-Type: application/json' \
  -d '{"product":{"title":"Robot Vacuum Cleaner, 4000Pa Suction, Self-Charging, Was $399.99","brand":"ZXQVLM","price":129.99,"listPrice":399.99,"currency":"USD","url":"https://www.example.com/p/robot-vacuum-4000pa","seller":"ZXQVLM Direct","rating":4.7,"reviewCount":1843}}'

curl -X POST https://api.buywise.fyi/agent/v1/products -H 'Content-Type: application/json' \
  -d '{"products":[{"id":"a","title":"Anker 737 Power Bank (PowerCore 24K)","brand":"Anker","price":89.99,"url":"https://www.example.com/p/anker-737"},{"id":"b","title":"Power Bank 50000mAh Fast Charging Portable Charger","price":19.99,"listPrice":59.99,"rating":4.8,"reviewCount":212}]}'
```

Success is `{"ok": true, "brand": {...}}`, `{"ok": true, "brands": [...]}`, `{"ok": true, "product": {...}}` or `{"ok": true, "products": [...]}`, each with its `quota` (see Limits, keys and payment). In a batch, a listing that can't be checked gets its own `{"id", "error", "message"}` entry, a brand the checks didn't reach a `{"query", "error", "message"}` entry, and the rest still succeed.

## Errors

Errors are `{"ok": false, "error": "<code>", "message": "...", "retryAfter": <seconds>}`; `retryAfter`, and a Retry-After header, come when waiting helps, and a refusal for running out of checks also carries `quota`.

- `bad_request` (400): Malformed request. The message names the first bad field.
- `unauthorized` (401): The API key is malformed, unknown or revoked (leave out Authorization to use the free checks), or this connection needs a BuyWise account connected first.
- `payment_required` (402): Pay for the request with x402 (see the PAYMENT-REQUIRED header). Only over REST, and only for callers without an API key.
- `blocked_site` (403): The listing's site isn't checked: banking, health, government, email, sign-in and private hosts.
- `too_many_items` (413): The batch is larger than the limit.
- `quota_exceeded` (429): Today's free checks are used up. They come back at 00:00 UTC.
- `allowance_reached` (429): The Pro plan's checks for this billing month are used up. They come back when the next billing month starts.
- `throttled` (429): Today's fair-use limit is reached. It resets at 00:00 UTC.
- `rate_limited` (429): Too many requests this minute.
- `budget_exhausted` (503): The service is busy; try again later. A listing check answers 503; a brand check still answers, with its findings empty and "error": "budget_exhausted".
- `upstream` (503): A check couldn't be completed. Try again in a moment.

## Product fields

Only `title` is required. Each extra field sharpens the read.

- `title`: the product title exactly as the listing shows it.
- `brand`: the brand or maker, if the listing names one.
- `price`: what the buyer would pay now. Strings such as "$1,299.99" are fine.
- `currency`: ISO 4217 code for the prices. Default USD.
- `listPrice`: the seller's "was" or "list" price, if shown. Needed for the fake-discount check.
- `url`: the listing URL. Only its domain is used.
- `seller`: the seller or store name.
- `category`: e.g. "Headphones".
- `rating`: average stars out of 5. "4.5 out of 5" is fine.
- `reviewCount`: number of ratings or reviews. "12,345 ratings" is fine.
- `details`: key specs or bullet points as plain text. Long text is trimmed.
- `id`: your own id, echoed back so batch results can be matched up.
- Options: `detail: true` adds each finding's full probability distribution. `includeBrand: false` leaves the brand report out of product checks.

Field names from the Agentic Commerce Protocol (ACP) product feed and common snake_case variants are accepted as they are: `sale_price` (what the buyer pays now, which makes `price` the list price), `seller_name`, `store_name`, `star_rating`, `average_rating`, `review_count`, `rating_count`, `ratings_count`, `list_price`, `name`, `product_name`, `product_category`, `description`, `link`, `product_url` and `seller_url`. A price such as "79.99 USD" carries its own currency.

## Limits, keys and payment

- Each brand or listing checked counts as one check. Days are UTC.
- Free: 1000 checks a day.
- An API key is optional: a key's checks count against its own plan. Send it as `Authorization: Bearer <key>`, over REST or MCP. A malformed, unknown or revoked key gets 401 rather than falling back to the free checks.
- Up to 50 brands or 20 listings per request; 300 requests a minute without a key, 1,200 with one.
- Every successful answer carries `quota`: `plan` ("free" or "pro"), `used` (checks counted today), `limit` (today's free checks; null on Pro), `resetsAt` (the next 00:00 UTC, when today's count resets), `period` (Pro only: the billing month, with `start`, `end`, `included` and `used`). MCP tool results carry the same `quota` in their structured content.
- When checks run out partway through a request, the items that fit are checked and the rest carry `"error": "quota_exceeded"`.
- No key? Over REST, pay per check with x402 (protocol v2): $0.01 per check in USDC on Base. A request is priced at one check per brand or listing it checks. No sign-up. MCP never asks for payment.
- Send the request as usual. Once your free checks are used up you get HTTP 402 with a PAYMENT-REQUIRED header; sign it with any x402 client (exact scheme, EIP-3009) and resend the same request with PAYMENT-SIGNATURE. You're charged only when the check succeeds, and the answer carries PAYMENT-RESPONSE. Callers without an API key get that 402 (`"error": "payment_required"`, with the same `retryAfter`) instead of a 429 once their free checks are used up. A request that carries PAYMENT-SIGNATURE always takes the paid route and uses none of the free checks. Callers with an API key never get a 402.

## Privacy

- From a URL only the listing's domain is used. The path and query are dropped before anything else happens.
- Banking, health, government, email and sign-in sites, and private or local hosts, are refused and never checked.
- Personal details such as emails and phone numbers are redacted from free text before it's checked.
- No data is sold or used for ads, and responses carry no ads, sponsored results or affiliate links.
- [Privacy policy](https://buywise.fyi/privacy)

## Optional

- [Generic white-label products](https://buywise.fyi/learn/white-label)
- [Fake discounts](https://buywise.fyi/learn/fake-discounts)
- [When a price is too low, or too high](https://buywise.fyi/learn/pricing)
- [Judging quality from a listing](https://buywise.fyi/learn/product-quality)
- [Reviews you can't trust](https://buywise.fyi/learn/reviews)
- [Checking who's selling](https://buywise.fyi/learn/sellers)
- [BuyWise](https://buywise.fyi): the browser extension that runs the same checks for people. Support: support@buywise.fyi
