> ## 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.

# Setting up governance

This guide covers the catalog setup you make as the vendor — both from the Stigg console and via the [Stigg REST API](/api-and-sdks/api-reference/rest/overview). Most of these are one-time or infrequent operations; the [Check and Ingest](/documentation/governance/check-and-ingest) calls happen per-request at runtime.

## Via the Stigg console

### Define entity types

In the Stigg app, go to **Governance → Entity types**. The list shows all entity types defined for the environment, along with their attribution keys and the last time each was updated.

<Frame caption="Entity types list">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-entity-types-list.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=d1fdea99bbbde074d5977e6959f47428" alt="Entity types list" width="2880" height="1398" data-path="images/docs/governance-entity-types-list.png" />
</Frame>

Click **+ New entity type** to open the creation drawer.

<Frame caption="New entity type drawer">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-entity-type-new-empty.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=e8930b209469a8d0307fbe83163fc3d1" alt="New entity type — empty" width="2880" height="1398" data-path="images/docs/governance-entity-type-new-empty.png" />
</Frame>

Fill in:

* **Display name** — a human-readable label (e.g. `Organization`). The entity type ID is auto-generated from it and can be edited.
* **Attribution keys** — the dimension keys your usage events carry to identify instances of this type (e.g. `orgId`). Type a key and press Enter to add it; multiple keys are supported.

<Frame caption="Filling in name and attribution key">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-entity-type-new-fill.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=7b481204a308adbe07581b146fd7d4a7" alt="New entity type — filling in" width="2880" height="1398" data-path="images/docs/governance-entity-type-new-fill.png" />
</Frame>

<Frame caption="Attribution key added — ready to create">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-entity-type-new-ready.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=323b0073cfddb1feb7b6998aa308e962" alt="New entity type — ready to create" width="2880" height="1398" data-path="images/docs/governance-entity-type-new-ready.png" />
</Frame>

Once created, the new type appears in the list. Hover a row and click the **⋮** menu to **Edit** it.

<Frame caption="Newly created entity type with edit option">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-entity-type-created.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=b4df12f58f58ff3bded1df1d6797fa47" alt="Entity type created" width="2880" height="1398" data-path="images/docs/governance-entity-type-created.png" />
</Frame>

<Frame caption="Edit entity type drawer">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-entity-type-edit.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=d938fe53d1171e5d2b55bfa9fb802848" alt="Edit entity type" width="2880" height="1398" data-path="images/docs/governance-entity-type-edit.png" />
</Frame>

### View and manage entities for a customer

To view governance data for a specific customer:

1. Go to **Customers → Customer accounts** and open the customer record.

<Frame caption="Customer accounts list">
  <img src="https://mintcdn.com/stigg/RjVKlcnBc3TW7R6e/images/docs/governance-customer-accounts-list.png?fit=max&auto=format&n=RjVKlcnBc3TW7R6e&q=85&s=e42d0ed509242c9cda4deebdc0abaf97" alt="Customer accounts list" width="2880" height="1398" data-path="images/docs/governance-customer-accounts-list.png" />
</Frame>

2. Click the **Governance** tab.

The tab shows the customer's entity hierarchy on the left, their entity types in the **Type** column, and — for each entitlement — the current usage vs. limit broken out by scope (Node-wide and per-model or other dimension).

<Frame caption="Customer Governance tab — entity hierarchy with usage">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-customer-tab-overview.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=f4a54aa7e6ec6830f6552c3b7fff5169" alt="Customer Governance tab overview" width="2880" height="1398" data-path="images/docs/governance-customer-tab-overview.png" />
</Frame>

### Sort and prioritize entities

Use the **Order by** control (the sliders icon next to the type filter) to rank entities by consumption. Two modes are available:

* **Usage** — ranks by absolute consumption, so the heaviest consumers appear first
* **Utilization** — ranks by percentage of limit used, so entities closest to being blocked surface first

<Frame caption="Order by — Usage vs. Utilization">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-customer-sort-order.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=38cdbd36e514f52f6323a2106395100d" alt="Sort order panel" width="1466" height="416" data-path="images/docs/governance-customer-sort-order.png" />
</Frame>

Switching to **Utilization** is the fastest way to spot entities that are about to hit their limit and may need a budget increase or intervention before they get blocked.

### Add an entity to a customer

Click **+ Add entity** to open the drawer.

