{"openapi":"3.1.0","info":{"title":"Plaid Investments for Orchet — REST tool surface","version":"0.1.0","description":"Read-only portfolio tools backed by Plaid's Investments product. Once the user has linked at least one brokerage via Plaid Link (Robinhood, Schwab, Fidelity, E*TRADE, Vanguard, and 1000+ others), these tools surface accounts, fresh balances, holdings (positions + securities), and recent investment transactions. Orchet cannot place trades or move money — Plaid does not expose those APIs in this product, and that limit is enforced at the manifest level."},"servers":[{"url":"https://plaid-investments.orchet.ai"}],"paths":{"/tools/plaid_list_accounts":{"post":{"operationId":"plaid_list_accounts","summary":"List all accounts the user has linked via Plaid","description":"Returns every account at every Plaid Item (institution link) the user has connected. Each account includes account_id (use this as the filter on every other tool), institution display name when available, type (`investment`, `depository`, `credit`, etc.), subtype (`brokerage`, `401k`, `ira`, `roth`, `cash isa`, …), masked account number, and current/available balances. Call this first when the user asks about 'my accounts', 'what brokerages am I connected to', or before any account-scoped tool so you can show the user a chooser. Cached at most 1 minute upstream; for fresher balances use plaid_get_balance instead.","x-lumo-tool":true,"x-lumo-cost-tier":"free","x-lumo-requires-confirmation":false,"x-lumo-pii-required":[],"x-lumo-intent-tags":["plaid_investments","list_accounts","portfolio"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAccountsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationError"},"502":{"$ref":"#/components/responses/VendorError"}}}},"/tools/plaid_get_balance":{"post":{"operationId":"plaid_get_balance","summary":"Get fresh balances (forces an upstream refresh from the brokerage)","description":"Returns the latest balances by hitting the brokerage in real time (slower than plaid_list_accounts but always fresh). Use when the user asks 'what's my balance RIGHT NOW' or after they just placed a trade in their brokerage app and want to see the new cash position. Optionally filter to specific account_ids (from plaid_list_accounts). Returns the same balance shape as plaid_list_accounts: current, available, iso_currency_code, limit (for credit only). Note: each call has a small Plaid usage cost in production — prefer plaid_list_accounts for general 'show my accounts' questions and only call plaid_get_balance when freshness genuinely matters.","x-lumo-tool":true,"x-lumo-cost-tier":"free","x-lumo-requires-confirmation":false,"x-lumo-pii-required":[],"x-lumo-intent-tags":["plaid_investments","balance","cash_position"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBalanceRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBalanceResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationError"},"502":{"$ref":"#/components/responses/VendorError"}}}},"/tools/plaid_get_holdings":{"post":{"operationId":"plaid_get_holdings","summary":"List investment holdings (positions) + the underlying securities","description":"Returns the user's CURRENT holdings (positions) across their linked investment accounts. Plaid returns TWO arrays: `holdings` (one row per account-security pair: quantity, institution_price, institution_value, cost_basis, iso_currency_code, account_id, security_id) and `securities` (the dictionary of security metadata: ticker_symbol, name, type, close_price, …). Join them via security_id when summarizing. Optionally filter to specific account_ids. When the user asks 'how many AAPL do I own', sum quantity across all matching holdings (the same ticker may appear in multiple accounts). When asked 'what's my portfolio worth', sum institution_value across all holdings. Use 'name' from the securities dictionary, not 'ticker_symbol', when the security has no ticker (e.g. money-market funds).","x-lumo-tool":true,"x-lumo-cost-tier":"free","x-lumo-requires-confirmation":false,"x-lumo-pii-required":[],"x-lumo-intent-tags":["plaid_investments","holdings","positions","portfolio_value"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetHoldingsRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetHoldingsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationError"},"502":{"$ref":"#/components/responses/VendorError"}}}},"/tools/plaid_get_transactions":{"post":{"operationId":"plaid_get_transactions","summary":"List investment transactions in a date window (buy/sell/dividend/fee/transfer)","description":"Returns INVESTMENT transactions in a date range — buys, sells, dividends, capital gains, transfers, fees, etc. These are distinct from cash-account transactions (Plaid /transactions/get) and from holdings (which are the current state). Required: start_date and end_date in `YYYY-MM-DD` format. Optional: account_ids filter, count (default 100, max 500), offset for pagination. Plaid returns `investment_transactions` (each with type — `buy`, `sell`, `cash`, `transfer`, `fee` — plus subtype, quantity, price, amount, fees, security_id, date) and the `securities` dictionary (join on security_id like in plaid_get_holdings). When summarizing trades, prefer the type+subtype combination over the free-text name (the latter is brokerage-specific and noisy).","x-lumo-tool":true,"x-lumo-cost-tier":"free","x-lumo-requires-confirmation":false,"x-lumo-pii-required":[],"x-lumo-intent-tags":["plaid_investments","transactions","trades","trade_history"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTransactionsRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTransactionsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationError"},"502":{"$ref":"#/components/responses/VendorError"}}}},"/tools/plaid_get_institution":{"post":{"operationId":"plaid_get_institution","summary":"Resolve a Plaid institution_id to a display name + logo","description":"Look up an institution by its Plaid institution_id (e.g. 'ins_115575' for Robinhood, 'ins_1' for Bank of America). Returns the canonical name, country_codes, products supported, primary_color hex, logo (base64 PNG or url), and url. Use when displaying the user's linked brokerages to put a proper name + logo next to the account list (most account-scoped Plaid responses include institution_id but not the display name). Cheap and cacheable — Plaid charges nothing for this lookup and the data changes rarely.","x-lumo-tool":true,"x-lumo-cost-tier":"free","x-lumo-requires-confirmation":false,"x-lumo-pii-required":[],"x-lumo-intent-tags":["plaid_investments","institution_lookup","branding"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInstitutionRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInstitutionResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationError"},"502":{"$ref":"#/components/responses/VendorError"}}}}},"components":{"schemas":{"EmptyRequest":{"type":"object","properties":{},"additionalProperties":false},"GetBalanceRequest":{"type":"object","properties":{"account_ids":{"type":"array","items":{"type":"string"},"description":"Optional list of account_ids (from plaid_list_accounts) to limit the refresh to. Omit to refresh all accounts at every linked Item."}},"additionalProperties":false},"GetHoldingsRequest":{"type":"object","properties":{"account_ids":{"type":"array","items":{"type":"string"},"description":"Optional list of account_ids to filter holdings to. Omit to return holdings from every linked investment account."}},"additionalProperties":false},"GetTransactionsRequest":{"type":"object","required":["start_date","end_date"],"properties":{"start_date":{"type":"string","description":"Inclusive start date in `YYYY-MM-DD` format (e.g. '2026-01-01')."},"end_date":{"type":"string","description":"Inclusive end date in `YYYY-MM-DD` format. Must be on or after start_date."},"account_ids":{"type":"array","items":{"type":"string"},"description":"Optional account_ids filter."},"count":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Max transactions to return in this page (default 100, max 500)."},"offset":{"type":"integer","minimum":0,"default":0,"description":"Pagination offset within the total result set."}},"additionalProperties":false},"GetInstitutionRequest":{"type":"object","required":["institution_id"],"properties":{"institution_id":{"type":"string","description":"Plaid institution_id (e.g. 'ins_115575' for Robinhood). Returned on every account-scoped Plaid response."}},"additionalProperties":false},"ListAccountsResponse":{"type":"object","properties":{"accounts":{"type":"array","items":{"type":"object","properties":{"account_id":{"type":"string"},"name":{"type":["string","null"]},"official_name":{"type":["string","null"]},"type":{"type":["string","null"]},"subtype":{"type":["string","null"]},"mask":{"type":["string","null"]},"balances":{"type":"object","properties":{"current":{"type":["number","null"]},"available":{"type":["number","null"]},"limit":{"type":["number","null"]},"iso_currency_code":{"type":["string","null"]},"unofficial_currency_code":{"type":["string","null"]}}}}}},"item":{"type":"object","properties":{"item_id":{"type":["string","null"]},"institution_id":{"type":["string","null"]}}},"count":{"type":"integer"}}},"GetBalanceResponse":{"type":"object","properties":{"accounts":{"type":"array","items":{"type":"object"}},"count":{"type":"integer"}}},"GetHoldingsResponse":{"type":"object","properties":{"accounts":{"type":"array","items":{"type":"object"}},"holdings":{"type":"array","items":{"type":"object","properties":{"account_id":{"type":"string"},"security_id":{"type":"string"},"quantity":{"type":["number","null"]},"institution_price":{"type":["number","null"]},"institution_price_as_of":{"type":["string","null"]},"institution_value":{"type":["number","null"]},"cost_basis":{"type":["number","null"]},"iso_currency_code":{"type":["string","null"]},"unofficial_currency_code":{"type":["string","null"]}}}},"securities":{"type":"array","items":{"type":"object","properties":{"security_id":{"type":"string"},"ticker_symbol":{"type":["string","null"]},"name":{"type":["string","null"]},"type":{"type":["string","null"]},"close_price":{"type":["number","null"]},"close_price_as_of":{"type":["string","null"]},"iso_currency_code":{"type":["string","null"]}}}}}},"GetTransactionsResponse":{"type":"object","properties":{"accounts":{"type":"array","items":{"type":"object"}},"investment_transactions":{"type":"array","items":{"type":"object","properties":{"investment_transaction_id":{"type":"string"},"account_id":{"type":"string"},"security_id":{"type":["string","null"]},"date":{"type":"string"},"name":{"type":["string","null"]},"quantity":{"type":["number","null"]},"amount":{"type":["number","null"]},"price":{"type":["number","null"]},"fees":{"type":["number","null"]},"type":{"type":["string","null"]},"subtype":{"type":["string","null"]},"iso_currency_code":{"type":["string","null"]}}}},"securities":{"type":"array","items":{"type":"object"}},"total_investment_transactions":{"type":"integer"}}},"GetInstitutionResponse":{"type":"object","properties":{"institution":{"type":"object","properties":{"institution_id":{"type":"string"},"name":{"type":["string","null"]},"country_codes":{"type":"array","items":{"type":"string"}},"products":{"type":"array","items":{"type":"string"}},"primary_color":{"type":["string","null"]},"url":{"type":["string","null"]},"logo":{"type":["string","null"]}}}}}},"responses":{"Unauthorized":{"description":"User has not connected Plaid Investments (or their access_token was revoked). orchet-backend catches 401 and renders the inline Connect card.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}},"ValidationError":{"description":"Request validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"VendorError":{"description":"Upstream Plaid API returned an error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"status":{"type":"integer"},"error_code":{"type":"string"},"detail":{"type":"string"}}}}}}}}}