Skip to main content
Lesson 10 of 14 · Management API: Keys & Billing

Advanced Consumption Reports

Lesson 10 of 14 Updated July 29, 2026 Developer
On this page
  1. Building consumption reports
  2. Comparative monthly report
  3. Anomaly detection
  4. Breakdown by model
  5. Automated weekly report
  6. Granularity and performance
  7. Key takeaways

Building consumption reports

Consumption data that no one looks at is useless. A report is only useful if it answers a question you actually ask, and there are only three: is it increasing, did something abnormal happen, and where is the money going.

The next three sections address these questions in that order. Each produces a number you can act on—not just another chart.

Comparative monthly report

Consumption only makes sense in comparison. $400 in a month is neither good nor bad in absolute terms: what matters is whether it follows a $200 month or a $600 month. Always contextualize changes with what you know about activity—a 40% increase after launching a feature is expected, the same increase with nothing new warrants opening the next section.

import requests
import json

MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."

def get_monthly_usage(year, month):
    """Retrieves total consumption for a given month."""
    next_month = month + 1 if month < 12 else 1
    next_year = year if month < 12 else year + 1

    response = requests.post(
        f"{MANAGEMENT_API}/v1/billing/teams/{TEAM_ID}/usage",
        headers={
            "Authorization": f"Bearer {MGMT_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "analyticsRequest": {
                "timeRange": {
                    "startTime": f"{year}-{month:02d}-01 00:00:00",
                    "endTime": f"{next_year}-{next_month:02d}-01 00:00:00",
                    "timezone": "Europe/Paris"
                },
                "timeUnit": "MONTH",
                "values": [
                    {"name": "tokens", "aggregation": "SUM"},
                    {"name": "requests", "aggregation": "COUNT"}
                ],
                "groupBy": ["model"]
            }
        }
    )
    return response.json()

# Compare March and April 2026
march = get_monthly_usage(2026, 3)
april = get_monthly_usage(2026, 4)

print("=== Comparative Report March vs April 2026 ===")
print(json.dumps(march, indent=2))
print(json.dumps(april, indent=2))

Anomaly detection

Standard deviation defines “abnormal” here without needing to set an arbitrary threshold: a day beyond two standard deviations from your average falls outside the usual pattern, regardless of your volume. This is the method that adapts automatically as your activity grows, where a dollar threshold becomes obsolete the following month.

import requests
import statistics

MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."

# Retrieve daily consumption for the month
response = requests.post(
    f"{MANAGEMENT_API}/v1/billing/teams/{TEAM_ID}/usage",
    headers={
        "Authorization": f"Bearer {MGMT_KEY}",
        "Content-Type": "application/json"
    },
    json={
        "analyticsRequest": {
            "timeRange": {
                "startTime": "2026-03-01 00:00:00",
                "endTime": "2026-04-01 00:00:00",
                "timezone": "Europe/Paris"
            },
            "timeUnit": "DAY",
            "values": [{"name": "tokens", "aggregation": "SUM"}]
        }
    }
)

data = response.json()
daily_values = [point.get("value", 0) for point in data.get("dataPoints", [])]

if daily_values:
    mean = statistics.mean(daily_values)
    stdev = statistics.stdev(daily_values) if len(daily_values) > 1 else 0
    threshold = mean + 2 * stdev  # Threshold at 2 standard deviations

    for i, val in enumerate(daily_values):
        if val > threshold:
            print(f"Day {i+1}: {val} tokens (anomaly, threshold = {threshold:.0f})")

Breakdown by model

This is the report that pays off the most, because it points to concrete action. Total cost doesn’t tell you what to do; breakdown by model does—it reveals simple tasks routed to the most expensive model, which are the easiest savings to realize on an API bill.

curl -X POST "https://management-api.x.ai/v1/billing/teams/$TEAM_ID/usage" \
  -H "Authorization: Bearer $MANAGEMENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "analyticsRequest": {
      "timeRange": {
        "startTime": "2026-03-01 00:00:00",
        "endTime": "2026-04-01 00:00:00",
        "timezone": "UTC"
      },
      "timeUnit": "MONTH",
      "values": [
        {"name": "tokens", "aggregation": "SUM"},
        {"name": "cost", "aggregation": "SUM"}
      ],
      "groupBy": ["model"]
    }
  }'

This analysis can reveal optimization opportunities: if a large portion of your requests use grok-4.20-0309-reasoning for simple tasks, switching to grok-4.3 could significantly reduce costs.

Automated weekly report

Automatic delivery changes the nature of the exercise: a report you have to fetch is only consulted after the incident, a report that arrives is read beforehand. Weekly is the right cadence for API consumption—frequent enough to catch drift before the bill, spaced enough that you keep opening it.

import requests
from datetime import datetime, timedelta

MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."

# Previous week
end = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
start = end - timedelta(days=7)

response = requests.post(
    f"{MANAGEMENT_API}/v1/billing/teams/{TEAM_ID}/usage",
    headers={
        "Authorization": f"Bearer {MGMT_KEY}",
        "Content-Type": "application/json"
    },
    json={
        "analyticsRequest": {
            "timeRange": {
                "startTime": start.strftime("%Y-%m-%d %H:%M:%S"),
                "endTime": end.strftime("%Y-%m-%d %H:%M:%S"),
                "timezone": "Europe/Paris"
            },
            "timeUnit": "DAY",
            "values": [
                {"name": "tokens", "aggregation": "SUM"},
                {"name": "requests", "aggregation": "COUNT"}
            ],
            "groupBy": ["model"]
        }
    }
)

report = response.json()
print(f"=== Weekly Report {start.date()} → {end.date()} ===")

# Format report for email/Slack
# ... send via your preferred notification tool

Granularity and performance

Choosing the right granularity

Use caseRecommended granularity
Monthly reportMONTH
Daily trackingDAY
Spike analysisHOUR or QUARTER_HOUR
Real-time debugMINUTE
Detailed incident analysisSECOND

The finer the granularity, the larger the amount of data returned: over a month, SECOND granularity produces millions of points, with corresponding response time and memory consumption. The rule of thumb is to choose granularity based on the duration of what you’re looking for—a few-minute spike is invisible at MONTH granularity, and drowned in noise at SECOND granularity.

Key takeaways

  • Combine SUM (total), COUNT (count), and groupBy: ["model"] for complete reports
  • Anomaly detection with standard deviation identifies overconsumption days
  • Breakdown by model reveals cost optimization opportunities
  • Adapt temporal granularity to the use case: MONTH for reports, HOUR for debug
  • Automate weekly reports to keep an eye on consumption