OpenSea API

Three prices per NFT — and the symbol is not always ETH

The OpenSea API returns NFT marketplace data — floor prices, items and activity — as clean JSON.

no credit card1,000 free credits · instant API key · live in 10 seconds
Missing a OpenSea endpoint, or need a source we don't have yet?Contact us real people · same-day reply.
O
/opensea/v1

7 active endpoints. Every call is 1 credit.

  • POST/opensea/v1/collection
  • POST/opensea/v1/search
  • POST/opensea/v1/items
  • POST/opensea/v1/item
  • POST/opensea/v1/activity
  • POST/opensea/v1/holders
  • POST/opensea/v1/trending

What OpenSea endpoints does ReefAPI ship?

7 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.

7 endpoints

collection

1 cr

Full collection detail by slug.

required
slug
optional

search

1 cr

Search OpenSea collections by free-text name.

required
query
optional
limit

items

1 cr

Paginated items (NFTs) in a collection.

required
slug
optional
limit, cursor, sort_by, direction

item

1 cr

Single NFT / item detail by collection contract + token id.

required
contract_address, token_id
optional
chain

activity

1 cr

Recent on-chain activity for a collection (default.

required
slug
optional
limit, event_type

holders

1 cr

Top holders (owners) of a collection, ranked by quantity owned.

required
slug
optional
limit, cursor

trending

1 cr

Trending or top collections ranked over a time window.

required
optional
ranking, timeframe, limit

Every parameter, every allowed value →

OpenSea API

3 of 7 endpoints, ready to run

View docs ↗

Every item in a collection with THREE different prices side by side: the cheapest live listing and which marketplace it sits on, the highest standing offer, and what the token last actually sold for — each as an amount, a currency symbol and, where the source has one, a US dollar figure.

1 credit1 required · 3 optional
POST/opensea/v1/items
ok744 ms · 20 records · sample
{
  "ok": true,
  "meta": {
    "api": "opensea",
    "endpoint": "items",
    "mode": "live",
    "latency_ms": 744,
    "record_count": 20,
    "cache_hit": false
  },
  "data": {
    "items": [
      {
        "id": "b640a12230bd3318a6c6471254c6496a",
        "name": "#1774",
        "token_id": "1774",
        "contract_address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
        "image_url": "https://i2c.seadn.io/robinhood/0x5c61f00fe68c6bff5d91dca67f7e61bf2dca712a/58d5cc3fc342034b39b344374d1e77/fd58d5cc3fc342034b39b344374d1e77.png",
        "animation_url": null,
        "rarity_rank": 2409,
        "best_listing": {
          "amount": 7.8989999999999,
          "symbol": "ETH",
          "usd": 19204.601729999755
        },
        "best_offer": {
          "amount": 7.45,
          "symbol": "WETH",
          "usd": 18119.0705
        },
        "last_sale": {
          "amount": 7.53,
          "symbol": "ETH",
          "usd": null
        },
        "listing_marketplace": "blur"
      },
      {
        "id": "46ea13b38b073359afe9e377334180cb",
        "name": "#5688",
        "token_id": "5688",
        "contract_address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
        "image_url": "https://i2c.seadn.io/base/0x7e72abdf47bd21bf0ed6ea8cb8dad60579f3fb50/9a3a78ecc50b35babe5a47e2711870/909a3a78ecc50b35babe5a47e2711870.png",
        "animation_url": null,
        "rarity_rank": 3119,
        "best_listing": {
          "amount": 7.899,
          "symbol": "ETH",
          "usd": 19204.60173
        },
        "best_offer": {
          "amount": 7.45,
          "symbol": "WETH",
          "usd": 18119.0705
        },
        "last_sale": {
          "amount": 7.85,
          "symbol": "ETH",
          "usd": null
        },
        "listing_marketplace": "blur"
      },
      {
        "id": "4c1f484d1c3332319109fe92ac94b9cd",
        "name": "#4590",
        "token_id": "4590",
        "contract_address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
        "image_url": "https://i2c.seadn.io/base/0x7e72abdf47bd21bf0ed6ea8cb8dad60579f3fb50/77d0dfcb06a01529e9f699034e019e/d177d0dfcb06a01529e9f699034e019e.png",
        "animation_url": null,
        "rarity_rank": 5924,
        "best_listing": {
          "amount": 7.9,
          "symbol": "ETH",
          "usd": 19207.033
        },
        "best_offer": {
          "amount": 7.45,
          "symbol": "WETH",
          "usd": 18119.0705
        },
        "last_sale": {
          "amount": 7.59,
          "symbol": "ETH",
          "usd": null
        },
        "listing_marketplace": "blur"
      }
    ]
  }
}
Real response, fetched from the live endpoint with the parameters on the left — trimmed to the first few rows, with seller names left out. Press Try it for the untrimmed response.

How the OpenSea API works

OpenSea is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.

01
Authenticate
x-api-key header

No OAuth app, no request signing, no per-site account. One key covers all 184 engines.

02
Call
POST /opensea/v1/…

Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.

03
Pay
1 credit per call

Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.

04
Read
{ ok, data, meta, error }

One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.

Find the mispriced token in a collection

The trade is the gap between the cheapest ask and the highest bid on the same token. Both numbers live on the same row, which means you never have to join two feeds to see it.

01collection
POST/opensea/v1/collection
{"slug": "boredapeyachtclub"}

The baseline floor and top offer, with the currency symbol on each — read the symbol, because it is not always the one you expect.

02items
POST/opensea/v1/items
{"slug": "boredapeyachtclub", "limit": 100, "sort_by": "PRICE", "direction": "ASC"}

One hundred items with best listing, best offer and last sale on every row. The spread is a subtraction, not a second request.

03activity
POST/opensea/v1/activity
{"slug": "boredapeyachtclub", "limit": 50}

The recent sales, to check whether the offers on those rows are the level things are actually clearing at.

A ranked list of tokens where the standing bid is close to the standing ask, with the last traded price beside each — computed from one call rather than reconciled from three feeds.

request
curl -X POST https://api.reefapi.com/opensea/v1/items \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"slug":"pudgypenguins","limit":5}'
response envelope
{
  "ok": true,
  "data": { … },
  "meta": {
    "api": "opensea",
    "endpoint": "items",
    "mode": "live",
    "latency_ms": …,
    "record_count": …
  },
  "error": null
}

Identifiers, price units, and the fields that are ratios rather than percentages

Two things break integrations here. Token ids exceed what a JSON number can safely hold, so they are strings, and several fields that look like percentages are decimal fractions. Prices are whole token units, not wei. All values below are a live read of pudgypenguins in August 2026.

FieldType and unitMeasured
slugThe last path segment of an OpenSea collection URL. A wrong one is rejected, not guessedpudgypenguins; an invented slug returned NOT_FOUND with retryable false
contracts[].address and chain0x address plus a chain enum value from ethereum, matic, base, solana, arbitrum, optimism, klaytn, avalanche, blast, zora, bsc, sei0xbd3531da5cf5857e7cfaa92426877b022e612cf8 on ethereum
token_idString, always. Never parse it as an integer"7526"
idA 32-character hex OpenSea internal id, unrelated to token_id45f2e6872b19330896ce4f1a187c4a5c
floor_price, best_listing, best_offer, last_sale, price{amount, symbol, usd}, where amount is whole token units and not weifloor 4.44899 ETH, usd 11102.63
symbolNOT always ETH. Read it on every row before you do arithmeticRe-measured 2026-08-28 across 60 trending rows on two rankings: floor_price.symbol came back as ETH, USDG, HYPE, USDC and RON, and null on one row. OpenSea lists across chains, so a stablecoin- or side-chain-denominated floor sits next to an ether one. Within Ethereum collections the older rule still holds: ETH for listings and sales, WETH for offers and some sales
one_day_floor_changeA signed decimal fraction, so multiply by 100 for a percentage-0.0135, meaning the floor was down about 1.35 percent
holders[].percentAlso a fraction of supply0.034 for a wallet holding 302 of 8,888
fees[].feeA percentage, with a required flag separating the marketplace fee from the creator fee1.0 required plus 5.0 optional
rarity_rankInteger rank inside the collection6160 out of 8,888

The activity action takes event_type in upper case (SALE, LISTING, OFFER, TRANSFER, MINT) but returns type in title case, so a filter of SALE yields rows whose type reads Sale. Compare case-insensitively.

Which currency, which of the three prices, and which marketplace

Measured against the live gateway across trending collections and individual items. The first row is the one that will cost you money if you skip it.

The floor is NOT always priced in ETH

Across twenty trending collections, the floor price symbol came back as ETH, USDG, HYPE, USDC and RON — five different currencies, because OpenSea lists across several chains. A hard-coded assumption that the number is ether mis-prices a stablecoin-denominated collection by three orders of magnitude, silently, with no error anywhere. Read the symbol on every row.

Every price is an amount, a symbol and a dollar value — but not all three are always filled

On twenty items: best listing and best offer carried an amount, a symbol and a USD figure; last sale carried the amount and the symbol with USD null on twenty of twenty. On the trending list it inverts — floor price had amount and symbol with no USD, while total volume had the USD and no symbol. Null-check each of the three fields independently rather than trusting one to imply the others.

Three prices, three different meanings

best_listing is the cheapest thing you can buy right now. best_offer is the highest standing bid, and it comes back denominated in WETH rather than ETH because that is what bids are made in. last_sale is what somebody actually paid. Quoting any one of them as 'the price' is wrong in a different way; the point of this endpoint is that you do not have to choose.

The best listing may not be on OpenSea at all

listing_marketplace named a competing marketplace on one collection and OpenSea on another. OpenSea aggregates other venues, so the cheapest ask you are shown is sometimes not one OpenSea itself is hosting — and the field tells you which, rather than leaving you to discover it when a purchase routes somewhere unexpected.

Paging is cursor-based and does not repeat

Page one and the page fetched with its next_cursor shared zero of twenty item ids. The cursor is opaque and comes back in meta; there is no page number to get wrong and no offset that drifts while the market moves under you.

Against us: the same query twice is not quite identical

One items query run back to back shared nineteen of twenty ids. The one that moved is not jitter in our ranking — it is a live order book, and a token that was listed or delisted between the two calls genuinely leaves the sorted window. Treat a single-row difference as a real event, not as noise to suppress.

A dead slug and a dead token id both answer not-found

An invented collection slug answers NOT_FOUND naming the slug; a token id outside the supply answers NOT_FOUND naming the contract, the id and the chain. Both are retryable false. That distinguishes 'this thing does not exist' from a transient failure, which is the call an inventory sync makes every night.

Holders are wallets, and this page does not publish that endpoint

The holders action returns the top owners of a collection with their wallet address, quantity, share of supply and an estimated portfolio value. It works, it is in the catalogue and it is in the reference documentation — but a wallet address resolves to a public trading history, so no sample of it is published here.

What people build with OpenSea

The jobs this data is most often used for.

7

endpoints

1

credit per call

01

NFT-analytics tools call collection to track a project's floor price, supply and listed count.

02

Portfolio apps use holders and items to value a wallet's holdings across collections.

03

Web3 products use activity and trending to power market feeds and discovery.

What OpenSea data costs

The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.

Full pricing →
$0.67–$1.50 / 1,000 credits
  • 1,000 free credits on signup, no card
  • One key, all 184 APIs, one credit pool
  • Failed and blocked calls are never charged
  • Credits roll over and never expire

Call it in two lines

Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.

curl
curl -X POST https://api.reefapi.com/opensea/v1/items \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"slug":"pudgypenguins","limit":5}'
python
import requests

r = requests.post(
    "https://api.reefapi.com/opensea/v1/items",
    headers={"x-api-key": REEF_KEY},
    json={
  "slug": "pudgypenguins",
  "limit": 5
},
)
print(r.json()["data"])
FAQ

Have a question? We got answers.

The questions people actually ask before wiring up OpenSea.

Get a free key →
Is token_id a number or a string?

A string, in every action that returns it. Measured items rows came back as "5898", "8247" and "2028", and the item action needs token_id passed as a string too. This is not cosmetic: token ids on many contracts run far past the 2^53 limit JavaScript can represent exactly, so parsing them as numbers silently corrupts the tail. The separate id field is a 32-character hex OpenSea identifier and is not interchangeable with it.

Are prices in wei?

No. amount is denominated in whole token units, so a floor of 4.44899 means 4.44899 ETH, not a wei integer. Each price object also carries symbol and usd, and the symbol is worth reading rather than assuming: a measured collection returned floor_price in ETH and top_offer in WETH, and one of three recent sales settled in WETH while the other two settled in ETH.

Why is best_listing null on an item that clearly exists?

Because that token is not currently listed for sale. A measured item, token 7526 of pudgypenguins, returned best_listing null while best_offer still carried 4.37 WETH — the standing collection-wide offer applies to every token whether or not the owner is selling. last_sale was also populated at 4.619955 ETH. So null on best_listing means unlisted, not missing data.

Why does listing_marketplace say blur instead of opensea?

Because the best listing for that token is not always on OpenSea. Measured items rows for pudgypenguins all carried listing_marketplace blur, with best_listing prices matching the collection floor. Treat floor_price as the cheapest listing OpenSea knows about across marketplaces, and read listing_marketplace before you tell a user where to buy.

Why is usd null on some rows but filled on others?

The lighter actions skip the conversion. Measured: last_sale.usd came back null on every items row while amount and symbol were present; the search action returned floor_price.usd null; and trending rows returned floor_price.usd null, top_offer null and unique_item_count null. The collection action is the one that fills all of them, so use search or trending to find a slug and then call collection for the numbers you intend to display.

What happens if I pass the wrong chain for a contract?

You get NOT_FOUND rather than a silent fallback. The same ethereum contract and token, requested with chain matic, returned NOT_FOUND with the message naming matic explicitly, and a nonexistent token id on the correct chain returned NOT_FOUND naming ethereum. chain defaults to ethereum and is on_invalid=ignore, so an unrecognised chain string quietly becomes ethereum instead of erroring.

How do I page through items, holders or activity?

With cursors, not offsets. meta returns next_cursor and has_more, and you pass next_cursor back as cursor. A measured items page of 5 returned an opaque base64-style cursor and has_more true. Ceilings differ per action: items allow up to 100 per page, holders and activity up to 50, and trending up to 100 collections.

What is estimated_nft_value_usd on a holder?

An estimate of that wallet's whole NFT portfolio, not its stake in the collection you asked about. The top pudgypenguins holder measured 302 tokens, percent 0.034, and estimated_nft_value_usd of about 8.6 million, which is more than 302 tokens at the 11,100 dollar floor. display_name is null when the wallet has neither an ENS name nor an OpenSea username, so fall back to address.

What is the OpenSea API?

OpenSea API is a ReefAPI endpoint group for opensea It returns live JSON through POST requests under /opensea/v1.

Is the OpenSea API free to try?

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

Do I need an OpenSea login or account?

No login to OpenSea 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 OpenSea data?

The page example is captured from a live collection call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the OpenSea API use?

OpenSea actions currently cost 1 credit per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

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

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

36 E-commerce & Marketplaces APIs on the same key

One key, one credit pool, one response envelope. If you are pulling OpenSea, you are one call away from the rest of the category — no second contract, no second integration.

Need something this API does not do?

Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.

0/4000

No account needed · we reply from [email protected]

Try it on your own data before you pay anything

The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.

Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-28.