Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Enjoei API page →
E-commerce & Marketplaces

Enjoei API & Scraper

The Enjoei API returns Brazil's largest second-hand marketplace as clean JSON in eight actions: search, product/detail, product/similar, seller/listings, seller/sold, seller/profile, filters and suggest.

8 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 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.

search takes a Portuguese keyword or browses a department, sub-category or brand, and filters by price range, condition (used or new), clothing/shoe/waist size, discount percentage, seller location and how recently the item was listed, sorted by relevance, cheapest, dearest or biggest discount. Every row carries the listing id, slug and URL, the title, the asking price in BRL, the seller's struck-through price when the item is reduced, a computed discount percentage, condition, size and the available size variants, brand, department, category and sub-category, the photo, whether shipping is free, and the seller's shop handle, display name and shop URL. product/detail adds the full description, every photo, the item's weight in kilograms, the category breadcrumb, Google's product category, whether the listing is still on sale, and the offer range the seller has said they will consider — Enjoei is a haggling marketplace, so that band is published. seller/sold is the one most marketplaces do not give you: a shop's completed sales with both the price the item was listed at and the price it actually sold for. Measured on 2026-09-23: 86 of 86 live calls returned data; a 30-row search answered in a median 0.88 s and a listing in 1.9 s; on 14 listings across 8 categories the price product/detail returns matched the price on the item's own page 14 times out of 14. No Enjoei account is involved. One ReefAPI key, one shared credit pool, the standard { ok, data, meta, error } envelope.

Reference

What a live call returns — 400 rows across eight categories, counted not assumed

Fifty search rows were taken from each of eight categories on 2026-09-23 (sportswear, electronics, womenswear, bags, toys, books, footwear, watches) and every field counted. Two of these lines go against us; they are the ones worth reading.

FieldFilled (of 400)Why it is not always filled
listing id, URL, title, price, currency, discount percentage400
condition (used or new), brand, department, category400
photo, free shipping, shipping type400
seller handle, display name, shop URL, avatar400
sub-category347shallow on books (7 of 50); department and category are still complete there
struck-through price and promotion tag215only on a reduced listing — 54% of rows, steady across all eight categories
size and size variants155a clothing field: ~100% on womenswear and footwear, 47 of 50 on sportswear, and 0-4% on bags, watches, electronics and toys, which have no size on Enjoei
like count, view count, listing date, sold date, colour, seller rating0Enjoei does not publish any of them on a listing — see the coverage table

