Gazelle API & Scraper
The Gazelle API returns buy.gazelle.com, the US first-party refurbished phone and tablet store, as clean JSON in four actions: search, product, facets and collections.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
Gazelle is not a marketplace — it buys, grades and sells every device itself — so there is exactly one seller, one warranty and one price per SKU, and no buy-box to reverse-engineer. The unit it actually sells is model x storage x carrier x colour x cosmetic condition, and the first three of those are a separate listing on its storefront while colour and condition are variants of it. That is what makes one product call worth more than a page scrape: Gazelle ships the whole sibling group with the product, so a single call returns every capacity and every carrier of that model at once, each with its full offer table. Measured in one run, the iPhone 17e resolved to 8 sibling products and 72 offers, and the Galaxy Z Fold8 Ultra to 12 products and 144 offers. Each offer carries its price, its crossed-out price when there is a real one, its cosmetic grade and colour, and the ACTUAL UNIT COUNT behind it — a number that appears on none of the site's own JSON endpoints and only in the page a human sees. Each product also carries the new-device MSRP, so the saving is computable rather than guessed. search browses the catalogue: 1,000 live products over 108 model lines and 13,329 priced variants when measured, 824 phones and 175 tablets, with free text plus filters on brand, model line, capacity, carrier, colour, cosmetic grade, device class, price band and stock, and eight sort orders. The cosmetic ladder is Gazelle's own three grades, carried verbatim and never remapped — Fair, Good, Excellent — and it is a price ladder too: measured on the iPhone 17e 256 GB in one run, Fair 489.99, Good 509.99, Excellent 524.99 USD. Every row returns the cheapest price at each grade, so the whole condition ladder is visible without a second call. The number that matters most about this catalogue is the one most APIs would hide: only 464 of those 13,329 variants were actually buyable, across 153 of the 1,000 products. Gazelle keeps sold-out variants published with a live price, which is useful history but a trap if you quote it — and on 55 of the 153 in-stock products the cheapest published variant is sold out and the cheapest one you can buy costs more. Every row therefore carries both figures side by side, and in_stock_only judges every other filter against the buyable variants alone. facets returns Gazelle's own inventory census: every value its storefront offers for brand, model, capacity, carrier, colour, grade and availability, each with GAZELLE'S OWN product count beside it — which is also the only size figure on the site worth trusting, because its collections endpoint claims 4,058 products for the whole store where the catalogue really holds 1,000, and claims 1,224 MacBooks where it has none left. Two honest limits before you build: Gazelle sells into the United States only and quotes USD only, and it publishes no trade-in payouts on its own domain even though it buys devices back, because that quoting runs on ecoATM's systems. One ReefAPI key, no Gazelle account, and the standard { ok, data, meta, error } envelope.
Gazelle's three cosmetic grades, and what each one does to the price
The grade names are Gazelle's own, read from its own variant options and its own filter form; nothing is remapped onto a scale of ours. The price column is one measured run on the iPhone 17e 256 GB (Unlocked), the same device re-quoted at each grade — it is there to show that the grade is a price ladder, and the exact figures move with the market. The product column is Gazelle's own count from its own filter form the same day: nearly every one of its 1,000 live products carries all three grades, which is why the grade you want is usually in stock on some products and sold out on others rather than missing from the catalogue.
| grade (Gazelle's own name) | what it means | iPhone 17e 256 GB | products at this grade |
|---|---|---|---|
| Fair | visible wear — the cheapest tier | USD 489.99 | 922 |
| Good | light wear | USD 509.99 | 923 |
| Excellent | minimal to no visible wear | USD 524.99 | 922 |
Measured 2026-10-08. The grade selects VARIANTS, so a product is returned when any of its variants matches and is then quoted at the cheapest matching one. Because a grade is often the thing that is sold out rather than the thing that is missing, combine the grade with in_stock_only to see what can be bought today.
Real request and response JSON
Captured from the indexed primary action, search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/gazelle/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"collection": "iphone",
"in_stock_only": true,
"sort": "price_asc",
"limit": 25
}
}{
"ok": true,
"meta": {
"api": "gazelle",
"endpoint": "search",
"mode": "live",
"latency_ms": 1541.2,
"record_count": 25,
"bytes": 6496868,
"cache_hit": false,
"collection": "iphone",
"currency": "USD",
"total_matched": 56,
"returned": 25,
"page": 1,
"limit": 25,
"has_more": true,
"source_product_count": 332,
"source_variant_count": 4533,
"source_available_variant_count": 240,
"in_stock_product_count": 56,
"source_pages_read": 2,
"catalogue_fully_scanned": true,
"price_range": {
"min": 95.99,
"max": 482.99
},
"filters_applied": {
"in_stock_only": true,
"sort": "price_asc"
},
"filtering": "applied by this API over the source's own product and variant fields; buy.gazelle.com's catalogue endpoint honours only `limit` and `page` (every filter and sort parameter it advertises was measured returning the identical product ids in the identical order)",
"price_semantics": "price_min covers EVERY published variant; price_min_available covers only buyable ones, and on 55 of 153 in-stock products measured they differ because the cheapest variant is sold out",
"upstream_requests": 5,
"charged_credits": 6,
"version": "1.0.0",
"request_id": "31d07038c1b441c0",
"queue_ms": 1.1,
"fetched_at": "2026-10-08T11:33:19.576Z"
},
"data": {
"products": [
{
"handle": "iphone-se-2nd-gen-64gb-unlocked-2",
"product_id": 4622459961397,
"title": "iPhone SE (2nd generation) 64GB (Unlocked)",
"url": "https://buy.gazelle.com/products/iphone-se-2nd-gen-64gb-unlocked-2",
"brand": "Apple",
"brand_source": "model_line",
"model_line": "iPhone SE (2nd generation)",
"storage_gb": 64,
"storage_label": "64GB",
"carrier": "Unlocked",
"carrier_raw": "Unlocked",
"product_type": "Cell Phones",
"currency": "USD",
"price_min": 95.99,
"price_max": 115.99,
"price_min_available": 95.99,
"price_max_available": 105.99,
"compare_at_price_max": null,
"in_stock": true,
"variant_count": 9,
"available_variant_count": 3,
"colors": [
"Black",
"White",
"Red"
],
"colors_available": [
"Black",
"White"
],
"conditions": [
"Fair",
"Good",
"Excellent"
],
"conditions_available": [
"Fair",
"Good"
],
"price_by_condition": {
"Fair": 95.99,
"Good": 102.99,
"Excellent": 110.99
},
"price_by_condition_available": {
"Fair": 95.99,
"Good": 102.99
},
"tags": [
"4G",
"bestsellers-resort",
"Carrier:Unlocked"
],
"image_url": "https://cdn.shopify.com/s/files/1/0008/9296/0821/files/iPhone_SE_2nd_Gen_-_Black-_Overlap_Trans-cropped.jpg?v=1757019448",
"image_count": 9,
"created_at": "2020-07-13T11:31:48-07:00",
"updated_at": "2026-10-08T04:33:18-07:00",
"published_at": "2026-01-19T14:04:14-08:00",
"detail_params": {
"handle": "iphone-se-2nd-gen-64gb-unlocked-2"
}
},
{
"handle": "iphone-11-64gb-unlocked-1",
"product_id": 4426120822837,
"title": "iPhone 11 64GB (Unlocked)",
"url": "https://buy.gazelle.com/products/iphone-11-64gb-unlocked-1",
"brand": "Apple",
"brand_source": "model_line",
"model_line": "iPhone 11",
"storage_gb": 64,
"storage_label": "64GB",
"carrier": "Unlocked",
"carrier_raw": "Unlocked",
"product_type": "Cell Phones",
"currency": "USD",
"price_min": 149.99,
"price_max": 185.99,
"price_min_available": 149.99,
"price_max_available": 167.99,
"compare_at_price_max": null,
"in_stock": true,
"variant_count": 18,
"available_variant_count": 8,
"colors": [
"Black",
"White",
"Yellow"
],
"colors_available": [
"Black",
"White",
"Yellow"
],
"conditions": [
"Fair",
"Good",
"Excellent"
],
"conditions_available": [
"Fair",
"Good"
],
"price_by_condition": {
"Fair": 149.99,
"Good": 159.99,
"Excellent": 174.99
},
"price_by_condition_available": {
"Fair": 149.99,
"Good": 159.99
},
"tags": [
"4G",
"bestsellers-resort",
"Carrier:Unlocked"
],
"image_url": "https://cdn.shopify.com/s/files/1/0008/9296/0821/files/iPhone_11_-_Black_-_Overlap_Trans-cropped_6bc79086-431f-4ce3-8c31-cd94298c2331.jpg?v=1757019483",
"image_count": 10,
"created_at": "2020-01-08T14:53:21-08:00",
"updated_at": "2026-10-08T04:33:18-07:00",
"published_at": "2026-01-20T07:04:26-08:00",
"detail_params": {
"handle": "iphone-11-64gb-unlocked-1"
}
},
{
"handle": "iphone-12-64gb-unlocked",
"product_id": 5027453894709,
"title": "iPhone 12 64GB (Unlocked)",
"url": "https://buy.gazelle.com/products/iphone-12-64gb-unlocked",
"brand": "Apple",
"brand_source": "model_line",
"model_line": "iPhone 12",
"storage_gb": 64,
"storage_label": "64GB",
"carrier": "Unlocked",
"carrier_raw": "Unlocked",
"product_type": "Cell Phones",
"currency": "USD",
"price_min": 145.99,
"price_max": 187.99,
"price_min_available": 154.99,
"price_max_available": 154.99,
"compare_at_price_max": null,
"in_stock": true,
"variant_count": 18,
"available_variant_count": 1,
"colors": [
"Black",
"White",
"Green"
],
"colors_available": [
"Blue"
],
"conditions": [
"Fair",
"Good",
"Excellent"
],
"conditions_available": [
"Fair"
],
"price_by_condition": {
"Fair": 145.99,
"Good": 150.99,
"Excellent": 187.99
},
"price_by_condition_available": {
"Fair": 154.99
},
"tags": [
"5G",
"bestsellers-resort",
"Carrier:Unlocked"
],
"image_url": "https://cdn.shopify.com/s/files/1/0008/9296/0821/files/iPhone_12_-_Black_-_Overlap_Trans-cropped_92b85fb5-aa00-4a57-865c-67afc6c1402d.jpg?v=1757019383",
"image_count": 16,
"created_at": "2021-02-04T12:35:37-08:00",
"updated_at": "2026-10-08T04:33:18-07:00",
"published_at": "2024-03-06T01:05:48-08:00",
"detail_params": {
"handle": "iphone-12-64gb-unlocked"
}
}
],
"seller": {
"name": "Gazelle",
"kind": "first_party_retailer",
"legal_name": "ecoATM LLC (Gazelle brand)",
"country": "US",
"url": "https://buy.gazelle.com/",
"note": "Gazelle buys, grades and sells every device itself; there is exactly one seller on this catalogue and one warranty behind it."
}
}
}What the Gazelle API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| search | Browse the Gazelle catalogue: one row per PRODUCT (a model x storage x carrier) with its price band, the cheapest price AT EACH cosmetic grade, the colours and grades it is stocked in, and how many of its variants can actually be bought today. Free-text `q` plus filters on brand, model line, capacity, carrier, colour, cosmetic grade, device class, price band and stock. Two numbers are always given side by side, because the source makes them differ: `price_min` over every published variant and `price_min_available` over the ones you can buy — on 55 of the 153 in-stock products the cheapest variant is sold out and the cheapest buyable one costs more. Gazelle's catalogue endpoint honours only `limit` and `page` (every filter and sort parameter it advertises was measured returning the identical product ids in the identical order), so the filtering and ordering here are done by this API over the source's own fields and `meta.filtering` says so rather than pretending otherwise. | Pricing teams call search to get browse the Gazelle catalogue. | collection, q, brand, model, storage, ... |
| product | The COMPLETE live offer table of one Gazelle product and, by default, of every sibling product of the same model — each capacity x carrier combination — in a single request, straight from the storefront's own variant picker. Per offer: colour, cosmetic grade, price, the crossed-out price when there is a real one, and THE ACTUAL UNIT COUNT, which neither /products.json nor the product's own JSON endpoint publishes anywhere on the site. Per product: the new-device MSRP and the saving against it, the warranty code, the collections it sits in, and the cheapest price at each grade. Measured on 2026-10-08: 8 sibling products / 72 offers for the iPhone 17e, 12 / 144 for the Galaxy Z Fold8 Ultra, 3 / 36 for the iPhone 11 Pro 512 GB. The page's own schema.org block is read as a second witness for price and availability and any disagreement is reported in `meta.ld_json_cross_check`, not hidden. An unknown handle is NOT_FOUND. | Marketplace operators call product to get the COMPLETE live offer table of one Gazelle product and, by default, of every sibling produc…. | handle, include_group, in_stock_only_offers |
| facets | Gazelle's own inventory census of one collection: every value its storefront filter form offers for brand, model, capacity, carrier, colour, cosmetic grade and availability, each with THE SOURCE'S OWN product count beside it, plus the price slider's bounds and the live page count of the grid. This is the one number on the site that can be trusted about size: `collections.json` claims 4,058 products for `all` while the catalogue pages out at 1,000, and claims 1,224 MacBooks where there are none. Unlike the catalogue endpoint, the collection page really does honour filters, so `filters` returns Gazelle's own answer to a combined question (how many Unlocked iPhone 15 Pro in Excellent, etc.). Filter values are case-sensitive at the source — `brand=apple` returns 0 products with HTTP 200 while `brand=Apple` returns all 332 — so every value sent is checked against the form the source renders back and anything it does not offer lands in `meta.warnings`. | Catalog enrichment teams call facets to get gazelle's own inventory census of one collection. | collection, filters, min_price, max_price |
| collections | Every collection the Gazelle storefront publishes — 205 on 2026-10-08 — with its handle, title, URL and ready-made `search_params`. This is how you find the handle to narrow `search` and `facets` with, which is also how you make those calls cheap. The count the source attaches to each collection is published as `products_count_claimed` and nothing else, because it is not a live number: it says 4,058 for `all` where the catalogue really pages out at 1,000, and it says 1,224 for `macbook-pro` and 2 for `apple-watches` where both return zero products and the storefront itself prints 'No products found'. Use `facets` or `search` for a number you can rely on. | Retail analysts call collections to get every collection the Gazelle storefront publishes. | q, limit |
Call search from your stack
curl -X POST https://api.reefapi.com/gazelle/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"collection":"iphone","in_stock_only":true,"sort":"price_asc","limit":25}'import requests
r = requests.post(
"https://api.reefapi.com/gazelle/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"collection": "iphone",
"in_stock_only": true,
"sort": "price_asc",
"limit": 25
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/gazelle/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"collection": "iphone",
"in_stock_only": true,
"sort": "price_asc",
"limit": 25
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.gazelle.search with {"collection":"iphone","in_stock_only":true,"sort":"price_asc","limit":25}.Who uses this API and why
- Price your own refurbished phone inventory against a US market leader at the right condition, using Gazelle's own three grades instead of a mapping you invented.
- Measure the real cost of condition: one call returns the cheapest price at Fair, Good and Excellent for the same device — 489.99 / 509.99 / 524.99 USD on an iPhone 17e 256 GB in one measured run.
- See what is actually buyable, not what is listed: only 464 of 13,329 published variants were in stock when measured, and on 55 of 153 in-stock products the cheapest listing is the one that is gone.
- Compare a refurbished price against the new-device MSRP the store itself publishes, per capacity and per carrier, instead of sourcing list prices separately.
- Watch carrier-locked versus unlocked pricing across a whole model line in one call: every capacity x carrier sibling comes back together, with the unit count behind each grade.
- Track a single model's stock day to day with a real number — the unit count is published per variant, not as an in-stock flag.
Questions developers ask before integrating
What is the Gazelle API?
Gazelle API is a ReefAPI endpoint group for the us refurbished-phone store as json: every model with a price for each cosmetic grade, every capacity and carrier, the real unit count behind each variant, and the new-device msrp to measure the saving against. It returns live JSON through POST requests under /gazelle/v1.
Is the Gazelle API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Gazelle calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Gazelle login or account?
No login to Gazelle is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Gazelle data?
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Gazelle API use?
Gazelle actions currently cost 1-6 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call Gazelle from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call gazelle actions with the same key, credit pool and JSON envelope used by normal REST requests.
Is the Gazelle API a Gazelle scraper?
It is the managed alternative to a DIY Gazelle scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same the us refurbished-phone store as json: every model with a price for each cosmetic grade, every capacity and carrier, the real unit count behind each variant, and the new-device msrp to measure the saving against back as clean JSON.
Why does my Gazelle scraper keep getting blocked?
Most Gazelle scrapers break on anti-bot defenses, rate limits and IP bans that need rotating residential proxies and browser fingerprinting to clear. ReefAPI handles all of that for you — no proxies, no captchas, no maintenance — and returns live JSON. Blocked calls are free.