# Managing Sub-Accounts

> Update credit limits, manage API keys, and monitor sub-account spending

> **Warning:**
> All endpoints under `/v1/sub-accounts` require a **main account** API key. A sub-account API key calling these endpoints receives `HTTP 403`. Sub-accounts can read their own balance via `GET /v1/balance`.

## List Sub-Accounts

```typescript
const { items, nextCursor } = await zavu.subAccounts.list({
  limit: 50,
});

for (const sub of items) {
  console.log(`${sub.name}: $${(sub.totalSpent / 100).toFixed(2)} spent`);
}
```

```bash
curl https://api.zavu.dev/v1/sub-accounts?limit=50 \
  -H "Authorization: Bearer zv_live_xxx"
```

## Update a Sub-Account

Update the name, credit limit, external ID, metadata, or status:

```typescript
const { subAccount } = await zavu.subAccounts.update("jx7abc123def456", {
  creditLimit: 200000, // Increase to $2,000
  metadata: { plan: "enterprise-plus" },
});
```

```bash
curl -X PATCH https://api.zavu.dev/v1/sub-accounts/jx7abc123def456 \
  -H "Authorization: Bearer zv_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "creditLimit": 200000,
    "metadata": { "plan": "enterprise-plus" }
  }'
```

### Updatable Fields

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Sub-account display name |
| `externalId` | string | Your reference ID |
| `creditLimit` | integer \| null | Spending cap in cents. Set to `null` or `0` to remove |
| `metadata` | object | Arbitrary key-value data |
| `status` | string | `"active"` or `"inactive"` |

## Monitor Spending

### Check a Sub-Account's Balance

```typescript
const balance = await zavu.subAccounts.getBalance("jx7abc123def456");

console.log(`Team balance: $${(balance.balance / 100).toFixed(2)}`);
console.log(`Sub-account spent: $${(balance.totalSpent / 100).toFixed(2)}`);
console.log(`Credit limit: $${(balance.creditLimit / 100).toFixed(2)}`);
```

```bash
curl https://api.zavu.dev/v1/sub-accounts/jx7abc123def456/balance \
  -H "Authorization: Bearer zv_live_xxx"
```

Response:

```json
{
  "balance": 150000,
  "currency": "usd",
  "creditLimit": 100000,
  "totalSpent": 45000,
  "isSubAccount": true
}
```

### Check Balance from the Sub-Account's Perspective

When a sub-account uses its own API key to call `GET /v1/balance`, it sees the team balance plus its own spending data:

```bash
curl https://api.zavu.dev/v1/balance \
  -H "Authorization: Bearer zv_live_sub_xxxxxxxxxxxx"
```

```json
{
  "balance": 150000,
  "currency": "usd",
  "creditLimit": 100000,
  "totalSpent": 45000,
  "isSubAccount": true
}
```

## Manage API Keys

Each sub-account can have multiple API keys. Create additional keys or revoke compromised ones.

### List API Keys

```typescript
const { items } = await zavu.subAccounts.apiKeys.list("jx7abc123def456");

for (const key of items) {
  console.log(`${key.name} (${key.keyPrefix}...): ${key.environment}`);
}
```

```bash
curl https://api.zavu.dev/v1/sub-accounts/jx7abc123def456/api-keys \
  -H "Authorization: Bearer zv_live_xxx"
```

### Create an API Key

```typescript
const { apiKey } = await zavu.subAccounts.apiKeys.create("jx7abc123def456", {
  name: "Production Key",
  environment: "live",
});

// Save this — only shown once
console.log("New key:", apiKey.key);
```

```bash
curl -X POST https://api.zavu.dev/v1/sub-accounts/jx7abc123def456/api-keys \
  -H "Authorization: Bearer zv_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production Key", "environment": "live"}'
```

> **Warning:**
> The full API key is only returned once in the creation response. Store it securely.

### Revoke an API Key

```typescript
// The key id comes first; the sub-account it belongs to is a param.
await zavu.subAccounts.apiKeys.revoke("key_id_here", { id: "jx7abc123def456" });
```

```bash
curl -X DELETE https://api.zavu.dev/v1/sub-accounts/jx7abc123def456/api-keys/key_id_here \
  -H "Authorization: Bearer zv_live_xxx"
```

Revoked keys stop working immediately.

## Suspend a Sub-Account

Set a sub-account's status to `inactive` to temporarily block all messaging without revoking API keys:

```bash
curl -X PATCH https://api.zavu.dev/v1/sub-accounts/jx7abc123def456 \
  -H "Authorization: Bearer zv_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"status": "inactive"}'
```

Re-activate later by setting `status` back to `"active"`.

## Next Steps

  - [Deletion & Deactivation](https://www.zavu.dev/docs/guides/sub-accounts/deletion): Permanently deactivate sub-accounts
  - [Sub-Accounts Concept](https://www.zavu.dev/docs/concepts/sub-accounts): Understand the billing model and architecture
