Skip to main content
Sub Accounts let a parent account create and manage isolated child accounts under a single billing relationship. A sub account is a full, regular AhaSend account in its own right, with the same feature set and isolation as any standalone account. It simply lives and is billed under the parent’s umbrella. Each sub account has its own domains, members, suppressions, and sending activity, while the parent keeps administrative control and one consolidated bill. This model is built for platforms and agencies that send on behalf of many customers: provision a sub account per customer, and let it use the full feature set of AhaSend in complete isolation, all billed back to the parent.
Platform Partner feature: Sub Accounts is part of our Platform Partner capabilities and is currently in early access. Contact us to enable it on your account.

Why Use Sub Accounts?

Full Sending Isolation

Each sub account has its own domains, suppressions, reputation context, and sending activity. One customer’s sending never affects another’s.

Consolidated Billing

All sub-account usage rolls up to the parent account as a single invoice, with per-sub-account cost visibility.

The Full API, Per Customer

A sub-account API key authenticates as the child and can use every regular v2 endpoint: domains, messages, webhooks, routes, and more.

Central Control

Create, update, suspend, unsuspend, and soft-delete sub accounts from the parent, view per-sub-account usage, and set an optional monthly sending cap on each one.

How It Works

Sub accounts follow a parent and child model:
  • All sub-account management endpoints are addressed under the parent account ID, for example /v2/accounts/{account_id}/sub-accounts. The {account_id} is always the parent.
  • Each sub account has its own child account ID (sub_account_id). Once a sub account has its own API key, that key uses the child account ID on ordinary routes, for example /v2/accounts/{sub_account_id}/domains.
  • Sub-account API keys can only be created and managed with parent credentials that hold the right sub-account-api-keys:* scope. A sub account cannot manage its own nested API keys.
From the parent account you stay in control end to end: manage the full lifecycle (create and update sub accounts, suspend, unsuspend, and soft-delete), pull per-sub-account statistics with Get Sub-Account Usage, and, because the parent provisions the sub account’s API keys, act on the sub account’s behalf to manage anything inside it (domains, webhooks, sending, and more).
Each sub account has an optional monthly_credit field, a monthly sending cap where 0 means no cap.

When to Use Sub Accounts

Sub Accounts are ideal when you send on behalf of distinct end customers and need each kept separate:
  • SaaS platforms giving each of their customers their own sending setup and domains.
  • Agencies managing email for multiple clients under one account and one bill.
  • Resellers who want isolation and per-customer usage reporting without running multiple top-level accounts.
  • Cloud and hosting providers offering transactional email as part of their platform, with a separate, isolated sending account provisioned per tenant.
  • Managed service providers (MSPs) running transactional email on behalf of the clients they manage, keeping each client’s sending, domains, and reputation cleanly separated and individually reportable.
For a single business sending its own transactional mail, a regular account with multiple domains is simpler and is the better fit.

Provisioning a Sub Account

You provision a sub account from the parent in two API calls: create the sub account, then create its bootstrap API key. After that, the child key and child account ID are all you need to run that customer’s email.
1

Create the sub account

With parent credentials, call POST /v2/accounts/{account_id}/sub-accounts using the parent account ID and a unique Idempotency-Key. The response id is the new sub_account_id.
2

Create a bootstrap API key

Call POST /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/api-keys with the parent account ID, the new sub_account_id, and a different unique Idempotency-Key. The parent credential must hold the sub-account-api-keys:write scope. The 201 response returns a one-time secret_key.
3

Use the child key for that customer

Authenticate with the child secret_key and use the sub_account_id as the account_id on ordinary v2 routes. The child key acts as the sub account and can use the full feature set in complete isolation.
The secret_key is shown only once, on creation, and is omitted from all later responses (exact idempotent replays within 5 minutes return the same value). Store it securely the moment you receive it.

Example: Provision, Verify a Domain, and Send

The flow below runs end to end: it provisions a sub account with the parent key, then switches to the child key to verify a sending domain and send a message. It uses jq to capture the IDs and secret returned along the way.
PARENT_ACCOUNT_ID="your-parent-account-id"
PARENT_SECRET="aha-sk-parent-64-character-key"

# Create the sub account and capture its account ID
CHILD_ACCOUNT_ID="$(curl -sS -X POST "https://api.ahasend.com/v2/accounts/${PARENT_ACCOUNT_ID}/sub-accounts" -H "Authorization: Bearer ${PARENT_SECRET}" -H "Content-Type: application/json" -H "Idempotency-Key: subacct-20240101-acme" -d '{"name":"Acme Subsidiary","website":"acme.example.com"}' | jq -r '.id')"

# Create its bootstrap API key and capture the one-time secret (shown only once)
CHILD_SECRET="$(curl -sS -X POST "https://api.ahasend.com/v2/accounts/${PARENT_ACCOUNT_ID}/sub-accounts/${CHILD_ACCOUNT_ID}/api-keys" -H "Authorization: Bearer ${PARENT_SECRET}" -H "Content-Type: application/json" -H "Idempotency-Key: child-bootstrap-key-20240101-acme" -d '{"label":"Bootstrap key","scopes":["domains:read","domains:write","messages:send:all"]}' | jq -r '.secret_key')"
Step 1 uses the parent credentials. Steps 2 and 3 use the child account ID and the child secret. Parent credentials are only needed to manage the sub account itself and its API keys.
See Create Domain, Check Domain DNS, and Create Message for the full reference.

Sub Account Status

Each sub account reports a status:
StatusMeaning
activeThe sub account is operating normally.
suspendedThe sub account was suspended directly via the suspend endpoint.
parent-suspendedThe sub account is suspended because its parent account is suspended.
deletedThe sub account has been soft-deleted.

Usage and Billing

The usage endpoint returns current billing-period message volume and the proportional cost allocated to the parent and each active sub account:
  • Proportional allocation: each sub account’s allocated_cost is a share of the parent’s pooled invoice for the period, distributed by message volume.
  • Not standalone pricing: allocated_cost reflects a proportional share of the parent’s pooled invoice, not what the sub account would pay on its own plan.
  • Removed sub accounts: usage from sub accounts soft-deleted during the period is still billed to the parent and reported in a separate aggregate.

Scopes

Sub-account operations require dedicated scopes, all granted to parent-account API keys:
ScopeGrants
sub-accounts:readList and read sub accounts
sub-accounts:writeCreate and update sub accounts
sub-accounts:deleteSoft-delete sub accounts
sub-accounts:suspendSuspend and unsuspend sub accounts
sub-accounts:usageRead per-sub-account usage and allocated cost
sub-account-api-keys:readList and read sub-account API keys
sub-account-api-keys:writeCreate and update sub-account API keys
sub-account-api-keys:deleteDelete sub-account API keys

Next Steps

Sub Accounts API Overview

The full API model for managing sub accounts and their keys

Create a Sub Account

Provision a new isolated child account under your parent account

Create a Sub-Account API Key

Issue a bootstrap key that authenticates as the child account

Sub-Account Usage

Track per-sub-account volume and allocated cost for the billing period