Skip to main content
Skip table of contents

Unified NFT API (Beta)

OnFinality Unified NFT API

OnFinality’s Unified NFT API will provide access to NFTs and their metadata for all popular standards across the Polkadot and Kusama ecosystems and beyond, in a single, simple request.

The OnFinality NFT API will just be the first Unified API offered by OnFinality, with plans to expand to transactions, staking, and more.

The highly flexible GraphQL Unified API includes

  • Collections

  • NFTs

  • Transactions

  • Metadata

We welcome all feedback at support@onfinality.io

Have fun 🥳

Why GraphQL?

The NFT universe is a weird and wonderful place. We couldn’t begin to imagine all possible use cases, so the flexibility of GraphQL gives you complete access without restrictions

Supported Networks/Standards

The Beta Unified NFT API includes the following networks and standards, with plans to expand rapidly

Network

Chain ID

Standard

Status

Acala

787

EVM ERC-721

LIVE

EVM ERC-1155

LIVE

Astar

592

EVM ERC-721

LIVE

EVM ERC-1155

LIVE

Shiden

336

EVM ERC-721

LIVE

EVM ERC-1155

LIVE

Moonbeam

1284

EVM ERC-721

LIVE

EVM ERC-1155

LIVE

Moonriver

1285

EVM ERC-721

LIVE

EVM ERC-1155

LIVE

We’d love to hear from you, contact support@onfinality.io to put in a request for more networks and standards!

Coming Soon

  • WASM PSP34

  • Substrate Uniques

  • Substrate NFTs

  • Substrate ormlNFT

How to Connect

Public Endpoint

GraphQL Endpoint (Beta): https://nft-beta.api.onfinality.io/public

The Beta version of our public endpoint is intended for development, experimentation, and validation purposes. It should not be used in a production environment

A public rate limit is applied, contact support@onfinality.io to receive a higher rate limit

Playground

http://nft-beta.onfinality.io

Schema

The complete schema is available here https://github.com/OnFinality-io/api-nft/blob/main/schema.graphql

GraphQL Schema
CODE
enum ContractType {
  ERC721,
  ERC1155
}

enum StatusType {
  PENDING,
  PROCESSING,
  COMPLETED,
  FAILED,
  UNKNOWN,
  INVALID
}

type AnyJson @jsonField {
  # Need a value for codegen but type is any
  _: String
}

type Nft @entity {
  id: ID! #CollectionID-TokenId
  tokenId: String! @index
  amount: BigInt! #1 for Erc721. 1155 semi-fungible has other values
  collection: Collection!
  minted_block: BigInt! @index# Should be bigInt
  minted_timestamp: BigInt! # unix epoch timestamp
  minter_address: String! @index # event transaction from
  current_owner: String! @index # event args to
  metadata: Metadata
}

type Collection @entity {
  id: ID! # chainID-contract adddress
  network: Network!
  contract_address: String! @index # event address
  created_block: BigInt! @index
  created_timestamp: BigInt! @index# unix epoch timestamp
  creator_address: String! # event transaction from
  total_supply: BigInt!
  name: String
  symbol: String
  contract_type: ContractType! # e.g. ERC721, RMRK Hardcode
  #  floor_price: Int # Later on
}

type Transfer @entity {
  id: ID!
  tokenId: String! @index
  amount: BigInt! # Same as with NFT
  network: Network!
  block: BigInt! @index
  timestamp: BigInt! @index
  transaction_hash: String! @index# event transaction hash
  nft: Nft
  from: String! @index
  to: String! @index
}

type Network @entity {
  id: ID!
}

type Metadata @entity {
  id: ID! # hashed metadata_uri
  metadata_uri: String!
  raw: AnyJson
  metadata_status: StatusType!
  name: String
  symbol: String
  token_uri: String
  image_uri: String
  description: String
}

type Address @entity {
  id: ID! #network account address ?
  network: Network!
  account: Account #optinal for now
}

type Account @entity {
  """Id is a base58 encoded public key"""
  id: ID! # base58 encoded public key (only substrate chains ?)
  addresses: [Address] @derivedFrom(field: "account") # addresses
}

Tips

  1. All addresses and contracts are in lower case. Convert to lower case before querying to avoid performance issues

  2. NFT IDs are in the format [network id]-[contract id]-[nft id]
    E.g.
    ”592-0x1b57c69838cdbc59c8236dda73287a4780b4831f-1001”

Example Queries & Responses

Paste these queries into https://nft-beta.onfinality.io and press play ▶️

Get NFTs for Collection

