Multi-Account Access
A single Lev user can belong to more than one account — for example, a broker who works across two brokerages, or a user who sits on both a sponsor account and a lender account. Every External API v2 response is scoped to a single active account, so callers that need data across accounts must tell Lev which account a given request targets.
How scoping works
Every v2 request on a multi-account user must carry the X-Active-Account header with the target account's slug. The backend resolves the slug against the user's active memberships and returns that account's data. Requests from single-account users, or from API keys (which are bound to a specific account at issuance and don't read this header), may omit it — the account is implied.
X-Active-Account: broker-magiciansGET /me is the one exception. It's the discovery endpoint — calling it without X-Active-Account is how clients bootstrap, and it returns the unscoped response with available_accounts[]. Every other v2 endpoint enforces the rule.
If a multi-account user sends a non-/me v2 request without X-Active-Account (and the caller is not an API key), the backend returns 400 Bad Request:
{
"error": "Active account required. Provide X-Active-Account header or use an API key."
}Discovering available accounts
Call GET /api/external/v2/me without the X-Active-Account header. The unscoped response returns the authenticated user plus an available_accounts array — every account the user has an active membership on — so clients can present a picker or pass a slug programmatically. The Current User section below documents both response branches.
Switching accounts
"Switching" is purely a client-side header change: drop or change the X-Active-Account value on the next request and the backend rescopes. There is no switch endpoint to call — the MCP server's switch_account tool is a convenience wrapper around exactly this header toggle.
Current User
/api/external/v2/meGet the authenticated user's profile, account, and platform details
GET /me has two response branches depending on whether the request carries X-Active-Account. Multi-account users should call it unscoped first to discover their memberships, then supply X-Active-Account on every subsequent request.
Scoped response (200) — request carries X-Active-Account: <slug>:
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"user": {
"id": 1234,
"uuid": "550e8400-e29b-...",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Smith",
"full_name": "Jane Smith",
"role": null,
"photo_url": null,
"last_login_at": "2026-03-20T10:00:00Z"
},
"account": {
"id": 56,
"name": "Acme CRE Advisors",
"account_type": "brokerage",
"org_id": 789
},
"profile": {
"id": 1001,
"title": "Managing Director",
"role": "admin"
},
"subscription": {
"type": "enterprise",
"status": "active",
"billing_cycle": "annual",
"end_date": "2027-01-01T00:00:00Z"
},
"platform": {
"api_tier": "standard",
"granted_scopes": ["deals:read", "deals:write", "contacts:read"],
"rate_limits": {
"requests_per_minute": 200,
"per_tool_per_minute": 60,
"concurrent_requests": 5,
"ai_actions_per_minute": 10,
"daily_read_cap": null,
"daily_write_caps": null
},
"api_keys": {
"current_count": 2,
"max_allowed": 10
}
}
}
}The platform section includes your API tier, granted scopes, current rate limits, and API key usage.
Unscoped response (200) — request omits X-Active-Account:
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"user": {
"id": 1234,
"uuid": "550e8400-e29b-...",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Smith",
"full_name": "Jane Smith",
"role": null,
"photo_url": null,
"last_login_at": "2026-03-20T10:00:00Z"
},
"account": null,
"available_accounts": [
{
"id": 56,
"name": "Acme CRE Advisors",
"slug": "acme-cre",
"account_type": "brokerage"
},
{
"id": 72,
"name": "Redwood Capital Partners",
"slug": "redwood-capital",
"account_type": "lender"
}
],
"profile": null,
"subscription": null,
"platform": null
}
}account, profile, subscription, and platform are all null until an account is selected. available_accounts lists every account the authenticated user has an active membership on (capped at 50); use any entry's slug as the X-Active-Account value on subsequent requests.
| Field | Type | Description |
|---|---|---|
id | integer | Account identifier |
name | string | Account display name |
slug | string | URL-safe identifier; pass as X-Active-Account |
account_type | string|null | Account classification. One of brokerage, borrower, lender, credit (or lev_internal for Lev-internal accounts, which external callers are unlikely to see). |
unauthorizedAccount Team
/api/external/v2/account/teamList team members in your account
Response (200):
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": [
{
"id": 1234,
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"role": "admin",
"title": "Managing Director",
"photo_url": null
}
]
}Each team member object contains:
| Field | Type | Description |
|---|---|---|
id | integer | User identifier |
first_name | string|null | First name |
last_name | string|null | Last name |
email | string|null | Email address |
role | string|null | Account role (admin, member, etc.) |
title | string|null | Job title |
photo_url | string|null | Profile photo URL |
unauthorized