Skip to main content

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 {
baseUrlTemplate
}
}
}
}
}

Get Collection Details by Slug​

query CollectionBySlug($slug: String!) {
collectionsPage(request: {filter: {slugs: [$slug]}, first: 1}) {
nodes {
id
name
slug
description
blockchain
}
}
}

Read Artist-Curated Artwork Details​

Read the configuration and sale information for an artist-curated project.

query ArtistCuratedArtwork($artworkId: ID!) {
artworksPage(request: {filter: {ids: [$artworkId]}, first: 1}) {
nodes {
id
title
artworkKind {
... on ProjectArtworkKind {
allowUserSelection
withRepetitions
}
}
primaryMarketListing {
startsAt
endsAt
strategy {
... on PMBuyNowLimitedEditionStrategy {
price {
value
currency
}
maxEditions
stats {
issuedEditions
}
}
}
}
}
}
}

Key fields:

  • allowUserSelection — When true, collectors can choose a specific item to purchase. When false, a random item is assigned.

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​

query ArtistProfile($slug: String!) {
personsPage(request: {filter: {slugs: [$slug]}, first: 1}) {
nodes {
name
bio
location
profileLinks
}
}
}

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 }
}
}
}
}

Check Edition Minting Status​

After a purchase, the on-chain mint happens asynchronously. Use this query to poll for minting completion and retrieve the tokenId once available:

query EditionStatus($editionId: ID!) {
asset(id: $editionId, assetType: EDITION) {
asset {
... on Edition {
editionNumber
tokenId
status
}
}
}
}
  • status — NOT_MINTED → MINTING → ON_PLATFORM. See Edition Lifecycle.
  • tokenId — null until the mint completes and status reaches ON_PLATFORM.
  • editionNumber — Available immediately. This is Verse's internal numbering and may differ from the on-chain tokenId.

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://api.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 baseUrlTemplate and previewImageUrlTemplate 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 baseUrlTemplate directly
const imgSrc = resolveImageUrl(imageAsset.baseUrlTemplate);

// VideoAsset — use previewImageUrlTemplate for thumbnails, baseUrlTemplate for <video src>
const videoThumb = resolveImageUrl(videoAsset.previewImageUrlTemplate);
const videoSrc = videoAsset.baseUrlTemplate; // direct URL, no placeholders

// SVGAsset — use baseUrlTemplate at original size, no format
const svgSrc = svgAsset.baseUrlTemplate
.replace("{{SIZE}}", "source")
.replace("@{{FORMAT}}", "");

// IFrameAsset — use previewImageUrlTemplate for thumbnails, iframeUrl for <iframe src>
const iframeThumb = resolveImageUrl(iframeAsset.previewImageUrlTemplate);
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.