> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stigg.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Query the governance tree

Returns a paginated, sortable, filterable view of an owner's governance tree — each node with its hierarchy position, budget configuration, and current usage. Use this endpoint to power dashboards, admin UIs, and leaderboards.

<Note>
  Usage figures are served from a periodically-refreshed read model and may lag the live counter by a few minutes. This endpoint never gates — use [Check](/documentation/governance/check-and-ingest#check) for real-time gate decisions.
</Note>

All calls use the [Stigg REST API](/api-and-sdks/api-reference/rest/overview) with your server-side API key in the `X-API-KEY` header.

***

## Basic query

<CodeGroup>
  ```typescript TypeScript theme={null}
  const res = await fetch('https://api.stigg.io/api/v1/governance/owners/cus-acme/query?limit=20', {
    headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! },
  });
  const { data, pagination } = await res.json();
  // data: QueryResponse[]
  // pagination: { next: string | null, prev: string | null }
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?limit=20" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

***

## Response shape

```json theme={null}
{
  "data": [
    {
      "entityId": "team-eng",
      "parentId": "org-acme",
      "entityTypeId": "team",
      "featureId": "feature_ai_tokens",
      "scopeEntityIds": [],
      "usageLimit": 200000,
      "currentUsage": 164000,
      "utilization": 0.82,
      "cadence": "P1M",
      "usagePeriodStart": "2026-05-01T00:00:00.000Z",
      "usagePeriodEnd": "2026-06-01T00:00:00.000Z"
    },
    {
      "entityId": "team-eng",
      "parentId": "org-acme",
      "entityTypeId": "team",
      "featureId": "feature_ai_tokens",
      "scopeEntityIds": ["model-gpt4o"],
      "usageLimit": 10000,
      "currentUsage": 2600,
      "utilization": 0.26,
      "cadence": "P1M",
      "usagePeriodStart": "2026-05-01T00:00:00.000Z",
      "usagePeriodEnd": "2026-06-01T00:00:00.000Z"
    }
  ],
  "pagination": {
    "next": "eyJpZCI6InRlYW0tZW5nIn0=",
    "prev": null
  }
}
```

| Field              | Description                                                                                            |
| ------------------ | ------------------------------------------------------------------------------------------------------ |
| `entityId`         | External ID of the entity (hierarchy node).                                                            |
| `parentId`         | External ID of the parent entity; `null` for a root node. Use this to rebuild the tree client-side.    |
| `entityTypeId`     | External ID of the entity type (e.g., `org`, `team`, `user`).                                          |
| `featureId`        | The Stigg feature or credit ID this budget governs.                                                    |
| `scopeEntityIds`   | The cardinality scope. `[]` is the node-wide budget; a non-empty set is a dimension-scoped sub-budget. |
| `usageLimit`       | Hard usage limit per cadence period.                                                                   |
| `currentUsage`     | Usage consumed in the current cadence period (may lag by minutes).                                     |
| `utilization`      | `currentUsage / usageLimit`. `1.0` when at or over limit; `null` if no limit.                          |
| `cadence`          | ISO-8601 reset cadence (e.g., `P1M`).                                                                  |
| `usagePeriodStart` | Start of the cadence period the snapshot belongs to.                                                   |
| `usagePeriodEnd`   | When usage resets (exclusive).                                                                         |

***

## Filtering

### Filter by feature/credit

<CodeGroup>
  ```typescript TypeScript theme={null}
  const res = await fetch(
    'https://api.stigg.io/api/v1/governance/owners/cus-acme/query?featureIds=feature_ai_tokens&featureIds=feature_api_calls',
    { headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! } },
  );
  const { data } = await res.json();
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?featureIds=feature_ai_tokens&featureIds=feature_api_calls" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

### Filter by entity type