Speed and size, 2026-09-23, 86 consecutive live calls, all returning data: search 40 calls, median 877 ms, about 36 KB for 30 rows; product/detail 10 calls, median 1.9 s, about 4 KB; seller/profile 27 calls, median 1.7 s, about 1 KB; seller/listings 2 calls, median 2.2 s; seller/sold 3 calls, median 1.5 s, 40 rows; product/similar median 1.7 s; filters 2 calls, median 779 ms; suggest median 943 ms.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/enjoei/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "nike",
    "per_page": 30
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "enjoei",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 666.5,
    "record_count": 30,
    "bytes": 36437,
    "cache_hit": false,
    "pagination": {
      "page_size": 30,
      "next_cursor": "167687559023008922:1",
      "has_more": true
    },
    "upstream_requests": 1,
    "charged_credits": 1,
    "version": "0.1.0"
  },
  "data": {
    "results": [
      {
        "listing_id": "151454979",
        "slug": "tenis-nike-lebron-xviii-low-space-jam-42-43-us-10-5-151454979",
        "url": "https://www.enjoei.com.br/p/tenis-nike-lebron-xviii-low-space-jam-42-43-us-10-5-151454979",
        "title": "tênis nike lebron xviii low space jam 42/43 us 10.5",
        "price": 2000,
        "original_price": null,
        "discount_percent": 0,
        "currency": "BRL",
        "condition": "new",
        "condition_label": "novo",
        "size": "42",
        "sizes": [
          "42"
        ],
        "size_slug": "42",
        "variants": [
          {
            "name": "[trimmed-depth]",
            "slug": "[trimmed-depth]",
            "available": "[trimmed-depth]"
          }
        ],
        "brand": "nike",
        "department": "rapazes",
        "category": "rapazes-calcados",
        "subcategory": "rapazes-calcados-tenis",
        "image": "https://photos.enjoei.com.br/public/800x800/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy8yMzA1MjQ0My8xYzk5M2ZkZDFiNWQ1OTc1YzQyODk2MGM2OWM0YjQ2MC5qcGc",
        "image_id": "czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy8yMzA1MjQ0My8xYzk5M2ZkZDFiNWQ1OTc1YzQyODk2MGM2OWM0YjQ2MC5qcGc",
        "free_shipping": false,
        "shipping_type": "charge_by_weight",
        "bundle_allowed": true,
        "promo_tags": null,
        "seller": {
          "username": "bruno-f9d16e",
          "display_name": "Bruno",
          "url": "https://www.enjoei.com.br/@bruno-f9d16e",
          "avatar": "https://photos.enjoei.com.br/public/200x200/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9hdmF0YXJzLzIzMDUyNDQzLzUxY2IyY2MwYjUyYzZhYjcyYjg5YTQ0Yjg0YThiYmNmLmpwZw"
        }
      },
      {
        "listing_id": "151454963",
        "slug": "bermuda-nike-racing-club-preta-151454963",
        "url": "https://www.enjoei.com.br/p/bermuda-nike-racing-club-preta-151454963",
        "title": "bermuda nike racing club preta",
        "price": 390,
        "original_price": null,
        "discount_percent": 0,
        "currency": "BRL",
        "condition": "used",
        "condition_label": "usado",
        "size": "G",
        "sizes": [
          "G"
        ],
        "size_slug": "g",
        "variants": [
          {
            "name": "[trimmed-depth]",
            "slug": "[trimmed-depth]",
            "available": "[trimmed-depth]"
          }
        ],
        "brand": "nike",
        "department": "rapazes",
        "category": "rapazes-roupas",
        "subcategory": "rapazes-roupas-bermudas",
        "image": "https://photos.enjoei.com.br/public/800x800/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy84NTExMTg4LzE4NTU1MzUxZDhjODZjZWY5NjMzMWIxZGMzN2QyYzllLmpwZw",
        "image_id": "czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy84NTExMTg4LzE4NTU1MzUxZDhjODZjZWY5NjMzMWIxZGMzN2QyYzllLmpwZw",
        "free_shipping": false,
        "shipping_type": "charge_by_weight",
        "bundle_allowed": true,
        "promo_tags": null,
        "seller": {
          "username": "felipe-03d5b7",
          "display_name": "felipe",
          "url": "https://www.enjoei.com.br/@felipe-03d5b7",
          "avatar": "https://photos.enjoei.com.br/public/200x200/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9kZWZhdWx0aW1hZ2VzL3VzZXIvZGRhMGY2MWU4ODIxODgwYmMyZjliYzQ3NDViZWY2MmUuanBn"
        }
      },
      {
        "listing_id": "151379064",
        "slug": "tenis-nike-grandstand-2-camurca-br-43-us-11-151379064",
        "url": "https://www.enjoei.com.br/p/tenis-nike-grandstand-2-camurca-br-43-us-11-151379064",
        "title": "tênis nike grandstand 2 camurça br 43 us 11",
        "price": 350,
        "original_price": null,
        "discount_percent": 0,
        "currency": "BRL",
        "condition": "new",
        "condition_label": "novo",
        "size": "43",
        "sizes": [
          "43"
        ],
        "size_slug": "43",
        "variants": [
          {
            "name": "[trimmed-depth]",
            "slug": "[trimmed-depth]",
            "available": "[trimmed-depth]"
          }
        ],
        "brand": "nike",
        "department": "rapazes",
        "category": "rapazes-calcados",
        "subcategory": "rapazes-calcados-tenis",
        "image": "https://photos.enjoei.com.br/public/800x800/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy80MzI4NDc0NC9hNjQxYjkwOGYzMmQ2ZWFiNmFiZmIxNmM0ZjAzM2YwMS5qcGc",
        "image_id": "czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy80MzI4NDc0NC9hNjQxYjkwOGYzMmQ2ZWFiNmFiZmIxNmM0ZjAzM2YwMS5qcGc",
        "free_shipping": false,
        "shipping_type": "charge_by_weight",
        "bundle_allowed": true,
        "promo_tags": null,
        "seller": {
          "username": "t3store",
          "display_name": "Ramon",
          "url": "https://www.enjoei.com.br/@t3store",
          "avatar": "https://photos.enjoei.com.br/public/200x200/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9hdmF0YXJzLzQzMjg0NzQ0L2NhODNiM2M3NmFjYzgzNmIwZmQ5ZWEzYTg0YzEzZDk1LmpwZw"
        }
      }
    ],
    "count": 30,
    "total_results": 10000,
    "total_results_capped": true,
    "next_cursor": "167687559023008922:1",
    "has_more": true,
    "tiles_dropped": 0,
    "filters": {
      "sort": "relevance"
    },
    "query": "nike"
  }
}
Actions

