API reference

Listings

Active listings for one collection, cheapest first, deduplicated across our own order book and every external marketplace we mirror.

Endpoint

GET/v1/collections/{id}/listings
curl
curl "https://exclusivo.one/v1/collections/solgods_/listings?limit=2"
Response
{
  "data": [
    {
      "chain": "solana",
      "contractAddress": null,
      "tokenId": null,
      "mint": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
      "collectionId": "solana_85ghq5exuysxeu4aexgs7d44udegrf3bvf6gx8ysgame",
      "price": { "raw": "12500000000", "decimal": 12.5, "currency": "SOL", "usd": 2437.5 },
      "seller": "HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH",
      "buyer": null,
      "marketplace": "EXC",
      "status": "active",
      "expiresAt": null,
      "timestamp": "2026-07-24T09:41:07.000Z",
      "orderId": "exclusivo_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
      "tx": null
    },
    {
      "chain": "solana",
      "contractAddress": null,
      "tokenId": null,
      "mint": "4uQeVj5tqViQh7yWWGStvkEG1ZmhX6uasJtWCJziofMk",
      "collectionId": "solana_85ghq5exuysxeu4aexgs7d44udegrf3bvf6gx8ysgame",
      "price": { "raw": "12900000000", "decimal": 12.9, "currency": "SOL", "usd": 2515.5 },
      "seller": "5FHwkrdxkjqQhLwoDdRQ4hd1gz4bmL7cUHrz1yfEcvsN",
      "buyer": null,
      "marketplace": "magic-eden",
      "status": "active",
      "expiresAt": null,
      "timestamp": "2026-07-25T18:02:44.000Z",
      "orderId": "me_3n2Kq1s8bTfYb2rJ7wLuGmXcVaDe",
      "tx": null
    }
  ],
  "pagination": {
    "nextCursor": "eyJrIjoibGlzdGluZ3Mtb2Zmc2V0IiwidiI6IjIifQ",
    "hasMore": true
  }
}

Mints, wallets and order ids above are illustrative examples. Cached for 15 seconds at the edge with a further 15 seconds of stale-while-revalidate.

Why this is the canonical feed

Exclusivo EVM listings are signed Seaport orders held off-chain. Creating one and cancelling one both cost nothing and emit no transaction, no log, and no event. There is nothing on Ethereum, Base, Ink, Polygon, ApeChain or Abstract for you to index. The order only touches the chain at the moment somebody fills it, and by then it is a sale, not a listing.

A chain-only indexer will never see our EVM order book

If you build an aggregator by crawling logs, you will see every Exclusivo EVM sale and zero Exclusivo EVM listings. The collection will appear to have no supply for sale on our marketplace, right up until a sale prints from nowhere. This endpoint is the only complete source. The same applies to cancellations: an order that disappears from this feed was cancelled or expired, and there is no on-chain event corresponding to that.

Solana is different — listings there move the asset into escrow, so a transaction does exist and carries our memo. You can index those from the chain if you prefer; see the Solana memo format. This endpoint still gives you both chains in one normalized shape.

Parameters

ParameterInDefaultNotes
idpathrequiredCanonical slug, contract address or collection mint, or a <chain>_<contract> document id.
cursorquerynoneThe pagination.nextCursor from your previous page. Scoped to this endpoint — a cursor from /sales or /collections is rejected as bad_request.
limitquery25Page size, 1–100 inclusive. Out-of-range values are rejected, not clamped.

There is no sort parameter. The feed is always cheapest-first, which is what a floor, sweep, or “cheapest available” surface needs. There is also no way to filter by marketplace, trait, or seller — do that client-side.

Errors: bad_request for a bad parameter or cursor; not_found when the identifier does not resolve, or resolves to a collection with no recognised chain; rate_limited at 120 req/min. Upstream failures do not error — they degrade and set meta.stale.

How sources are merged

Two sources cover different ground, and the response is the union of both:

SourceCoversFreshness
Exclusivo order bookExclusivo-native EVM Seaport listings. The only store for them — they exist nowhere else, on-chain or off.Live. Read directly per request, up to 200 eligible rows for the contract.
Indexer mirrorExternal marketplace rows (OpenSea on EVM, Magic Eden on Solana) plus the mirror of Exclusivo-native Solana listings.Roughly a 2-minute sync cycle for the Exclusivo-Solana rows.

Deduplication

Rows are keyed by asset identity — (chain, contractAddress, tokenId) for EVM, the mint for Solana. When both sources describe the same asset, the Exclusivo order book wins, because it is authoritative for our own EVM listings and the mirror may be showing a copy that is minutes behind. Anything the order book does not know about (Solana, and every external marketplace) comes through from the mirror.

Only rows with status: "active" survive the merge, and the result is sorted ascending by price.decimal with orderId as a deterministic tiebreak, so equal-priced listings keep a stable relative order across your pages.

One asset, one row — even if it is listed twice

A token listed on both Exclusivo and OpenSea appears once, at whichever price the winning source reports. That is usually what you want for a floor calculation, but it means you cannot use this endpoint to enumerate every order in existence for a token, and the count of rows is a count of listed assets rather than of orders.

Pagination and the snapshot

The merged set is a bounded snapshot of at most 250 listings, taken from the cheapest end of the book. The cursor is a position within that snapshot. Once you have walked 250 items, hasMore goes false even if the collection has thousands of listings.

