# API integration

Source: https://docs.graphops.xyz/subgraphs/api

Use this reference to build Subgraph requests and interpret their responses. GraphOps Subgraphs
exposes standard GraphQL query endpoints over HTTPS. Each endpoint is selected by
Deployment CID, Graph Network Subgraph ID, or GraphOps Endpoint Alias, and
authenticated with an API key that includes Subgraphs.

## Endpoint patterns

Header-authenticated endpoints:

```text
https://subgraphs.graphops.xyz/v1/deploymentCID/<DEPLOYMENT_CID>
https://subgraphs.graphops.xyz/v1/subgraphId/<SUBGRAPH_ID>
https://subgraphs.graphops.xyz/v1/alias/<ALIAS>

```

_A Subgraphs endpoint names what to query in its path: the identifier type, then the identifier. This example uses an Endpoint Alias; deploymentCID and subgraphId work the same way. Send the API key in the Authorization header or append it to the path._

```text
https://subgraphs.graphops.xyz/v1/alias/<ALIAS>
Authorization: Bearer <GRAPHOPS_API_KEY>
```

- Subgraphs host: `https://subgraphs.graphops.xyz`
- Identifier type: `alias`
- Identifier: `<ALIAS>`

Route-token endpoints:

```text
https://subgraphs.graphops.xyz/v1/deploymentCID/<DEPLOYMENT_CID>/<GRAPHOPS_API_KEY>
https://subgraphs.graphops.xyz/v1/subgraphId/<SUBGRAPH_ID>/<GRAPHOPS_API_KEY>
https://subgraphs.graphops.xyz/v1/alias/<ALIAS>/<GRAPHOPS_API_KEY>

```

Endpoint preview. Replace placeholders with your identifier and API key before making requests.

```text
https://subgraphs.graphops.xyz/v1/deploymentCID/<DEPLOYMENT_CID>
Authorization: Bearer <GRAPHOPS_API_KEY>
```

