# Manage API Tiers

This guide explains how to check your organization's current plan tier, understand the enforced
limits, and initiate an upgrade via Stripe.

---

## Prerequisites

- A running AgentIdP instance
- A valid Bearer token with `organization_id` in its claims

---

## Check current tier status

`GET /api/v1/tiers/status`

Returns your organization's tier, the configured limits, and live usage counters for today.

```bash
curl -s "http://localhost:3000/api/v1/tiers/status" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

Response:

```json
{
  "tier": "free",
  "limits": {
    "maxAgents": 10,
    "maxCallsPerDay": 1000,
    "maxTokensPerDay": 1000
  },
  "usage": {
    "agentCount": 3,
    "callsToday": 142,
    "tokensToday": 87
  }
}
```

**Understanding the fields**:

| Field | Description |
|-------|-------------|
| `tier` | Current plan: `free`, `pro`, or `enterprise` |
| `limits.maxAgents` | Maximum active (non-decommissioned) agents allowed |
| `limits.maxCallsPerDay` | Maximum total API calls per calendar day (UTC) |
| `limits.maxTokensPerDay` | Maximum token issuances per calendar day (UTC) |
| `usage.agentCount` | Current number of active agents |
| `usage.callsToday` | API calls made so far today |
| `usage.tokensToday` | Tokens issued so far today |

**When limits are reached**: The relevant endpoint returns `403 FREE_TIER_LIMIT_EXCEEDED`.
Daily counters reset at midnight UTC. The agent count limit is a current count, not a daily
counter — decommissioning an agent immediately frees capacity.

---

## Tier comparison

| Limit | Free | Pro | Enterprise |
|-------|------|-----|------------|
| Max agents | 10 | 100 | Unlimited |
| Max API calls / day | 1,000 | 50,000 | Unlimited |
| Max token issuances / day | 1,000 | 50,000 | Unlimited |

---

## Upgrade your tier

`POST /api/v1/tiers/upgrade`

Creates a Stripe Checkout Session and returns a one-time URL. Complete the payment in the
browser to upgrade your organization's tier.

```bash
curl -s -X POST http://localhost:3000/api/v1/tiers/upgrade \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "target_tier": "pro" }' | jq .
```

Response:

```json
{
  "checkoutUrl": "https://checkout.stripe.com/pay/cs_live_a1b2c3d4e5f6..."
}
```

Open `checkoutUrl` in a browser to complete payment. After successful payment, Stripe sends a
webhook to AgentIdP which automatically upgrades your organization's tier.

**Constraints**:
- `target_tier` must be `pro` or `enterprise`
- `target_tier` must be higher than your current tier (you cannot downgrade via this endpoint)
- Attempting to upgrade to the current or a lower tier returns `400 VALIDATION_ERROR`

```bash
# Upgrade from free to pro
curl -s -X POST http://localhost:3000/api/v1/tiers/upgrade \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "target_tier": "pro" }' | jq .

# Upgrade from pro to enterprise
curl -s -X POST http://localhost:3000/api/v1/tiers/upgrade \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "target_tier": "enterprise" }' | jq .
```

---

## Common errors

### `400 VALIDATION_ERROR` — target_tier missing or invalid

```json
{
  "code": "VALIDATION_ERROR",
  "message": "target_tier must be one of: free, pro, enterprise.",
  "details": { "received": "premium" }
}
```

**Fix**: Use `"pro"` or `"enterprise"`.

### `400 TIER_UPGRADE_NOT_REQUIRED` — not an upgrade

**Fix**: You are already on this tier or a higher tier. Check `GET /api/v1/tiers/status` first.

### `401 UNAUTHORIZED` — token lacks organization_id

The tier endpoints require a token with an `organization_id` claim. Use a token issued by an
agent that was registered with `organization_id`. Tokens issued via the bootstrap method
(without an org) do not carry `organization_id` and will fail.