<CodeGroup>
  ```typescript TypeScript theme={null}
  const res = await fetch(
    'https://api.stigg.io/api/v1/governance/owners/cus-acme/query?entityTypeIds=team&entityTypeIds=user',
    { headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! } },
  );
  const { data } = await res.json();
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?entityTypeIds=team&entityTypeIds=user" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

### Filter by scope

| `scope` value     | Rows included                                 |
| ----------------- | --------------------------------------------- |
| `'all'` (default) | All rows                                      |
| `'nodeWide'`      | Only node-wide budgets (`scopeEntityIds: []`) |
| `'scoped'`        | Only dimension-scoped sub-budgets             |

<CodeGroup>
  ```typescript TypeScript theme={null}
  const res = await fetch(
    'https://api.stigg.io/api/v1/governance/owners/cus-acme/query?scope=nodeWide',
    { headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! } },
  );
  const { data } = await res.json();
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?scope=nodeWide" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

### Filter by utilization

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Entities at ≥ 80% utilization
  const nearLimitRes = await fetch(
    'https://api.stigg.io/api/v1/governance/owners/cus-acme/query?minUtilization=0.8',
    { headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! } },
  );
  const { data: nearLimit } = await nearLimitRes.json();
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?minUtilization=0.8" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

### Search by entity ID

Case-insensitive substring match on the entity ID.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const res = await fetch(
    'https://api.stigg.io/api/v1/governance/owners/cus-acme/query?entityIdSearch=team',
    { headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! } },
  );
  const { data } = await res.json();
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?entityIdSearch=team" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

***

## Sorting

| `sortBy` value            | Description                                   |
| ------------------------- | --------------------------------------------- |
| `'utilization'` (default) | `currentUsage / usageLimit`                   |
| `'currentUsage'`          | Raw usage count                               |
| `'usageLimit'`            | Configured limit                              |
| `'scopeSize'`             | Node-wide rows first, then scoped by set size |
| `'id'`                    | Entity ID alphabetical                        |
| `'createdAt'`             | Creation timestamp                            |

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Teams closest to their limit, descending
  const res = await fetch(
    'https://api.stigg.io/api/v1/governance/owners/cus-acme/query?featureIds=feature_ai_tokens&entityTypeIds=team&sortBy=utilization&order=desc&limit=20',
    { headers: { 'X-API-KEY': process.env.STIGG_SERVER_API_KEY! } },
  );
  const { data } = await res.json();
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?featureIds=feature_ai_tokens&entityTypeIds=team&sortBy=utilization&order=desc" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

***

## Pagination

The query endpoint uses forward-only cursor pagination.

<CodeGroup>
  ```typescript TypeScript theme={null}
  async function* queryAllNodes(customerId: string) {
    let after: string | undefined;
    const apiKey = process.env.STIGG_SERVER_API_KEY!;

    do {
      const url = new URL(`https://api.stigg.io/api/v1/governance/owners/${customerId}/query`);
      url.searchParams.set('limit', '50');
      if (after) url.searchParams.set('after', after);

      const res = await fetch(url.toString(), { headers: { 'X-API-KEY': apiKey } });
      const page = await res.json();
      yield* page.data;
      after = page.pagination.next ?? undefined;
    } while (after);
  }
  ```

  ```bash curl theme={null}
  # First page
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?limit=10" \
    -H "X-API-KEY: <SERVER_API_KEY>"

  # Next page — pass pagination.next from the previous response
  curl "https://api.stigg.io/api/v1/governance/owners/cus-acme/query?limit=10&after=<CURSOR>" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

`pagination.next` is `null` when you have reached the last page.

***

## Rebuilding the tree client-side

Each row carries `parentId`, so you can reconstruct the full hierarchy from a flat response:

<CodeGroup>
  ```typescript TypeScript theme={null}
  type QueryRow = { entityId: string; parentId: string | null; [key: string]: unknown };
  type TreeNode = QueryRow & { children: TreeNode[] };

  function buildTree(rows: QueryRow[]): TreeNode[] {
    const byId = new Map<string, TreeNode>(
      rows.map(r => [r.entityId, { ...r, children: [] }])
    );
    const roots: TreeNode[] = [];

    for (const node of byId.values()) {
      if (node.parentId && byId.has(node.parentId)) {
        byId.get(node.parentId)!.children.push(node);
      } else {
        roots.push(node);
      }
    }

    return roots;
  }
  ```
</CodeGroup>
