API reference

Collections

Two endpoints: a cursor-paginated browse across every chain, and a single-collection lookup with volume, sales and ownership windows.

List collections

GET/v1/collections

A page of collections with summary stats, ranked by traded volume by default. Collections launched on Exclusivo are ranked ahead of collections we merely index.

curl
curl "https://exclusivo.one/v1/collections?chain=solana&limit=2&sort=volume"
Response
{
  "data": [
    {
      "id": "solana_85ghq5exuysxeu4aexgs7d44udegrf3bvf6gx8ysgame",
      "chain": "solana",
      "contractAddress": "85Ghq5ExuySXEU4aExGs7d44udeGrF3bvF6GX8YsgaMe",
      "name": "SolGods",
      "slug": "solgods_",
      "image": "https://exclusivo.one/api/image-proxy?url=…",
      "banner": "https://exclusivo.one/api/image-proxy?url=…",
      "description": "4,444 gods on Solana.",
      "tokenStandard": "ProgrammableNonFungible",
      "royaltyBps": 500,
      "stats": {
        "floor": { "raw": "12500000000", "decimal": 12.5, "currency": "SOL", "usd": 2437.5 },
        "volumeAllTime": 48210.4,
        "supply": 4444,
        "owners": 1872
      }
    }
  ],
  "pagination": {
    "nextCursor": "eyJrIjoiY29sbGVjdGlvbnMiLCJ2IjoiMjUifQ",
    "hasMore": true
  }
}

Addresses above are illustrative examples. Note that contractAddress preserves the base58 casing of the Solana mint while id is a lowercased database key — see Gotchas.

List parameters

ParameterTypeDefaultNotes
chainstringnoneRestrict to one chain. One of solana, ethereum, polygon, base, ink, apechain, abstract. Anything else is a bad_request. Omit for all chains.
cursorstringnoneThe pagination.nextCursor from your previous page. Omit on the first page — never send an empty value.
limitinteger25Page size, 1–100 inclusive. Values outside that range are rejected rather than clamped.
sortstringvolumeOne of volume, floor, recent.

Sorting and paging must stay consistent

The cursor encodes a position within the sort you requested. Changing sort or chain partway through a walk while reusing the cursor produces an undefined slice of the index. Start a new walk instead.

Errors: bad_request for any invalid parameter or cursor, rate_limited at 120 req/min, and upstream_error when the collection index is unreachable. This endpoint has no degraded mode — it never returns a partial page with a stale flag.

Get one collection

GET/v1/collections/{id}

The same identity fields as the list, plus the windowed statistics that only make sense for one collection at a time.

curl
curl "https://exclusivo.one/v1/collections/solgods_"
Response
{
  "data": {
    "id": "solana_85ghq5exuysxeu4aexgs7d44udegrf3bvf6gx8ysgame",
    "chain": "solana",
    "contractAddress": "85Ghq5ExuySXEU4aExGs7d44udeGrF3bvF6GX8YsgaMe",
    "name": "SolGods",
    "slug": "solgods_",
    "image": "https://exclusivo.one/api/image-proxy?url=…",
    "banner": "https://exclusivo.one/api/image-proxy?url=…",
    "description": "4,444 gods on Solana.",
    "tokenStandard": "ProgrammableNonFungible",
    "royaltyBps": 500,
    "stats": {
      "floor": { "raw": "12500000000", "decimal": 12.5, "currency": "SOL", "usd": 2437.5 },
      "volume": { "allTime": 48210.4, "sevenDay": 612.8, "twentyFourHour": 74.2 },
      "sales":  { "allTime": 9184, "sevenDay": 61, "twentyFourHour": 7 },
      "supply": 4444,
      "owners": 1872,
      "listedCount": 143
    },
    "stale": false
  }
}

stats is not the same shape on both endpoints

The detail response replaces stats wholesale. stats.volumeAllTime exists only on the list endpoint; on the detail endpoint the same number lives at stats.volume.allTime, and listedCount exists only here. A parser written against one shape will read undefined against the other.

