---
title: "Fetch Plaid-synced portfolio holdings"
method: GET
path: "/plaid/holdings"
tags: ["Plaid Integration"]
---

# Fetch Plaid-synced portfolio holdings

`GET /plaid/holdings`

## Request

- Base URL: `https://riskmodels.app/api`
- URL: `https://riskmodels.app/api/plaid/holdings`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://riskmodels.app/oauth/authorize`, token URL `https://riskmodels.app/api/oauth/token`, scopes: `mcp:read`)

Returns enriched holdings from connected Plaid accounts with risk metrics.

**Features:**
- Automatic ticker resolution and normalization
- Risk enrichment with factor exposures
- Real-time portfolio valuation
- Multi-account aggregation

**Authentication:** Required (API Key or OAuth2 with plaid:holdings scope)
**Billing:** $0.10 per request
**Rate Limit:** 60 requests/minute

## Response `200`

Enriched holdings with risk metrics

- object
  - `holdings` PlaidHolding[]
    - `account_id` string
    - `security_id` string
    - `institution_value` number: Current value in USD
    - `quantity` number
    - `ticker` string: Normalized ticker symbol
    - `name` string: Security name
    - `risk_metrics` RiskMetrics: Optional risk enrichment on Plaid holdings; names may match batch `full_metrics` or V3 `metrics` keys depending on pipeline version.
      - `annualized_volatility` number, nullable
      - `volatility` number, nullable
      - `sharpe_ratio` number, nullable
      - `l3_mkt_hr` number, nullable
      - `l3_sec_hr` number, nullable
      - `l3_sub_hr` number, nullable
      - `l3_res_er` number, nullable
      - `l3_market_hr` number, nullable
      - `l3_sector_hr` number, nullable
      - `l3_subsector_hr` number, nullable
      - `l3_residual_er` number, nullable
  - `accounts` object[]: Plaid account objects from Investments Holdings (per connected item).
  - `securities` object[]: Plaid security objects referenced by holdings.
  - `connections_count` integer: Number of connected Plaid items for this user.
  - `summary` object
    - `total_value` number
    - `account_count` integer
    - `position_count` integer
  - `_metadata` object
  - `_agent` AgentMeta: Per-request billing and telemetry metadata appended to metered responses.
    - `cost_usd` number, float: Cost deducted from prepaid balance for this request. 0 if served from cache.
    - `latency_ms` integer: Server processing time in milliseconds.
    - `request_id` string: Unique request identifier for support lookups.
    - `confidence` object
      - `overall` number, float
      - `factors` object
    - `data_freshness` string, date-time: ISO timestamp of the data's as-of datetime.
    - `billing_code` string: Internal billing classification for this request type.
    - `cache_status` 'HIT' | 'MISS' | 'BYPASS': Whether this response was served from cache.
    - `llm_cost_usd` number, float: POST /chat only: portion of cost from LLM token billing (estimated preflight charge).
    - `tool_cost_usd` number, float: POST /chat only; sum of internal data tool charges for this turn.
    - `tool_calls` integer: POST /chat only; number of tool invocations in this request.

## Other responses

- `401`: Authentication required
- `402`: Insufficient balance.
- `403`: API key missing `plaid:holdings` scope.
- `429`: Rate limit exceeded.
- `503`: Plaid or token encryption not configured.

---

[API](https://skmtc.dev/riskmodels/apis/riskmodels-api.md) · [All operations](https://skmtc.dev/riskmodels/apis/riskmodels-api/llms.txt) · [OpenAPI document](https://skmtc.dev/riskmodels/apis/riskmodels-api/revisions/1a034cad408a?raw)
