{"openapi":"3.1.0","info":{"title":"FeelConnect API","version":"2026-07-01","summary":"The developer-first financial data platform.","description":"Universal bank Link, normalized financial data (/v1), and standalone AI enrichment products. All data endpoints are POST + JSON with `Authorization: Bearer fc_sk_…`. Test keys (fc_sk_test_…) hit a fully simulated sandbox — search institutions, authenticate with user_good / pass_good (MFA code 1234), and read deterministic, realistic data. Also available: GraphQL at /api/v1/graphql and an MCP server (Streamable HTTP) at /api/mcp for AI agents. Every operation path below is joined to the server URL, so the live API root is https://connect.feels.money/api/v1.","contact":{"name":"FeelConnect","url":"https://connect.feels.money/docs","email":"animicaorg@gmail.com"},"x-api-root":"https://connect.feels.money/api/v1","x-llms-txt":"https://connect.feels.money/llms.txt","x-llms-full-txt":"https://connect.feels.money/llms-full.txt","x-mcp-server":{"url":"https://connect.feels.money/api/mcp","transport":"streamable-http","descriptor":"https://connect.feels.money/.well-known/mcp.json"},"x-ai-plugin":"https://connect.feels.money/.well-known/ai-plugin.json"},"servers":[{"url":"https://connect.feels.money","description":"This deployment. Operation paths carry the /v1 major-version prefix, so requests go to https://connect.feels.money/v1/… (https://connect.feels.money/api/v1/… is the same handler and also works)."}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Link","description":"Token creation and exchange for the hosted Link flow."},{"name":"Items","description":"Connected institution logins."},{"name":"Institutions","description":"The institution catalog."},{"name":"Accounts","description":"Accounts and balances."},{"name":"Transactions","description":"Incremental sync and date-range reads."},{"name":"Identity","description":"Account-holder identity."},{"name":"Income","description":"Detected income streams."},{"name":"Assets","description":"Net-worth rollups."},{"name":"Investments","description":"Holdings and investment transactions."},{"name":"Liabilities","description":"Debt details."},{"name":"Recurring","description":"Recurring stream detection."},{"name":"Categories","description":"The category taxonomy."},{"name":"AI","description":"Standalone AI enrichment products (rules-first, model-enhanced)."},{"name":"Sandbox","description":"Test-environment helpers."},{"name":"GraphQL","description":"The GraphQL read gateway."}],"paths":{"/v1/link/token/create":{"post":{"operationId":"createLinkToken","tags":["Link"],"summary":"Create a Link token","description":"Mint a 30-minute link_token that opens the hosted Link flow (`/link?token=…`) or the Link SDK modal for an end user.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"client_name":{"type":"string","description":"Shown in the Link UI.","maxLength":120},"user":{"type":"object","properties":{"client_user_id":{"type":"string","description":"Your stable id for the end user."}},"required":["client_user_id"]},"products":{"type":"array","items":{"$ref":"#/components/schemas/Product"},"description":"Products to request consent for.","minItems":1},"institution_id":{"type":"string","description":"Pre-select an institution."},"update_item_id":{"type":"string","description":"Re-auth an existing item in update mode."},"webhook":{"type":"string","description":"URL to receive this application's webhooks. Registered as an endpoint for the environment the key belongs to; signed with your existing endpoint secret.","format":"uri"}},"required":["user","products"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"link_token":{"type":"string","description":"fc_link_…"},"expiration":{"type":"string","description":"ISO 8601 expiry."}},"required":["link_token","expiration"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/link/token/exchange":{"post":{"operationId":"exchangePublicToken","tags":["Link"],"summary":"Exchange a public token","description":"Exchange the single-use public_token from a successful Link session for a permanent access_token. The public token cannot be replayed. Update-mode sessions need no exchange — your stored access_token keeps working — and exchanging one rotates the item's access_token (rotated: true).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"public_token":{"type":"string","description":"fc_pub_… from Link onSuccess."}},"required":["public_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"fc_at_… — store securely, shown once."},"item_id":{"type":"string"},"rotated":{"type":"boolean","description":"True when this replaced an existing access_token (update mode); the previous token stops working."}},"required":["access_token","item_id","rotated"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/items/get":{"post":{"operationId":"getItem","tags":["Items"],"summary":"Get an item","description":"Connection status, institution, consented products, and last sync time for the item behind an access token.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/Item"}},"required":["item"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/items/remove":{"post":{"operationId":"removeItem","tags":["Items"],"summary":"Remove an item","description":"Permanently disconnect the item and delete its cached data. The access token is invalidated.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}},"required":["removed"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/items/refresh":{"post":{"operationId":"refreshItem","tags":["Items"],"summary":"Refresh an item","description":"Trigger an on-demand data refresh from the institution. New transactions arrive via the transactions.sync_updates_available webhook.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"refreshing":{"type":"boolean"}},"required":["refreshing"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/institutions/search":{"post":{"operationId":"searchInstitutions","tags":["Institutions"],"summary":"Search institutions","description":"Case-insensitive search across the institution catalog, ordered by popularity, capped at 20. Empty query browses the most popular.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Name or fragment; empty browses.","maxLength":120},"types":{"type":"array","items":{"type":"string","enum":["bank","credit_union","payment_app","investment","crypto_exchange","crypto_wallet","business"]},"description":"Filter by institution type."},"country_codes":{"type":"array","items":{"type":"string"},"description":"Filter by ISO country code."}},"required":["query"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"institutions":{"type":"array","items":{"$ref":"#/components/schemas/Institution"}}},"required":["institutions"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/institutions/get_by_id":{"post":{"operationId":"getInstitutionById","tags":["Institutions"],"summary":"Get an institution","description":"Fetch a single institution by id.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"institution_id":{"type":"string"}},"required":["institution_id"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"institution":{"$ref":"#/components/schemas/Institution"}},"required":["institution"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/accounts/get":{"post":{"operationId":"getAccounts","tags":["Accounts"],"summary":"Get accounts","description":"All consented accounts for an item with cached balances.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"options":{"type":"object","properties":{"account_ids":{"type":"array","items":{"type":"string"},"description":"Narrow the response to these account ids. Ids that do not belong to the item are rejected with invalid_account_id.","minItems":1}}}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"item":{"$ref":"#/components/schemas/Item"}},"required":["accounts","item"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/accounts/balance/get":{"post":{"operationId":"getBalances","tags":["Accounts"],"summary":"Get real-time balances","description":"Like /v1/accounts/get, but refreshes from the institution first when cached balances are older than 15 minutes.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"options":{"type":"object","properties":{"account_ids":{"type":"array","items":{"type":"string"},"description":"Narrow the response to these account ids. Ids that do not belong to the item are rejected with invalid_account_id.","minItems":1}}}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"item":{"$ref":"#/components/schemas/Item"}},"required":["accounts","item"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transactions/sync":{"post":{"operationId":"syncTransactions","tags":["Transactions"],"summary":"Sync transactions (incremental)","description":"Cursor-based incremental sync. First call (no cursor) pages the full history as `added`; subsequent calls with the stored cursor return only added/modified/removed since. Loop while has_more.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"cursor":{"type":"string","description":"Opaque cursor from the previous response. Omit on the first call."},"count":{"type":"integer","description":"Page size 1-500 (default 100).","minimum":1,"maximum":500}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"added":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"modified":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"removed":{"type":"array","items":{"$ref":"#/components/schemas/RemovedTransaction"}},"next_cursor":{"type":"string","description":"Store and pass on the next call."},"has_more":{"type":"boolean","description":"True when another page is immediately available."}},"required":["added","modified","removed","next_cursor","has_more"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transactions/get":{"post":{"operationId":"getTransactions","tags":["Transactions"],"summary":"Get transactions (date range)","description":"Date-ranged reads with count/offset pagination and optional account narrowing. Removed transactions are excluded (use /transactions/sync for deltas).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"start_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"end_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"options":{"type":"object","properties":{"count":{"type":"integer","description":"1-500, default 100.","minimum":1,"maximum":500},"offset":{"type":"integer","description":"Rows to skip.","minimum":0},"account_ids":{"type":"array","items":{"type":"string"},"description":"Narrow to these account ids.","minItems":1}}}},"required":["access_token","start_date","end_date"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"total_transactions":{"type":"integer","description":"Total matching rows across all pages."}},"required":["accounts","transactions","total_transactions"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/identity/get":{"post":{"operationId":"getIdentity","tags":["Identity"],"summary":"Get identity","description":"Names, emails, phones, and addresses on file at the institution.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"identity":{"$ref":"#/components/schemas/Identity"}},"required":["accounts","identity"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/income/get":{"post":{"operationId":"getIncome","tags":["Income"],"summary":"Get income","description":"Detected income streams (employer, cadence, average gross, confidence).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"income_streams":{"type":"array","items":{"$ref":"#/components/schemas/IncomeStream"}}},"required":["income_streams"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/assets/get":{"post":{"operationId":"getAssets","tags":["Assets"],"summary":"Get assets summary","description":"Net-worth style rollup: total assets, total liabilities, net worth, and a breakdown by account class. Account balances are the source of truth — investment/crypto balances already include their holdings, so holdings are never added on top. Totals use a single iso_currency_code; accounts in other currencies are excluded (no FX conversion).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"total_assets":{"type":"number"},"total_liabilities":{"type":"number"},"net_worth":{"type":"number"},"iso_currency_code":{"type":"string"},"summary":{"type":"object","properties":{"total_assets":{"type":"number","description":"Mirrors the top-level field."},"total_liabilities":{"type":"number"},"net_worth":{"type":"number"},"iso_currency_code":{"type":"string"}},"required":["total_assets","total_liabilities","net_worth","iso_currency_code"]},"breakdown":{"type":"object","properties":{"depository":{"type":"number"},"investment":{"type":"number","description":"Investment balances; already includes their holdings."},"crypto":{"type":"number","description":"Crypto balances; already includes their holdings."},"holdings":{"type":"number","description":"Market value of all holdings. Informational — already counted inside investment/crypto, never added on top."},"credit":{"type":"number"},"loan":{"type":"number"}}},"generated_at":{"type":"string","description":"ISO 8601."}},"required":["accounts","total_assets","total_liabilities","net_worth","iso_currency_code","summary","breakdown","generated_at"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/investments/holdings/get":{"post":{"operationId":"getHoldings","tags":["Investments"],"summary":"Get holdings","description":"Positions across investment and crypto accounts with security details.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"holdings":{"type":"array","items":{"$ref":"#/components/schemas/Holding"}}},"required":["accounts","holdings"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/investments/transactions/get":{"post":{"operationId":"getInvestmentTransactions","tags":["Investments"],"summary":"Get investment transactions","description":"Buys, sells, dividends, deposits, withdrawals, and fees. Both date bounds are optional: omit them for the full history.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"start_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive lower bound; omit for no lower bound."},"end_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive upper bound; omit for no upper bound."},"options":{"type":"object","properties":{"count":{"type":"integer","description":"1-500, default 100.","minimum":1,"maximum":500},"offset":{"type":"integer","description":"Rows to skip.","minimum":0},"account_ids":{"type":"array","items":{"type":"string"},"description":"Narrow to these account ids.","minItems":1}}}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"investment_transactions":{"type":"array","items":{"$ref":"#/components/schemas/InvestmentTransaction"}},"total_investment_transactions":{"type":"integer"}},"required":["accounts","investment_transactions","total_investment_transactions"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/liabilities/get":{"post":{"operationId":"getLiabilities","tags":["Liabilities"],"summary":"Get liabilities","description":"Credit cards, mortgages, student and auto loans with APR, minimum payment, and next due date.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"liabilities":{"type":"array","items":{"$ref":"#/components/schemas/Liability"}}},"required":["accounts","liabilities"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/recurring/get":{"post":{"operationId":"getRecurring","tags":["Recurring"],"summary":"Get recurring streams","description":"Detected recurring payment streams: subscriptions, bills, payroll — with cadence, average amount, and predicted next date.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"recurring_streams":{"type":"array","items":{"$ref":"#/components/schemas/RecurringStream"}}},"required":["recurring_streams"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/categories/get":{"post":{"operationId":"getCategories","tags":["Categories"],"summary":"Get the category taxonomy","description":"The static category taxonomy used across transactions and AI products. Takes no parameters — send `{}` or an empty body.","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}}},"required":["categories"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/categorize":{"post":{"operationId":"aiCategorize","tags":["AI"],"summary":"AI: categorize transactions","description":"Categorize transactions into the FeelConnect taxonomy with confidence scores. Rules-first, AI-enhanced; never fails because of the model.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"categorized":{"type":"array","items":{"$ref":"#/components/schemas/CategorizedTxn"}}},"required":["categorized"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/subscriptions":{"post":{"operationId":"aiSubscriptions","tags":["AI"],"summary":"AI: detect subscriptions","description":"Find paid subscriptions with cadence, annual cost, likely-unused flags, and savings notes.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/DetectedSubscription"}},"monthly_total":{"type":"number"},"annual_total":{"type":"number"}},"required":["subscriptions","monthly_total","annual_total"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/cashflow":{"post":{"operationId":"aiCashflow","tags":["AI"],"summary":"AI: cash-flow forecast","description":"Project daily balance over a horizon from recurring streams and spending patterns. Accepts 1-365; the forecaster clamps the effective horizon to 7-120 days (default 30).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000},"horizon_days":{"type":"integer","description":"1-365; clamped to 7-120. Default 30.","minimum":1,"maximum":365,"default":30}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"forecast":{"$ref":"#/components/schemas/CashflowForecast"}},"required":["forecast"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/merchant":{"post":{"operationId":"aiMerchant","tags":["AI"],"summary":"AI: merchant intelligence","description":"Identify the merchant behind a raw bank-statement descriptor.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Raw descriptor, e.g. \"SQ *BLUE BTL 0492\"."}},"required":["query"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"merchant":{"$ref":"#/components/schemas/MerchantIntel"}},"required":["merchant"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/health-score":{"post":{"operationId":"aiHealthScore","tags":["AI"],"summary":"AI: financial health score","description":"0-100 score with explainable subscores, narrative, and one top recommendation.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"health":{"$ref":"#/components/schemas/HealthScore"}},"required":["health"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/financial-summary":{"post":{"operationId":"aiFinancialSummary","tags":["AI"],"summary":"AI: financial summary","description":"Narrative summary of a week/month/quarter window with highlight bullets.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000},"period":{"type":"string","enum":["week","month","quarter"],"description":"Default month."}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"summary":{"type":"string"},"highlights":{"type":"array","items":{"type":"string"}}},"required":["summary","highlights"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/fraud-risk":{"post":{"operationId":"aiFraudRisk","tags":["AI"],"summary":"AI: fraud risk","description":"Flag suspicious transactions (micro-charge testing patterns, out-of-pattern spend) with per-transaction risk and reasons.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"signals":{"type":"array","items":{"$ref":"#/components/schemas/FraudSignal"}},"overall_risk":{"type":"string","enum":["low","medium","high"]}},"required":["signals","overall_risk"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/purchase-analysis":{"post":{"operationId":"aiPurchaseAnalysis","tags":["AI"],"summary":"AI: purchase analysis","description":"Buy/wait/skip verdict for a prospective purchase with regret score, opportunity cost, and alternatives. Pass access_token to ground it in real finances.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"item":{"type":"object","properties":{"name":{"type":"string"},"price":{"type":"number","description":"Major units."},"url":{"type":"string"}},"required":["name","price"]},"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"context":{"type":"object","description":"Optional free-form context."}},"required":["item"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"analysis":{"$ref":"#/components/schemas/PurchaseAnalysis"}},"required":["analysis"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/weekly-report":{"post":{"operationId":"aiWeeklyReport","tags":["AI"],"summary":"AI: weekly report","description":"A coaching-style weekly money report: totals, largest purchases, subscription changes, biggest win/opportunity, recommended action.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TxnInput"},"description":"Bring-your-own transactions (alternative to access_token).","maxItems":1000},"week_of":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Any date inside the target week (defaults to last completed week)."}},"description":"Provide access_token OR a non-empty transactions array.","anyOf":[{"required":["access_token"]},{"required":["transactions"]}]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"report":{"$ref":"#/components/schemas/WeeklyReport"}},"required":["report"]},{"$ref":"#/components/schemas/AiEngineMeta"}]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sandbox/fire_webhook":{"post":{"operationId":"sandboxFireWebhook","tags":["Sandbox"],"summary":"Sandbox: fire a test webhook","description":"Test environment only. Fire a representative webhook of the given type for an item to exercise your handler end to end.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."},"type":{"type":"string","description":"A webhook event type, e.g. transactions.sync_updates_available."}},"required":["access_token","type"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"fired":{"type":"boolean"}},"required":["fired"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sandbox/item/reset_login":{"post":{"operationId":"sandboxResetLogin","tags":["Sandbox"],"summary":"Sandbox: reset item login","description":"Test environment only. Force the item into LOGIN_REQUIRED to test the Link update-mode re-auth flow.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Item access token (fc_at_…) from /v1/link/token/exchange."}},"required":["access_token"]}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"schema":{"type":"string"},"description":"Unique request id."},"FC-Version":{"schema":{"type":"string"},"description":"API version (2026-07-01)."},"X-RateLimit-Remaining":{"schema":{"type":"string"},"description":"Requests remaining in the current window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"reset":{"type":"boolean"}},"required":["reset"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/graphql":{"get":{"operationId":"graphqlIde","tags":["GraphQL"],"summary":"GraphiQL IDE","description":"A bare GET serves the GraphiQL IDE as HTML (no key required — paste one into its headers pane). A GET carrying ?query= executes and is authenticated exactly like POST.","security":[],"responses":{"200":{"description":"GraphiQL IDE.","content":{"text/html":{"schema":{"type":"string"}}}},"401":{"description":"Missing or invalid API key (only when ?query= is present).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"graphql","tags":["GraphQL"],"summary":"GraphQL gateway","description":"Read-only GraphQL over the same data plane: item, accounts, transactions (cursor-paginated connection), institutions, recurring. Same bearer auth. GraphiQL IDE served on GET.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"GraphQL document."},"variables":{"type":"object"},"operationName":{"type":["string","null"]}},"required":["query"]}}}},"responses":{"200":{"description":"GraphQL response ({ data, errors? }).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"errors":{"type":"array","items":{"type":"object"}}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Permission denied (plan or consent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or monthly quota exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream provider error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"link.session_finished":{"post":{"operationId":"webhook_link_session_finished","summary":"link.session_finished","description":"A Link session ended — successfully or not. data carries link_session_id and status. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"item.connected":{"post":{"operationId":"webhook_item_connected","summary":"item.connected","description":"An item finished connecting and its first sync completed. data carries item_id. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"item.error":{"post":{"operationId":"webhook_item_error","summary":"item.error","description":"The item entered an error state (usually LOGIN_REQUIRED). data carries item_id and error. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"item.removed":{"post":{"operationId":"webhook_item_removed","summary":"item.removed","description":"The item was removed and its access token invalidated. data carries item_id. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"transactions.initial_update":{"post":{"operationId":"webhook_transactions_initial_update","summary":"transactions.initial_update","description":"The first historical transaction pull completed for an item. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"transactions.sync_updates_available":{"post":{"operationId":"webhook_transactions_sync_updates_available","summary":"transactions.sync_updates_available","description":"New/changed transactions are available — call /v1/transactions/sync. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"recurring.updated":{"post":{"operationId":"webhook_recurring_updated","summary":"recurring.updated","description":"Recurring stream detection produced changes for the item. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"holdings.updated":{"post":{"operationId":"webhook_holdings_updated","summary":"holdings.updated","description":"Investment holdings changed for the item. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}},"usage.limit_approaching":{"post":{"operationId":"webhook_usage_limit_approaching","summary":"usage.limit_approaching","description":"The application is nearing a monthly plan quota. Delivered to your configured endpoint with headers FC-Webhook-Id, FC-Timestamp, and FC-Signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Return any 2xx within 10s to acknowledge; non-2xx is retried (0s/1m/5m/30m/2h, max 5 attempts)."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"fc_sk_test_… | fc_sk_live_…","description":"Secret API key from the FeelConnect dashboard. Test keys read sandbox data; live keys require the Startup plan or above."}},"schemas":{"Product":{"type":"string","enum":["transactions","balances","identity","income","assets","investments","liabilities","recurring","crypto"],"description":"A consentable FeelConnect data product."},"Institution":{"type":"object","properties":{"institution_id":{"type":"string","description":"Prefixed id (inst_…)."},"name":{"type":"string"},"type":{"type":"string","enum":["bank","credit_union","payment_app","investment","crypto_exchange","crypto_wallet","business"]},"country_codes":{"type":"array","items":{"type":"string"},"description":"ISO country codes served."},"primary_color":{"type":"string","description":"Brand hex color."},"monogram":{"type":"string","description":"1-2 letter logo monogram."},"logo_url":{"type":["string","null"],"description":"Logo path on the FeelConnect origin (e.g. /institutions/inst_chase.png), or null when no mark exists — fall back to the monogram."},"oauth":{"type":"boolean","description":"True when the institution authenticates via OAuth redirect."},"mfa":{"type":"boolean","description":"True when logins may require an MFA challenge."},"status":{"type":"string","enum":["healthy","degraded","down"],"description":"Live connection health."}},"required":["institution_id","name","type","country_codes","primary_color","monogram","logo_url","oauth","mfa","status"]},"Balances":{"type":"object","properties":{"current":{"type":"number","description":"Current balance, major units."},"available":{"type":["number","null"],"description":"Available balance, major units (null when the institution does not report it)."},"limit":{"type":["number","null"],"description":"Credit limit for credit accounts, else null."},"iso_currency_code":{"type":"string","description":"ISO 4217 currency code, e.g. USD."}},"required":["current","available","limit","iso_currency_code"]},"Account":{"type":"object","properties":{"account_id":{"type":"string","description":"Prefixed id (acct_…)."},"name":{"type":"string"},"official_name":{"type":["string","null"]},"type":{"type":"string","enum":["depository","credit","loan","investment","crypto","payment"]},"subtype":{"type":["string","null"],"description":"e.g. checking, savings, credit card."},"mask":{"type":["string","null"],"description":"Last 2-4 digits of the account number."},"balances":{"$ref":"#/components/schemas/Balances"},"verification_status":{"type":"string"}},"required":["account_id","name","official_name","type","subtype","mask","balances","verification_status"]},"Transaction":{"type":"object","properties":{"transaction_id":{"type":"string","description":"Prefixed id (txn_…)."},"account_id":{"type":"string"},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Posted date."},"authorized_datetime":{"type":["string","null"],"description":"ISO 8601 authorization timestamp, or null."},"name":{"type":"string","description":"Statement descriptor."},"merchant_name":{"type":["string","null"]},"amount":{"type":"number","description":"Major units. Positive = outflow (money leaving the account), negative = inflow."},"iso_currency_code":{"type":"string"},"pending":{"type":"boolean"},"category":{"type":["string","null"],"description":"Primary category from the FeelConnect taxonomy."},"category_detailed":{"type":["string","null"],"description":"Detailed category."},"payment_channel":{"type":"string","enum":["online","in_store","transfer","other"]}},"required":["transaction_id","account_id","date","authorized_datetime","name","merchant_name","amount","iso_currency_code","pending","category","category_detailed","payment_channel"]},"RemovedTransaction":{"type":"object","properties":{"transaction_id":{"type":"string"}},"required":["transaction_id"]},"ItemError":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"Item":{"type":"object","properties":{"item_id":{"type":"string","description":"Prefixed id (item_…)."},"institution_id":{"type":"string"},"institution_name":{"type":"string"},"connector":{"type":"string","description":"Connector that serves this item (sandbox, manual, evm-wallet, plaid, …)."},"status":{"type":"string","enum":["active","login_required","error","removed"]},"error":{"oneOf":[{"$ref":"#/components/schemas/ItemError"},{"type":"null"}]},"consented_products":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"last_successful_sync":{"type":["string","null"],"description":"ISO 8601 timestamp of the last successful data sync, or null."}},"required":["item_id","institution_id","institution_name","connector","status","error","consented_products","last_successful_sync"]},"Security":{"type":"object","properties":{"security_id":{"type":"string","description":"Prefixed id (sec_…)."},"ticker":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["equity","etf","crypto","cash","bond"]},"close_price":{"type":"number","description":"Latest close price, major units."}},"required":["security_id","ticker","name","type","close_price"]},"Holding":{"type":"object","properties":{"holding_id":{"type":"string","description":"Prefixed id (hold_…)."},"account_id":{"type":"string"},"security":{"$ref":"#/components/schemas/Security"},"quantity":{"type":"number"},"cost_basis":{"type":["number","null"]},"value":{"type":"number","description":"quantity × close_price, major units."}},"required":["holding_id","account_id","security","quantity","cost_basis","value"]},"InvestmentTransaction":{"type":"object","properties":{"investment_transaction_id":{"type":"string"},"account_id":{"type":"string"},"ticker":{"type":["string","null"]},"type":{"type":"string","enum":["buy","sell","dividend","deposit","withdrawal","fee"]},"quantity":{"type":["number","null"]},"price":{"type":["number","null"]},"amount":{"type":"number"},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"name":{"type":"string"}},"required":["investment_transaction_id","account_id","ticker","type","quantity","price","amount","date","name"]},"Liability":{"type":"object","properties":{"account_id":{"type":"string"},"type":{"type":"string","enum":["credit_card","mortgage","student","auto","personal"]},"apr":{"type":["number","null"],"description":"Annual percentage rate, e.g. 24.99."},"minimum_payment":{"type":["number","null"]},"next_payment_due":{"type":["string","null"],"description":"Calendar date (YYYY-MM-DD), or null."},"original_principal":{"type":["number","null"]}},"required":["account_id","type","apr","minimum_payment","next_payment_due","original_principal"]},"RecurringStream":{"type":"object","properties":{"recurring_id":{"type":"string","description":"Prefixed id (rcr_…)."},"merchant_name":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":["string","null"]},"cadence":{"type":"string","enum":["weekly","biweekly","monthly","quarterly","annual"]},"average_amount":{"type":"number","description":"Average absolute amount per occurrence, major units."},"last_amount":{"type":["number","null"]},"last_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"next_date":{"type":["string","null"],"description":"Predicted next occurrence, null when the stream ended."},"is_subscription":{"type":"boolean"},"direction":{"type":"string","enum":["outflow","inflow"]},"status":{"type":"string","enum":["active","paused","ended"]}},"required":["recurring_id","merchant_name","description","category","cadence","average_amount","last_amount","last_date","next_date","is_subscription","direction","status"]},"IncomeStream":{"type":"object","properties":{"income_id":{"type":"string","description":"Prefixed id (inc_…)."},"employer_name":{"type":"string"},"cadence":{"type":"string","description":"weekly | biweekly | monthly | irregular."},"average_gross":{"type":"number"},"last_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"confidence":{"type":"number","description":"Detection confidence 0-1."}},"required":["income_id","employer_name","cadence","average_gross","last_date","confidence"]},"Identity":{"type":"object","properties":{"names":{"type":"array","items":{"type":"string"}},"emails":{"type":"array","items":{"type":"string"}},"phones":{"type":"array","items":{"type":"string"}},"addresses":{"description":"Structured addresses as reported by the institution — an array of address objects, or null when the institution reports none."}},"required":["names","emails","phones","addresses"]},"Category":{"type":"object","properties":{"primary":{"type":"string"},"detailed":{"type":"array","items":{"type":"string"}}},"required":["primary","detailed"],"description":"One primary category and its detailed subcategories."},"TxnInput":{"type":"object","properties":{"id":{"type":"string","description":"Your stable transaction id, echoed back in results."},"description":{"type":"string","description":"Bank statement descriptor."},"amount":{"type":"number","description":"Major units; positive = outflow."},"merchant":{"type":["string","null"]},"date":{"type":["string","null"],"description":"Calendar date (YYYY-MM-DD), or null."},"category":{"type":["string","null"],"description":"Existing category hint, if any."},"account_id":{"type":["string","null"]},"datetime":{"type":["string","null"],"description":"ISO 8601 timestamp, when known."}},"required":["id","description","amount"],"description":"A caller-supplied raw transaction for the AI endpoints (bring-your-own data)."},"AiEngineMeta":{"type":"object","properties":{"engine":{"type":"string","enum":["rules","ai","ai+rules"],"description":"Which engine produced the result. AI endpoints always succeed: when the model is unreachable the deterministic rules result ships as \"rules\"."},"model":{"type":"string","description":"Model id when engine involved AI."}},"required":["engine"]},"CategorizedTxn":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string"},"category_detailed":{"type":"string"},"confidence":{"type":"number","description":"0-1."}},"required":["id","category","category_detailed","confidence"]},"DetectedSubscription":{"type":"object","properties":{"merchant_name":{"type":"string"},"cadence":{"type":"string"},"average_amount":{"type":"number"},"annual_cost":{"type":"number"},"last_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"next_date":{"type":["string","null"],"description":"Calendar date (YYYY-MM-DD), or null."},"likely_unused":{"type":"boolean"},"note":{"type":["string","null"],"description":"One-sentence practical note (savings tip, duplicate warning), or null."}},"required":["merchant_name","cadence","average_amount","annual_cost","last_date","next_date","likely_unused","note"]},"CashflowForecast":{"type":"object","properties":{"horizon_days":{"type":"integer"},"daily":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"inflow":{"type":"number"},"outflow":{"type":"number"},"balance":{"type":"number"}},"required":["date","inflow","outflow","balance"]}},"summary":{"type":"object","properties":{"projected_end_balance":{"type":"number"},"lowest_point":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."},"balance":{"type":"number"}},"required":["date","balance"]},"risk":{"type":"string","enum":["low","medium","high"]},"narrative":{"type":["string","null"]}},"required":["projected_end_balance","lowest_point","risk","narrative"]}},"required":["horizon_days","daily","summary"]},"MerchantIntel":{"type":"object","properties":{"query":{"type":"string"},"merchant_name":{"type":"string"},"category":{"type":"string"},"website":{"type":["string","null"]},"description":{"type":["string","null"]}},"required":["query","merchant_name","category","website","description"]},"HealthScore":{"type":"object","properties":{"score":{"type":"number","description":"0-100."},"subscores":{"type":"object","additionalProperties":{"type":"number"},"description":"Explainable subscores, each 0-100."},"narrative":{"type":["string","null"]},"top_recommendation":{"type":["string","null"]}},"required":["score","subscores","narrative","top_recommendation"]},"FraudSignal":{"type":"object","properties":{"transaction_id":{"type":"string"},"risk":{"type":"string","enum":["low","medium","high"]},"reasons":{"type":"array","items":{"type":"string"}}},"required":["transaction_id","risk","reasons"]},"PurchaseAnalysis":{"type":"object","properties":{"verdict":{"type":"string","enum":["buy","wait","skip"]},"regret_score":{"type":"number","description":"0-100; higher = more likely to regret."},"feeling_score":{"type":"number","description":"0-100; higher = more likely to feel good about it."},"opportunity_cost":{"type":"array","items":{"type":"object","properties":{"years":{"type":"integer"},"value":{"type":"number"}},"required":["years","value"]}},"budget_impact":{"type":"string"},"reasoning":{"type":"string"},"alternatives":{"type":"array","items":{"type":"string"}}},"required":["verdict","regret_score","feeling_score","opportunity_cost","budget_impact","reasoning","alternatives"]},"WeeklyReport":{"type":"object","properties":{"week_start":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Monday of the reported week."},"income":{"type":"number"},"expenses":{"type":"number"},"net":{"type":"number"},"largest_purchases":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"amount":{"type":"number"},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date (YYYY-MM-DD)."}},"required":["name","amount","date"]}},"subscription_changes":{"type":"array","items":{"type":"string"}},"biggest_win":{"type":["string","null"]},"biggest_opportunity":{"type":["string","null"]},"recommended_action":{"type":["string","null"]},"narrative":{"type":["string","null"]}},"required":["week_start","income","expenses","net","largest_purchases","subscription_changes","biggest_win","biggest_opportunity","recommended_action","narrative"]},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","description":"Event id (evt_…). Also sent as the FC-Webhook-Id header."},"type":{"type":"string","enum":["link.session_finished","item.connected","item.error","item.removed","transactions.initial_update","transactions.sync_updates_available","recurring.updated","holdings.updated","usage.limit_approaching"],"description":"Event type."},"created":{"type":"integer","description":"Unix seconds."},"environment":{"type":"string","enum":["test","live"]},"data":{"type":"object","description":"Event payload. Item events carry item_id; transaction events add counts; usage.limit_approaching carries the metric and percentage."}},"required":["id","type","created","environment","data"],"description":"Webhook delivery body. Verify FC-Signature: v1=hex(hmacSHA256(secret, `${FC-Timestamp}.${rawBody}`)) and reject when |now − FC-Timestamp| > 300s."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","rate_limit_error","provider_error","api_error"]},"code":{"type":"string","description":"Machine-readable error code, e.g. item_not_found."},"message":{"type":"string","description":"Human-readable explanation."},"request_id":{"type":"string","description":"Echo of X-Request-Id for support."}},"required":["type","code","message","request_id"]}},"required":["error"],"description":"Standard error envelope returned by every non-2xx response."}}}}