Errors: not_found when the identifier does not resolve, rate_limited at 300 req/min. Indexer failures do not error — they set stale.

How {id} resolves

{id} accepts three forms on this endpoint and on every other collection-scoped endpoint. All three run through the same resolver the public collection pages use, so a value that works in a browser URL works here.

FormExampleNotes
Canonical slugsolgods_The platform slug, as it appears in a /collection/… URL. The most readable option and the one to hard-code in examples.
Contract address / collection mint0x8a90cab2b38dba80c64b7734e58ee1db38b8992eEVM contract addresses match case-insensitively. Solana collection mints are matched as base58 — pass the real mixed-case mint.
Document idethereum_0x8a90cab2b38dba80c64b7734e58ee1db38b8992eThe <chain>_<contract> key returned as id / collectionId. Round-trips exactly, which makes it the right value to persist.

The identifier may be at most 200 characters. Anything longer, or anything that resolves to no collection, returns not_found.

Which form to store

Store the id you received. Slugs are human-facing and can be re-pointed; contract addresses do not identify a collection on their own, because the same address can exist on more than one chain. The document id carries the chain and the address together and is stable.

Field reference

FieldTypeNotes
idstringCanonical document id. Opaque — pass it back, do not parse it.
chainstring | nullNull when the stored chain value is missing or unrecognised. A null chain also means no floor price is computed for that row.
contractAddressstring | nullEVM contract lowercased; Solana collection mint with base58 casing preserved. This is the address to use for on-chain work.
namestringFalls back to the document id when the collection has no stored name.
slugstring | nullPlatform slug, falling back to the OpenSea slug, then the Magic Eden symbol, then the contract address.
imagestring | nullCollection avatar. Usually proxied through our image service.
bannerstring | nullCollection banner.
descriptionstring | nullFree text as supplied by the creator or the source marketplace.
tokenStandardstring | nullSource-reported standard, e.g. ERC721, ProgrammableNonFungible, Core. Not normalised across chains.
royaltyBpsnumber | nullCreator royalty in basis points — 500 is 5%. Charged to the buyer on top of the ask.
stats.floorPrice | nullSeller-ask floor, never the buyer all-in cost. For the buyer figure use the floor endpoint.
stats.supplynumber | nullTotal supply. On the detail endpoint this falls back to the indexed token count when the stored supply is absent.
stats.ownersnumber | nullUnique holders, best-effort. Indexer-reported where available, otherwise the stored snapshot.
stats.listedCountnumber | nullDetail endpoint only. Null when the indexer stats call did not return.
stalebooleanDetail endpoint only. True only when both indexer calls failed — see below.

Gotchas

The two floors are not the same number

stats.floor on the list endpoint comes from the stored collection snapshot. On the detail endpoint the live indexer analytics floor is preferred, falling back to that same snapshot. Both are seller-ask floors, but the detail figure is fresher, so the same collection can legitimately show two different floors across the two endpoints within one cache window. If you need a single authoritative number, call the floor endpoint.

slug is not guaranteed to be a slug

When a collection has no platform slug, the field falls back through the OpenSea slug and the Magic Eden symbol to the contract address. So slug can legitimately contain 0x8a90cab2b38dba80c64b7734e58ee1db38b8992e. It still works as an {id}, but do not assume it is short, human-readable, or unique across chains.

stale is narrower than it sounds

stale: true on the detail endpoint means both indexer sources failed. If only one failed — say the analytics call timed out but the stats call succeeded — you get stale: false with volume and sales windows silently null. Check for null windows on their own merits rather than relying on the flag to warn you.

id is lowercased, including on Solana

Document ids are built by lowercasing the address, which is safe for EVM and destructive for base58. The suffix of a Solana id is therefore not a usable mint. Read contractAddress whenever you need the real address, and never reconstruct one from id.