CVS
CVS price range, regular price, rating, brand, category and every variant with its shipping, pickup and same-day flags, by product id, about 400,000 products per credit. Search too. Prescription items are never returned. CVS refuses more requests than most stores; refused requests are retried and never charged.
CVS price range, regular price, rating, brand, category and every variant with its shipping, pickup and same-day flags, by product id, about 400,000 products per credit. Search too. Prescription items are never returned. CVS refuses more requests than most stores; refused requests are retried and never charged.
At a glance
Property | Value |
|---|---|
|
|
Product id | The number after |
Marketplaces | Live: |
Tier |
|
Ids per call | 100 |
Typical call | 30–90 s for 100 products |
Search |
|
Reliability | CVS refuses a share of requests. A refused request is retried elsewhere and is never charged; an id that still cannot be read comes back |
Example
- cURL
- Python
- Node.js
curl -X POST "https://api.scrapelyserp.com/v1/products" \
-H "Authorization: Bearer $SCRAPELY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"platform":"cvs","ids":["949346","832677"]}'import os
import requests
HEADERS = {"Authorization": f"Bearer {os.environ['SCRAPELY_API_KEY']}"}
r = requests.post(
"https://api.scrapelyserp.com/v1/products",
headers=HEADERS,
json={"platform": "cvs", "ids": ["949346", "832677"]},
timeout=120,
)
r.raise_for_status()
data = r.json()
for p in data["results"]:
print(p["id"], p["status"], (p.get("price") or {}).get("amount"), p["cvs"]["rating"])const res = await fetch('https://api.scrapelyserp.com/v1/products', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SCRAPELY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ platform: 'cvs', ids: ['949346', '832677'] }),
signal: AbortSignal.timeout(120_000),
});
if (!res.ok) throw new Error((await res.json()).error.code);
const data = await res.json();
for (const p of data.results) console.log(p.id, p.status, p.price?.amount, p.cvs?.rating);Full reference → POST /v1/products
CVS fields
Besides the common fields, each result carries a cvs object. A product can come in several variants (sizes or counts) at different prices: price is the lowest variant price and cvs.priceMax the highest. A missing price is null or absent, never 0. Prices are the regular web prices for the default price zone; no store is chosen.
Field | Description |
|---|---|
| The highest variant price, and the regular price of the cheapest variant when it is on sale ( |
| Average review rating (0 to 5) and the number of reviews; |
| The brand and the category path, broadest first. |
| Whether CVS offers shipping, store pickup or same-day delivery for any variant. |
| Every variant: |
The ship, pickup and sameDay values are availability flags the site shows, not stock counts; ship is false for items sold in stores only, and pickup and sameDay are true or null (unknown), never false, because no store is chosen, and no store or ZIP code is used, so pickup and same-day describe the site in general rather than a store near you. availability is therefore left out of results. Search results carry in_stock: null for the same reason.
Statuses on CVS
partial: CVS answered without a title. Ask again later.not_found: CVS has no such id. Prescription items are never returned and read the same way.unavailable: no usable answer after retries (CVS refused the requests). Not charged; ask again.
Watchlists
A watchlist with "platform": "cvs" reads each id once per run and reports changes to price, inStock, listPrice. inStock there is true when any variant offers shipping, pickup or same-day: an availability flag, not a stock count.