Skip to main content

Working With API Responses

Structure of the Response

This is an example response you might get when executing the Get NFT Token Details example query from the Playgrounds guide.

{
"data": {
"token": {
"name": "Singular Focus",
"description": "The Partition is formed End Chapter 1 These former husks / Vessels adorned with ancestry / Carry the code / Of shared memory // Though flayed and quartered / The bone is porous / Fertile grounds / Ripe for the return // New flesh grows / Once we learn how to die / Souls for the bankless / The tree decides // Power sown in urns and ashes / Eternity learned / in collective demise.",
"image": {
"thumbnails": [
{
"url": "/nftindexer/thumbnail/1/42141102/medium"
}
]
},
"contract": {
"id": "0xc9041f80dce73721a5f6a779672ec57ef255d27c",
"isERC721": true,
"isERC1155": false
}
}
}
}

Response Structure

Here's the general response structure for the Get NFT Token Details query.

{
"data": {
"token": {
"name": "String",
"description": "String",
"image": {
"thumbnails": [
{
"url": "String"
}
]
},
"contract": {
"id": "String",
"isERC721": Boolean,
"isERC1155": Boolean
}
}
}
}

Response Object Definitions

  • data: The root object containing the response data.
  • token: The object representing the token details.
    • name: The name of the token.
    • description: A description of the token.
    • image: An object containing media details.
      • thumbnails: A list of thumbnail objects.
        • url: The URL of the thumbnail image.
    • contract: An object representing the contract details.
      • id: The contract address.
      • isERC721: Whether the contract is ERC-721 compliant.
      • isERC1155: Whether the contract is ERC-1155 compliant.

Accessing the Data

The response structure is static and its response fields can be accessed in a consistent manner.

Below are some examples of how the response fields may be accessed in a project.

JavaScript

if (response.data && response.data.token) {
const tokenName = response.data.token.name;
const tokenDescription = response.data.token.description;
const thumbnailUrl = response.data.token.image.thumbnails[0].url;
const contractId = response.data.token.contract.id;
const isERC721 = response.data.token.contract.isERC721;
const isERC1155 = response.data.token.contract.isERC1155;

console.log("Token Name: " + tokenName);
console.log("Description: " + tokenDescription);
console.log("Thumbnail URL: " + thumbnailUrl);
console.log("Contract ID: " + contractId);
console.log("Is ERC-721: " + isERC721);
console.log("Is ERC-1155: " + isERC1155);

// Example: Determine token type
if (isERC721) {
console.log("This is an ERC-721 token.");
} else if (isERC1155) {
console.log("This is an ERC-1155 token.");
} else {
console.log("This token does not match ERC-721 or ERC-1155 standards.");
}
} else {
console.error("Invalid response structure");
}

Python

if "data" in response and "token" in response["data"]:
token_name = response["data"]["token"]["name"]
token_description = response["data"]["token"]["description"]
thumbnail_url = response["data"]["token"]["image"]["thumbnails"][0]["url"]
contract_id = response["data"]["token"]["contract"]["id"]
is_erc721 = response["data"]["token"]["contract"]["isERC721"]
is_erc1155 = response["data"]["token"]["contract"]["isERC1155"]

print("Token Name: " + token_name)
print("Description: " + token_description)
print("Thumbnail URL: " + thumbnail_url)
print("Contract ID: " + contract_id)
print("Is ERC-721: " + str(is_erc721))
print("Is ERC-1155: " + str(is_erc1155))

# Example: Determine token type
if is_erc721:
print("This is an ERC-721 token.")
elif is_erc1155:
print("This is an ERC-1155 token.")
else:
print("This token does not match ERC-721 or ERC-1155 standards.")
else:
print("Invalid response structure")

Pagination

When querying lists of objects (e.g. multiple tokens), you should page through results to avoid returning huge payloads in a single response. OneSource GraphQL supports simple offset‑based pagination using two arguments:

ArgumentDescription
firstMaximum number of items to return.
skipNumber of items to skip before returning results.

Example GraphQL Query

query Tokens($first: Int!, $skip: Int!) {
tokens(first: $first, skip: $skip) {
id
contract { id }
image { thumbnails { url } }
}
}

JavaScript

