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

# Cost Attribution

> Tag every LLM request with custom metadata and break down spend by team, feature, environment, or any dimension you care about.

Every request through the gateway can carry custom metadata via `X-Majordomo-*` headers. This metadata is stored with the request log and queryable in the dashboard and directly in Postgres.

## Adding metadata

Any header prefixed with `X-Majordomo-` (except `-Key` and `-Provider`) is stored as metadata:

<CodeGroup>
  ```python Python (OpenAI) theme={null}
  response = client.chat.completions.create(
      model="gpt-4o",
      messages=[...],
      extra_headers={
          "X-Majordomo-Feature": "document-review",
          "X-Majordomo-Team": "legal",
          "X-Majordomo-Environment": "production",
          "X-Majordomo-User-Tier": "enterprise",
      }
  )
  ```

  ```python Python (Anthropic) theme={null}
  response = client.messages.create(
      model="claude-sonnet-4-6",
      max_tokens=1024,
      messages=[...],
      extra_headers={
          "X-Majordomo-Key": "mdm_sk_your_key_here",
          "X-Majordomo-Feature": "contract-analysis",
          "X-Majordomo-User-Id": "user_456",
      }
  )
  ```

  ```bash curl theme={null}
  curl -X POST https://gateway.gomajordomo.com/v1/chat/completions \
    -H "X-Majordomo-Key: mdm_sk_your_key_here" \
    -H "X-Majordomo-Feature: chat" \
    -H "X-Majordomo-Team: product" \
    -H "X-Majordomo-Environment: production" \
    ...
  ```
</CodeGroup>

## Recommended dimensions

| Header                    | Example values                        | When to use                              |
| ------------------------- | ------------------------------------- | ---------------------------------------- |
| `X-Majordomo-Feature`     | `chat`, `document-review`, `code-gen` | Per product feature                      |
| `X-Majordomo-Team`        | `platform`, `data`, `legal`           | Per team                                 |
| `X-Majordomo-Environment` | `production`, `staging`, `dev`        | Per environment                          |
| `X-Majordomo-User-Id`     | `user_123`                            | Per end user (use an opaque ID, not PII) |
| `X-Majordomo-User-Tier`   | `free`, `pro`, `enterprise`           | Per pricing tier                         |
| `X-Majordomo-Experiment`  | `model-test-v2`                       | Per A/B test or experiment               |

Start with the dimensions you'll actually query. You can add more over time — new keys are stored immediately without any schema changes.

## Querying spend

### By feature

```sql theme={null}
SELECT
    raw_metadata->>'Feature' AS feature,
    COUNT(*) AS requests,
    SUM(input_tokens) AS input_tokens,
    SUM(output_tokens) AS output_tokens,
    SUM(total_cost) AS total_cost
FROM llm_requests
WHERE raw_metadata->>'Feature' IS NOT NULL
GROUP BY 1
ORDER BY total_cost DESC;
```

### By team (monthly)

```sql theme={null}
SELECT
    raw_metadata->>'Team' AS team,
    date_trunc('month', requested_at) AS month,
    SUM(total_cost) AS total_cost
FROM llm_requests
WHERE requested_at > now() - interval '3 months'
GROUP BY 1, 2
ORDER BY 2 DESC, 3 DESC;
```

### By model

```sql theme={null}
SELECT
    model,
    COUNT(*) AS requests,
    SUM(total_cost) AS total_cost,
    AVG(response_time_ms) AS avg_latency_ms
FROM llm_requests
GROUP BY model
ORDER BY total_cost DESC;
```

### Top spenders this week

```sql theme={null}
SELECT
    raw_metadata->>'User-Id' AS user_id,
    COUNT(*) AS requests,
    SUM(total_cost) AS total_cost
FROM llm_requests
WHERE
    requested_at > now() - interval '7 days'
    AND raw_metadata->>'User-Id' IS NOT NULL
GROUP BY 1
ORDER BY total_cost DESC
LIMIT 20;
```

## Indexed metadata

High-cardinality metadata keys (user IDs, experiment names) can be activated for GIN indexing in the dashboard. Activated keys are copied to the `indexed_metadata` JSONB column, which supports fast `@>` queries.

```sql theme={null}
-- Fast query on an indexed key
SELECT COUNT(*), SUM(total_cost)
FROM llm_requests
WHERE indexed_metadata @> '{"Feature": "document-review"}';
```

Non-indexed keys are still queryable via `raw_metadata` — just without the index. Activate keys for dimensions you query frequently.

## Grouping an agent's calls

Metadata attributes cost across dimensions (feature, team, user). To instead group the
**multiple LLM calls of one conversation or agent run** into a single run — with a rolled-up
cost and a nested waterfall — use [Agent Run Tracking](/guides/agent-runs). The two compose:
tag a run with a trace id and an `X-Majordomo-Feature` to both drill into one run and roll
runs up by feature.