What the Enjoei API does

ActionDescriptionConcrete use caseKey params
searchSearch Enjoei's live second-hand catalogue by keyword, brand, department, size, price, condition, discount or seller location. Returns the asking price and the seller's struck-through reference price on every row.Pricing teams call search to search Enjoei's live second-hand catalogue by keyword, brand, department, size, price, condit….query, department, subcategory, brand, price_min, ...
product/detailOne listing in full: the LIVE price (read from Enjoei's own pricing route, not the search index), description, every photo, weight, size, brand, category path, the offer range the seller will consider, and whether it is still on sale.Marketplace operators call product/detail to get one listing in full.listing, max_rotations
product/similarListings comparable to a given one — same sub-category, same brand and a price band around it, which is the recipe Enjoei's own page uses. Useful for pricing a second-hand item against live competition.Catalog enrichment teams call product/similar to get listings comparable to a given one.listing, per_page, sort, condition, max_rotations
seller/listingsEverything a shop currently has for sale, with the same row shape as search and the same filters.Retail analysts call seller/listings to get everything a shop currently has for sale, with the same row shape as search and the same filt….seller, seller_id, query, brand, subcategory, ...
seller/soldA shop's completed sales: what the item was listed at AND what it actually sold for. Enjoei publishes both, which makes this the price-comparison surface for second-hand goods in Brazil.Pricing teams call seller/sold to get a shop's completed sales.seller, page, max_rotations
seller/profileA shop's public page: handle, display name, city/state, bio, avatar, the date it joined, and its public counters — items for sale, items sold, likes received, followers and following.Marketplace operators call seller/profile to get a shop's public page.seller, max_rotations
filtersThe brand and sub-category facets Enjoei itself offers for a query, each with its live listing count — the slugs you feed back into `search`.Catalog enrichment teams call filters to get the brand and sub-category facets Enjoei itself offers for a query, each with its live listin….query, department, subcategory, brand, price_min, ...
suggestEnjoei's own search typeahead: completed search terms and matching shops.Retail analysts call suggest to get enjoei's own search typeahead.term, max_rotations
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/enjoei/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"nike","per_page":30}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.enjoei.search with {"query":"nike","per_page":30}.
Use cases

Who uses this API and why

  • Price a second-hand item for the Brazilian market: search comparable listings, then read what a shop's equivalents actually sold for with seller/sold.
  • Track resale value of a brand or model over time by polling search with a fixed brand and sub-category and recording the price distribution.
  • Find under-priced stock for resale: sort by biggest discount, or filter discount_min with a price ceiling, and check the offer range on each candidate.
  • Build a Brazilian second-hand feed for a fashion or sneaker app, filtered by department, size and condition.
  • Research a shop before buying or partnering: seller/profile for its public counters and joining date, seller/listings for what it stocks, seller/sold for what it has shifted.
FAQ

Questions developers ask before integrating

What did the item actually sell for?

seller/sold answers that, and it is the reason to use this API for second-hand pricing in Brazil. Each row of a shop's completed sales carries both numbers: price, what the seller was asking, and sold_price, what a buyer actually paid. A measured example: a Nike t-shirt listed at R$65 sold for R$41. Enjoei publishes this per shop, 40 rows a page, newest first. There is no marketplace-wide sold search, and no sale date.

Is original_price a real discount?

Yes, and it is only there when it is real. Enjoei sends the reference price and the current price on every row, and on an undiscounted listing the two are the same number. Returning that as a struck-through price would invent a discount on every item, so original_price is returned only when it is genuinely higher than the price you pay. It was filled on 215 of 400 rows measured; on the other 185 it is null and discount_percent is 0.

Why can the price on a search row differ from the price on product/detail?