const PAGE_SIZE = 50;
let skip = 0;
let allTokens = [];

while (true) {
const response = await fetch(endpoint, {
method: "POST",
headers: { "x-bp-token": apiKey, "Content-Type": "application/json" },
body: JSON.stringify({ query, variables: { first: PAGE_SIZE, skip } }),
}).then((r) => r.json());

const tokens = response.data?.tokens || [];
allTokens.push(...tokens);
if (tokens.length < PAGE_SIZE) break;
skip += PAGE_SIZE;
}
console.log("Total tokens fetched:", allTokens.length);

Python

PAGE_SIZE = 50
skip = 0
all_tokens = []

while True:
payload = {"query": query, "variables": {"first": PAGE_SIZE, "skip": skip}}
resp = requests.post(url, json=payload, headers=headers).json()
tokens = resp.get("data", {}).get("tokens", [])
all_tokens.extend(tokens)
if len(tokens) < PAGE_SIZE:
break
skip += PAGE_SIZE

print("Total tokens fetched:", len(all_tokens))

Best Practices

  • Choose a sensible first value (50–100) to balance response size vs. number of requests.
  • Always check for an empty or smaller-than‑page response to know when you've reached the end.

Handling Errors

Since the response is dynamic, developers should always check for errors and validate the structure of the response before accessing data.

JavaScript

if (response.errors) {
console.error("Error: " + response.errors[0].message);
} else if (response.data && response.data.token) {
const isERC721 = response.data.token.contract.isERC721;
const isERC1155 = response.data.token.contract.isERC1155;

if (isERC721) {
console.log("This is an ERC-721 token.");
} else if (isERC1155) {
console.log("This is an ERC-1155 token.");
} else {
console.log("This token does not match ERC-721 or ERC-1155 standards.");
}
} else {
console.error("Invalid response structure");
}

Python

if "errors" in response:
print("Error: " + response["errors"][0]["message"])
elif "data" in response and "token" in response["data"]:
is_erc721 = response["data"]["token"]["contract"]["isERC721"]
is_erc1155 = response["data"]["token"]["contract"]["isERC1155"]

if is_erc721:
print("This is an ERC-721 token.")
elif is_erc1155:
print("This is an ERC-1155 token.")
else:
print("This token does not match ERC-721 or ERC-1155 standards.")
else:
print("Invalid response structure")

Common Use Cases

Displaying Token Information

JavaScript

function displayTokenInfo(response) {
if (response.data && response.data.token) {
const tokenName = response.data.token.name;
const tokenDescription = response.data.token.description;
const thumbnailUrl = response.data.token.image.thumbnails[0].url;
const isERC721 = response.data.token.contract.isERC721;
const isERC1155 = response.data.token.contract.isERC1155;

document.getElementById("token-name").innerText = tokenName;
document.getElementById("token-description").innerText = tokenDescription;
document.getElementById("token-image").src = thumbnailUrl;

if (isERC721) {
document.getElementById("token-type").innerText = "ERC-721";
} else if (isERC1155) {
document.getElementById("token-type").innerText = "ERC-1155";
} else {
document.getElementById("token-type").innerText = "Unknown Token Type";
}
} else {
console.error("Invalid response structure");
}
}

Filtering Tokens by Contract Type

Python

def filter_tokens(response):
if "data" in response and "tokens" in response["data"]:
tokens = response["data"]["tokens"]
erc721_tokens = [token for token in tokens if token["contract"]["isERC721"]]
erc1155_tokens = [token for token in tokens if token["contract"]["isERC1155"]]

print("ERC-721 Tokens: " + str(erc721_tokens))
print("ERC-1155 Tokens: " + str(erc1155_tokens))
else:
print("Invalid response structure")

Best Practices

  • Validate the Response Structure: Always check if the expected fields (including isERC721 and isERC1155) exist before accessing them.
  • Handle Missing Fields Gracefully: Use optional chaining (JavaScript) or .get() (Python) to avoid runtime errors.
  • Cache Responses: Cache frequently accessed data to reduce API calls and improve performance.
  • Use TypeScript or Type Annotations: If possible, use TypeScript (JavaScript) or type annotations (Python) to ensure type safety when working with the response.