Billing Endpoints

The billing API manages API keys, subscriptions, usage metering, and pricing tiers. All endpoints are prefixed with /console/billing.

MethodPathDescription
POST/console/billing/keysCreate a new API key
GET/console/billing/keysList API keys for an organization
DELETE/console/billing/keys/{key_id}Revoke an API key
GET/console/billing/subscription/{org_id}Get subscription status
POST/console/billing/subscriptionUpdate subscription tier
GET/console/billing/usage/{org_id}Get usage data
GET/console/billing/pricingGet pricing tiers and limits
GET/console/billing/statsGet billing overview stats

Create API Key

Generate a new API key for an organization. The raw key is returned only once and must be stored securely. Keys use the format th_live_{secret}.

POST /console/billing/keys
{
  "org_id": "acme",
  "name": "Production Key",
  "start_trial": true
}

# Response:
{
  "api_key": "th_live_aBcDeFgH...",
  "key_id": "key_abc123",
  "key_prefix": "th_live_aBcDeFgH...",
  "org_id": "acme",
  "tier": "free",
  "name": "Production Key",
  "created_at": "2026-03-16T00:00:00+00:00",
  "trial_ends_at": "2026-03-30T00:00:00+00:00",
  "warning": "Store this API key securely — it cannot be retrieved again."
}

List API Keys

List all API keys for an organization. Keys are returned masked (prefix only).

GET /console/billing/keys?org_id=acme

# Response:
{
  "keys": [
    {
      "key_id": "key_abc123",
      "key_prefix": "th_live_aBcDeFgH...",
      "org_id": "acme",
      "tier": "pro",
      "name": "Production Key",
      "created_at": "2026-03-16T00:00:00+00:00",
      "last_used_at": "2026-03-16T12:30:00+00:00",
      "revoked": false,
      "trial_ends_at": null
    }
  ],
  "total": 1
}

Revoke API Key

Permanently revoke an API key. Revoked keys cannot be reactivated.

DELETE /console/billing/keys/{key_id}

# Response:
{
  "status": "revoked",
  "key_id": "key_abc123"
}

Get Subscription

Retrieve the current subscription status and tier limits for an organization. Returns free-tier defaults if no subscription exists.

GET /console/billing/subscription/{org_id}

# Response:
{
  "org_id": "acme",
  "tier": "pro",
  "status": "active",
  "limits": {
    "requests_per_day": 50000,
    "requests_per_minute": 500,
    "max_dids": 10000,
    "max_skills": 500
  },
  "subscription": {
    "stripe_subscription_id": "sub_abc123",
    "stripe_customer_id": "cus_xyz789",
    "current_period_start": "2026-03-01",
    "current_period_end": "2026-04-01",
    "cancel_at_period_end": false
  }
}

Update Subscription

Update an organization's subscription tier. Typically called by the Stripe webhook handler when a payment is confirmed.

POST /console/billing/subscription
{
  "org_id": "acme",
  "tier": "pro",
  "stripe_subscription_id": "sub_abc123",
  "stripe_customer_id": "cus_xyz789",
  "stripe_price_id": "price_def456"
}

# Response:
{
  "status": "updated",
  "org_id": "acme",
  "tier": "pro",
  "limits": {
    "requests_per_day": 50000,
    "requests_per_minute": 500,
    "max_dids": 10000,
    "max_skills": 500
  }
}

Get Usage

Retrieve usage data for an organization over a configurable window (default 30 days). Includes daily breakdowns and aggregate totals alongside current tier limits.

GET /console/billing/usage/{org_id}?days=30

# Response:
{
  "org_id": "acme",
  "tier": "pro",
  "limits": {
    "requests_per_day": 50000,
    "requests_per_minute": 500,
    "max_dids": 10000,
    "max_skills": 500
  },
  "totals": {
    "total_requests": 12450,
    "total_dids_created": 87,
    "total_skills_registered": 12
  },
  "daily_usage": [
    {
      "date": "2026-03-16",
      "request_count": 430,
      "dids_created": 3,
      "skills_registered": 1
    }
  ]
}

Get Pricing

Public endpoint returning all pricing tiers, their limits, and free trial duration. Used by the marketing site and console UI.

GET /console/billing/pricing

# Response:
{
  "free_trial_days": 14,
  "tiers": {
    "free": {
      "name": "Community",
      "price": "$0",
      "price_monthly": 0,
      "description": "For individual developers and open-source projects",
      "limits": { ... }
    },
    "pro": {
      "name": "Pro",
      "price": "$99/mo",
      "price_monthly": 99,
      "description": "For teams building production AI agent systems",
      "limits": { ... }
    },
    "enterprise": {
      "name": "Enterprise",
      "price": "Custom",
      "price_monthly": null,
      "description": "For organizations with advanced security and compliance needs",
      "limits": { ... }
    }
  }
}

Get Billing Stats

Returns an overview of API key statistics including total keys, active keys, and distribution by tier.

GET /console/billing/stats

# Response:
{
  "total_keys": 42,
  "active_keys": 38,
  "by_tier": {
    "free": 20,
    "pro": 15,
    "enterprise": 3
  }
}

Authentication

All billing endpoints require a valid API key passed via the X-API-Key header. Keys are validated using SHA-256 hash comparison and checked for revocation, expiration, and trial status. Expired trial keys are automatically downgraded to the free tier unless an active Stripe subscription exists.

Rate Limiting

Usage is enforced at two levels: per-minute sliding window and per-day counters. Limits vary by tier:

TierRequests/DayRequests/MinMax DIDsMax Skills
Community (Free)1,0006010010
Pro ($99/mo)50,00050010,000500
Enterprise (Custom)Unlimited5,000UnlimitedUnlimited