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

Validating the Management Key

Lesson 13 of 14 Updated July 29, 2026 Developer
On this page
  1. Verify the integrity of your keys
  2. Validation endpoint
  3. Integrating into your scripts
  4. Auditing inference keys
  5. Key security checklist
  6. Principle of separation of duties
  7. Key takeaways

Verify the integrity of your keys

Management key validation is your API infrastructure’s first line of defense. Before any critical operation—deployment, rotation, billing changes—verify that your key is valid and its permissions are correct.

Validation endpoint

GET /auth/management-keys/validation
curl "https://management-api.x.ai/auth/management-keys/validation" \
  -H "Authorization: Bearer $MANAGEMENT_API_KEY"

The response confirms the key is active and returns the team, permissions, and associated dates. Do not overlook the expiration date: this is the only information that lets you anticipate an outage instead of suffering it, since an expired key does not warn you—it simply returns 401 on the first call that follows.

Error cases

  • 401 Unauthorized: The key is invalid, expired, or has been deleted
  • 403 Forbidden: The key is valid but lacks the necessary permissions for the requested operation

Integrating into your scripts

Startup verification

Validating at startup moves failure to where it costs the least. Without this check, an invalid key manifests on the first useful call—that is, in the middle of processing, sometimes after several steps have already executed. With it, the script stops in three seconds with a message that names the cause.

import requests
import sys

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

def validate_management_key():
    """Checks that the management key is valid."""
    try:
        response = requests.get(
            f"{MANAGEMENT_API}/auth/management-keys/validation",
            headers={"Authorization": f"Bearer {MGMT_KEY}"},
            timeout=10
        )
        if response.status_code == 200:
            print("Management key valid")
            return True
        elif response.status_code == 401:
            print("ERROR: Management key invalid or expired")
            return False
        else:
            print(f"ERROR: Unexpected status {response.status_code}")
            return False
    except requests.exceptions.RequestException as e:
        print(f"CONNECTION ERROR: {e}")
        return False

if not validate_management_key():
    sys.exit(1)

Periodic healthcheck

The periodic healthcheck covers what startup validation misses: long-running services, started weeks ago, whose key may expire or be revoked along the way. An hourly check is enough—the endpoint is lightweight and consumes no inference tokens.

#!/bin/bash
# healthcheck-xai.sh — run every hour via cron

STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  "https://management-api.x.ai/auth/management-keys/validation" \
  -H "Authorization: Bearer $MANAGEMENT_API_KEY")

if [ "$STATUS" != "200" ]; then
    echo "ALERT: xAI management key invalid (HTTP $STATUS)"
    # Send an alert (PagerDuty, Slack, email)
fi

Auditing inference keys

Periodic auditing answers three questions no alert will ask for you: which keys still carry a wildcard, which have no rate limits, and which haven’t been used in months. The first two are risks, the third an opportunity to clean up—and all three are handled in one pass.

import requests
from datetime import datetime

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

def audit_api_keys():
    """Audits all API keys for the team."""
    response = requests.get(
        f"{MANAGEMENT_API}/auth/teams/{TEAM_ID}/api-keys",
        headers={"Authorization": f"Bearer {MGMT_KEY}"}
    )
    keys = response.json().get("apiKeys", [])

    print(f"=== API Key Audit — {datetime.now().strftime('%d/%m/%Y %H:%M')} ===")
    print(f"Total number of keys: {len(keys)}")

    for key in keys:
        name = key.get("name", "Unnamed")
        acls = key.get("acls", [])
        expire = key.get("expireTime", "Never")
        created = key.get("createdAt", "N/A")

        # Alerts
        warnings = []

        # Key with wildcard access
        if "api-key:endpoint:*" in acls and "api-key:model:*" in acls:
            warnings.append("TOTAL ACCESS (wildcards)")

        # Key without expiration
        if expire == "Never" or not expire:
            warnings.append("NO EXPIRATION")

        # Key without rate limits
        if not key.get("qps") and not key.get("qpm"):
            warnings.append("NO RATE LIMITS")

        status = " | ".join(warnings) if warnings else "OK"
        print(f"  [{name}] ACLs: {len(acls)} | Expire: {expire} | {status}")

audit_api_keys()

Key security checklist

Management keys

Management keys control everything else—their compromise grants access to create, modify, and delete all inference keys. They therefore demand the strictest handling: exclusive storage in a vault, never in plaintext in code or versioned configuration; access limited to infrastructure administrators only, not application developers; and regular validation via GET /auth/management-keys/validation, ideally automated as a healthcheck—an expired management key discovered when you urgently need it is the worst operational scenario.

Inference keys (API keys)

For inference keys, the guiding principle is isolation: each application receives its own key, never a key shared between services—otherwise rotating a compromised key breaks all services at once, and analytics no longer allow attributing consumption. Each key carries restrictive ACLs calibrated to its actual usage (no wildcards in production), rate limits sized for expected traffic, and an expiration date when usage is temporary—a POC meant to last two weeks does not need an eternal key. Regular auditing via the script above closes the loop: it reveals forgotten, over-privileged, or expiring keys before they become problems.

Principle of separation of duties

Maintain a clear separation between keys:

TypeUsageWho has access
Management keyAdministration, billing, analyticsInfrastructure admins
Prod keyAPI calls in productionProduction application
Staging keyPre-production testingDevelopment team
Dev keyLocal developmentIndividual developer

Each key has a defined scope. If a developer leaves the team, only their dev key is deleted—the others remain intact.

Key takeaways

  • GET /auth/management-keys/validation checks the validity of your management key
  • Integrate validation into your script startup and monitoring
  • Regularly audit all keys to detect overly broad access
  • Separate keys by environment and responsibility
  • Alert immediately on an invalid key (expired or deleted)