# Vollector documentation > Vollector connects tokenized collectibles to their owner's identity on X. Collectors link the wallets holding their vaulted cards and get a public profile, a portfolio and a place on the leaderboard; they can trade cards peer to peer, borrow or lend against them, and compare gacha packs by their expected value. # What is Vollector A tracker for your tokenized collectibles, linked to your X profile, and how to set it up. Page: https://vollector.id/docs/getting-started ## What is Vollector? Vollector is a tracker for your tokenized collectibles, linked to your X profile. It allows you to verify ownership and showcase your cards, comics, and physical assets to the world. You prove they are yours either by signing with the wallet that holds them or by importing your wallets automatically, and once a wallet is connected your collections are tracked for you. We pull the data straight from the chain to prove it is yours. Once you are set up you join the [leaderboard](https://vollector.id/docs/profiles#the-experience) and stand alongside other top collectors. There is also a private [Trader Mode](https://vollector.id/docs/trader-mode) that tracks all your positions and sales from the moment you connect any wallet onward, just for you. On top of that, we integrate tokens and [loans](https://vollector.id/docs/loans) into the ecosystem, plus a private OTC desk for [private offers](https://vollector.id/docs/offers) and a [gachas](https://vollector.id/docs/gachas) catalog, so there is a lot more to do than just showcasing your collection. We also welcome projects: as a [Partner](https://vollector.id/docs/partner) you can connect your token to your profile, with a live price chart and a swap widget, and get listed on the public Tokens page. ### Platforms We Support Vollector works with the leading tokenized collectible platforms. As soon as you connect a wallet, the collectibles you hold on any of these platforms are tracked automatically, so you never have to add anything by hand. You can browse and compare them all on our [Platforms page](https://vollector.id/p). - [Courtyard](https://vollector.id/p/courtyard) - [Collector Crypt](https://vollector.id/p/collectorCrypt) - [Phygitals](https://vollector.id/p/phygitals) - [Beezie](https://vollector.id/p/beezie) - [RIP.FUN](https://vollector.id/p/ripFun) - [DYLI](https://vollector.id/p/dyli) - [Rip Cars](https://vollector.id/p/ripCars) ## How It Works ### 1. Log in with X That is the only way in. We want this experience to be social first. ### 2. Connect Wallets or Import Go to your profile and hit the Wallets button. From there you have two ways to prove the collectibles are yours. You can connect a wallet directly and sign a message with it, which verifies you own that wallet and everything in it (up to 10 wallets). Or you can import from the platforms we support: if your X account is linked there, we match the profiles and pull in the connected wallets automatically, no signing needed. Either way, only verified collectibles show up on your profile. ### 3. Auto-Sync If you hold collectibles from our supported issuers, they appear in your profile instantly. We have a detection system that tracks when an item enters or leaves your collection to keep it up to date, and we also perform a global sync every 12 hours to update any metadata changes or collection movements. --- # Profiles and leaderboard The leaderboard, collectibles, tokens, portfolio charts, the activity feed and sharing. Page: https://vollector.id/docs/profiles Once you are set up, you join the [Leaderboard](https://vollector.id/), our main page where you stand alongside other top collectors. It is the ultimate flex. You can also browse and filter the collectibles in our community vaults on the [Collectibles](https://vollector.id/c) page. When you click on a specific item, you get the full breakdown: high-res imagery, the current owner linked to their X profile, the issuer linked to their website, asset attributes and metadata, direct links to marketplaces like Magic Eden or block explorers, and if the item is graded, a direct link to its grading company certificate. On the [Tokens](https://vollector.id/t) page you can browse the partner project tokens listed on Vollector, each with live price, market cap, 24h change and a chart, and follow the ones you care about. Each profile also includes a **Portfolio Chart** that tracks the total value of any collection over time. You can view history across 7 days, 30 days, 90 days, and up to 1 year. Pro users get the full year of history unlocked. The **Activity Feed** at [/f](https://vollector.id/f) shows a live stream of everything happening across the community: new collectors joining, collectibles being added to vaults, and Pro or Partner activations. You can also filter the feed to any specific collector by hitting the Activity button on their profile. Plus, sharing is beautiful. You can share a link to your profile, binder page, or a specific collectible. We automatically generate a custom preview image so it looks great on your timeline. Profile Binder page Collectible --- # Trader Mode Your private cost basis and P&L dashboard. Page: https://vollector.id/docs/trader-mode **Trader Mode** is your private cost basis and P&L dashboard. It is available to any signed-in user at [/v](https://vollector.id/v). You can track how much you paid for each collectible, see its current market value, and check your unrealized or realized profit and loss. For each item you can set a cost basis, record the sell price when you sell it, and mark it as sold or discard it. The dashboard shows your full portfolio totals: total invested, current value, unrealized P&L on items you still hold, and realized P&L on items you have already sold. You can sort by name, cost, price, P&L, or date, and filter by chain or contract to focus on a specific collection. --- # Private offers Make funded offers on any tracked collectible, or list your own at a fixed price. Page: https://vollector.id/docs/offers **Private Offers** are our built-in OTC desk, and it runs both ways: make a private, funded offer on any tracked collectible straight from its detail page, or list one of your own at a fixed price for anyone to buy. It is peer-to-peer with no oracles, so you deal directly with the owner, and it works on both EVM chains (Ethereum, Base, Polygon and more) and Solana. To make an offer, set your amount in USDC and an expiry, then sign. Nothing is held in custody: on EVM you sign a Seaport bid order and on Solana you approve the USDC, so the owner always sees a real, funded offer they can settle at any time. Buying below market is the whole point of OTC, but there is a floor: an offer must be at least 70% of the card's fair market value. You can even pay with USDC from a different chain and it bridges over automatically before the offer goes live. The owner finds every offer in their inbox at [/o](https://vollector.id/o), split into **Received** and **Sent**, and can accept, reject, or ignore each one. When they accept, the trade settles on-chain atomically: the collectible moves to the buyer and the USDC goes to the seller, minus a small 1% fee charged only on the cash leg. The desk also works the other way round. On any collectible you own you can hit **List for sale**, name a price in USDC and an expiry, and anyone can buy it outright at that price without negotiating. Prices go up to 30% above fair market value, so a listing is always something a buyer could realistically take. Listed cards show a USDC price button wherever they appear, and the switch beside the search bar filters the whole site down to what is for sale. Listing keeps custody exactly where offers do: nowhere. Your card never leaves your wallet, you only approve the sale so it can be delivered the instant someone buys, and you can delist whenever you like. Buying a listing needs only a wallet, no account, and the buyer can pay with USDC from another chain and let it bridge over first; every sale is checked on chain before the listing is marked sold. The same flat 1% applies, paid by the seller, and once it sells you can see who bought it. --- # Loans Borrow against your collectibles or lend USDC against them, peer to peer. Page: https://vollector.id/docs/loans With **Loans** at [/l](https://vollector.id/l) you can put your collectibles to work without selling them. It is a peer-to-peer lending market, with no oracles involved. You deal directly with the other side. If you want to borrow, you lock a tokenized collectible as collateral and take a loan in stablecoins against it. If you want to lend, you create an offer setting the principal in USDC, the APR, and the duration, and you earn interest backed by real collateral. If a loan is not repaid by the end of its term, the collateral goes to the lender. You can track every loan you have opened or funded from the same page, including active positions and the ones that are due. --- # Gachas Every pack and machine with its expected value, odds and chase cards. Page: https://vollector.id/docs/gachas The **Gachas** page at [/g](https://vollector.id/g) is a live catalog of mystery packs and gacha machines from the platforms we support, with all the math done for you. Instead of guessing whether a pack is worth opening, you get the numbers up front and can compare every pack side by side. Each pack shows its pull price next to a full set of metrics: **Expected Value** (the average worth of a single pull) and EV Yield, **Gross EV** after the platform's instant buyback rate, a **Volatility** rating, **Risk-Adjusted EV**, and a **Win Rate** read straight from the published odds. The data is live and refreshes about once a minute, so the values track the real market. Open any pack for the full breakdown: a rarity and odds table with the value bracket of each tier, and the **chase cards** still sitting in the machine's inventory pool. When you are ready, hit Open on the issuer to pull directly on their platform. Prefer to hunt a specific item instead of a whole pack? Switch to the [Collectibles](https://vollector.id/g/collectibles) tab. It flips the catalog around and lists every individual item still sitting unpulled across the machines, graded cards, watches, sneakers and more, so you can search straight for the chase you want. We only list an item when its odds are knowable from the provider's own published data, so you never see a guessed number. For each item you get the exact **Hit Odds** on a single pull (as a percentage and as "1 in N"), which pack it lives in, its market price, the **Expected Cost to Hit** (the average spend to land it, pack price ÷ odds), and a **Best Value** read of what you get back per dollar chased. Sort by any of these or filter by price, odds, expected cost, availability, platform and category, then hit Open to pull that item's pack on the issuer. --- # Browser extension Collections on X profiles, and graded card values anywhere on the web. Page: https://vollector.id/docs/extension The **Vollector Browser Extension** puts a Vollector Collection widget into the X (Twitter) profile of every Vollector user, so you can see what somebody holds without leaving your feed. Available for all Chromium-based browsers (Chrome, Edge, Brave, Opera, Arc, and more). It also values graded cards anywhere on the web. Right-click the picture of a **PSA, CGC, BGS or SGC** slab on a marketplace, an auction or a post, and the extension reads the label, identifies the card and its grade, and shows Alt's current value for that grade with a link to its research page. **Pro users** get their binders displayed directly on their X profile through the extension, so anyone browsing Twitter can see their collections at a glance. **Partner users** go even further: their token price chart and a direct buy button are shown on their X profile, driving traffic and purchases straight from the timeline. - [Chrome Web Store](https://chromewebstore.google.com/detail/pdbaicmgbngiaomehacmpkiaabepgoih) - [Microsoft Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/gcfakfcemhoaijibepojdpbkbdafanoe) --- # Vollector Pro Binders, the full-year chart, the token tracker and more. Page: https://vollector.id/docs/pro For the power collectors, we introduced Vollector Pro ($10/month or $96/year). Pro users get: ### Custom Binders Create up to 10 binders to organize your sets exactly how you want them using our drag-and-drop system. Binder pages are fully reorderable. ### Visibility Your box on the leaderboard will literally glow, and you get a Pro Badge next to your name. ### Portfolio Chart: Full Year Free users can view up to 90 days of portfolio history on any collector's profile. Pro unlocks the full year so you can track how any collection has grown over time. ### Token Tracker Keep tabs on partner tokens: follow any token and filter the tokens page to only those you track. Following collectors — and filtering the leaderboard or the activity feed to them — is free for every signed-in user. ### Binders on Twitter Your binders are displayed directly on your X (Twitter) profile through the Vollector Browser Extension, letting anyone see your collections without leaving their timeline. --- # Vollector Partner Everything in Pro, plus your token, your link and a gold badge on your profile. Page: https://vollector.id/docs/partner For projects and creators who want to take their presence to the next level, we offer Vollector Partner ($50/month or $480/year). It includes everything in Pro plus exclusive tools to promote your project. ### Gold Partner Badge Instead of the standard badge, you get an exclusive golden version displayed next to your name platform-wide. ### Golden Glow Your rank row on the leaderboard stands out even more with a unique golden glow effect that separates you from other collectors. ### Token Integration Connect your project token to display a live price chart and an integrated swap widget directly on your profile, making it easier than ever for followers to support your project. Your token is also listed automatically on the public Tokens page (/t) with live price, market cap, 24h change and chart, where every visitor can find and follow it. Supported Chains EthereumBasePolygonBSCArbitrumAvalancheAbstractSolana ### Custom Profile Link Add a prominent link to your profile to drive traffic directly to your website, marketplace, or official mint page. ### Token Chart & Buy Button on Twitter Your token price chart and a direct buy button are shown on your X (Twitter) profile through the Vollector Browser Extension, so followers can discover and purchase your token without leaving their timeline. **Important:** We have a zero tolerance policy for scams or fraudulent projects. Any project found to be promoting them will be permanently banned without a refund. --- # Vollector Connect API Put a "Connect with Vollector" button on your platform. Your user presses it, signs in with X on our side, and the wallets you already know are theirs land on their Vollector profile. It takes one endpoint and no account system on your end. The API is a signed link: your server builds it, your user opens it. There are no JSON calls to make and nothing to poll. Docs home: https://vollector.id/docs/connect ## What this is for You already know which wallets belong to which user. You send us that list, signed with your secret, and we take it as given: the wallets in a claim are that user's. There is nothing for the collector to paste, export or sign. Identity stays on our side. They sign in with X here, so you are never asked for a handle and never have to store one. ## The link One URL, built server side. No token exchange, no OAuth round trip, nothing to store on your end. ``` https://api.vollector.id/v1/connect?p=&d=&s= ``` It opens https://vollector.id/connect, where the collector signs in, with the query as you sent it. Links built on https://vollector.id/connect work the same. - `p` is the partner id we issue you. - `d` is your claim, JSON, base64url encoded. - `s` is `HMAC-SHA256(secret, "v1." + partner_id + "." + d)`, base64url encoded. Showing Vollector listings as well? Pass the same partner id as `ref` to the Listings API (https://vollector.id/docs/public-api), and both integrations count as you. ## The claim | Field | Type | Required | Notes | | --- | --- | --- | --- | | v | number | yes | Format version. Always 1 today. | | wallets | array | yes | Up to 10 entries of { address, chain }. | | nonce | string | yes | Unique per link, at least 8 characters. Redeeming burns it. | | iat | number | yes | Issued at, seconds since epoch. | | exp | number | yes | Expiry, seconds since epoch. At most 600 seconds after iat. | | uid | string | no | Your own id for this user. Opaque to us, never shown. | | redirect_uri | string | no | Where the Back button sends them. Must be an origin you registered. | Supported chains: solana, ethereum, polygon, base, abstract, bsc, evm. ## Reference implementation Node, and nothing outside its standard library. Any language with HMAC-SHA256 and base64url does the same job. ```js import { createHmac, randomBytes } from "node:crypto"; const PARTNER_ID = "your-partner-id"; const SECRET = process.env.VOLLECTOR_SECRET; export function connectUrl(wallets, opts = {}) { const iat = Math.floor(Date.now() / 1000); const claim = { v: 1, wallets, // [{ address, chain }] nonce: randomBytes(16).toString("hex"), iat, exp: iat + 600, uid: opts.uid, // your id for this user, optional redirect_uri: opts.redirectUri // must be a registered origin, optional }; const d = Buffer.from(JSON.stringify(claim)).toString("base64url"); const s = createHmac("sha256", SECRET) .update(`v1.${PARTNER_ID}.${d}`) .digest("base64url"); return `https://api.vollector.id/v1/connect?p=${PARTNER_ID}&d=${d}&s=${s}`; } ``` ## Test vector Run your implementation against this before you call us. If your signing input and your signature match these strings, your integration is correct and any remaining problem is on our side. The secret below is published here, so it is valid for nothing. - partner_id: `example` - secret: `vollector-test-secret` claim: ```json { "v": 1, "wallets": [ { "address": "0x8a981c2cfdd7fbc65395dd2c02ead94e9a2f65a7", "chain": "base" }, { "address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", "chain": "solana" } ], "nonce": "b7c1e0a2f4d94e3a", "iat": 1767225600, "exp": 1767226200, "uid": "user_12345", "redirect_uri": "https://example.com/settings?vollector=done" } ``` - d (base64url payload): `eyJ2IjoxLCJ3YWxsZXRzIjpbeyJhZGRyZXNzIjoiMHg4YTk4MWMyY2ZkZDdmYmM2NTM5NWRkMmMwMmVhZDk0ZTlhMmY2NWE3IiwiY2hhaW4iOiJiYXNlIn0seyJhZGRyZXNzIjoiOVd6RFh3QmJta2c4WlRiTk1xVXh2UVJBeXJaekRzR1lkTFZMOXpZdEFXV00iLCJjaGFpbiI6InNvbGFuYSJ9XSwibm9uY2UiOiJiN2MxZTBhMmY0ZDk0ZTNhIiwiaWF0IjoxNzY3MjI1NjAwLCJleHAiOjE3NjcyMjYyMDAsInVpZCI6InVzZXJfMTIzNDUiLCJyZWRpcmVjdF91cmkiOiJodHRwczovL2V4YW1wbGUuY29tL3NldHRpbmdzP3ZvbGxlY3Rvcj1kb25lIn0` - signing input: `v1.example.eyJ2IjoxLCJ3YWxsZXRzIjpbeyJhZGRyZXNzIjoiMHg4YTk4MWMyY2ZkZDdmYmM2NTM5NWRkMmMwMmVhZDk0ZTlhMmY2NWE3IiwiY2hhaW4iOiJiYXNlIn0seyJhZGRyZXNzIjoiOVd6RFh3QmJta2c4WlRiTk1xVXh2UVJBeXJaekRzR1lkTFZMOXpZdEFXV00iLCJjaGFpbiI6InNvbGFuYSJ9XSwibm9uY2UiOiJiN2MxZTBhMmY0ZDk0ZTNhIiwiaWF0IjoxNzY3MjI1NjAwLCJleHAiOjE3NjcyMjYyMDAsInVpZCI6InVzZXJfMTIzNDUiLCJyZWRpcmVjdF91cmkiOiJodHRwczovL2V4YW1wbGUuY29tL3NldHRpbmdzP3ZvbGxlY3Rvcj1kb25lIn0` - s (signature): `fjL7l4tymKmO6lHglIY_Ga5mkQ_LbNE9fEilWrDChvA` - full URL: `https://api.vollector.id/v1/connect?p=example&d=eyJ2IjoxLCJ3YWxsZXRzIjpbeyJhZGRyZXNzIjoiMHg4YTk4MWMyY2ZkZDdmYmM2NTM5NWRkMmMwMmVhZDk0ZTlhMmY2NWE3IiwiY2hhaW4iOiJiYXNlIn0seyJhZGRyZXNzIjoiOVd6RFh3QmJta2c4WlRiTk1xVXh2UVJBeXJaekRzR1lkTFZMOXpZdEFXV00iLCJjaGFpbiI6InNvbGFuYSJ9XSwibm9uY2UiOiJiN2MxZTBhMmY0ZDk0ZTNhIiwiaWF0IjoxNzY3MjI1NjAwLCJleHAiOjE3NjcyMjYyMDAsInVpZCI6InVzZXJfMTIzNDUiLCJyZWRpcmVjdF91cmkiOiJodHRwczovL2V4YW1wbGUuY29tL3NldHRpbmdzP3ZvbGxlY3Rvcj1kb25lIn0&s=fjL7l4tymKmO6lHglIY_Ga5mkQ_LbNE9fEilWrDChvA` ## Trying it live Add `&dry=1` to any connect link. It checks the link and reports what we saw, without signing anyone in and without writing anything. ## When something is rejected | Reason | What it means | | --- | --- | | `bad_signature` | The HMAC does not match. Check the signing input, not the payload. | | `malformed` | The payload is not base64url JSON, or a required field is missing. | | `bad_version` | The v field is not 1. | | `expired` | exp is in the past. Links last ten minutes. | | `not_yet_valid` | iat is more than a minute in the future. Usually a clock problem. | | `ttl_too_long` | exp is more than 600 seconds after iat. | | `no_wallets` | The wallets array is empty. | | `too_many_wallets` | More than 10 wallets in one link. | | `bad_wallet` | A wallet has no address. | | `bad_chain` | A wallet is on a chain we do not index. | Users see plain language, not these codes. The dry run shows you the code. ## The button Implement it however you want, wherever you want. The mark as SVG, and as a square icon for dark and light interfaces: - Mark: SVG, takes the color of the text around it: next to a price, in a button. [SVG](https://vollector.id/vollector-mark.svg) - Icon, dark: White mark on black, square: avatars, source lists, app grids on dark interfaces. [PNG 512](https://vollector.id/brand/vollector-icon-dark-512.png), [PNG 1024](https://vollector.id/brand/vollector-icon-dark-1024.png) - Icon, light: Black mark on white, square: the same, on light interfaces. [PNG 512](https://vollector.id/brand/vollector-icon-light-512.png), [PNG 1024](https://vollector.id/brand/vollector-icon-light-1024.png) - Use the files as they are: not stretched, recolored or redrawn. - Next to a listing, the mark with "Vollector" or "Buy on Vollector" says where it is sold. ## Getting your credentials Tell us your platform name and the exact origins we should allow as return URLs, and we send back a partner id and a secret. Keep the secret on your server, never in client code. It can be rotated at any time, and the old one keeps working alongside the new one until you tell us you have finished deploying. You can build and test the whole integration with a dry run before we switch you on. See "Trying it live" above. Contact: @vollectorid on X (https://x.com/vollectorid), or hi@vollector.id. --- # Vollector Listings API Everything collectors list for sale on Vollector, for any app, aggregator or bot that wants to show it. Read-only, free, no key, open to any origin (CORS `*`). Each listing carries a link that opens the purchase on Vollector: buyers check out here, so you never hold an order or a signature. Docs home: https://vollector.id/docs/public-api Base URL: `https://api.vollector.id/v1` ## Endpoints | Method | Path | What it answers | |---|---|---| | GET | `/listings` | Every live listing, a page at a time | | GET | `/listings/{id}` | One listing: 200 while for sale, 410 with its status after, 404 if unknown | | GET | `/changes` | What changed since a cursor: upserts and removals, oldest first | ## Quick start ```sh # Everything for sale, first page curl "https://api.vollector.id/v1/listings?ref=yourapp" # Courtyard cards under $500, 500 per page curl "https://api.vollector.id/v1/listings?issuer=courtyard&max_price=500&limit=500&ref=yourapp" # Everything for sale on Solana curl "https://api.vollector.id/v1/listings?chain=solana&ref=yourapp" # One listing curl "https://api.vollector.id/v1/listings/7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13" # A starting cursor for the changes feed, then what changed since curl "https://api.vollector.id/v1/changes" curl "https://api.vollector.id/v1/changes?since=MjAyNi0xMC0wMlQxODowNDo0NS4wMDBafGZmZmZmZmZmLWZmZmYtZmZmZi1mZmZmLWZmZmZmZmZmZmZmZg" ``` ## GET /listings Every live listing, in id order. Walk it with `after` until `has_more` is false. Unknown parameters are refused with a 400, and so is a parameter given twice. | Parameter | Type | Meaning | |---|---|---| | `limit` | `integer` | Listings per page, 1 to 500. Default 100. | | `after` | `listing id` | The next_after of the previous page. Leave it out for the first page. | | `chain` | `string` | Only this chain: solana, ethereum, polygon, base, abstract, flow. | | `issuer` | `string` | Only this issuer's collectibles: courtyard, collector-crypt, phygitals, beezie, rip-fun, rip-cars, dyli. | | `ref` | `string` | Your app's name, 1 to 32 letters, digits, - or _. It rides on every listing's url, so we can see the buyers you send. A Connect API partner uses its partner id. | | `min_price` | `number` | Lowest price, in USD. | | `max_price` | `number` | Highest price, in USD. | ```json { "listings": [ { "id": "7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13", "url": "https://vollector.id/buy/7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13?ref=yourapp", "price": { "amount": "1250.00", "currency": "USDC" }, "item": { "chain": "polygon", "contract": "0x251BE3A17Af4892035C37ebf5890F4a4D889dcAD", "token_id": "48211393570123994812385730016622931807", "standard": "erc721", "quantity": 1, "name": "2023 Pokemon Scarlet & Violet 151 Charizard ex #199 PSA 10", "image": "https://images.example.com/charizard-151-psa10.png", "issuer": { "slug": "courtyard", "name": "Courtyard" }, "grader": "PSA", "grade": "10", "tier": null, "cert": "84512039" }, "seller": { "wallet": "0x9f3a2b8c41d5e6f70812a3b4c5d6e7f8091a2b3c" }, "listed_at": "2026-10-02T18:00:00.124518+00:00", "updated_at": "2026-10-02T18:00:00.124518+00:00", "expires_at": "2026-11-01T18:00:00+00:00" } ], "next_after": "7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13", "has_more": true } ``` ## GET /changes What changed after a cursor, oldest first, as far as 20 to 35 seconds ago. An `upsert` carries the listing as it is now (new, or its price or expiry moved); a `remove` says why it left. Follow `next_cursor` while `has_more` is true; once it is false you are up to date, poll again in 30 to 60 seconds. Without `since`, the answer is empty and its `next_cursor` is where to start: 15 minutes back, so a snapshot read just after it misses nothing. Pass the same filters you used for the snapshot. | Parameter | Type | Meaning | |---|---|---| | `since` | `cursor` | The next_cursor of the previous answer. Leave it out to get a starting cursor. | | `limit` | `integer` | Changes per page, 1 to 500. Default 100. | | `chain` | `string` | Only this chain: solana, ethereum, polygon, base, abstract, flow. | | `issuer` | `string` | Only this issuer's collectibles: courtyard, collector-crypt, phygitals, beezie, rip-fun, rip-cars, dyli. | | `ref` | `string` | Your app's name, 1 to 32 letters, digits, - or _. It rides on every listing's url, so we can see the buyers you send. A Connect API partner uses its partner id. | Removal reasons: | Reason | Meaning | |---|---| | `sold` | Somebody bought it. | | `cancelled` | The seller took it down. | | `expired` | It reached expires_at. | | `failed` | A purchase reverted on-chain, which usually means the seller's approval is gone; it stays off until they relist. | ```json { "changes": [ { "type": "upsert", "id": "7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13", "updated_at": "2026-10-02T18:00:00.124518+00:00", "listing": { "id": "7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13", "url": "https://vollector.id/buy/7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13?ref=yourapp", "price": { "amount": "1250.00", "currency": "USDC" }, "item": { "chain": "polygon", "contract": "0x251BE3A17Af4892035C37ebf5890F4a4D889dcAD", "token_id": "48211393570123994812385730016622931807", "standard": "erc721", "quantity": 1, "name": "2023 Pokemon Scarlet & Violet 151 Charizard ex #199 PSA 10", "image": "https://images.example.com/charizard-151-psa10.png", "issuer": { "slug": "courtyard", "name": "Courtyard" }, "grader": "PSA", "grade": "10", "tier": null, "cert": "84512039" }, "seller": { "wallet": "0x9f3a2b8c41d5e6f70812a3b4c5d6e7f8091a2b3c" }, "listed_at": "2026-10-02T18:00:00.124518+00:00", "updated_at": "2026-10-02T18:00:00.124518+00:00", "expires_at": "2026-11-01T18:00:00+00:00" } }, { "type": "remove", "id": "c41d9a07-6e2b-4f13-8a55-0b7e9c3d1f28", "updated_at": "2026-10-02T18:03:12.551902+00:00", "reason": "sold" } ], "next_cursor": "MjAyNi0xMC0wMlQxODowNDo0NS4wMDBafGZmZmZmZmZmLWZmZmYtZmZmZi1mZmZmLWZmZmZmZmZmZmZmZg", "has_more": false } ``` ## Keeping a full copy 1. Call `/changes` without `since` and keep its `next_cursor`. 2. Walk `/listings` to the end. That is the book. 3. Poll `/changes?since=`: apply each upsert and removal, keep the new `next_cursor`, and fetch again at once while `has_more` is true. Replays are harmless: an upsert always carries the current listing, and a removal of something you do not have is a no-op. Store the cursor and a restart resumes where it stopped. Cursors do not expire. ```js const API = "https://api.vollector.id/v1"; const REF = "yourapp"; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); async function get(path) { for (;;) { const res = await fetch(API + path); if (res.ok) return res.json(); if (res.status !== 503) throw new Error(res.status + " " + (await res.text())); await sleep(5000); // our side hiccuped: retry shortly } } // 1. A starting cursor, taken BEFORE the snapshot so nothing slips between them. let cursor = (await get("/changes?ref=" + REF)).next_cursor; // 2. The snapshot: every live listing. const book = new Map(); let after = null; do { const page = await get("/listings?limit=500&ref=" + REF + (after ? "&after=" + after : "")); for (const l of page.listings) book.set(l.id, l); after = page.has_more ? page.next_after : null; } while (after); // 3. Keep up, for as long as you run. for (;;) { const page = await get("/changes?limit=500&ref=" + REF + "&since=" + cursor); for (const c of page.changes) { if (c.type === "upsert") book.set(c.id, c.listing); else book.delete(c.id); } cursor = page.next_cursor; // store it: a restart resumes from here if (!page.has_more) await sleep(30_000); } ``` ## GET /listings/{id} ```json { "listing": { "id": "7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13", "url": "https://vollector.id/buy/7b0c1e52-3f4a-4c8e-9d21-5a6f0b8e2c13?ref=yourapp", "price": { "amount": "1250.00", "currency": "USDC" }, "item": { "chain": "polygon", "contract": "0x251BE3A17Af4892035C37ebf5890F4a4D889dcAD", "token_id": "48211393570123994812385730016622931807", "standard": "erc721", "quantity": 1, "name": "2023 Pokemon Scarlet & Violet 151 Charizard ex #199 PSA 10", "image": "https://images.example.com/charizard-151-psa10.png", "issuer": { "slug": "courtyard", "name": "Courtyard" }, "grader": "PSA", "grade": "10", "tier": null, "cert": "84512039" }, "seller": { "wallet": "0x9f3a2b8c41d5e6f70812a3b4c5d6e7f8091a2b3c" }, "listed_at": "2026-10-02T18:00:00.124518+00:00", "updated_at": "2026-10-02T18:00:00.124518+00:00", "expires_at": "2026-11-01T18:00:00+00:00" } } ``` Once the listing is gone: `410 {"id": "...", "status": "sold"}`. The status is one of the removal reasons above. ## The listing object | Field | Type | Meaning | |---|---|---| | `id` | `string` | The listing's id. Stable for its whole life; a relist is a new id. | | `url` | `string` | Where to send a buyer. Opens the card on Vollector with the purchase ready. Link to this, not to a page you build. | | `price.amount` | `string` | The price as a decimal string, at least two decimals ("1250.00"). A string so no float rounds it. | | `price.currency` | `string` | Always USDC today. | | `item.chain` | `string` | The chain the collectible lives on. | | `item.contract` | `string` | Its contract (EVM) or collection (Solana) address. EVM addresses may come in either case; compare them lowercased. | | `item.token_id` | `string` | Its token id on EVM; its asset (mint) address on Solana. | | `item.standard` | `string` | erc721, erc1155 or solana. | | `item.quantity` | `integer` | Units for sale in this listing, 1 for a single card. | | `item.name` | `string | null` | The collectible's name as the issuer gives it. | | `item.image` | `string | null` | An image URL. Hotlinking is fine. | | `item.issuer` | `object | null` | { slug, name } of the platform that tokenized it; the slug is what the issuer filter takes. | | `item.grader` | `string | null` | PSA, BGS, CGC, SGC and so on, when graded. | | `item.grade` | `string | null` | The grade, as a string ("10", "9.5"). | | `item.tier` | `string | null` | The tier above a plain 10, when the card has it: black_label (Beckett, all four subgrades 10) or pristine (CGC). Its grade reads 10. | | `item.cert` | `string | null` | The grading certificate number, when known. | | `seller.wallet` | `string` | The wallet the listing is signed by. | | `listed_at` | `timestamp` | When it was listed. | | `updated_at` | `timestamp` | When something on this object last changed. | | `expires_at` | `timestamp | null` | When the listing lapses on its own. Hide it from then on, even before the feed says so. | There is no fair-market value in this API. The price is the seller's. ## Linking and attribution Send buyers to `url` as it is. It goes through https://vollector.id/buy/{id}, which opens the card's current page with the purchase ready; once the listing is gone it opens the card alone, so a stale link never dead-ends. Add `ref=` to your calls and every `url` carries it, so we can credit the buyers you send. Without it we go by the site the click came from, which apps and links with `rel="noreferrer"` do not reveal. If you also integrate the Connect API, use your partner id as `ref`: one identifier across both. Show the price as `price.amount` `price.currency`, and hide a listing once its `expires_at` has passed, even before the feed sends its removal. ## Logo and icon To show where a listing is sold: the mark next to the price or the buy button, with "Vollector" or "Buy on Vollector", or the icon wherever you list your sources. - Mark: SVG, takes the color of the text around it: next to a price, in a button. [SVG](https://vollector.id/vollector-mark.svg) - Icon, dark: White mark on black, square: avatars, source lists, app grids on dark interfaces. [PNG 512](https://vollector.id/brand/vollector-icon-dark-512.png), [PNG 1024](https://vollector.id/brand/vollector-icon-dark-1024.png) - Icon, light: Black mark on white, square: the same, on light interfaces. [PNG 512](https://vollector.id/brand/vollector-icon-light-512.png), [PNG 1024](https://vollector.id/brand/vollector-icon-light-1024.png) - Use the files as they are: not stretched, recolored or redrawn. - Next to a listing, the mark with "Vollector" or "Buy on Vollector" says where it is sold. ## Caching and limits Every answer is the same for every caller and is cached at our CDN, so polling costs us next to nothing and answers fast. There is no key and no hard rate limit; be reasonable (a poll every 30 seconds is plenty) and we will keep it that way. | Answer | CDN cache (s) | Served stale while refreshing (s) | |---|---|---| | /listings | 60 | 300 | | /listings/{id} | 15 | 60 | | /changes | 15 | 30 | | A 400 (bad parameters) | 300 | 0 | Errors are JSON, `{"error": "..."}`. A 400 names the bad parameter. A 503 means our side hiccuped: retry after the `Retry-After` seconds. ## Versioning This is v1. Fields may be added to any object; nothing is removed or changes meaning within v1. Anything breaking ships as v2, with v1 kept running.