Request
CODE
{
    nfts(
        first: 20
        filter: {
          collection: {
            contractAddress: {
              equalTo: "0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a"
            }
          }
        }
    ) {
        nodes {
            mintedBlock
            tokenId
            currentOwner
            metadata {
                metadataUri
                metadataStatus
                imageUri
                description
                name
                raw
            }
        }
    }
}
Response
CODE
{
  "data": {
    "collections": {
      "nodes": [
        {
          "nfts": {
            "nodes": [
              {
                "mintedBlock": "442806",
                "tokenId": "1",
                "currentOwner": "0xf5aff98659f5934a4f5ed1e23da81996d140ff40",
                "metadata": {
                  "metadataUri": "ipfs://QmS3VmXBrVFRRdkSSBfgbRB5mzVdnANNdGaZPyo69BMwsR/hidden.json",
                  "metadataStatus": "COMPLETED",
                  "imageUri": "ipfs://QmNMjVu59ouiuMFdpMqJny8SRfoLP118zrVQFKQpYt6g6g/hidden.png",
                  "description": "AstarDegens Collection (revealed when minted out)",
                  "name": "AstarDegens (Hidden)",
                  "raw": {
                    "name": "AstarDegens (Hidden)",
                    "image": "ipfs://QmNMjVu59ouiuMFdpMqJny8SRfoLP118zrVQFKQpYt6g6g/hidden.png",
                    "description": "AstarDegens Collection (revealed when minted out)"
                  }
                }
              },
            ...
            }
        }
      }
    }
  }            

Get NFTs for Wallet Address (All Networks)

Request
CODE
{
    nfts(
      first: 20
      filter: {
          currentOwner: {
              equalTo: "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"
              },
            }
    ) {
        nodes {
            mintedBlock
            tokenId
            currentOwner
            metadata {
                metadataUri
                metadataStatus
                imageUri
                description
                name
                raw
            }
          collection {
            networkId
          }
        }
    }
}
Response
CODE
{
  "data": {
    "nfts": {
      "nodes": [
        {
          "mintedBlock": "1931736",
          "tokenId": "1939",
          "currentOwner": "0xf5aff98659f5934a4f5ed1e23da81996d140ff40",
          "metadata": {
            "metadataUri": "ipfs://bafybeiaxax2xbml3dxdr2ohcrovgiwmpxyd4bykjl37sbn4ujqs7htr26u/1939.json",
            "metadataStatus": "COMPLETED",
            "imageUri": "ipfs://bafybeiezmgo7mthlzygckiugpbytvuhsqs4nxvzhs7rbwslgqbxla2kczi/1939.png",
            "description": "COSMIZE×Astar Degens collabo NFT",
            "name": "Astar Degens Desk 1939",
            "raw": {
              "name": "Astar Degens Desk 1939",
              "image": "ipfs://bafybeiezmgo7mthlzygckiugpbytvuhsqs4nxvzhs7rbwslgqbxla2kczi/1939.png",
              "tokenId": 1939,
              "attributes": [
                {
                  "value": "Gray Gorilla",
                  "trait_type": "Body"
                },
                {
                  "value": "Sherrif Hat",
                  "trait_type": "Hat"
                },
                {
                  "value": "Purple Wedge Shield",
                  "trait_type": "Shield"
                },
                {
                  "value": "Big Blue Sunglass",
                  "trait_type": "Sunglass"
                }
              ],
              "description": "COSMIZE×Astar Degens collabo NFT",
              "external_url": "https://cosmize.io/item/AstarDegens-Desk/1939"
            }
          },
          "collection": {
            "networkId": "592"
          }
        },
      ...
      ]
    }
  }

Get NFTs for Wallet Address (Single Network)

Request
CODE
{
    nfts(
      first: 20
      filter: {
          currentOwner: {
              equalTo: "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"
              }, 
          collection: {networkId: {equalTo: "592"}}}
    ) {
        nodes {
            mintedBlock
            tokenId
            currentOwner
            metadata {
                metadataUri
                metadataStatus
                imageUri
                description
                name
                raw
            }
        }
    }
}
Response
CODE
{
  "data": {
    "nfts": {
      "nodes": [
        {
          "mintedBlock": "1931736",
          "tokenId": "1939",
          "currentOwner": "0xf5aff98659f5934a4f5ed1e23da81996d140ff40",
          "metadata": {
            "metadataUri": "ipfs://bafybeiaxax2xbml3dxdr2ohcrovgiwmpxyd4bykjl37sbn4ujqs7htr26u/1939.json",
            "metadataStatus": "COMPLETED",
            "imageUri": "ipfs://bafybeiezmgo7mthlzygckiugpbytvuhsqs4nxvzhs7rbwslgqbxla2kczi/1939.png",
            "description": "COSMIZE×Astar Degens collabo NFT",
            "name": "Astar Degens Desk 1939",
            "raw": {
              "name": "Astar Degens Desk 1939",
              "image": "ipfs://bafybeiezmgo7mthlzygckiugpbytvuhsqs4nxvzhs7rbwslgqbxla2kczi/1939.png",
              "tokenId": 1939,
              "attributes": [
                {
                  "value": "Gray Gorilla",
                  "trait_type": "Body"
                },
                {
                  "value": "Sherrif Hat",
                  "trait_type": "Hat"
                },
                {
                  "value": "Purple Wedge Shield",
                  "trait_type": "Shield"
                },
                {
                  "value": "Big Blue Sunglass",
                  "trait_type": "Sunglass"
                }
              ],
              "description": "COSMIZE×Astar Degens collabo NFT",
              "external_url": "https://cosmize.io/item/AstarDegens-Desk/1939"
            }
          }
        },
      ...
      ]
    }
  }     

Get Transfers for Wallet Address (All Networks)

Request
CODE
{
    transfers(
      first: 20
      filter: {
        or: [
          {to: {equalTo: "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"}}, 
          {from: {equalTo: "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"}}
        ]
      }) 
      {
        nodes {
            nft {
                collection {
                    contractAddress
                }
                tokenId
            }
            timestamp
          	from
            to
            transactionHash
            network {
              id
            }
        }
    }
}
Response
CODE
{
  "data": {
    "transfers": {
      "nodes": [
        {
          "nft": {
            "collection": {
              "contractAddress": "0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a"
            },
            "tokenId": "1"
          },
          "timestamp": "1645544268",
          "from": "0xc779ceb0853fa7ab6a38c587c1cfc702e4603d9b",
          "to": "0xf5aff98659f5934a4f5ed1e23da81996d140ff40",
          "transactionHash": "0x1b85af43d6584f29475e70ba179a53d274f5abfa15bac38ed395a827cee83435",
          "network": {
            "id": "592"
          }
        },
        ...
      ]
    }
  }
}

Get Transfers for Wallet Address (Single Network)

Request
CODE
{
    transfers(
      first: 20
      filter: {networkId: {equalTo: "592"}, 
      or: [{
      to: {equalTo: "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"}},
       {from: {equalTo: "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"}}]}
    ) {
        nodes {
            nft {
                collection {
                    contractAddress
                }
                tokenId
            }
            timestamp
          	from
            to
            transactionHash
        }
    }
}
Response
CODE
{
  "data": {
    "transfers": {
      "nodes": [
        {
          "nft": {
            "collection": {
              "contractAddress": "0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a"
            },
            "tokenId": "1"
          },
          "timestamp": "1645544268",
          "from": "0xc779ceb0853fa7ab6a38c587c1cfc702e4603d9b",
          "to": "0xf5aff98659f5934a4f5ed1e23da81996d140ff40",
          "transactionHash": "0x1b85af43d6584f29475e70ba179a53d274f5abfa15bac38ed395a827cee83435"
        },
        ...
      ]
    }
  }  
}   

Count NFTs in Collection

Request
CODE
{
  nfts(filter: {collection: {contractAddress: {equalTo: "0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a"}}}) {
    totalCount
  }
}
Response
CODE
{
  "data": {
    "nfts": {
      "totalCount": 10000
    }
  }
}

Count Transfers for Collection

Request
CODE
{
    transfers(
        filter: {nft: {collection: {contractAddress: {equalTo: "0xd3e93ff701fee4402e91b63bbdb06aad125cbd4c"}}}}
    ) {
        totalCount
    }
}
Response
CODE
{
  "data": {
    "transfers": {
      "totalCount": 2142
    }
  }
}

Count Transfers for NFT

Request
CODE
{
  transfers(filter: {
    nftId: {equalTo: "592-0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a-1"}
  }) {
    totalCount
  }
}
Response
CODE
{
  "data": {
    "transfers": {
      "totalCount": 2
    }
  }
}

Get Current Owners for Collection

Request
CODE
{
  collections(
    first: 20
    filter: {contractAddress: {equalTo: "0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a"}}) {
    nodes {
      nfts {
        nodes {
          id
          currentOwner
        }
      }
    }
  }
}
Response
CODE
{
  "data": {
    "collections": {
      "nodes": [
        {
          "nfts": {
            "nodes": [
              {
                "id": "592-0xd59fc6bfd9732ab19b03664a45dc29b8421bda9a-1",
                "currentOwner": "0xf5aff98659f5934a4f5ed1e23da81996d140ff40"
              },
            ...
            ]
          }
        }
      ]
    }
  }
}

Best Practices

For optimal performance and responsible use of our shared resources, we recommend:

❌ Avoid using the equalToInsensitive filter, which has poor performance.

✅ Convert addresses to lower case and use the equalTo filter

✅ Use pagination, e.g. first: 10

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.