[Get query endpoint](https://platform.graphops.xyz/organizations/current/overview/endpoint?product=subgraphs)
[Supported networks](/subgraphs/networks)

See [Authentication](./authentication) to choose how to send your API key and protect it in logs.

## Request envelope

Subgraph queries use the standard GraphQL HTTP request shape:

| Field           | Type   | Required | Notes                                                                         |
| --------------- | ------ | -------- | ----------------------------------------------------------------------------- |
| `query`         | string | Yes      | GraphQL query or mutation text. Query support depends on the Subgraph schema. |
| `variables`     | object | No       | Variables referenced by the query.                                            |
| `operationName` | string | No       | Required only when the document contains multiple named operations.           |

```json
{
  "query": "query Pools($first: Int!) { pools(first: $first) { id } }",
  "variables": {
    "first": 5
  },
  "operationName": "Pools"
}

```

Output

```json
{
  "data": {
    "pools": [
      {
        "id": "0x000024feb293b6c6c3a80a95f1f830a8746400b9"
      },
      {
        "id": "0x0000d36ab86d213c14d93cd5ae78615a20596505"
      },
      {
        "id": "0x00013bffe4c38c1372a450fac78b01cb4f554781"
      },
      {
        "id": "0x0001fcbba8eb491c3ccfeddc5a5caba1a98c4c28"
      },
      {
        "id": "0x00024b66a38a676c0eae59126c1367ad141afa79"
      }
    ]
  }
}
```

Present when the query ran

No matching entities, not an error

## Request

These clients send the request envelope above through an Endpoint Alias.

CLI · curl

Prerequisites

1. Set GRAPHOPS\_API\_KEY to your GraphOps API key.

2. Replace `<ALIAS>` with your Endpoint Alias.

[Example project](/examples/subgraphs.api.sh-4.tar.gz)

```sh
curl --fail-with-body --silent --show-error "https://subgraphs.graphops.xyz/v1/alias/<ALIAS>" \
  -H "Authorization: Bearer ${GRAPHOPS_API_KEY}" \
  -H "Content-Type: application/json" \
  --data '{
    "query": "query Pools($first: Int!) { pools(first: $first) { id token0 { symbol } token1 { symbol } } _meta { block { number hash } } }",
    "variables": { "first": 5 },
    "operationName": "Pools"
  }'

```

Output

```json
{
  "data": {
    "pools": [
      {
        "id": "0x000024feb293b6c6c3a80a95f1f830a8746400b9",
        "token0": {
          "symbol": "TRUMP"
        },
        "token1": {
          "symbol": "WETH"
        }
      },
      {
        "id": "0x0000d36ab86d213c14d93cd5ae78615a20596505",
        "token0": {
          "symbol": "RALPH"
        },
        "token1": {
          "symbol": "WETH"
        }
      },
      {
        "id": "0x00013bffe4c38c1372a450fac78b01cb4f554781",
        "token0": {
          "symbol": "Pectra"
        },
        "token1": {
          "symbol": "WETH"
        }
      },
      {
        "id": "0x0001fcbba8eb491c3ccfeddc5a5caba1a98c4c28",
        "token0": {
          "symbol": "BCZ"
        },
        "token1": {
          "symbol": "WETH"
        }
      },
      {
        "id": "0x00024b66a38a676c0eae59126c1367ad141afa79",
        "token0": {
          "symbol": "WETH"
        },
        "token1": {
          "symbol": "TI"
        }
      }
    ],
    "_meta": {
      "block": {
        "number": 26285619,
        "hash": "0x09fffa722f278b60998290f6534850d5b2248e083ada05d332aa684f24f8302e"
      }
    }
  }
}
```

Present when the query ran

No matching entities, not an error

Indexed block behind the result

TypeScript · fetch

Prerequisites

1. Install Node.js.

2. Install tsx. `npm install tsx`

3. Set GRAPHOPS\_API\_KEY to your GraphOps API key.

4. Replace `<ALIAS>` with your Endpoint Alias.

Tested with Node.js 24.22.1, tsx 4.23.15.

[Example project](/examples/subgraphs.api.ts-5.tar.gz)

```typescript
export {};

const response = await fetch(
  "https://subgraphs.graphops.xyz/v1/alias/<ALIAS>",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GRAPHOPS_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: `
        query Pools($first: Int!) {
          pools(first: $first) {
            id
            token0 { symbol }
            token1 { symbol }
          }
          _meta { block { number hash } }
        }
      `,
      variables: { first: 5 },
      operationName: "Pools",
    }),
  },
);
if (!response.ok) throw new Error(await response.text());

const result = await response.json();
console.log(JSON.stringify(result.data.pools));

```

Output

```json
[
  {
    "id": "0x000024feb293b6c6c3a80a95f1f830a8746400b9",
    "token0": {
      "symbol": "TRUMP"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0000d36ab86d213c14d93cd5ae78615a20596505",
    "token0": {
      "symbol": "RALPH"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00013bffe4c38c1372a450fac78b01cb4f554781",
    "token0": {
      "symbol": "Pectra"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0001fcbba8eb491c3ccfeddc5a5caba1a98c4c28",
    "token0": {
      "symbol": "BCZ"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00024b66a38a676c0eae59126c1367ad141afa79",
    "token0": {
      "symbol": "WETH"
    },
    "token1": {
      "symbol": "TI"
    }
  }
]
```

No matching entities, not an error

Go · net/http

Prerequisites

1. Install Go.

2. Set GRAPHOPS\_API\_KEY to your GraphOps API key.

3. Replace `<ALIAS>` with your Endpoint Alias.

Tested with Go 1.26.0.

[Example project](/examples/subgraphs.api.go-8.tar.gz)

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"time"
)

func main() {
	payload, err := json.Marshal(struct {
		Query         string         `json:"query"`
		Variables     map[string]any `json:"variables"`
		OperationName string         `json:"operationName"`
	}{
		Query: `
        query Pools($first: Int!) {
          pools(first: $first) {
            id
            token0 { symbol }
            token1 { symbol }
          }
          _meta { block { number hash } }
        }
        `,
		Variables:     map[string]any{"first": 5},
		OperationName: "Pools",
	})
	if err != nil {
		log.Fatal(err)
	}

	req, err := http.NewRequest(http.MethodPost,
		"https://subgraphs.graphops.xyz/v1/alias/<ALIAS>", bytes.NewReader(payload))
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("GRAPHOPS_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := (&http.Client{Timeout: 30 * time.Second}).Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		log.Fatalf("HTTP %d: %s", resp.StatusCode, body)
	}

	var result struct {
		Data struct {
			Pools json.RawMessage `json:"pools"`
		} `json:"data"`
	}
	if err := json.Unmarshal(body, &result); err != nil {
		log.Fatal(err)
	}
	var pools bytes.Buffer
	if err := json.Compact(&pools, result.Data.Pools); err != nil {
		log.Fatal(err)
	}
	fmt.Println(pools.String())
}

