# CVS Pharmacy (cvs.com) — US drugstore catalogue, pricing, stock and coupons

> Keyword search over the cvs.com catalogue. Returns CVS's own result total, the product grid with full pricing, and optionally its live facet counts. Paging with `offset` walks the whole result set and stops honestly at the end. No sort or filter parameter is offered: CVS accepts both and then returns either zero rows or the unfiltered set, so neither can be sold.
> ReefAPI engine `cvs` · 3 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/cvs/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/cvs/v1/search — 2 credits
Keyword search over the cvs.com catalogue. Returns CVS's own result total, the product grid with full pricing, and optionally its live facet counts. Paging with `offset` walks the whole result set and stops honestly at the end. No sort or filter parameter is offered: CVS accepts both and then returns either zero rows or the unfiltered set, so neither can be sold.

**Parameters:**
- `query` (string, required) — Keyword to search the cvs.com catalogue for — a product type ('shampoo'), a brand ('Nature Made') or a full product name. A CVS product id also works and returns that one product. Nonsense keywords return an honest empty answer (total_results 0), not an error.
- `limit` (integer, optional, default 20) — Products to ask for, 1-48 (default 20). CVS injects its own sponsored tiles into every page, so the answer usually holds a FEW MORE rows than asked for (measured: 20 asked → 20-26 returned). Bytes grow with it: 20 ≈ 110 KB, 48 ≈ 334 KB.
- `offset` (integer, optional, default 0) — Rows to skip, for paging (default 0). Paging is real on this source: successive windows are different products, and an offset past the end returns zero rows with the true total still reported. Sponsored tiles are re-injected per page, so 0-1 id may repeat between windows.
- `include_facets` (boolean, optional, default false) — Also return CVS's own facet vocabulary with live counts for this keyword (brand, on-sale promotion, form, concern, HSA/FSA eligible, OTC eligible). Costs no extra request. Read-only: CVS does not honour a filter on this surface, so there is no filter parameter to pair with it.

**Returns:** total_results (CVS's own numFound), count, offset, limit, has_more, and products[] with product_id, title, brand, url, image_url, sponsored, rating, review_count, variant_count, sku_ids (every variant sku of the product — feed these to product/batch) and a price block (price, sale_price, on_sale, discount_pct, carepass_price, unit_price + parsed unit_price_amount/unit, promo, and the min/max price range for multi-variant products). Optionally facets[] with CVS's live counts.

**Example request body:**
```json
{
  "query": "shampoo",
  "limit": 20
}
```

### POST https://api.reefapi.com/cvs/v1/product/detail — 1 credit
Everything cvs.com publishes about ONE product: the full price block, the variant matrix with per-variant prices and attributes, per-channel stock STATUS AND QUANTITY, ExtraBucks + manufacturer coupons with expiry dates, and the eligibility flags (CarePass, HSA/FSA, SNAP, store pickup, same-day). One upstream request. For many ids at once use `product/batch`.

**Parameters:**
- `product_id` (string, required) — A CVS product id — the digits after `-prodid-` in any cvs.com product url (/shop/…-prodid-797389 → 797389). Ids returned by this engine's `search` and `product/batch` are the same ids.

**Returns:** One product in full: title, brand, url, image_url, swatch_image_url, the price block with its range, rating, review_count, max_quantity_per_order, attributes (only the ones this product has: size, group_size, color, scent, spf, form, count, pack…), flags (carepass_eligible, fsa_hsa_eligible, snap_eligible, store_pickup, same_day_delivery, store_only, online_only, hot_deal, pseudoephedrine_restricted), availability per fulfilment channel (ship / pickup / same_day / store, each with status and CVS's own promise QUANTITY), coupons (ExtraBucks rewards and manufacturer coupons with expiry), and variants[] with each variant's own price, attributes and stock.

**Example request body:**
```json
{
  "product_id": "797389"
}
```

### POST https://api.reefapi.com/cvs/v1/product/batch — 2 credits
Resolve up to 200 CVS product ids to live price, sale price, rating and title in a SINGLE upstream request (~700 bytes per product). The bulk lane: use it to re-price a catalogue. Ids CVS did not resolve come back in `missing_ids` instead of disappearing.

**Parameters:**
- `product_ids` (array, required) — 1-200 CVS product ids in ONE request (a list, or a comma-separated string). The source accepts 200 and rejects 250, so 200 is the hard ceiling. Multi-variant PARENT ids are accepted by CVS and then silently omitted from its answer, so any id that did not resolve is returned in `missing_ids` rather than dropped quietly.

**Returns:** requested, resolved, missing_ids[], and products[] with product_id, title, url, image_url, price (price, sale_price, on_sale, discount_pct), rating, review_count, multi_variant, rx_attach_eligible and pseudoephedrine_restricted — up to 200 ids for ONE upstream request. An id CVS did not resolve is a multi-variant parent: take that product's `sku_ids` from `search` (or its variants from `product/detail`) and ask for those instead — measured, that resolves 217 of 222 ids where the parent ids resolved 59 of 78.

**Example request body:**
```json
{
  "product_ids": [
    "797389",
    "708463",
    "268308",
    "240604"
  ]
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=cvs
- Human docs page: https://reefapi.com/docs/cvs
- Overview page: https://reefapi.com/cvs-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
