Example Queries
Practical examples for common use cases with the Verse GraphQL API.
Browse Live Collections
Fetch collections with active primary market sales:
query LiveCollections {
explore(
filter: {
exploreTab: [LIVE]
market: [PRIMARY]
}
sorting: { sort: FEATURED_SCORE, direction: DESC }
first: 10
) {
nodes {
id
name
slug
blockchain
previewAsset {
... on ImageAsset { baseUrl } # baseUrl is a template — see "Displaying Images" below
}
artworks {
title
primaryMarketListing {
startsAt
endsAt
strategy {
... on PMBuyNowLimitedEditionStrategy {
price { value currency }
maxEditions
stats { issuedEditions }
}
... on PMBuyNowOpenEditionStrategy {
price { value currency }
stats { issuedEditions }
}
}
}
}
}
}
}
Get Collection Details by Slug
query CollectionBySlug($slug: String!) {
collectionsPage(request: {
filter: { slugs: [$slug] }
first: 1
}) {
nodes {
id
name
slug
description
blockchain
artists { name slug }
stats {
issuedEditions
ownersCount
floorPrice { value currency }
tradedVolume { value currency }
lastSalePrice { value currency }
}
artworks {
id
title
primaryMarketListing {
startsAt
endsAt
}
}
}
}
}
Fetch Project Items for an Artist-Curated Artwork
Query the curated set of items for an artist-curated project. Each item includes its availability, preview asset, and feature traits.
query ProjectItems($artworkId: ID!) {
artworksPage(request: {
filter: { ids: [$artworkId] }
first: 1
}) {
nodes {
id
title
artworkKind {
... on ProjectArtworkKind {
allowUserSelection
withRepetitions
items {
id
isAvailable
featuresJson
staticAsset {
... on ImageAsset { baseUrl } # template URL — resolve before displaying
... on VideoAsset { baseUrl previewImageUrl } # baseUrl = video file; previewImageUrl = thumbnail template
}
}
}
}
primaryMarketListing {
startsAt
endsAt
strategy {
... on PMBuyNowLimitedEditionStrategy {
price { value currency }
maxEditions
stats { issuedEditions }
}
}
}
}
}
}
Key fields:
allowUserSelection— Whentrue, collectors can choose a specific item to purchase. Whenfalse, a random item is assigned.isAvailable— Whether the item can still be purchased (relevant for projects without repetitions).featuresJson— JSON string of trait/feature data for the item.
List Editions for an Artwork
Fetch editions with sorting and availability filtering:
query ArtworkEditions($artworkId: ID!) {
assetsPage(
filter: {
artworkIds: [$artworkId]
assetType: EDITION
}
sorting: { sort: EDITION_NUMBER, direction: ASC }
first: 50
) {
totalCount
pageInfo {
endCursor
hasNextPage
}
nodes {
id
asset {
... on Edition {
editionNumber
tokenId
hash
status
owner {
... on UserEditionOwner {
owner { username }
}
... on BlockchainAddressEditionOwner {
blockchainAddress { address }
}
}
features {
... on StringFeatureValue {
name
value
}
}
}
}
}
}
}
Editions Available for Purchase
query BuyNowEditions($artworkId: ID!) {
assetsPage(
filter: {
artworkIds: [$artworkId]
assetType: EDITION
availability: [BUY_NOW]
}
sorting: { sort: LIST_PRICE, direction: ASC }
first: 20
) {
totalCount
nodes {
id
asset {
... on Edition {
editionNumber
floorListing {
price { value currency }
source
}
}
}
}
}
}
Activity Feed for an Artwork
query ArtworkActivity($artworkId: ID!) {
activityPage(
filter: {
artworkId: $artworkId
activityType: [PM_SALE, SM_SALE, SM_LISTED, OS_SALE]
}
first: 30
) {
nodes {
id
entryType
timestamp
amount
edition {
editionNumber
}
fromUserId { username }
toUserId { username }
transactionHash
}
}
}
Search Across the Platform
query Search($query: String!) {
search(query: $query) {
artists {
name
slug
}
collections {
name
slug
blockchain
}
exhibitions {
name
slug
}
}
}
Marketplace Statistics
query WeeklyStats {
stats(period: PERIOD_7D) {
topCollectionsByVolume {
collection {
name
slug
blockchain
}
totalVolume
totalSales
primaryVolume
primarySales
secondaryVolume
secondarySales
}
topSales {
artwork { title }
collection { name }
amount { value currency }
market
timestamp
}
}
}
Artist Profile and Works
query ArtistProfile($slug: String!) {
personsPage(request: {
filter: { slugs: [$slug] }
first: 1
}) {
nodes {
name
bio
location
profileLinks
artworks {
id
title
blockchain
collection { name slug }
}
collections {
name
slug
stats {
issuedEditions
tradedVolume { value currency }
}
}
}
}
}
Marketplace Orders (Listings & Offers)
Get active buy-now listings for a collection:
query CollectionListings($collectionId: String!) {
orders(request: {
filter: {
side: ASK
collectionId: $collectionId
}
first: 20
}) {
nodes {
id
price { value currency }
usdPrice
chain
createdAt
expiresAt
asset {
asset {
... on Edition {
editionNumber
artwork { title }
}
}
}
}
}
}
Get offers on a specific edition:
query EditionOffers($assetId: ID!) {
orders(request: {
filter: {
side: BID
asset: { assetId: $assetId, assetType: EDITION }
}
first: 20
}) {
nodes {
price { value currency }
createdAt
expiresAt
maker {
... on UserPublic { username }
... on EthereumAddress { address ensName }
}
}
}
}
Look Up Edition by On-Chain Data
query EditionByToken($contract: String!, $tokenId: String!) {
editionByContract(contractAddress: $contract, tokenId: $tokenId) {
id
editionNumber
artwork {
title
artist { name }
collection { name slug }
}
owner {
... on UserEditionOwner {
owner { username }
}
}
status
contractInfo {
contractAddress
contractType
chain
}
}
}
Estimate Secondary Sale Fees
query EstimateFees($artworkId: ID!) {
estimateSecondaryMarketFees(
artworkId: $artworkId
price: { value: "1.0", currency: "ETH" }
) {
royaltyFee
royaltyAmount { value currency }
marketplaceFee
marketplaceAmount { value currency }
youWillReceive { value currency }
}
}
Paginating Through Results
Use cursors to iterate through large result sets:
async function fetchAllEditions(artworkId) {
const editions = [];
let cursor = null;
let hasMore = true;
while (hasMore) {
const response = await fetch("https://verse.works/query", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
query ($artworkId: ID!, $after: Cursor) {
assetsPage(
filter: { artworkIds: [$artworkId], assetType: EDITION }
sorting: { sort: EDITION_NUMBER, direction: ASC }
after: $after
first: 50
) {
pageInfo { endCursor hasNextPage }
nodes {
asset { ... on Edition { editionNumber tokenId status } }
}
}
}
`,
variables: { artworkId, after: cursor },
}),
});
const { data } = await response.json();
editions.push(...data.assetsPage.nodes);
cursor = data.assetsPage.pageInfo.endCursor;
hasMore = data.assetsPage.pageInfo.hasNextPage;
}
return editions;
}
Displaying Images from Query Results
The baseUrl and previewImageUrl fields returned by the API are template URLs — they contain {{SIZE}} and {{FORMAT}} placeholders that must be replaced before use:
// Resolve a template URL into a displayable image URL
function resolveImageUrl(templateUrl, width = "w640", format = "webp") {
return templateUrl
.replace("{{SIZE}}", width)
.replace("{{FORMAT}}", format);
}
// ImageAsset — use baseUrl directly
const imgSrc = resolveImageUrl(imageAsset.baseUrl);
// VideoAsset — use previewImageUrl for thumbnails, baseUrl for <video src>
const videoThumb = resolveImageUrl(videoAsset.previewImageUrl);
const videoSrc = videoAsset.baseUrl; // direct URL, no placeholders
// SVGAsset — use baseUrl at original size, no format
const svgSrc = svgAsset.baseUrl
.replace("{{SIZE}}", "source")
.replace("@{{FORMAT}}", "");
// IFrameAsset — use previewImageUrl for thumbnails, iframeUrl for <iframe src>
const iframeThumb = resolveImageUrl(iframeAsset.previewImageUrl);
const iframeSrc = iframeAsset.iframeUrl; // direct URL
Available width tokens: w80, w160, w320, w480, w640, w980, w1400, w2400, w3840, source.
Available formats: webp, jpeg, png, gif, avif.
See the full Static Assets guide for responsive images, GIF handling, and framework-specific patterns.