Build

Account & Team

Access account details, team members, and user profile in the Lev External API v2.

Updated March 2026

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-magicians

GET /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

GET/api/external/v2/me

Get 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.

FieldTypeDescription
idintegerAccount identifier
namestringAccount display name
slugstringURL-safe identifier; pass as X-Active-Account
account_typestring|nullAccount classification. One of brokerage, borrower, lender, credit (or lev_internal for Lev-internal accounts, which external callers are unlikely to see).
unauthorized
Authentication requiredMissing or invalid Authorization header

Account Team

GET/api/external/v2/account/team

List 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:

FieldTypeDescription
idintegerUser identifier
first_namestring|nullFirst name
last_namestring|nullLast name
emailstring|nullEmail address
rolestring|nullAccount role (admin, member, etc.)
titlestring|nullJob title
photo_urlstring|nullProfile photo URL
unauthorized
Authentication requiredMissing or invalid Authorization header
More in this section