<Frame caption="Add entity drawer — empty">
  <img src="https://mintcdn.com/stigg/RjVKlcnBc3TW7R6e/images/docs/governance-customer-add-entity-empty.png?fit=max&auto=format&n=RjVKlcnBc3TW7R6e&q=85&s=af10069cd6ae9dbd4c2f2c1a8cae9e8c" alt="Add entity — empty" width="2880" height="1398" data-path="images/docs/governance-customer-add-entity-empty.png" />
</Frame>

Fill in:

* **Entity ID** — the unique identifier used in API calls (e.g. `org-acme`)
* **Entity type** — select from the entity types defined for this environment

<Frame caption="Selecting an entity type">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-customer-add-entity-type.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=0d46f299e13401b653ba8c6e7aaa7cc3" alt="Add entity — entity type dropdown" width="2880" height="1398" data-path="images/docs/governance-customer-add-entity-type.png" />
</Frame>

* **Parent entity** *(optional)* — place this entity under a parent in the hierarchy (e.g. nest a user under a team)

<Frame caption="Selecting a parent entity">
  <img src="https://mintcdn.com/stigg/RjVKlcnBc3TW7R6e/images/docs/governance-customer-add-entity-parent.png?fit=max&auto=format&n=RjVKlcnBc3TW7R6e&q=85&s=12f5b416e9ec43a4758cf4b0356f53b1" alt="Add entity — parent selected" width="2880" height="1398" data-path="images/docs/governance-customer-add-entity-parent.png" />
</Frame>

* **Cardinality** *(optional)* — restrict this entity's budget to a specific sub-context by selecting entities to slice by

<Frame caption="Cardinality — selecting entities to slice by">
  <img src="https://mintcdn.com/stigg/RjVKlcnBc3TW7R6e/images/docs/governance-customer-add-entity-cardinality.png?fit=max&auto=format&n=RjVKlcnBc3TW7R6e&q=85&s=d0a8a9e3ff7e430f070ce261c5f886cd" alt="Add entity — cardinality dropdown" width="2880" height="1398" data-path="images/docs/governance-customer-add-entity-cardinality.png" />
</Frame>

After adding entities, the full hierarchy is visible in the Governance tab with all entitlement columns.

<Frame caption="Full governance hierarchy with all entities and entitlement columns">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-customer-hierarchy-full.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=8ae3e9b3acea59fed8c324172621267c" alt="Full governance hierarchy" width="2880" height="1398" data-path="images/docs/governance-customer-hierarchy-full.png" />
</Frame>

### Edit an entitlement value inline

Click any entitlement cell in the Governance tab to edit the limit value inline, then confirm with the checkmark.

<Frame caption="Inline editing an entitlement value">
  <img src="https://mintcdn.com/stigg/_TNIA08bS1sdXVQ5/images/docs/governance-customer-inline-edit.png?fit=max&auto=format&n=_TNIA08bS1sdXVQ5&q=85&s=0793eb7c5c36f3c4e0903358f1d43a02" alt="Inline edit entitlement" width="2880" height="1398" data-path="images/docs/governance-customer-inline-edit.png" />
</Frame>

***

## Via the SDK

Install the Stigg TypeScript client and initialize it with your server-side API key:

```bash theme={null}
npm install @stigg/typescript
```

```typescript theme={null}
import Stigg from '@stigg/typescript';

const client = new Stigg({
  apiKey: process.env.STIGG_API_KEY,
});
```

All examples in the governance docs use this `client` instance.

***

## Via the REST API

All governance operations use the [Stigg REST API](/api-and-sdks/api-reference/rest/overview). Authenticate with your server-side API key:

```bash theme={null}
X-API-KEY: <SERVER_API_KEY>
```

***

## Step 1 — Define entity types