Because Enjoei's search index keeps its own copy of the price and it can lag behind a re-pricing. On 14 listings checked against their own product pages, product/detail matched the page 14 times out of 14, while the search-index copy differed on 5 of them, by as much as a third — one item indexed at R$160 was really R$238. Use search rows to find and rank items, and product/detail for the number you are going to quote or transact on.

What is the offer range on a listing?

Enjoei is a haggling marketplace: buyers make offers and sellers publish the band they will consider. product/detail returns it as offer, with accepted, min_price and max_price — for example a R$150 listing accepting offers between R$90 and R$149. It is a negotiating band, not a price anything sold at; for real sale prices use seller/sold.

Does the API tell me when a listing was posted or sold?

No, and no approximation is invented. Enjoei does not publish a listing date, a sold date, a like count, a view count, a colour or a per-listing seller rating anywhere a logged-out visitor can see, so none of them are returned. What you can do is filter by recency: published_within accepts 24h, 7d, 14d or 30d and Enjoei applies it server-side — on one measured query it cut 10,000+ matches to 302.

How many results can I page through?

Fifty rows per page, by cursor. Enjoei clamps the page size at 50 and silently ignores anything larger, so the API caps it too rather than promising a page it will not deliver. A 4-page walk returned 200 listings with no repeats. total_results is Enjoei's own count and stops at 10,000; when it does, total_results_capped comes back true, so you never mistake a ceiling for a total.

Can I sort by newest?

No. Enjoei's own ordering choices are relevance, cheapest, dearest and biggest discount, and those four are what the API offers. Other sort words are accepted by the source and then quietly ignored, which would look like a working filter and be a lie, so they are rejected with INVALID_PARAM instead. For recency use the published_within filter.

Whose data is in the seller block?

The public storefront only: the shop's @handle, its display name, shop URL, avatar and cover image, the date it joined, and its public counters — items for sale, items sold, likes received, followers and following. Sellers on Enjoei are private individuals running a shop page, so nothing beyond the shop page itself is read or returned.

What is the Enjoei API?

Enjoei API is a ReefAPI endpoint group for brazil's biggest second-hand marketplace: asking price, struck price and what items actually sold for. It returns live JSON through POST requests under /enjoei/v1.

Is the Enjoei API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Enjoei calls use the same shared credit balance as every other ReefAPI engine.

Do I need an Enjoei login or account?

No login to Enjoei 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 Enjoei 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 Enjoei API use?

Enjoei actions currently cost 1-2 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.

Can I call Enjoei from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call enjoei actions with the same key, credit pool and JSON envelope used by normal REST requests.

docs / enjoei

Enjoei

Brazil's biggest second-hand marketplace: asking price, struck price and what items actually sold for.

base /enjoei/v18 endpoints
post/enjoei/v1/product/detail2 credits

