Creating Sub-Accounts
Provision sub-accounts for your customers with API keys and spending controls
Create a Sub-Account
import Zavu from "@zavudev/sdk";
const zavu = new Zavu({ apiKey: "zv_live_xxx" });
const { subAccount } = await zavu.subAccounts.create({
name: "Client ABC",
externalId: "client_123",
creditLimit: 100000, // $1,000.00 in cents
metadata: {
plan: "enterprise",
region: "us-east",
},
});
// Save this — only shown once
console.log("API Key:", subAccount.apiKey);
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the sub-account (max 200 characters) |
externalId | string | No | Your own reference ID for tracking |
creditLimit | integer | No | Spending cap in cents. 0 or omitted = no limit |
metadata | object | No | Arbitrary key-value pairs for your own use |
Response
The API key is only returned in the creation response. Store it securely.
JSON{ "subAccount": { "id": "jx7abc123def456", "name": "Client ABC", "externalId": "client_123", "status": "active", "totalSpent": 0, "creditLimit": 100000, "metadata": { "plan": "enterprise", "region": "us-east" }, "apiKey": "zv_live_sub_xxxxxxxxxxxx", "createdAt": "2025-01-15T10:00:00Z" } }
Credit Limits
Credit limits act as a spending cap in cents. When a sub-account's totalSpent reaches the creditLimit, all messaging is blocked.
| Credit Limit | Behavior |
|---|---|
Omitted or 0 | No spending cap — uses full team balance |
100000 | Blocks messaging after $1,000.00 spent |
500 | Blocks messaging after $5.00 spent |
External IDs
The externalId field lets you map sub-accounts to your own system:
TypeScript// Create with your internal customer ID const { subAccount } = await zavu.subAccounts.create({ name: "Acme Corp", externalId: "cust_abc123", // Your CRM customer ID });
An externalId is unique within your team: creating or updating a sub-account with one another sub-account already has returns 409 conflict.
This is useful for:
- Mapping sub-accounts to your CRM records
- Billing reconciliation
- Audit trails
Metadata
Store arbitrary key-value data with the sub-account:
TypeScriptconst { subAccount } = await zavu.subAccounts.create({ name: "Client ABC", metadata: { plan: "enterprise", billingEmail: "billing@client-abc.com", salesRep: "jane@yourcompany.com", }, });
One Main Account Rule
Each team is limited to one main account. All additional projects must be sub-accounts.
CodeTeam "My Company" ├── Main Account ← created automatically when the team is created ├── Sub-Account: Client A ✓ ├── Sub-Account: Client B ✓ └── Main Account ✗ (rejected — use a sub-account or create a new team)
If you try to create a second main account, the API returns an error:
JSON{ "code": "invalid_request", "message": "Team already has a main account. Create a sub-account instead, or create a new team for another main account." }