Entity types are the categories of resource you want to govern (e.g., `org`, `team`, `user`, `agent`). Define them once per environment. The `attributionKeys` are the dimension keys your ingest events carry to identify instances of each type.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.v1Beta.entityTypes.upsert({
    types: [
      { id: 'org',   displayName: 'Organization', attributionKeys: ['orgId'] },
      { id: 'team',  displayName: 'Team',         attributionKeys: ['teamId'] },
      { id: 'user',  displayName: 'User',         attributionKeys: ['userId'] },
      { id: 'agent', displayName: 'AI agent',     attributionKeys: ['agentId'] },
    ],
  });
  ```

  ```bash curl theme={null}
  curl -X PUT https://api.stigg.io/api/v1-beta/entity-types \
    -H "X-API-KEY: <SERVER_API_KEY>" \
    -H "Content-Type: application/json" \
    -d '{
      "types": [
        { "id": "org",   "displayName": "Organization", "attributionKeys": ["orgId"] },
        { "id": "team",  "displayName": "Team",         "attributionKeys": ["teamId"] },
        { "id": "user",  "displayName": "User",         "attributionKeys": ["userId"] },
        { "id": "agent", "displayName": "AI agent",     "attributionKeys": ["agentId"] }
      ]
    }'
  ```
</CodeGroup>

The upsert is **idempotent** — re-submitting the same payload is safe. Up to 100 types per request.

**Response** (`200 OK`):

```json theme={null}
[
  {
    "id": "org",
    "displayName": "Organization",
    "attributionKeys": ["orgId"],
    "createdAt": "2026-01-15T10:00:00.000Z",
    "updatedAt": "2026-01-15T10:00:00.000Z"
  }
]
```

### Listing entity types

<CodeGroup>
  ```typescript TypeScript theme={null}
  for await (const entityType of client.v1Beta.entityTypes.list()) {
    console.log(entityType.id, entityType.displayName);
  }
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1-beta/entity-types" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

***

## Step 2 — Provision entities per customer

When a customer creates an org, team, or user in your product, provision the corresponding entity in governance. The `ownerId` is the customer's ID in your system.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.v1Beta.customers.entities.upsert('cus-acme', {
    entities: [
      { id: 'org-acme',     entityTypeId: 'org',   metadata: { plan: 'enterprise' } },
      { id: 'team-eng',     entityTypeId: 'team' },
      { id: 'team-product', entityTypeId: 'team' },
      { id: 'agent-claude', entityTypeId: 'agent' },
    ],
  });
  ```

  ```bash curl theme={null}
  curl -X PUT https://api.stigg.io/api/v1-beta/customers/cus-acme/entities \
    -H "X-API-KEY: <SERVER_API_KEY>" \
    -H "Content-Type: application/json" \
    -d '{
      "entities": [
        { "id": "org-acme",     "entityTypeId": "org",   "metadata": { "plan": "enterprise" } },
        { "id": "team-eng",     "entityTypeId": "team" },
        { "id": "team-product", "entityTypeId": "team" },
        { "id": "agent-claude", "entityTypeId": "agent" }
      ]
    }'
  ```
</CodeGroup>

Up to 100 entities per request. Idempotent — safe to re-run during re-syncs.

**Metadata patch semantics**: keys present in `metadata` are merged over existing values. Set a key to `""` to delete it. Omitting `metadata` entirely leaves the stored metadata unchanged.

**Response** (`200 OK`):

```json theme={null}
[
  {
    "id": "org-acme",
    "entityTypeId": "org",
    "metadata": { "plan": "enterprise" },
    "archivedAt": null,
    "createdAt": "2026-01-15T10:00:00.000Z",
    "updatedAt": "2026-01-15T10:00:00.000Z"
  }
]
```

### Listing entities

<CodeGroup>
  ```typescript TypeScript theme={null}
  // All active entities for the customer
  for await (const entity of client.v1Beta.customers.entities.list('cus-acme')) {
    console.log(entity.id, entity.entityTypeId);
  }

  // Filter by entity type
  for await (const team of client.v1Beta.customers.entities.list('cus-acme', { entityTypeId: 'team' })) {
    console.log(team.id);
  }
  ```

  ```bash curl theme={null}
  # All active entities
  curl "https://api.stigg.io/api/v1-beta/customers/cus-acme/entities" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

### Getting a single entity

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.v1Beta.customers.entities.retrieve('org-acme', { id: 'cus-acme' });
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1-beta/customers/cus-acme/entities/org-acme" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

### Archiving and unarchiving entities

