Creating Sub-Accounts
A sub-account is a new Tenant under your billing account. Each one is a fully isolated workspace with its own conversations, contacts, channels, campaigns, and settings. This is the building block for provisioning one workspace per end-customer.
Prerequisites
- The user behind your credential must be an owner of the billing account you're adding the tenant to. Only billing-account owners can create additional tenants under an existing billing account.
- Use a session or token for an account that already has a billing account.
- An API token needs the
tenants:createscope (*:*andtenants:*include it). API tokens created before 27 October 2026 keep working without it; to take the ability away from such a token, replace it with a new one. - An API token or OAuth app can only add workspaces to the billing account of the workspace it was created in.
- An OAuth app needs
tenants:createin its requested scopes, and the owner has to approve it on the consent screen. Wildcard grants such as*:*don't include it for OAuth apps. OAuth apps can add workspaces to their own billing account, but can never create a new billing account. - Embedded sessions (for example the HubSpot inbox embed) can never create workspaces.
Create a tenant
POST /api/v1/tenants
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the workspace (e.g. your customer's company name). |
billing_account_id | string | No | The billing account to attach the tenant to. Provide this to add the sub-account to your existing billing account. If omitted and you already have billing accounts, the request is rejected asking you to specify one. |
slug | string | No | URL-safe identifier. Auto-generated from name if omitted. |
company_email | string | No | Contact email for the workspace. |
pricing_model_id | string | No | Reserved: leave this unset. A new workspace always uses its billing account's plan and shares the account's included message pool. You can't choose a different plan or rate when you create a workspace. If you send this field, it must be your billing account's current plan id; that is accepted and has no effect. Any other value is rejected with 403 and detail.code pricing_model_not_allowed, and no workspace is created (see Errors). A workspace on its own negotiated plan is set up by the SendSeven team (see Workspaces on their own plan). |
support_email | string | No | Support email used by default widgets. Defaults to the owner's email. |
Other optional fields control workspace defaults (ai_features_enabled, multi_agent_mode, auto_summarize_on_close, auto_transcript_export_format, …) and can be left at their defaults.
curl
curl -X POST "https://api.sendseven.com/api/v1/tenants" \
-H "Authorization: Bearer <owner_token_or_session>" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"billing_account_id": "ba_your_billing_account",
"company_email": "[email protected]"
}'
Response (201 Created)
{
"id": "tenant_acme_123",
"name": "Acme Corp",
"slug": "acme-corp",
"billing_account_id": "ba_your_billing_account",
"pricing_model_id": null,
"is_trial": true,
"trial_ends_at": "2026-04-04T00:00:00Z",
"is_active": true,
"subscription_tier": "trial",
"multi_agent_mode": true,
"auto_summarize_on_close": "ask"
}
Keep the returned id — it's the tenant_id you'll pass as X-Tenant-ID to manage this sub-account from your parent token.
Errors
A pricing_model_id other than your billing account's current plan is rejected and no workspace is created:
{
"detail": {
"code": "pricing_model_not_allowed",
"message": "A new workspace always uses its billing account's plan. Leave pricing_model_id unset; plan changes go through billing."
}
}
Status 403. Branch on detail.code, as described in Error Handling.
A credential that isn't allowed to create workspaces is rejected before anything else is checked:
{
"detail": {
"code": "workspace_create_not_allowed",
"message": "This API key needs the tenants:create permission.",
"required_scopes": ["tenants:create"]
}
}
Status 403. Create a token with tenants:create, or reconnect your OAuth app with that scope.
A billing account that is scheduled for deletion can't take new workspaces, and no workspace is created:
{
"detail": {
"code": "billing_account_deletion_scheduled",
"message": "New workspaces can't be added to this billing account right now. Please contact support."
}
}
Status 403. If you cancelled your account and want to keep using it, undo the cancellation in the app first, or contact support.
List the billing accounts your user belongs to, then pass the one you own as billing_account_id. A user with no billing account yet must sign up first: creating a tenant does not create a billing account automatically.
After creating a sub-account
A freshly created tenant has no channels, contacts, or webhooks. From here you typically:
- Register webhooks into it so you receive its events — see Registering webhooks for a sub-account.
- Onboard a channel — either connect one via the API, or send the customer a channel connect link.
- Drive it from your parent token using
X-Tenant-ID— no separate login required.
What you cannot do
- You cannot attach a tenant to a billing account you don't own.
- You cannot pick a different plan or rate for a new tenant. It always uses the billing account's plan.
- You cannot move a tenant into a different billing account to cross the isolation boundary — billing accounts are hard isolation boundaries.
Next steps
- Cross-Account API Access — control the sub-account you just created from one token
- Channel Connect Links — let the customer connect their own channel
- Billing for Multiple Workspaces: the new workspace shares your plan, pool and invoice; read its usage per workspace