Manage White Label Teams with API and MCP
Invite clients, control domain access, suspend or restore members, and review White Label activity through scoped REST endpoints and MCP tools.
Article details
Type, difficulty, plans, and last updated info.
▼
Article details
Type, difficulty, plans, and last updated info.
- Type
- Reference
- Difficulty
- Intermediate
- Plans
- Pro · Agency · + White Label add-on
- Last updated
- Oct 15, 2026
White Label accounts can be managed without switching back to the dashboard. The REST API and MCP server cover the account's setup status, clients and team members, roles, domain access, invitations, suspensions, removals, restores, client storage limits, and activity history. Branding is covered by the same White Label toolset and its own branding guide.
The important boundary is simple: a connection can never hand out more access than the person behind it already has. A domain-limited manager cannot invite someone to unrelated domains, and a custom role cannot grant permissions the caller does not hold.
What is available
The complete MCP catalog now contains 284 tools over stdio and up to 283 tools over hosted HTTP. White Label contributes 23 tools: seven for branding, 13 for account, member, and activity management, and three for client storage limits.
These tools are not loaded for everybody. TrekMail evaluates the account's live White Label entitlement, the person's current membership, the token or OAuth grant, any domain constraint, the selected toolsets, and local safety settings before building tools/list. A connection without White Label access does not receive the schemas at all.
Entitlement states
| State | Owner | Delegated members | Writes |
|---|---|---|---|
| Active | Full access allowed by scopes | Access allowed by scopes and membership | Available |
| Cancellation grace | Read-only recovery access | White Label access removed | Blocked |
| Unavailable | No White Label API or MCP access | No White Label API or MCP access | Blocked |
With White Label read access, call GET /api/v1/white-label or the get_white_label tool to distinguish active from read-only grace, and to see setup progress and the grace deadline. An unavailable account cannot call that endpoint: when a stored credential still names a White Label scope that the account can no longer use, the API returns scope_blocked_by_entitlement and explains where to reactivate it.
Scopes
| Scope | What it allows |
|---|---|
branding:read |
Read brand settings, assets, hosts, DNS records, and setup status |
branding:write |
Change branding, assets, previews, hosts, and DNS checks |
members:read |
Read clients, team members, roles, domain access, client storage limits, and the access catalog |
members:write |
Invite people, update, suspend, resume, remove, or restore access, and set client storage limits |
activity:read |
Read White Label account activity and member sign-ins |
The member activity endpoint needs both activity:read and members:read, because its response contains a member record as well as activity. The hosted OAuth connection uses the tools:white_label selector to request this tool family; the effective REST scopes are still capped by the account and membership.
For a self-hosted MCP server, add white_label to TREKMAIL_TOOLSETS when you use a toolset allow-list. Write tools also respect the local safety gates described below.
REST endpoints
All paths are under https://trekmail.net/api/v1.
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET |
/white-label |
branding:read |
Read entitlement, default brand, setup progress, and reachable domain status |
GET |
/white-label/access-catalog |
members:read |
Read roles, permission groups, grantable permissions, and reachable domains |
GET |
/white-label/members |
members:read |
List members and invitations, with search and status filters |
POST |
/white-label/members |
members:write |
Invite a client or teammate |
GET |
/white-label/members/{id} |
members:read |
Read one member and its allowed next operations |
PATCH |
/white-label/members/{id} |
members:write |
Change role, domain access, custom permissions, or note |
POST |
/white-label/members/{id}:suspend |
members:write |
Stop access immediately and revoke the member's keys |
POST |
/white-label/members/{id}:resume |
members:write |
Resume a suspended membership |
POST |
/white-label/members/{id}:resend-invitation |
members:write |
Replace a pending invitation and send a fresh one |
DELETE |
/white-label/members/{id} |
members:write |
Remove access and revoke the member's keys |
POST |
/white-label/members/{id}:restore |
members:write |
Restore a removed membership without reviving old keys |
GET |
/white-label/activity |
activity:read |
Read account activity, optionally filtered by action or member |
GET |
/white-label/members/{id}/activity |
activity:read + members:read |
Read one member's actions and recent sign-ins |
GET |
/white-label/client-limits |
members:read |
List client storage limits with what is reserved, shared, and used |
POST |
/white-label/client-limits |
members:write |
Give domains a storage limit, or change the one they already share |
GET |
/white-label/client-limits/{id} |
members:read |
Read one client storage limit |
PATCH |
/white-label/client-limits/{id} |
members:write |
Change a limit's size, its full domain set, or both |
DELETE |
/white-label/client-limits/{id} |
members:write |
Remove a limit; its domains go back to the account's storage |
Every write in this table requires an Idempotency-Key header. Repeating the same request with the same key returns the original safe result; one-time secrets in a replay, such as an invitation token, are redacted. Reusing a key with a different body returns idempotency_mismatch.
Read the access catalog first
Do not hard-code role permissions into an integration. Call the access catalog before an invitation or access change. Its grantable flags reflect the caller's current membership and can change when the owner adjusts that membership.
The roles currently offered for new invitations are:
client— runs the assigned domains and mailboxes without seeing the reseller's private relationship with TrekMail.webmail_only— appears in the team list but receives no dashboard permissions.domain_admin— manages assigned domains and their DNS, not mailboxes.mailbox_operator— manages mailboxes inside assigned domains, not the domains themselves.read_only— can inspect the permitted account surface without changing it.custom— receives only the permissions listed inpermissions.
Some roles require explicit domain_ids; others can use all_domains. The access catalog tells you which rule applies. If the caller tries to grant a broader role, permission, or domain set, TrekMail returns scope_blocked_by_membership instead of silently narrowing the invitation.
Invite a client
curl -s -X POST "https://trekmail.net/api/v1/white-label/members" \
-H "Authorization: Bearer tm_live_your_token" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invite-northwind-admin-20260904" \
-d '{
"email": "admin@northwind.example",
"role": "client",
"all_domains": false,
"domain_ids": [123, 124],
"note": "Northwind primary contact"
}'
The response includes the member, whether email delivery succeeded, and a one-time invitation URL. A delivery problem does not erase the invitation: the owner can copy the URL or resend it later.
For a custom role, read grantable_permissions from the access catalog and send the selected values in permissions. At least one permission is required.
Follow the member state
Every member response includes allowed_operations. Use that list instead of guessing:
- A pending invitation can be updated, suspended, resent, or removed.
- An active member can be updated, suspended, or removed.
- A suspended member can be updated, resumed, or removed.
- A removed member can be restored.
- The owner row is visible for context but cannot be changed through these endpoints.
The list is also filtered for the current caller. It is empty for a read-only connection, for the caller's own membership, and for members whose permissions are broader than the caller may manage.
Callers cannot remove or suspend themselves. Delegated callers also cannot manage a member whose access is broader than their own. Invalid transitions return membership_state_conflict with a hint to read the member again.
Suspending or removing someone revokes the API and mailbox keys created under that membership. Resuming or restoring the membership never brings those old keys back; the person must reconnect or create new credentials.
Activity and privacy boundaries
GET /white-label/activity returns invitations, role and domain changes, suspensions, removals, restores, and related security actions. Filter with action, member_id, and per_page.
GET /white-label/members/{id}/activity combines that member's account actions with recent sign-ins, including time, IP address, approximate location, browser, operating system, and device type. This route deliberately requires both read scopes. Domain-constrained callers can only request members that fall completely inside their domain boundary; an inaccessible member is returned as 404, so the endpoint does not reveal that another tenant or client exists.
Client storage limits
A client storage limit gives a client's domains one amount of space, in MB, for their mailboxes and Drive. See Give each client their own storage limit for how it works in the dashboard. A limit whose domains nobody on the team has, for example one created here before the client is invited, appears on the Team & clients page under Storage limits without a client.
- Reading takes
members:read. A caller confined to some domains sees only the limits whose domains are all its own. Another client's limit, or one that also covers a domain outside its reach, is left out of the list and answers404, like an id that does not exist. - Changing takes
members:writeand a caller that reaches every domain of the account. A member confined to some domains gets403 scope_blocked_by_membership; a key confined to some domains gets403 token_resource_constrained. POSTfollows the Team page: domains without a limit get a new one (201); domains that already share one limit change it, and the given domains without a limit join it (200).PATCHtakesstorage_limit_mb,domain_ids, or both.domain_idsreplaces the whole set, and domains left out go back to the account's storage.- Each limit returns
storage_limit_mb,domain_ids,allocated_mb(fixed mailbox sizes),pending_invites_mb(fixed sizes of open invitations),pool_mb(what mailboxes on shared storage share),used_bytes, andmember_ids.
Every member record carries client_limit: the one limit all of the member's domains are under, as id, storage_limit_mb, allocated_mb and used_bytes, or null. For a caller confined to some domains it is also null when that limit covers a domain outside the caller's reach.
A mailbox's own size is set with PATCH /mailboxes/{id}/storage (mailboxes:write), or the set_mailbox_storage tool, described in the API overview.
MCP tools
| Tool | Gate | Purpose |
|---|---|---|
get_white_label |
Read | Entitlement, brand, setup progress, and domains |
get_white_label_access_catalog |
Read | Roles, permissions, and domains the caller may grant |
list_white_label_members |
Read | Search or filter clients, members, and invitations |
get_white_label_member |
Read | Read one member and allowed next operations |
invite_white_label_member |
Sending | Create and email an invitation |
update_white_label_member |
Destructive | Change role, domains, permissions, or note |
suspend_white_label_member |
Destructive | Stop access and revoke live keys |
resume_white_label_member |
Destructive | Resume a suspended membership |
resend_white_label_invitation |
Sending | Replace and email a pending invitation |
remove_white_label_member |
Destructive + confirmation | Remove access and revoke live keys |
restore_white_label_member |
Destructive | Restore a removed membership |
list_white_label_activity |
Read | Read account activity |
get_white_label_member_activity |
Read | Read one member's actions and sign-ins |
list_client_limits |
Read | List client storage limits and their usage |
set_client_limit |
Destructive | Give domains a limit, change it, or replace its domain set |
remove_client_limit |
Destructive + confirmation | Remove a limit; its domains go back to the account's storage |
Invitation tools require TREKMAIL_ALLOW_SENDING=true on self-hosted stdio MCP. Access-changing tools and the client storage limit tools require TREKMAIL_ALLOW_DESTRUCTIVE=true; removing a member or a limit also requires confirm_remove=true. set_mailbox_storage, outside the White Label toolset, has the same gate. These switches are local safety controls, not extra API permissions. Hosted MCP applies its own approved safety policy.
The tools create deterministic idempotency keys when you do not provide one. Supplying your own idempotency_key is useful when a workflow may restart in a different process.
A safe automation flow
- Call
get_white_label. Stop onscope_blocked_by_entitlement; in a successfulgraceresponse, continue only with reads. - Call
get_white_label_access_catalogimmediately before granting access. - List or read the target member before changing it.
- Check
allowed_operations, the intended role, permissions, and domain ids. - Use a stable idempotency key for the write.
- Read the member again and report the resulting status and effective permissions.
- Check White Label activity when you need an audit record of the change.
Errors that tell you what to do
| Code | Meaning | Next step |
|---|---|---|
insufficient_scope |
The credential was never granted the required scope | Add that scope or reauthorize the OAuth connection |
scope_blocked_by_entitlement |
The stored grant exists, but White Label is not active for it now | Reactivate White Label, then retry with the same credential |
scope_blocked_by_membership |
The person's current role is narrower than the requested action or grant | Ask the owner to change the membership, or request less access |
member_not_manageable |
The target is the owner, the caller itself, or a broader member | Choose a member inside the caller's management boundary |
membership_state_conflict |
The operation does not fit the member's current state | Read allowed_operations and choose one of those actions |
missing_idempotency_key |
A write was sent without a key | Retry with a stable Idempotency-Key |
idempotency_mismatch |
The same key was reused for different input | Use the original input or create a new key |
client_storage_limit_exceeded |
A fixed mailbox size does not fit what the client's limit has left | Choose at most details.available_mb, use shared storage, or raise the limit |
client_storage_below_usage |
A mailbox would be smaller than what it already stores | Choose at least details.used_mb, or shared storage |
client_storage_limit_too_low |
A limit would be lower than what its domains reserve or store | Choose at least details.minimum_mb |
client_storage_domains_conflict |
The domains are under different limits | Change each limit on its own domains, or take a domain out of its limit first |
Related articles
Jump to nearby guides that continue the workflow.