Traffic Data Import
The gateway governs the traffic that flows through it. But an enterprise’s AI spend rarely stops there — employees chat in claude.ai and Claude Desktop, developers run Claude Code against Anthropic directly, teams consume Azure OpenAI from their own subscriptions. Traffic Data Import pulls each vendor’s enterprise analytics/admin API into Brutor’s usage ledger, so Mission Control shows one cost, token and model-usage view across the whole estate: the traffic Brutor governs inline plus the traffic it can only observe.

What each provider’s API yields
Section titled “What each provider’s API yields”| Provider / API | Surfaces covered | Per-user | Per-workspace | Per-model | Metrics | Window / lookback / rate |
|---|---|---|---|---|---|---|
| Anthropic — Enterprise Analytics API | chat (claude.ai + Claude Desktop), code (Claude Code), agent, office — from the API’s product field |
~ no workspace dimension in the API — Brutor substitutes product, materialized as per-product resource groups |
✔ | tokens and cost (USD) | 31 d / 365 d / 60 rpm — excludes Bedrock-routed traffic | |
| OpenAI — Usage + Costs API | api (platform usage) |
✔ user_id | ✔ project_id | ✔ | tokens and cost | 31 d / 365 d / 60 rpm |
| Google — Vertex Monitoring | api |
✘ | ✔ GCP project_id | ✔ | tokens only — cost is computed from catalog prices | 30 d / 365 d / 60 rpm |
| Microsoft — Azure Cost Management | api (Azure OpenAI) |
✘ | ✔ resource / resource group | partial (via meter) | cost only | 365 d / 365 d / 30 rpm |
| Microsoft — Graph Copilot reports | office, chat (M365 Copilot) |
✔ | ✘ | ✘ | activity counts only — no tokens, no cost | 30 d / 180 d / 30 rpm |
Provider APIs differ in shape, so the import layer normalizes everything to one record: period, surface, user, workspace, model, tokens, cost, events. Where a vendor gives only half the picture (Google: tokens without cost; Azure Cost Management: cost without users), the table above is the honest contract of what you can and cannot attribute.
Anthropic’s product field
Section titled “Anthropic’s product field”Anthropic’s Enterprise Analytics API breaks usage out per user, per product and per model (group_by[]=product,model). The product values map to Brutor surfaces:
Anthropic product |
Brutor surface |
|---|---|
chat |
chat |
claude_code |
code |
cowork |
agent |
office_agent |
office |
claude_in_chrome |
chat |
claude_design |
chat |
Because the analytics API has no workspace dimension, product plays the workspace role in Brutor: discovery materializes each product as a child resource group (see below), giving you the same per-group cost attribution, budgets and drilldowns you get from a real workspace dimension — just cut by product instead of team. To cut by team as well, map users to your real resource groups with user_map. Anthropic’s Admin Usage & Cost API (organization/workspace API spend) is intentionally not imported — that traffic is API traffic you should route through the gateway, where it is governed inline.
What discovery auto-creates
Section titled “What discovery auto-creates”Every import run reconciles what it sees into real platform objects — all flagged source='import' (a quarantine mode can hold them for review instead):

| Discovered in the data | Created as | Notes |
|---|---|---|
| Users (email / user_id) | End users | Also added as members of the product/workspace resource group they used |
| Workspaces (OpenAI project, Azure resource) | Child resource group under “<Provider> (imported usage)” | Per-workspace cost attribution |
| Products (Anthropic) | Per-product child resource groups: chat / code / agent / office |
Cost-per-product; each can carry an advisory budget |
| Models | Model rows with enabled: false — shown as Observed (imported) models, invisible in the portal until promoted |
Also synced into the AI Asset Registry on the observed plane |
| The usage itself | Usage-ledger rows (idempotent — re-importing a window is a no-op) + a metrics mirror | Powers Mission Control’s Governed / Observed / All toggle |
Operator mappings always beat auto-creation. The import settings accept a mapping policy:
{ "mode": "auto_create", "workspace_map": { "proj_abc123": "rg-data-science" }, "user_map": { "@claims.example.com": "rg-claims-team" }, "default_group_id": null}user_map (by email or @domain) is the only way to attribute per-user-only data — like Anthropic’s — to your real team structure instead of the auto-created product groups.
Configuring an import
Section titled “Configuring an import”In the Admin UI: Resources → AI Models → Traffic Data Import — list providers, configure credentials and schedule, test the connection, run on demand, backfill, and inspect run history. Import-capable providers appear here even before you’ve configured any model for them.
Via the Admin API:
# Which providers support import?curl -H "Authorization: Bearer $TOKEN" \ http://localhost:5050/v1/admin/usage-import/providers?only_supported=true
# Configure + schedule (daily at 06:00)curl -X PATCH http://localhost:5050/v1/admin/usage-import/providers/{provider_id} \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{ "import_enabled": true, "import_schedule_cron": "0 6 * * *", "import_mapping_policy": {"mode": "auto_create"}, "import_backfill_through": "2026-01-01", "api_key": "sk-ant-admin-..." }'
# Run now / inspect historycurl -X POST http://localhost:5050/v1/admin/usage-import/providers/{provider_id}/run \ -H "Authorization: Bearer $TOKEN" -d '{}'curl -H "Authorization: Bearer $TOKEN" \ http://localhost:5050/v1/admin/usage-import/providers/{provider_id}/runsCredentials are encrypted at rest. Anthropic requires an Analytics API key with the read:analytics scope, provisioned by the claude.ai Primary Owner.
Budgets and alerts on imported usage
Section titled “Budgets and alerts on imported usage”Resource groups touched by an import — including the auto-created per-product groups — are evaluated against their configured dollar budgets after each run. Utilization at or over the warning threshold raises a normal usage alert, deduplicated per period. These alerts are notify-only: an imported request can’t be stopped retroactively, so hard_stop never applies on the observed plane.
