Every metric you see in my.cubepath.com comes from the CubePath GraphQL API. It's the same endpoint the panel uses, and you can query it yourself to build your own dashboards, reports and health checks.

POST https://api.cubepath.com/graphql

It's read-only and covers metrics and traffic: VPS, availability groups, baremetal (traffic, bandwidth and BMC sensors), IP transit, load balancers, NAT gateways and Kubernetes clusters. To create or change resources, use the REST API or the MCP server.

Authenticate

Use an API token in either header:

curl https://api.cubepath.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{"query":"{ vpsList { id name } }"}'

X-API-Key: YOUR_API_TOKEN works too. A token request needs no X-Requested-With header, even though it's a POST.

Each field checks the read scope of its product, so a monitoring token only needs the read scopes:

FieldScope
vps, vpsList, availabilityGroupvps:read
baremetalbaremetal:read
transitnetwork:read
loadBalancerloadbalancer:read
natGatewaynat_gateway:read
kubernetesCluster, kubernetesClusterskubernetes:read
bandwidthResources, bandwidthAggregatethe scope of each product it includes

Your first query

One request can ask for several resources at once, each with exactly the fields you need:

query Overview($id: ID!) {
  vps(id: $id) {
    name
    metrics(range: H6, metrics: [CPU_USAGE, MEMORY_USAGE]) {
      step
      series { name unit points { ts value } }
    }
    bandwidthUsage { inBytes outBytes totalBytes }
  }
  kubernetesClusters {
    name
    health { up nodesReady nodesTotal podsPending }
  }
}

Send it as JSON with query and variables:

curl https://api.cubepath.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{"query":"query($id: ID!){ vps(id:$id){ name metrics(range: H6, metrics:[CPU_USAGE]){ step series{ name unit points{ ts value } } } } }","variables":{"id":"1234"}}'

What you can query

FieldWhat it returns
vps(id) / vpsList(projectId)CPU, memory, disk I/O and network series, plus the month's bandwidth. vpsList returns up to 200 servers
availabilityGroup(uuid)Average CPU and total memory across the group, and how many servers it has
baremetal(id)Traffic and packets per second, the month's bandwidth, the last 30 days of traffic and the BMC sensors (temperatures, fans, power state)
transit(id)Traffic and packets per second of your IP transit port
loadBalancer(uuid)Active connections, new connections per second, traffic in and out, and the month's bandwidth
natGateway(uuid)Traffic in and out, and the month's bandwidth
kubernetesCluster(uuid) / kubernetesClusters(projectId)API server health, every node with its conditions and resources, and the cluster series (nodes ready, pending and failed pods, API latency)
bandwidthResources / bandwidthAggregateEvery service that moves public traffic and their traffic summed by location, product, project or service. It's what powers the Bandwidth page

Time ranges

metrics(range:) takes the same ranges as the panel: H1, H3, H6, H12, H24, D3, D7 and D30. The default is H1.

Longer ranges come back with a larger step (the bucket size, in seconds), so a 30-day chart has about 300 points rather than tens of thousands.

Reading a result

{
  "data": {
    "vps": {
      "name": "web-1",
      "metrics": {
        "step": 30,
        "series": [
          { "name": "cpu_usage", "unit": "RATIO", "points": [{ "ts": 1759406400, "value": 0.42 }] }
        ]
      }
    }
  }
}
  • ts is a Unix timestamp in seconds, UTC.
  • unit tells you how to format the value: RATIO is 0 to 1 (0.42 is 42%), BYTES, BYTES_PER_SECOND, PACKETS_PER_SECOND, CONNECTIONS, CELSIUS, RPM, MILLISECONDS and so on.
  • All the series of one metrics result share the same timestamps, so you can plot them on one chart without lining them up yourself.

Monthly bandwidth

bandwidthUsage(month: "2026-09") returns the traffic of that calendar month (UTC). Leave month out for the current month to date. The format is strictly YYYY-MM.

On the Bandwidth fields, inBytes is always traffic into your service and outBytes traffic out of it, whatever the product.

Errors

A request that GraphQL accepts always answers HTTP 200. When one field fails, that field is null and errors explains why, while the rest of the request still resolves:

extensions.codeMeaning
UNAUTHENTICATEDNo token, or the token is invalid
FORBIDDENThe token lacks the scope for that product, or the server is suspended
NOT_FOUNDNo such resource in your organization
BAD_USER_INPUTInvalid argument, such as a bad month or an unknown field
METRICS_UNAVAILABLEMetrics are temporarily unavailable. The resource still resolves and the series come back empty
QUERY_TOO_COMPLEXThe request asks for too much at once (see the limits below)

Limits

  • 600 requests per minute per token. One request counts once, whatever it asks for. Over the limit you get 429 with Retry-After.
  • A single request may return up to about 24,000 points: for example 200 one-hour series, or 80 series over 30 days. Split bigger requests in two.
  • Queries up to 6 levels deep, 15 aliases and 2,000 tokens. Batched operation arrays are not accepted.
  • vpsList, kubernetesClusters and each product in bandwidthResources return up to 200 items.

Schema and tooling

The schema is open to authenticated callers through standard introspection, so tools like GraphQL Code Generator, Postman or Insomnia can load it with your token. Anonymous introspection is refused.