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.
- thumbnails: A list of thumbnail objects.
- 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:
Argument | Description |
---|---|
first | Maximum number of items to return. |
skip | Number 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
andisERC1155
) 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.