Docs
Search⌘ K
  • Home
  • About The Graph
  • Supported Networks
  • Protocol Contracts
  • Subgraphs
    • Substreams
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Subgraphs > Querying

              6 minutes

              GraphQL API

              Explore the GraphQL Query API for interacting with Subgraphs on The Graph Network.

              GraphQL⁠ is a query language for APIs and a runtime for executing those queries with existing data.

              The Graph uses GraphQL to query Subgraphs.

              Core Concepts

              Entities

              • What they are: Persistent data objects defined with @entity in your schema
              • Key requirement: Must contain id: ID! as primary identifier
              • Usage: Foundation for all query operations

              Schema

              • Purpose: Blueprint defining the data structure and relationships using GraphQL IDL⁠
              • Key characteristics:
                • Auto-generates query endpoints
                • Read-only operations (no mutations)
                • Defines entity interfaces and derived fields

              Query Structure

              GraphQL queries in The Graph target entities defined in the Subgraph schema. Each Entity type generates corresponding entity and entities fields on the root Query type.

              Note: The query keyword is not required at the top level of GraphQL queries.

              Single Entity Queries Example

              Query for a single Token entity:

              1{2  token(id: "1") {3    id4    owner5  }6}

              Note: Single entity queries require the id parameter as a string.

              Collection Queries Example

              Query format for all Token entities:

              1{2  tokens {3    id4    owner5  }6}

              Sorting Example

              Collection queries support the following sort parameters:

              • orderBy: Specifies the attribute for sorting
              • orderDirection: Accepts asc (ascending) or desc (descending)

              Standard Sorting Example

              1{2  tokens(orderBy: price, orderDirection: asc) {3    id4    owner5  }6}

              Nested Entity Sorting Example

              1{2  tokens(orderBy: owner__name, orderDirection: asc) {3    id4    owner {5      name6    }7  }8}

              Note: Nested sorting supports one-level-deep String or ID types on @entity and @derivedFrom fields.

              Pagination Example

              When querying a collection, it is best to:

              • Use the first parameter to paginate from the beginning of the collection.
                • The default sort order is by ID in ascending alphanumeric order, not by creation time.
              • Use the skip parameter to skip entities and paginate. For instance, first:100 shows the first 100 entities and first:100, skip:100 shows the next 100 entities.
              • Avoid using skip values in queries because they generally perform poorly. To retrieve a large number of items, it’s best to page through entities based on an attribute as shown in the previous example above.

              Standard Pagination Example

              1{2  tokens(first: 10) {3    id4    owner5  }6}

              Offset Pagination Example

              1{2  tokens(first: 10, skip: 10) {3    id4    owner5  }6}

              Cursor-based Pagination Example

              1query manyTokens($lastID: String) {2  tokens(first: 1000, where: { id_gt: $lastID }) {3    id4    owner5  }6}

              Filtering

              The where parameter filters entities based on specified conditions.

              Basic Filtering Example

              1{2  challenges(where: { outcome: "failed" }) {3    challenger4    outcome5    application {6      id7    }8  }9}

              Numeric Comparison Example

              1{2  applications(where: { deposit_gt: "10000000000" }) {3    id4    whitelisted5    deposit6  }7}

              Block-based Filtering Example

              1{2  applications(where: { _change_block: { number_gte: 100 } }) {3    id4    whitelisted5    deposit6  }7}

              Nested Entity Filtering Example

              1{2  challenges(where: { application_: { id: 1 } }) {3    challenger4    outcome5    application {6      id7    }8  }9}

              Logical Operators

              AND Operations Example

              The following example filters for challenges with outcome succeeded and number greater than or equal to 100.

              1{2  challenges(where: { and: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {3    challenger4    outcome5    application {6      id7    }8  }9}

              Syntactic sugar: You can simplify the above query by removing the and operator and by passing a sub-expression separated by commas.

              1{2  challenges(where: { number_gte: 100, outcome: "succeeded" }) {3    challenger4    outcome5    application {6      id7    }8  }9}
              OR Operations Example
              1{2  challenges(where: { or: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {3    challenger4    outcome5    application {6      id7    }8  }9}

              Global filter parameter:

              1_change_block(number_gte: Int)

              Time-travel Queries Example

              Queries support historical state retrieval using the block parameter:

              • number: Integer block number
              • hash: String block hash

              Note: The current implementation is still subject to certain limitations that might violate these guarantees. The implementation can not always tell that a given block hash is not on the main chain at all, or if a query result by a block hash for a block that is not yet considered final could be influenced by a block reorganization running concurrently with the query. They do not affect the results of queries by block hash when the block is final and known to be on the main chain. This issue⁠ explains what these limitations are in detail.

              Block Number Query Example

              1{2  challenges(block: { number: 8000000 }) {3    challenger4    outcome5    application {6      id7    }8  }9}

              Block Hash Query Example

              1{2  challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {3    challenger4    outcome5    application {6      id7    }8  }9}

              Full-Text Search Example

              Full-text search query fields provide an expressive text search API that can be added to the Subgraph schema and customized. Refer to Defining Full-text Search Fields to add full-text search to your Subgraph.

              Full-text search queries have one required field, text, for supplying search terms. Several special full-text operators are available to be used in this text search field.

              Full-text search fields use the required text parameter with the following operators:

              OperatorSymbolDescription
              And&Matches entities containing all terms
              Or|Return all entities with a match from any of the provided terms
              Follow by<->Matches terms with specified distance
              Prefix:*Matches word prefixes (minimum 2 characters)

              Search Examples

              OR operator:

              1{2  blogSearch(text: "anarchism | crumpets") {3    id4    title5    body6    author7  }8}

              “Follow” by operator:

              1{2  blogSearch(text: "decentralized <-> philosophy") {3    id4    title5    body6    author7  }8}

              Combined operators:

              1{2  blogSearch(text: "lou:* <-> music") {3    id4    title5    body6    author7  }8}

              Schema Definition

              Entity types require:

              • GraphQL Interface Definition Language (IDL) format
              • @entity directive
              • ID field

              Subgraph Metadata Example

              The _Meta_ object provides subgraph metadata:

              1{2  _meta(block: { number: 123987 }) {3    block {4      number5      hash6      timestamp7    }8    deployment9    hasIndexingErrors10  }11}

              Metadata fields:

              • deployment: IPFS CID of the subgraph.yaml
              • block: Latest block information
              • hasIndexingErrors: Boolean indicating past indexing errors

              Note: When writing queries, it is important to consider the performance impact of using the or operator. While or can be a useful tool for broadening search results, it can also have significant costs. One of the main issues with or is that it can cause queries to slow down. This is because or requires the database to scan through multiple indexes, which can be a time-consuming process. To avoid these issues, it is recommended that developers use and operators instead of or whenever possible. This allows for more precise filtering and can lead to faster, more accurate queries.

              GraphQL Filter Operators Reference

              This table explains each filter operator available in The Graph’s GraphQL API. These operators are used as suffixes to field names when filtering data using the where parameter.

              OperatorDescriptionExample
              _Matches entities where the specified field equals another entity{ where: { owner_: { name: "Alice" } } }
              _notNegates the specified condition{ where: { active_not: true } }
              _gtGreater than (>){ where: { price_gt: "100" } }
              _ltLess than (\<){ where: { price_lt: "100" } }
              _gteGreater than or equal to (>=){ where: { price_gte: "100" } }
              _lteLess than or equal to (\<=){ where: { price_lte: "100" } }
              _inValue is in the specified array{ where: { category_in: ["Art", "Music"] } }
              _not_inValue is not in the specified array{ where: { category_not_in: ["Art", "Music"] } }
              _containsField contains the specified string (case-sensitive){ where: { name_contains: "token" } }
              _contains_nocaseField contains the specified string (case-insensitive){ where: { name_contains_nocase: "token" } }
              _not_containsField does not contain the specified string (case-sensitive){ where: { name_not_contains: "test" } }
              _not_contains_nocaseField does not contain the specified string (case-insensitive){ where: { name_not_contains_nocase: "test" } }
              _starts_withField starts with the specified string (case-sensitive){ where: { name_starts_with: "Crypto" } }
              _starts_with_nocaseField starts with the specified string (case-insensitive){ where: { name_starts_with_nocase: "crypto" } }
              _ends_withField ends with the specified string (case-sensitive){ where: { name_ends_with: "Token" } }
              _ends_with_nocaseField ends with the specified string (case-insensitive){ where: { name_ends_with_nocase: "token" } }
              _not_starts_withField does not start with the specified string (case-sensitive){ where: { name_not_starts_with: "Test" } }
              _not_starts_with_nocaseField does not start with the specified string (case-insensitive){ where: { name_not_starts_with_nocase: "test" } }
              _not_ends_withField does not end with the specified string (case-sensitive){ where: { name_not_ends_with: "Test" } }
              _not_ends_with_nocaseField does not end with the specified string (case-insensitive){ where: { name_not_ends_with_nocase: "test" } }

              Notes

              • Type support varies by operator. For example, Boolean only supports _not, _in, and _not_in.
              • The _ operator is only available for object and interface types.
              • String comparison operators are especially useful for text fields.
              • Numeric comparison operators work with both number and string-encoded number fields.
              • Use these operators in combination with logical operators (and, or) for complex filtering.

              Validation

              Graph Node implements specification-based⁠ validation of the GraphQL queries it receives using graphql-tools-rs⁠, which is based on the graphql-js reference implementation⁠. Queries which fail a validation rule do so with a standard error - visit the GraphQL spec⁠ to learn more.

              ⁠Edit on GitHub⁠

              Distributed SystemsSubgraph ID vs Deployment ID
              On this page
              • Core Concepts
              • Entities
              • Schema
              • Query Structure
              • Single Entity Queries Example
              • Collection Queries Example
              • Sorting Example
              • Pagination Example
              • Filtering
              • Time-travel Queries Example
              • Full-Text Search Example
              • Schema Definition
              • Subgraph Metadata Example
              • GraphQL Filter Operators Reference
              • Validation
              The GraphStatusTestnetBrand AssetsForumSecurityPrivacy PolicyTerms of Service