```

Output

```json
[
  {
    "id": "0x000024feb293b6c6c3a80a95f1f830a8746400b9",
    "token0": {
      "symbol": "TRUMP"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0000d36ab86d213c14d93cd5ae78615a20596505",
    "token0": {
      "symbol": "RALPH"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00013bffe4c38c1372a450fac78b01cb4f554781",
    "token0": {
      "symbol": "Pectra"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0001fcbba8eb491c3ccfeddc5a5caba1a98c4c28",
    "token0": {
      "symbol": "BCZ"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00024b66a38a676c0eae59126c1367ad141afa79",
    "token0": {
      "symbol": "WETH"
    },
    "token1": {
      "symbol": "TI"
    }
  }
]
```

No matching entities, not an error

Rust · reqwest

Prerequisites

1. Install Rust.

2. Install reqwest, serde\_json, and tokio. `cargo add reqwest serde_json tokio -F reqwest/json -F tokio/macros -F tokio/rt-multi-thread`

3. Set GRAPHOPS\_API\_KEY to your GraphOps API key.

4. Replace `<ALIAS>` with your Endpoint Alias.

Tested with Rust 1.98.1, reqwest 0.13.5, serde\_json 1.0.145, tokio 1.48.0.

[Example project](/examples/subgraphs.api.rust-9.tar.gz)

```rust
use serde_json::{json, Value};
use std::{env, error::Error, time::Duration};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let response = reqwest::Client::new()
        .post("https://subgraphs.graphops.xyz/v1/alias/<ALIAS>")
        .bearer_auth(env::var("GRAPHOPS_API_KEY")?)
        .timeout(Duration::from_secs(30))
        .json(&json!({
            "query": r#"
        query Pools($first: Int!) {
          pools(first: $first) {
            id
            token0 { symbol }
            token1 { symbol }
          }
          _meta { block { number hash } }
        }
        "#,
            "variables": { "first": 5 },
            "operationName": "Pools",
        }))
        .send()
        .await?
        .error_for_status()?;
    let result: Value = response.json().await?;
    println!("{}", result["data"]["pools"]);
    Ok(())
}

```

Output

```json
[
  {
    "id": "0x000024feb293b6c6c3a80a95f1f830a8746400b9",
    "token0": {
      "symbol": "TRUMP"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0000d36ab86d213c14d93cd5ae78615a20596505",
    "token0": {
      "symbol": "RALPH"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00013bffe4c38c1372a450fac78b01cb4f554781",
    "token0": {
      "symbol": "Pectra"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0001fcbba8eb491c3ccfeddc5a5caba1a98c4c28",
    "token0": {
      "symbol": "BCZ"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00024b66a38a676c0eae59126c1367ad141afa79",
    "token0": {
      "symbol": "WETH"
    },
    "token1": {
      "symbol": "TI"
    }
  }
]
```

No matching entities, not an error

Python · requests

Prerequisites

1. Install Python.

2. Install requests. `python -m pip install requests`

3. Set GRAPHOPS\_API\_KEY to your GraphOps API key.

4. Replace `<ALIAS>` with your Endpoint Alias.

Tested with Python 3.12.12, requests 2.34.2.

[Example project](/examples/subgraphs.api.python-7.tar.gz)

```python
import json
import os

import requests

response = requests.post(
    "https://subgraphs.graphops.xyz/v1/alias/<ALIAS>",
    headers={
        "Authorization": f"Bearer {os.environ['GRAPHOPS_API_KEY']}",
    },
    json={
        "query": """
        query Pools($first: Int!) {
          pools(first: $first) {
            id
            token0 { symbol }
            token1 { symbol }
          }
          _meta { block { number hash } }
        }
        """,
        "variables": {"first": 5},
        "operationName": "Pools",
    },
    timeout=30,
)
response.raise_for_status()
print(json.dumps(response.json()["data"]["pools"]))

```

Output

```json
[
  {
    "id": "0x000024feb293b6c6c3a80a95f1f830a8746400b9",
    "token0": {
      "symbol": "TRUMP"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0000d36ab86d213c14d93cd5ae78615a20596505",
    "token0": {
      "symbol": "RALPH"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00013bffe4c38c1372a450fac78b01cb4f554781",
    "token0": {
      "symbol": "Pectra"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x0001fcbba8eb491c3ccfeddc5a5caba1a98c4c28",
    "token0": {
      "symbol": "BCZ"
    },
    "token1": {
      "symbol": "WETH"
    }
  },
  {
    "id": "0x00024b66a38a676c0eae59126c1367ad141afa79",
    "token0": {
      "symbol": "WETH"
    },
    "token1": {
      "symbol": "TI"
    }
  }
]
```

No matching entities, not an error

## Response

Successful GraphQL responses include `data`. An empty list is a valid result when no entities match:

```json
{
  "query": "query EmptyPools { pools(first: 10, where: { id_gt: \"0xffffffffffffffffffffffffffffffffffffffff\" }, orderBy: id) { id } _meta { block { number } } }"
}

```

Output

```json
{
  "data": {
    "pools": [],
    "_meta": {
      "block": {
        "number": 26285631
      }
    }
  }
}
```

A successful query with no matching pools

Historical block served: 26,285,631

Responses can include `errors` even when the HTTP request succeeds. Check for `errors` on every
response:

```json
{
  "query": "query InvalidField { notARealField }"
}

```

Output

```json
{
  "errors": [
    {
      "message": "Cannot query field \"notARealField\" on type \"Query\".",
      "locations": [
        {
          "line": 1,
          "column": 22
        }
      ]
    }
  ]
}
```

Can arrive with HTTP 200

Fix the query; retrying will not help

## Response headers

| Header             | Value                                                                                                    | Present when                                                                                                                             |
| ------------------ | -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Deployment-CID` | The Deployment CID that served the request, for example `QmRYcnVddpADmnZz812rc1WDE3n2TRsuP5PcGsMxZjaZMM` | Every response returned by a deployment, on all three endpoint patterns, including responses with GraphQL `errors` or a non-`2xx` status |

`X-Deployment-CID` tells you which deployment answered without changing your query. It matches
`_meta.deployment` for the same request. An Endpoint Alias or Graph Network Subgraph ID can serve a
different deployment over time: for example, after a promotion, while a new version is still being
indexed, or when an Endpoint Alias falls back to a previous version. Record the header with each
response when you need to know which version produced a result.

* The header is absent when GraphOps rejects the request before it reaches a deployment, such as
an invalid API key or an unknown Endpoint Alias.
* For a Deployment CID endpoint, the value is the CID in the endpoint path.
* Browser clients can read the header: responses list it in `Access-Control-Expose-Headers`.
* Header names are case-insensitive; some HTTP clients report it as `x-deployment-cid`.

## Error responses

GraphOps error responses carry a `code`; look it up in the
[gateway errors](/platform/errors/gateway) or [API key errors](/platform/errors/api-keys) reference.

| Code or status   | Meaning                                                                                                                                                                                                           | Typical response                                                                                                                                                                   |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`            | Invalid HTTP request, invalid JSON, or malformed GraphQL document.                                                                                                                                                | Fix request encoding or query syntax.                                                                                                                                              |
| `401`            | Missing or invalid API key.                                                                                                                                                                                       | Check [Authentication](./authentication).                                                                                                                                          |
| `403`            | The key is valid, but its limits do not include the Subgraph you called, the organization has no credits left, the key does not cover the route, or GraphOps support paused the organization or disabled the key. | Check the response `code`: allow the Subgraph in the key's limits, top up credits, check the endpoint, or contact support. See [Troubleshooting](./troubleshooting#403-forbidden). |
| `404`            | Deployment CID, Graph Network Subgraph ID, or Endpoint Alias was not found.                                                                                                                                       | Confirm the identifier in the platform UI.                                                                                                                                         |
| `413`            | The request body is too large.                                                                                                                                                                                    | Send a smaller query or fewer variables.                                                                                                                                           |
| `429`            | Organization exceeded query rate limits.                                                                                                                                                                          | Back off and reduce request rate.                                                                                                                                                  |
| `502`            | The indexing service returned an invalid or oversized response, or the request to it failed.                                                                                                                      | Retry; for large results, reduce the query selection or page size.                                                                                                                 |
| `503`            | The service is temporarily unavailable.                                                                                                                                                                           | Retry with backoff.                                                                                                                                                                |
| `504`            | The indexing service did not respond in time.                                                                                                                                                                     | Retry, or reduce the query's work.                                                                                                                                                 |
| GraphQL `errors` | Schema, validation, resolver, or indexing issue.                                                                                                                                                                  | Inspect the error message and `_meta`.                                                                                                                                             |

## Next steps

* [Authentication](./authentication): Choose header or route-token authentication and protect your key.
* [Query a Subgraph](./guides/query-a-subgraph): Send a complete query from curl, TypeScript, or Python.
* [Identifiers and Endpoint Aliases](./concepts/identifiers-and-aliases): Choose the identifier your endpoint uses.