{"openapi":"3.1.0","info":{"title":"BFF API","description":"Backend-for-Frontend service for Market Data APIs","version":"1.0.0"},"paths":{"/api/app/v1/":{"get":{"tags":["Root"],"summary":"Api V1 Root","description":"API v1 root endpoint - Discovery and available endpoints","operationId":"api_v1_root_api_app_v1__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Api V1 Root Api App V1  Get"}}}}}}},"/api/app/v1/pools":{"get":{"tags":["Pools"],"summary":"Get Pools","description":"Get pools with filtering and pagination\n\n**Cache TTL:** 300 seconds (5 minutes). Use `fresh=true` to bypass cache.","operationId":"get_pools_api_app_v1_pools_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of pools to return","default":20,"title":"Limit"},"description":"Number of pools to return"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search term for pool name or symbol","title":"Search"},"description":"Search term for pool name or symbol"},{"name":"categories","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated list of categories","title":"Categories"},"description":"Comma-separated list of categories"},{"name":"suggested","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter for suggested pools","title":"Suggested"},"description":"Filter for suggested pools"},{"name":"sbtc_incentives","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter for SBTC incentive pools","title":"Sbtc Incentives"},"description":"Filter for SBTC incentive pools"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pagination cursor","title":"Cursor"},"description":"Pagination cursor"},{"name":"fresh","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Bypass cache and return live DB data (e.g. for validation)","default":false,"title":"Fresh"},"description":"Bypass cache and return live DB data (e.g. for validation)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pools Api App V1 Pools Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/pools/grouped":{"get":{"tags":["Pools"],"summary":"Get Grouped Pools","description":"Get pools grouped by token pairs with filtering and pagination\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_grouped_pools_api_app_v1_pools_grouped_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of token pairs to return","default":20,"title":"Limit"},"description":"Number of token pairs to return"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search term for pool name or symbol","title":"Search"},"description":"Search term for pool name or symbol"},{"name":"categories","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated list of categories","title":"Categories"},"description":"Comma-separated list of categories"},{"name":"suggested","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter for suggested pools","title":"Suggested"},"description":"Filter for suggested pools"},{"name":"sbtc_incentives","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter for SBTC incentive pools","title":"Sbtc Incentives"},"description":"Filter for SBTC incentive pools"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pagination cursor","title":"Cursor"},"description":"Pagination cursor"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Grouped Pools Api App V1 Pools Grouped Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/pools/metrics":{"get":{"tags":["Pools"],"summary":"Get Pools Metrics","description":"Get aggregated pool metrics\n\n**Cache TTL:** 180 seconds (3 minutes)","operationId":"get_pools_metrics_api_app_v1_pools_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pools Metrics Api App V1 Pools Metrics Get"}}}}}}},"/api/app/v1/pools/categories":{"get":{"tags":["Pools"],"summary":"Get Pools Categories","description":"Get available pool categories\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_pools_categories_api_app_v1_pools_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pools Categories Api App V1 Pools Categories Get"}}}}}}},"/api/app/v1/pools/{pool_id}":{"get":{"tags":["Pools"],"summary":"Get Pool By Id","description":"Get a single pool by its ID\n\n**Fallback Behavior:**\n- Default: `X-Allow-Fallback` is enabled (no header needed)\n- `X-Allow-Fallback: false`: disables on-chain fallback (returns only DB/cached data)\n\n**Response Headers:**\n- `X-Data-Fallback-Applied`: true/false - indicates if on-chain fallback was used\n\n**Cache TTL:** 300 seconds (5 minutes)","operationId":"get_pool_by_id_api_app_v1_pools__pool_id__get","parameters":[{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID to retrieve","title":"Pool Id"},"description":"Pool ID to retrieve"},{"name":"X-Allow-Fallback","in":"header","required":false,"schema":{"type":"boolean","description":"Enable on-chain data fallback when DB data is stale","default":true,"title":"X-Allow-Fallback"},"description":"Enable on-chain data fallback when DB data is stale"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pool By Id Api App V1 Pools  Pool Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/pools/{pool_id}/activity":{"get":{"tags":["Pools"],"summary":"Get Pool Activity","description":"Get pool's swap and liquidity activity merged and ordered by newest first\n\n**Cache TTL:** 30 seconds","operationId":"get_pool_activity_api_app_v1_pools__pool_id__activity_get","parameters":[{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (1-indexed)","default":1,"title":"Page"},"description":"Page number (1-indexed)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of records per page","default":10,"title":"Limit"},"description":"Number of records per page"},{"name":"amm_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')","title":"Amm Type"},"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')"},{"name":"include_failed","in":"query","required":false,"schema":{"type":"boolean","description":"Include failed transactions in activity feed","default":false,"title":"Include Failed"},"description":"Include failed transactions in activity feed"},{"name":"after_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cursor-based pagination: raw timestamp of the last seen activity. When provided, returns activities older than this cursor with a fixed fetch limit. Mutually exclusive with page-based offset; if omitted, page-based pagination is used.","title":"After Cursor"},"description":"Cursor-based pagination: raw timestamp of the last seen activity. When provided, returns activities older than this cursor with a fixed fetch limit. Mutually exclusive with page-based offset; if omitted, page-based pagination is used."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pool Activity Api App V1 Pools  Pool Id  Activity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions/{pool_id}/bins":{"get":{"tags":["User Positions"],"summary":"Get User Pool Bins","description":"Get bin information for a specific user and pool\n\n**Real-time Updates:**\n- Default: 2-second cache for optimal performance\n- Use `fresh=true` to bypass cache and get immediate data\n\n**Fallback Behavior:**\n- Default: `X-Allow-Fallback` is enabled (no header needed)\n- `X-Allow-Fallback: false`: disables on-chain fallback (returns only DB/cached data)\n\n**Cache TTL:** 2 seconds (use `fresh=true` to bypass)\n\n**Response Headers:**\n- `X-Cache-Status`: HIT, MISS, or BYPASS\n- `X-Cache-TTL`: Cache TTL in seconds (2)\n- `X-Data-Fallback-Applied`: true/false - indicates if on-chain fallback was used\n- `X-Data-Age-Seconds`: seconds since the most recently updated bin (staleness indicator)\n\n**Response body `meta` (when present):** `dataSource`, `maxBinBlockHeight`, `minBinBlockHeight`,\n`unprocessedLiquidityEventCount` (DLMM liquidity pipeline backlog for the pool), `binRowCount`.\nUse with `bins[].blockHeight` for PnL anchoring (see core-adapter `docs/BIN_FRESHNESS_AND_REPROCESS_RUNBOOK.md`).","operationId":"get_user_pool_bins_api_app_v1_users__user_address__positions__pool_id__bins_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"fresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cache and fetch fresh data","default":false,"title":"Fresh"},"description":"Bypass cache and fetch fresh data"},{"name":"X-Allow-Fallback","in":"header","required":false,"schema":{"type":"boolean","description":"Enable on-chain data fallback when DB data is stale","default":true,"title":"X-Allow-Fallback"},"description":"Enable on-chain data fallback when DB data is stale"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Pool Bins Api App V1 Users  User Address  Positions  Pool Id  Bins Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/pools/{pool_id}/bin-price-history":{"get":{"tags":["Pools"],"summary":"Get Pool Bin Price History","description":"Get bin price history for a pool with OHLC data and active bin ID\n\n**Cache TTL:** Variable based on interval:\n- 1m: 60 seconds\n- 5m: 180 seconds (3 minutes)\n- 15m: 300 seconds (5 minutes)\n- 1h: 900 seconds (15 minutes)\n- 4h: 1800 seconds (30 minutes)\n- 1d: 3600 seconds (1 hour)","operationId":"get_pool_bin_price_history_api_app_v1_pools__pool_id__bin_price_history_get","parameters":[{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"interval","in":"query","required":false,"schema":{"type":"string","description":"Time interval (1m, 5m, 15m, 1h, 4h, 1d)","default":"1h","title":"Interval"},"description":"Time interval (1m, 5m, 15m, 1h, 4h, 1d)"},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start timestamp (UNIX seconds, UTC)","title":"Start"},"description":"Start timestamp (UNIX seconds, UTC)"},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End timestamp (UNIX seconds, UTC)","title":"End"},"description":"End timestamp (UNIX seconds, UTC)"},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of records to return (1-1000)","default":500,"title":"Limit"},"description":"Maximum number of records to return (1-1000)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pool Bin Price History Api App V1 Pools  Pool Id  Bin Price History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions/summary":{"get":{"tags":["User Positions"],"summary":"Get User Positions Summary","description":"Get user's position summary across all pools\n\n**Real-time Updates:**\n- Default: 2-second cache for optimal performance\n- Use `fresh=true` to bypass cache and get immediate data (within 500ms of worker processing)\n- Recommended: Poll with `fresh=false` every 2s, use `fresh=true` only after user action (add/remove liquidity)\n\n**Fallback Behavior:**\n- Default: `X-Allow-Fallback` is enabled (no header needed)\n- `X-Allow-Fallback: false`: disables on-chain fallback (returns only DB/cached data)\n\n**Cache TTL:** 2 seconds (use `fresh=true` to bypass)\n\n**Response Headers:**\n- `X-Cache-Status`: HIT, MISS, or BYPASS\n- `X-Cache-TTL`: Cache TTL in seconds (2)\n- `X-Data-Fallback-Applied`: true/false - indicates if on-chain fallback data was used","operationId":"get_user_positions_summary_api_app_v1_users__user_address__positions_summary_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"fresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cache and fetch fresh data","default":false,"title":"Fresh"},"description":"Bypass cache and fetch fresh data"},{"name":"X-Allow-Fallback","in":"header","required":false,"schema":{"type":"boolean","description":"Enable on-chain data fallback when DB data is stale","default":true,"title":"X-Allow-Fallback"},"description":"Enable on-chain data fallback when DB data is stale"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Positions Summary Api App V1 Users  User Address  Positions Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions/{pool_id}":{"get":{"tags":["User Positions"],"summary":"Get User Position Detail","description":"Get detailed position data for a specific pool\n\n**Real-time Updates:**\n- Default: 2-second cache for optimal performance\n- Use `fresh=true` to bypass cache and get immediate data (within 500ms of worker processing)\n- Recommended: Poll with `fresh=false` every 2s, use `fresh=true` only after user action\n\n**Cache TTL:** 2 seconds (use `fresh=true` to bypass)\n\n**Response Headers:**\n- `X-Cache-Status`: HIT, MISS, or BYPASS\n- `X-Cache-TTL`: Cache TTL in seconds (2)","operationId":"get_user_position_detail_api_app_v1_users__user_address__positions__pool_id__get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"fresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cache and fetch fresh data","default":false,"title":"Fresh"},"description":"Bypass cache and fetch fresh data"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Position Detail Api App V1 Users  User Address  Positions  Pool Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/liquidity/{pool_id}":{"get":{"tags":["User Liquidity"],"summary":"Get User Liquidity","description":"Get user's liquidity details for a specific pool\n\n**Real-time Updates:**\n- Default: 2-second cache for optimal performance\n- Use `fresh=true` to bypass cache and get immediate data\n\n**Fallback Behavior:**\n- Default: `X-Allow-Fallback` is enabled (no header needed)\n- `X-Allow-Fallback: false`: disables on-chain fallback (returns only DB/cached data)\n\n**Cache TTL:** 2 seconds (use `fresh=true` to bypass)\n\n**Response Headers:**\n- `X-Cache-Status`: HIT, MISS, or BYPASS\n- `X-Cache-TTL`: Cache TTL in seconds (2)\n- `X-Data-Fallback-Applied`: true/false - indicates if on-chain fallback was used","operationId":"get_user_liquidity_api_app_v1_users__user_address__liquidity__pool_id__get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"fresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cache and fetch fresh data","default":false,"title":"Fresh"},"description":"Bypass cache and fetch fresh data"},{"name":"X-Allow-Fallback","in":"header","required":false,"schema":{"type":"boolean","description":"Enable on-chain data fallback when DB data is stale","default":true,"title":"X-Allow-Fallback"},"description":"Enable on-chain data fallback when DB data is stale"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Liquidity Api App V1 Users  User Address  Liquidity  Pool Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/activity":{"get":{"tags":["User Activity"],"summary":"Get User Activity","description":"Get user's swap and liquidity activity merged and ordered by newest first\n\n**Cache TTL:** 30 seconds","operationId":"get_user_activity_api_app_v1_users__user_address__activity_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's STX address","title":"User Address"},"description":"User's STX address"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (1-indexed)","default":1,"title":"Page"},"description":"Page number (1-indexed)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of records per page","default":10,"title":"Limit"},"description":"Number of records per page"},{"name":"amm_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')","title":"Amm Type"},"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')"},{"name":"pool_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by pool ID","title":"Pool Id"},"description":"Filter by pool ID"},{"name":"include_failed","in":"query","required":false,"schema":{"type":"boolean","description":"Include failed transactions in activity feed","default":false,"title":"Include Failed"},"description":"Include failed transactions in activity feed"},{"name":"after_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cursor-based pagination: raw timestamp of the last seen activity. When provided, returns activities older than this cursor with a fixed fetch limit. Mutually exclusive with page-based offset; if omitted, page-based pagination is used.","title":"After Cursor"},"description":"Cursor-based pagination: raw timestamp of the last seen activity. When provided, returns activities older than this cursor with a fixed fetch limit. Mutually exclusive with page-based offset; if omitted, page-based pagination is used."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Activity Api App V1 Users  User Address  Activity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/analytics/dex-metrics":{"get":{"tags":["Analytics"],"summary":"Get Dex Metrics","description":"Get global DEX metrics and statistics\n\n**Cache TTL:** 30 seconds","operationId":"get_dex_metrics_api_app_v1_analytics_dex_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Dex Metrics Api App V1 Analytics Dex Metrics Get"}}}}}}},"/api/app/v1/analytics/dex-totals":{"get":{"tags":["Analytics"],"summary":"DEX totals (DLMM + Classic + Legacy)","description":"Returns aggregate metrics across three pool categories:\n- **DLMM**: From adapter DB (dex_metrics_summary), updated by core-adapter workers.\n- **Classic** (XYK/Stableswap): From contract_logs + Bitflow, stored in cache via cron.\n- **Legacy**: Static historical totals from retired contracts, baked into the service.\n\n**Combined totals** roll all three categories together. Each metric is also broken out by source:\n- **totalSwapVolumeUsd** / Dlmm / Classic / Legacy: All-time swap volume USD.\n- **totalTvlUsd** / Dlmm / Classic: Current TVL (Legacy pools have no active TVL).\n- **totalTransactions** / Dlmm / Classic / Legacy: Swap + add + withdraw event count.\n- **totalTransactionVolume** / Dlmm / Classic / Legacy: Sum of swap + add + withdraw volume USD.\n- **totalFeesUsd** / Dlmm / Classic / Legacy: All-time total fees USD.\n- **totalFeesProtocolUsd** / Dlmm / Classic: Protocol fee breakdown by source.\n- **totalFeesProviderUsd** / Dlmm / Classic: Provider (LP) fee breakdown by source.\n- **uniqueUsersClassic** / **uniqueUsersLegacy**: Unique callers per category.\n- **legacy\\***: Detailed Legacy breakdown (swap/add/withdraw volume + event counts).\n- **poolBreakdown**: Per-pool stats for Classic pools.\n- **dailyBreakdown**: Per-day aggregated volumes/counts/fees for Classic pools.\n- **tokenVolumes**: Per-token volumes in USD for Classic pools.","operationId":"get_dex_totals_api_app_v1_analytics_dex_totals_get","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DexTotalsResponse"},"examples":{"success":{"summary":"Success","value":{"totalSwapVolumeUsd":16368260.46,"totalSwapVolumeUsdDlmm":1000000.0,"totalSwapVolumeUsdClassic":234567.89,"totalSwapVolumeUsdLegacy":15133692.57,"totalTvlUsd":500000.0,"totalTvlUsdDlmm":450000.0,"totalTvlUsdClassic":50000.0,"totalTransactions":178662,"totalTransactionsDlmm":30000,"totalTransactionsClassic":12000,"totalTransactionsLegacy":136662,"totalTransactionVolume":31253947.6,"totalTransactionVolumeDlmm":1200000.0,"totalTransactionVolumeClassic":800000.0,"totalTransactionVolumeLegacy":29253947.6,"totalFeesUsd":58441.52,"totalFeesUsdDlmm":45000.0,"totalFeesUsdClassic":11789.12,"totalFeesUsdLegacy":1652.4,"totalFeesProtocolUsd":22394.56,"totalFeesProtocolUsdDlmm":16500.0,"totalFeesProtocolUsdClassic":5894.56,"totalFeesProviderUsd":34394.56,"totalFeesProviderUsdDlmm":28500.0,"totalFeesProviderUsdClassic":5894.56,"lastUpdated":"2026-03-29T12:00:00","uniqueUsersClassic":1500,"uniqueUsersLegacy":23513,"legacySwapVolumeUsd":15133692.57,"legacySwapEvents":97963,"legacyAddVolumeUsd":7662152.47,"legacyAddEvents":26216,"legacyWithdrawVolumeUsd":6458102.56,"legacyWithdrawEvents":12483,"poolBreakdown":[],"dailyBreakdown":[],"tokenVolumes":[]}}}}}}}}},"/api/app/v1/pools/{pool_id}/bin-metrics":{"get":{"tags":["Pools"],"summary":"Get Pool Bin Metrics","description":"Get bin-level metrics for a specific pool\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_pool_bin_metrics_api_app_v1_pools__pool_id__bin_metrics_get","parameters":[{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pool Bin Metrics Api App V1 Pools  Pool Id  Bin Metrics Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions":{"get":{"tags":["User Positions"],"summary":"Get User Positions","description":"Get user positions across all pools\n\n**Cache TTL:** 30 seconds","operationId":"get_user_positions_api_app_v1_users__user_address__positions_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Positions Api App V1 Users  User Address  Positions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/earnings":{"get":{"tags":["User Earnings"],"summary":"Get User Earnings History","description":"Get user earnings history (daily aggregated data)\n\nReturns daily earnings per bin including both USD and native token amounts.\n\n**Response includes:**\n- `earnings[].userEarningsUsd` - earnings in USD\n- `earnings[].userEarningsXToken` - earnings in token X (normalized, human-readable units)\n- `earnings[].userEarningsYToken` - earnings in token Y (normalized, human-readable units)\n- `earnings[].totalFeesXToken` - total pool fees in token X for the period\n- `earnings[].totalFeesYToken` - total pool fees in token Y for the period\n- `poolTokens` - token metadata (symbol, name, decimals, contractAddress) keyed by pool ID\n\n**Cache TTL:** 10 seconds (historical data)","operationId":"get_user_earnings_history_api_app_v1_users__user_address__earnings_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific pool ID","title":"Pool Id"},"description":"Filter by specific pool ID"},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"},{"name":"timescale","in":"query","required":false,"schema":{"anyOf":[{"const":"ALL"},{"type":"null"}],"description":"Use ALL to return all available earnings history","title":"Timescale"},"description":"Use ALL to return all available earnings history"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Earnings History Api App V1 Users  User Address  Earnings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/earnings/pnl":{"get":{"tags":["User Earnings"],"summary":"Get User Pnl Cards","description":"Get PnL card data for all user positions\n\n**Cache TTL:** 120 seconds (2 minutes)","operationId":"get_user_pnl_cards_api_app_v1_users__user_address__earnings_pnl_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"period_type","in":"query","required":true,"schema":{"type":"string","description":"Period type: 1d, 7d, 30d, life (also accepts legacy: 4hr, 6hr, 12hr, daily, weekly, monthly, yearly, lifetime)","title":"Period Type"},"description":"Period type: 1d, 7d, 30d, life (also accepts legacy: 4hr, 6hr, 12hr, daily, weekly, monthly, yearly, lifetime)"},{"name":"pool_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific pool ID","title":"Pool Id"},"description":"Filter by specific pool ID"},{"name":"amm_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')","title":"Amm Type"},"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Pnl Cards Api App V1 Users  User Address  Earnings Pnl Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/earnings/pnl/{pool_id}":{"get":{"tags":["User Earnings"],"summary":"Get User Pnl Card","description":"Get PnL card data for a specific pool\n\n**Cache TTL:** 120 seconds (2 minutes)","operationId":"get_user_pnl_card_api_app_v1_users__user_address__earnings_pnl__pool_id__get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"period_type","in":"query","required":true,"schema":{"type":"string","description":"Period type: 1d, 7d, 30d, life (also accepts legacy: 4hr, 6hr, 12hr, daily, weekly, monthly, yearly, lifetime)","title":"Period Type"},"description":"Period type: 1d, 7d, 30d, life (also accepts legacy: 4hr, 6hr, 12hr, daily, weekly, monthly, yearly, lifetime)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Pnl Card Api App V1 Users  User Address  Earnings Pnl  Pool Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/earnings/events":{"get":{"tags":["User Earnings"],"summary":"Get User Earnings Events","description":"Get event-level (per-swap) earnings for a user\n\nReturns individual swap-level earnings including both USD and native token amounts.\n\n**Response includes:**\n- `events[].userEarningsUsd` - earnings in USD\n- `events[].userEarningsXToken` - earnings in token X (normalized, human-readable units)\n- `events[].userEarningsYToken` - earnings in token Y (normalized, human-readable units)\n- `events[].totalFeesXToken` - total pool fees in token X from this swap\n- `events[].totalFeesYToken` - total pool fees in token Y from this swap\n- `poolTokens` - token metadata (symbol, name, decimals, contractAddress) keyed by pool ID\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_user_earnings_events_api_app_v1_users__user_address__earnings_events_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific pool ID","title":"Pool Id"},"description":"Filter by specific pool ID"},{"name":"amm_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')","title":"Amm Type"},"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')"},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO format)","title":"Start Date"},"description":"Start date (ISO format)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO format)","title":"End Date"},"description":"End date (ISO format)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (1-indexed)","default":1,"title":"Page"},"description":"Page number (1-indexed)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of records per page","default":50,"title":"Limit"},"description":"Number of records per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Earnings Events Api App V1 Users  User Address  Earnings Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/earnings/rollups":{"get":{"tags":["User Earnings"],"summary":"Get User Earnings Rollups","description":"Get pre-aggregated earnings rollups by period type\n\n**Cache TTL:** 120 seconds (2 minutes)","operationId":"get_user_earnings_rollups_api_app_v1_users__user_address__earnings_rollups_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"period_type","in":"query","required":true,"schema":{"type":"string","description":"Period type: 4hr, 6hr, 12hr, daily, weekly, monthly, yearly","title":"Period Type"},"description":"Period type: 4hr, 6hr, 12hr, daily, weekly, monthly, yearly"},{"name":"pool_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific pool ID","title":"Pool Id"},"description":"Filter by specific pool ID"},{"name":"amm_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')","title":"Amm Type"},"description":"Filter by AMM type (e.g., 'dlmm', 'stableswapv2', 'xyk')"},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO format)","title":"Start Date"},"description":"Start date (ISO format)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO format)","title":"End Date"},"description":"End date (ISO format)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Earnings Rollups Api App V1 Users  User Address  Earnings Rollups Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions/{pool_id}/history":{"get":{"tags":["User Positions"],"summary":"Get User Position History","description":"Get position evolution events over time\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_user_position_history_api_app_v1_users__user_address__positions__pool_id__history_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"},{"name":"start_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start time (ISO format)","title":"Start Time"},"description":"Start time (ISO format)"},{"name":"end_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End time (ISO format)","title":"End Time"},"description":"End time (ISO format)"},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by event type: add-liquidity, withdraw-liquidity, value-change, bin-change","title":"Event Type"},"description":"Filter by event type: add-liquidity, withdraw-liquidity, value-change, bin-change"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (1-indexed)","default":1,"title":"Page"},"description":"Page number (1-indexed)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of records per page","default":50,"title":"Limit"},"description":"Number of records per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Position History Api App V1 Users  User Address  Positions  Pool Id  History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions/{pool_id}/lots":{"get":{"tags":["User Positions"],"summary":"Get User Position Lots","description":"Get FIFO lot tracking data for a user position\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_user_position_lots_api_app_v1_users__user_address__positions__pool_id__lots_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Position Lots Api App V1 Users  User Address  Positions  Pool Id  Lots Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/users/{user_address}/positions/{pool_id}/impermanent-loss":{"get":{"tags":["User Positions"],"summary":"Get User Impermanent Loss","description":"Get impermanent loss calculations from lots\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_user_impermanent_loss_api_app_v1_users__user_address__positions__pool_id__impermanent_loss_get","parameters":[{"name":"user_address","in":"path","required":true,"schema":{"type":"string","description":"User's address","title":"User Address"},"description":"User's address"},{"name":"pool_id","in":"path","required":true,"schema":{"type":"string","description":"Pool ID","title":"Pool Id"},"description":"Pool ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get User Impermanent Loss Api App V1 Users  User Address  Positions  Pool Id  Impermanent Loss Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/tokens/prices":{"get":{"tags":["Tokens"],"summary":"Get Token Prices","description":"Get current token prices\n\n**Cache TTL:** 60 seconds (1 minute)","operationId":"get_token_prices_api_app_v1_tokens_prices_get","parameters":[{"name":"token_contracts","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated list of token contracts","title":"Token Contracts"},"description":"Comma-separated list of token contracts"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Token Prices Api App V1 Tokens Prices Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/tickers":{"get":{"tags":["Tickers"],"summary":"Get Tickers","description":"Get tickers data for CoinGecko listing (DEX format)\n\nReturns 24-hour pricing and volume information on each market pair available on the exchange.\n\n**Cache TTL:** 60 seconds (1 minute)\n\n**Response Format (DEX):**\n- ticker_id: base_currency_target_currency (contract addresses)\n- base_currency: contract address of base token\n- target_currency: contract address of target token\n- last_price: last transacted price (JSON number)\n- base_volume: 24-hour trading volume in base currency (JSON number)\n- target_volume: 24-hour trading volume in target currency (JSON number)\n- pool_id: pool/pair address or unique ID (mandatory for DEX)\n- liquidity_in_usd: pool liquidity in USD (mandatory for DEX, JSON number)\n- bid: current highest bid price (recommended, JSON number)\n- ask: current lowest ask price (recommended, JSON number)\n- high: rolling 24-hours highest transaction price (recommended, JSON number)\n- low: rolling 24-hours lowest transaction price (recommended, JSON number)","operationId":"get_tickers_api_app_v1_tickers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array","title":"Response Get Tickers Api App V1 Tickers Get"}}}}}}},"/api/app/v1/tokens/{token}/historical-prices/{quote}":{"get":{"tags":["Tokens"],"summary":"Get Historical Prices","description":"Get historical pricing data for a specific token and quote currency.\n\nReturns the token price history in the requested quote currency.\n\n**Response Format:**\nA list of timestamp/price pairs:\n\n[\n    [\"<timestamp>\", \"<price>\"],\n    [\"<timestamp>\", \"<price>\"],\n    ...\n]\n\n- `timestamp`: iso timestamp as a string\n- `price`: Token price in the requested quote currency, as a string","operationId":"get_historical_prices_api_app_v1_tokens__token__historical_prices__quote__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","description":"Token to lookup.","title":"Token"},"description":"Token to lookup."},{"name":"quote","in":"path","required":true,"schema":{"type":"string","description":"Quote currency.","title":"Quote"},"description":"Quote currency."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"array","minItems":2,"prefixItems":[{"type":"string"},{"type":"number"}],"maxItems":2},"title":"Response Get Historical Prices Api App V1 Tokens  Token  Historical Prices  Quote  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/v1/data-health":{"get":{"tags":["Health"],"summary":"Check data synchronization health","description":"Check if BFF API data is in sync with on-chain state.\n\nThis endpoint queries the Core Validation Service to determine if the cached/indexed\ndata is stale or out of sync with the blockchain.\n\n**Response Fields:**\n- `status`: Overall health status (`healthy`, `unhealthy`, `error`, `unconfigured`)\n- `isHealthy`: Boolean indicating if all data is in sync\n- `lastValidation`: Timestamp of the last validation run\n- `lastOverall`: Result of last validation (`pass` or `fail`)\n- `isRunning`: Whether a validation is currently in progress\n- `isRetrying`: Whether a retry is in progress after a failure\n- `validationCount`: Total number of validations performed\n- `failedPoolIds`: List of pool IDs that failed validation\n- `failedPoolCount`: Number of pools that failed validation\n- `poolSyncStatus`: Per-pool sync status with details on:\n  - `poolData`: Pool metadata sync status (`pass`, `fail`, `error`, `skipped`)\n  - `poolBins`: Bin data sync status\n  - `userBins`: User position bins sync status\n- `poolCount`: Total number of pools being monitored\n- `serviceAvailable`: Whether the Core Validation Service is reachable\n\n**Use Cases:**\n- Frontend can display a warning banner when data might be stale\n- Automated monitoring and alerting on data sync issues\n- Debugging data inconsistencies between on-chain and indexed data","operationId":"get_data_health_api_app_v1_data_health_get","responses":{"200":{"description":"Data health status retrieved successfully","content":{"application/json":{"schema":{},"examples":{"healthy":{"summary":"All data in sync","value":{"status":"healthy","isHealthy":true,"lastValidation":"2026-01-22T19:00:00.000Z","lastOverall":"pass","isRunning":false,"isRetrying":false,"validationCount":42,"failedPoolIds":[],"failedPoolCount":0,"poolSyncStatus":{"dlmm_1":{"poolData":"pass","poolBins":"pass","userBins":"pass"},"dlmm_2":{"poolData":"pass","poolBins":"pass","userBins":"pass"}},"poolCount":2,"serviceAvailable":true}},"unhealthy":{"summary":"Some pools out of sync","value":{"status":"unhealthy","isHealthy":false,"lastValidation":"2026-01-22T19:00:00.000Z","lastOverall":"fail","isRunning":false,"isRetrying":true,"validationCount":43,"failedPoolIds":["dlmm_4"],"failedPoolCount":1,"poolSyncStatus":{"dlmm_1":{"poolData":"pass","poolBins":"pass","userBins":"pass"},"dlmm_4":{"poolData":"pass","poolBins":"pass","userBins":"fail"}},"poolCount":2,"serviceAvailable":true}},"service_unavailable":{"summary":"Core Validation Service unreachable","value":{"status":"error","isHealthy":false,"isRunning":false,"isRetrying":false,"validationCount":0,"failedPoolIds":[],"failedPoolCount":0,"poolSyncStatus":{},"poolCount":0,"serviceAvailable":false,"error":"Service unavailable"}}}}}}}}},"/api/app/internal/cache/clear":{"post":{"summary":"Clear Cache","description":"Clear cache entries","operationId":"clear_cache_api_app_internal_cache_clear_post","parameters":[{"name":"pattern","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pattern to match (e.g., 'bff_api:pools*')","title":"Pattern"},"description":"Pattern to match (e.g., 'bff_api:pools*')"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Clear Cache Api App Internal Cache Clear Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/internal/cache/clear/pools":{"post":{"summary":"Clear Pool Cache","description":"Clear pool-related cache entries","operationId":"clear_pool_cache_api_app_internal_cache_clear_pools_post","parameters":[{"name":"pool_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Specific pool ID to clear","title":"Pool Id"},"description":"Specific pool ID to clear"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Clear Pool Cache Api App Internal Cache Clear Pools Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/internal/cache/clear/quotes":{"post":{"summary":"Clear Quotes Cache Endpoint","description":"Clear the in-memory quotes tokens cache, forcing a fresh fetch on the next request.","operationId":"clear_quotes_cache_endpoint_api_app_internal_cache_clear_quotes_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Clear Quotes Cache Endpoint Api App Internal Cache Clear Quotes Post"}}}}}}},"/api/app/internal/cache/clear/users":{"post":{"summary":"Clear User Cache","description":"Clear user-related cache entries","operationId":"clear_user_cache_api_app_internal_cache_clear_users_post","parameters":[{"name":"user_address","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Specific user address to clear","title":"User Address"},"description":"Specific user address to clear"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Clear User Cache Api App Internal Cache Clear Users Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/app/internal/cache/status":{"get":{"summary":"Get Cache Status","description":"Get cache status","operationId":"get_cache_status_api_app_internal_cache_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Cache Status Api App Internal Cache Status Get"}}}}}}},"/api/app/internal/non-dlmm-tvl/run":{"post":{"summary":"Run Non Dlmm Tvl Job","description":"Run the non-DLMM (XYK + Stableswap) TVL job once. For local/testing use.","operationId":"run_non_dlmm_tvl_job_api_app_internal_non_dlmm_tvl_run_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Run Non Dlmm Tvl Job Api App Internal Non Dlmm Tvl Run Post"}}}}}}},"/api/app/internal/non-dlmm-dex-totals":{"get":{"summary":"Get Non Dlmm Dex Totals","description":"Return current non-DLMM DEX totals (rich payload with per-pool, daily, token-volume breakdowns).\n\nUsed by the cron script for incremental merges: GET -> query new blocks -> merge -> POST.\nBackwards-compatible: old flat payloads are normalized when read.","operationId":"get_non_dlmm_dex_totals_api_app_internal_non_dlmm_dex_totals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Non Dlmm Dex Totals Api App Internal Non Dlmm Dex Totals Get"}}}}}},"post":{"summary":"Set Non Dlmm Dex Totals","description":"Store non-DLMM DEX totals (rich payload) for /analytics/dex-totals merge.\n\nAccepts both the new rich payload (with ``grand``, ``pools``, ``daily``, ``token_volumes``)\nand the legacy flat payload for backwards compatibility.","operationId":"set_non_dlmm_dex_totals_api_app_internal_non_dlmm_dex_totals_post","parameters":[{"name":"X-Internal-Api-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"},"example":{"last_processed_block":234567,"last_updated":"2026-03-29T12:00:00Z","grand":{"total_swap_volume_usd":100000.0,"total_add_volume_usd":50000.0,"total_withdraw_volume_usd":30000.0,"total_transactions":5000,"unique_users":1500},"pools":{},"daily":{},"token_volumes":{}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Set Non Dlmm Dex Totals Api App Internal Non Dlmm Dex Totals Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","description":"Root endpoint","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/app/health":{"get":{"summary":"Health Check","description":"Health check endpoint.\n\nReturns 503 only when critical deps (primary DB, Redis) are down.\nIndividual multi-DB backend failures return 200 with \"degraded\" status\nsince the BFF can still serve from the remaining backends.","operationId":"health_check_api_app_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/app/live":{"get":{"summary":"Liveness","description":"Lightweight liveness probe — confirms the process is running.","operationId":"liveness_api_app_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/app/":{"get":{"summary":"Api Root","description":"API root endpoint","operationId":"api_root_api_app__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"DailyTotals":{"properties":{"date":{"type":"string","title":"Date"},"swap_volume_usd":{"type":"number","title":"Swap Volume Usd"},"swap_count":{"type":"integer","title":"Swap Count"},"add_volume_usd":{"type":"number","title":"Add Volume Usd"},"add_count":{"type":"integer","title":"Add Count"},"withdraw_volume_usd":{"type":"number","title":"Withdraw Volume Usd"},"withdraw_count":{"type":"integer","title":"Withdraw Count"},"fees_protocol_usd":{"type":"number","title":"Fees Protocol Usd"},"fees_provider_usd":{"type":"number","title":"Fees Provider Usd"},"fees_usd":{"type":"number","title":"Fees Usd"},"total_volume_usd":{"type":"number","title":"Total Volume Usd"},"total_events":{"type":"integer","title":"Total Events"}},"type":"object","title":"DailyTotals","description":"Per-day aggregated totals across all non-DLMM pools."},"DexTotalsResponse":{"properties":{"totalSwapVolumeUsd":{"type":"number","title":"Totalswapvolumeusd"},"totalSwapVolumeUsdDlmm":{"type":"number","title":"Totalswapvolumeusddlmm"},"totalSwapVolumeUsdClassic":{"type":"number","title":"Totalswapvolumeusdclassic"},"totalSwapVolumeUsdLegacy":{"type":"number","title":"Totalswapvolumeusdlegacy"},"totalTvlUsd":{"type":"number","title":"Totaltvlusd"},"totalTvlUsdDlmm":{"type":"number","title":"Totaltvlusddlmm"},"totalTvlUsdClassic":{"type":"number","title":"Totaltvlusdclassic"},"totalTransactions":{"type":"integer","title":"Totaltransactions"},"totalTransactionsDlmm":{"type":"integer","title":"Totaltransactionsdlmm"},"totalTransactionsClassic":{"type":"integer","title":"Totaltransactionsclassic"},"totalTransactionsLegacy":{"type":"integer","title":"Totaltransactionslegacy"},"totalTransactionVolume":{"type":"number","title":"Totaltransactionvolume"},"totalTransactionVolumeDlmm":{"type":"number","title":"Totaltransactionvolumedlmm"},"totalTransactionVolumeClassic":{"type":"number","title":"Totaltransactionvolumeclassic"},"totalTransactionVolumeLegacy":{"type":"number","title":"Totaltransactionvolumelegacy"},"totalFeesUsd":{"type":"number","title":"Totalfeesusd"},"totalFeesUsdDlmm":{"type":"number","title":"Totalfeesusddlmm"},"totalFeesUsdClassic":{"type":"number","title":"Totalfeesusdclassic"},"totalFeesUsdLegacy":{"type":"number","title":"Totalfeesusdlegacy"},"totalFeesProtocolUsd":{"type":"number","title":"Totalfeesprotocolusd"},"totalFeesProtocolUsdDlmm":{"type":"number","title":"Totalfeesprotocolusddlmm"},"totalFeesProtocolUsdClassic":{"type":"number","title":"Totalfeesprotocolusdclassic"},"totalFeesProviderUsd":{"type":"number","title":"Totalfeesproviderusd"},"totalFeesProviderUsdDlmm":{"type":"number","title":"Totalfeesproviderusddlmm"},"totalFeesProviderUsdClassic":{"type":"number","title":"Totalfeesproviderusdclassic"},"lastUpdated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lastupdated"},"lastUpdatedDlmm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lastupdateddlmm"},"lastUpdatedClassic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lastupdatedclassic"},"uniqueUsersClassic":{"type":"integer","title":"Uniqueusersclassic"},"uniqueUsersLegacy":{"type":"integer","title":"Uniqueuserslegacy"},"legacySwapVolumeUsd":{"type":"number","title":"Legacyswapvolumeusd"},"legacySwapEvents":{"type":"integer","title":"Legacyswapevents"},"legacyAddVolumeUsd":{"type":"number","title":"Legacyaddvolumeusd"},"legacyAddEvents":{"type":"integer","title":"Legacyaddevents"},"legacyWithdrawVolumeUsd":{"type":"number","title":"Legacywithdrawvolumeusd"},"legacyWithdrawEvents":{"type":"integer","title":"Legacywithdrawevents"},"poolBreakdown":{"items":{"$ref":"#/components/schemas/PoolTotals"},"type":"array","title":"Poolbreakdown"},"dailyBreakdown":{"items":{"$ref":"#/components/schemas/DailyTotals"},"type":"array","title":"Dailybreakdown"},"tokenVolumes":{"items":{"$ref":"#/components/schemas/TokenVolumeTotals"},"type":"array","title":"Tokenvolumes"}},"type":"object","title":"DexTotalsResponse","description":"Response shape for /analytics/dex-totals (DLMM + Classic + Legacy merged)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PoolActivityTotals":{"properties":{"volume_usd":{"type":"number","title":"Volume Usd"},"count":{"type":"integer","title":"Count"},"unique_txs":{"type":"integer","title":"Unique Txs"}},"type":"object","title":"PoolActivityTotals","description":"Volume/count/unique-txs for one activity type (swaps, adds, or withdraws)."},"PoolFeesTotals":{"properties":{"protocol_usd":{"type":"number","title":"Protocol Usd"},"provider_usd":{"type":"number","title":"Provider Usd"},"total_usd":{"type":"number","title":"Total Usd"}},"type":"object","title":"PoolFeesTotals","description":"Fee breakdown for a single pool."},"PoolTotals":{"properties":{"amm_type":{"type":"string","title":"Amm Type"},"pool_name":{"type":"string","title":"Pool Name"},"pool_contract":{"type":"string","title":"Pool Contract"},"x_token":{"type":"string","title":"X Token"},"y_token":{"type":"string","title":"Y Token"},"swaps":{"$ref":"#/components/schemas/PoolActivityTotals"},"adds":{"$ref":"#/components/schemas/PoolActivityTotals"},"withdraws":{"$ref":"#/components/schemas/PoolActivityTotals"},"fees":{"$ref":"#/components/schemas/PoolFeesTotals"},"total_volume_usd":{"type":"number","title":"Total Volume Usd"},"total_events":{"type":"integer","title":"Total Events"},"unique_users":{"type":"integer","title":"Unique Users"}},"type":"object","title":"PoolTotals","description":"Per-pool aggregated totals for non-DLMM pools."},"TokenVolumeTotals":{"properties":{"contract":{"type":"string","title":"Contract"},"decimals":{"type":"integer","title":"Decimals"},"price_usd":{"type":"number","title":"Price Usd"},"swapped_usd":{"type":"number","title":"Swapped Usd"},"added_usd":{"type":"number","title":"Added Usd"},"withdrawn_usd":{"type":"number","title":"Withdrawn Usd"},"fees_usd":{"type":"number","title":"Fees Usd"}},"type":"object","title":"TokenVolumeTotals","description":"Per-token volume totals."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}