One listing in full: the LIVE price (read from Enjoei's own pricing route, not the search index), description, every photo, weight, size, brand, category path, the offer range the seller will consider, and whether it is still on sale.

ParameterAllowed / rangeDescription
listingrequiredListing id, slug or full product URL — `151426712`, `shorts-nike-nba-chicago-bulls-151426712` or the whole `/p/...` link.
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →
post/enjoei/v1/product/similar2 credits

Listings comparable to a given one — same sub-category, same brand and a price band around it, which is the recipe Enjoei's own page uses. Useful for pricing a second-hand item against live competition.

ParameterAllowed / rangeDescription
listingrequiredListing id, slug or full product URL — `151426712`, `shorts-nike-nba-chicago-bulls-151426712` or the whole `/p/...` link.
per_page = 30optional1–50Rows per page. Enjoei clamps this at 50 — a larger number is silently reduced, so the engine caps it too.
sort = relevanceoptionalrelevance · price_asc · price_desc · discount_descResult order. Only the four orders Enjoei itself applies are offered — every other value the API accepts is ignored upstream and would silently not sort.
conditionoptionalused · newRestrict to second-hand or to unused stock.
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →
post/enjoei/v1/seller/listings2 credits

Everything a shop currently has for sale, with the same row shape as search and the same filters.

ParameterAllowed / rangeDescription
sellerrequiredShop handle (`@diego-a02c80` or `diego-a02c80`) or the shop URL.
seller_idoptionalNumeric shop id, as `seller_id` on a listing detail. Faster than the handle because it needs no lookup.
queryoptionalFree-text search, in Portuguese as the site indexes it (`tênis nike`, `vestido zara`). Optional when you are browsing a department, category or brand instead.
brandoptionalOne or more brand slugs, exactly as `filters` returns them (`nike`, `zara`, `off-white`).
subcategoryoptionalOne or more sub-category slugs as they appear in a row's `subcategory` (`rapazes-roupas-bermudas`). Comma-separated is accepted.
price_minoptional0–Lowest listing price, in BRL.
price_maxoptional0–Highest listing price, in BRL.
conditionoptionalused · newRestrict to second-hand or to unused stock.
sort = relevanceoptionalrelevance · price_asc · price_desc · discount_descResult order. Only the four orders Enjoei itself applies are offered — every other value the API accepts is ignored upstream and would silently not sort.
per_page = 30optional1–50Rows per page. Enjoei clamps this at 50 — a larger number is silently reduced, so the engine caps it too.
cursoroptional`next_cursor` from the previous page. Enjoei pages by cursor, not by page number.
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →
post/enjoei/v1/seller/sold1 credit

A shop's completed sales: what the item was listed at AND what it actually sold for. Enjoei publishes both, which makes this the price-comparison surface for second-hand goods in Brazil.

ParameterAllowed / rangeDescription
sellerrequiredShop handle (`@diego-a02c80` or `diego-a02c80`) or the shop URL.
page = 1optional1–1-based page of the sold shelf (40 rows per page).
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →
post/enjoei/v1/seller/profile1 credit

A shop's public page: handle, display name, city/state, bio, avatar, the date it joined, and its public counters — items for sale, items sold, likes received, followers and following.

ParameterAllowed / rangeDescription
sellerrequiredShop handle (`@diego-a02c80` or `diego-a02c80`) or the shop URL.
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →
post/enjoei/v1/filters1 credit

The brand and sub-category facets Enjoei itself offers for a query, each with its live listing count — the slugs you feed back into `search`.

ParameterAllowed / rangeDescription
queryoptionalFree-text search, in Portuguese as the site indexes it (`tênis nike`, `vestido zara`). Optional when you are browsing a department, category or brand instead.
departmentoptionalDepartment slug, e.g. `mocas`, `rapazes`, `kids`, `casa`, `infoeletro`. Take the exact slug from a search row's `department`.
subcategoryoptionalOne or more sub-category slugs as they appear in a row's `subcategory` (`rapazes-roupas-bermudas`). Comma-separated is accepted.
brandoptionalOne or more brand slugs, exactly as `filters` returns them (`nike`, `zara`, `off-white`).
price_minoptional0–Lowest listing price, in BRL.
price_maxoptional0–Highest listing price, in BRL.
conditionoptionalused · newRestrict to second-hand or to unused stock.
size_clothesoptionalClothing sizes (`p`, `m`, `g`, `gg`) — shirts, tops, dresses.
size_shoesoptionalShoe sizes, Brazilian numbering (`38`, `40`).
size_waistoptionalWaist sizes for trousers, shorts and skirts (`38`, `40`, `42`).
sort = relevanceoptionalrelevance · price_asc · price_desc · discount_descResult order. Only the four orders Enjoei itself applies are offered — every other value the API accepts is ignored upstream and would silently not sort.
shipping_rangeoptionalsame_city · same_state · near_regions · same_countryLimit to sellers near a place. Anything other than `same_country` needs `city` and/or `state`.
cityoptionalCity the `shipping_range` is measured from.
stateoptionalTwo-letter Brazilian state the `shipping_range` is measured from.
published_withinoptional24h · 7d · 14d · 30dOnly listings published in this window.
discount_minoptional0–100Only listings discounted by at least this percentage.
discount_maxoptional0–100Only listings discounted by at most this percentage.
store_kindoptionalpro · celebrityRestrict to a kind of shop. These are the only two kinds Enjoei tags, and both are small slices of the catalogue (measured on `nike`: pro 190, celebrity 33).
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →
post/enjoei/v1/suggestfree

Enjoei's own search typeahead: completed search terms and matching shops.

ParameterAllowed / rangeDescription
termrequiredPartial search text to complete, as typed into Enjoei's search box.
max_rotations = 3optional1–5How many times to retry a failed upstream attempt before giving up.
Try in playground →