Archiving is a soft-delete: the entity disappears from the list but remains accessible via GET-by-ID.

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Archive
  await client.v1Beta.customers.entities.archive('cus-acme', { ids: ['team-old-project'] });

  // Unarchive
  await client.v1Beta.customers.entities.unarchive('cus-acme', { ids: ['team-old-project'] });
  ```

  ```bash curl theme={null}
  # Archive
  curl -X POST https://api.stigg.io/api/v1-beta/customers/cus-acme/entities/archive \
    -H "X-API-KEY: <SERVER_API_KEY>" \
    -H "Content-Type: application/json" \
    -d '{ "ids": ["team-old-project"] }'
  ```
</CodeGroup>

Both return `204 No Content`.

***

## Step 3 — Create assignments

Assignments set the usage limit for an `(entity, feature/credit)` pair — they are the governance equivalent of entitlements, and appear as entitlement columns in the Stigg console's Governance tab. They are typically created by your customers through an in-app interface, but you can also set them programmatically.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.v1Beta.customers.assignments.upsert('cus-acme', {
    assignments: [
      { entityId: 'org-acme', featureId: 'feature-ai-tokens', usageLimit: 1_000_000, cadence: 'P1M' },
      { entityId: 'team-eng', featureId: 'feature-ai-tokens', parentId: 'org-acme', usageLimit: 200_000, cadence: 'P1M' },
    ],
  });
  ```

  ```bash curl theme={null}
  curl -X PUT https://api.stigg.io/api/v1-beta/customers/cus-acme/assignments \
    -H "X-API-KEY: <SERVER_API_KEY>" \
    -H "Content-Type: application/json" \
    -d '{
      "assignments": [
        { "entityId": "org-acme", "featureId": "feature-ai-tokens", "usageLimit": 1000000, "cadence": "P1M" },
        { "entityId": "team-eng", "featureId": "feature-ai-tokens", "parentId": "org-acme", "usageLimit": 200000, "cadence": "P1M" }
      ]
    }'
  ```
</CodeGroup>

**Patch semantics**: on re-upsert, omitting `usageLimit` or `cadence` preserves the existing value. On first create, both are required.

**`usageLimit: null` — tracked but unlimited**: setting `usageLimit` to `null` means usage is still counted and appears in check responses, but the limit never blocks. Useful for observability before enforcing.

**Response** (`200 OK`):

```json theme={null}
[
  {
    "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "entityId": "org-acme",
    "featureId": "feature-ai-tokens",
    "scopeEntityIds": [],
    "usageLimit": 1000000,
    "cadence": "P1M",
    "parentId": null,
    "createdAt": "2026-01-15T10:00:00.000Z",
    "updatedAt": "2026-01-15T10:00:00.000Z"
  }
]
```

### Hierarchy — placing entities in a tree

The `parentId` field places an entity under a parent in the governance hierarchy. The check endpoint evaluates every budget in the chain from the target entity to the root — a request is only granted when all budgets along the path allow it.

<Note>
  `parentId` is tri-state: **omitting** it leaves the current parent unchanged (new nodes default to root); **`null`** detaches the entity to root; an **entity ID** sets or changes the parent. Reparenting is only allowed for leaf nodes — a node with children cannot be moved.
</Note>

### Dimension-scoped sub-budgets

Add a tighter budget for a specific context by setting `scopeEntityIds`. The scoped budget applies only when every listed entity is present in the resolved set for the request.

<CodeGroup>
  ```typescript TypeScript theme={null}
  await client.v1Beta.customers.assignments.upsert('cus-acme', {
    assignments: [
      // Node-wide budget — always applies
      { entityId: 'team-eng', featureId: 'feature-ai-tokens', scopeEntityIds: [],              usageLimit: 200_000, cadence: 'P1M' },
      // Tighter budget — applies only when model-gpt4o is in the request context
      { entityId: 'team-eng', featureId: 'feature-ai-tokens', scopeEntityIds: ['model-gpt4o'], usageLimit: 10_000,  cadence: 'P1M' },
    ],
  });
  ```
</CodeGroup>

### Listing assignments

<CodeGroup>
  ```typescript TypeScript theme={null}
  // All assignments for the customer
  for await (const assignment of client.v1Beta.customers.assignments.list('cus-acme')) {
    console.log(assignment.entityId, assignment.featureId, assignment.usageLimit);
  }

  // Filter by entity
  for await (const assignment of client.v1Beta.customers.assignments.list('cus-acme', { entityId: 'team-eng' })) {
    console.log(assignment);
  }
  ```

  ```bash curl theme={null}
  curl "https://api.stigg.io/api/v1-beta/customers/cus-acme/assignments?entityId=team-eng" \
    -H "X-API-KEY: <SERVER_API_KEY>"
  ```
</CodeGroup>

## What's next

<CardGroup cols={2}>
  <Card title="Check and ingest" icon="bolt" href="/documentation/governance/check-and-ingest">
    Gate access before consumption and record usage after
  </Card>

  <Card title="Query the governance tree" icon="chart-bar" href="/documentation/governance/query">
    Fetch usage and budget data for dashboards and admin UIs
  </Card>
</CardGroup>