Walking the book
let cursor = null;
const listings = [];

do {
  const url = new URL("https://exclusivo.one/v1/collections/solgods_/listings");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url);
  if (!res.ok) throw new Error((await res.json()).error.message);

  const { data, pagination, meta } = await res.json();
  if (meta?.stale) console.warn("partial book:", meta.staleSources);

  listings.push(...data);
  cursor = pagination.hasMore ? pagination.nextCursor : null;
} while (cursor);

// listings.length <= 250

The snapshot is rebuilt on every request

The 250-item window is recomputed per request, not frozen when you took page one. Within the 15-second cache window your pages line up; outside it, a new listing that undercuts the floor shifts every subsequent position by one, so you can see a duplicate or miss an item. Deduplicate the accumulated result by orderId before you use it, and do not treat a multi-page walk as a consistent read.

A cursor whose offset exceeds the snapshot ceiling is rejected with bad_requestrather than returning an empty page. That is a deliberate guard against hand-built cursors.

The listing item

Listings, sales and token listing state all use the same cross-chain item shape. Which identity fields are populated depends on the chain.

FieldTypeNotes
chainstringThe chain of this listing. Always populated.
contractAddressstring | nullEVM contract, lowercase. Always null on Solana rows.
tokenIdstring | nullEVM token id as a decimal string, so large ids survive JSON. Always null on Solana rows.
mintstring | nullSolana asset mint, Core asset id, or compressed-NFT asset id, base58 case preserved. Always null on EVM rows.
collectionIdstringCanonical collection document id. Opaque — pass it back as {id}, do not parse an address out of it.
pricePriceThe seller ask. Buyer fees are added on top at fill time and are not included here.
sellerstring | nullThe wallet that will receive the proceeds — the beneficial owner, not the escrow wallet holding the asset.
buyerstring | nullAlways null on active listings. The field exists because sales share this shape.
marketplacestring"EXC" for Exclusivo-native rows; otherwise the source slug, e.g. "opensea" or "magic-eden".
statusstringAlways "active" on this endpoint — non-active rows are filtered out during the merge.
expiresAtstring | nullISO 8601 expiry. Null means the listing does not expire. Already-expired rows are excluded.
timestampstringWhen the listing was created, where the source records it. See the gotcha below.
orderIdstring | nullThe join key for this order across our systems. Format varies by source — see below.
txstring | nullAlways null on this endpoint. Listings have no settlement transaction; the field is populated on sales.

orderId format is source-dependent

It is a stable identifier, but it is not one identifier scheme. Exclusivo EVM rows carry the order-book document id, in the form ethereum_0x8a90…992e_4271_1785412903117 — despite what the OpenAPI description suggests, this is not the Seaport order hash. Exclusivo-Solana mirror rows carry an exclusivo_-prefixed id, and external rows carry the source marketplace's id. Use it for deduplication and for joining our own endpoints together; do not parse it, and do not expect to look it up on Seaport with it. The real Seaport order hash for a single token is available on the token endpoint when the listing is read from the indexer overlay.

Staleness

When the indexer mirror is unreachable, the endpoint returns what it has rather than failing, and adds a meta object:

Degraded response
{
  "data": [ … ],
  "pagination": { "nextCursor": null, "hasMore": false },
  "meta": { "stale": true, "staleSources": ["indexer-mirror"] }
}

The severity of that flag depends on the chain, and the difference matters:

ChainWhat a stale mirror means
EVMExternal marketplace rows are missing. Exclusivo-native listings still come through from the order book, so the page is real but incomplete — the true floor may be lower than what you see.
SolanaEvery row is missing. The mirror is the only source for Solana on this endpoint, so an empty page with meta.stale means “unknown”, not “nothing listed”.

Do not write an empty stale page into your store

An ingest that overwrites its listing table with each response will wipe a Solana collection's entire book the first time the mirror blips. Check meta.stale before any destructive write and skip the cycle instead.

Gotchas

The Solana mirror lags by about two minutes

Exclusivo-native Solana listings reach this endpoint through a sync that runs roughly every two minutes. A listing created seconds ago may not be here yet, and a listing cancelled or filled seconds ago may still be here. Nothing flags this — the mirror is reachable and simply behind, so meta.stale stays absent.

The practical consequence is that you must not treat presence in this feed as proof that an order is fillable. Anything that spends money should re-check at fill time, and a failed fill on a listing you read here is expected behaviour rather than a bug in either system.

timestamp is best-effort

It is the source's creation time where one exists, falling back to the source's update time, and finally to the moment the response was built when the row carries no usable time at all. That last case makes the value look brand new. Do not use timestamp to compute listing age or “newly listed” signals without corroboration.

Cheapest-first is by native amount

Sorting uses the native price, not USD, and a collection lives on a single chain, so the ordering is well-defined. But it is price.decimal that sorts — a double. Two listings whose wei amounts differ in the last few digits can order arbitrarily relative to each other. If exact ordering matters, re-sort on price.raw as a big integer.

Not every collection is EVM-complete

The order-book read is keyed on the collection's contract address. A collection that resolves without one — rare, but possible for partially indexed records — contributes no Exclusivo EVM rows, and the response silently contains mirror rows only, with no stale flag. If a collection you expect to have Exclusivo listings shows none, check that contractAddress is populated on the collection object.