{"openapi":"3.1.0","info":{"title":"Deep Blue Alpha","description":"Ethereum Whale Intelligence — Real-time whale tracking for the community","version":"0.1.0"},"paths":{"/auth/register":{"post":{"summary":"Api Register","operationId":"api_register_auth_register_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/login":{"post":{"summary":"Api Login","operationId":"api_login_auth_login_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/refresh":{"post":{"summary":"Api Refresh","operationId":"api_refresh_auth_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/logout":{"post":{"summary":"Api Logout","operationId":"api_logout_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/tier":{"get":{"summary":"Api Auth Tier","description":"Lightweight endpoint that returns just the caller's tier (or 'anon').\n\nUsed by the GA4 user_properties wiring in base.html so that Realtime\nreports can filter on subscription tier without GA4 ever seeing email,\nuser_id, or any PII. Always returns 200 — never 401 — so anonymous\nvisitors don't pollute the browser console with errors.","operationId":"api_auth_tier_auth_tier_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/me":{"get":{"summary":"Api Me","operationId":"api_me_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/resend-verification":{"post":{"summary":"Api Resend Verification","description":"Re-send the email-verification link to the logged-in user (if unverified).\nPowers the on-site 'Verify your email' banner + the verify-to-save flow.","operationId":"api_resend_verification_auth_resend_verification_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/profile":{"post":{"summary":"Api Update Profile","description":"Update user profile (display name).","operationId":"api_update_profile_auth_profile_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/account-type":{"post":{"summary":"Api Switch To Business","description":"Switch the signed-in account to a Business account (2026-10-16).\n\nLabeling only: tier, subscription, entitlements and payment data are not\nread or written, so switching can never remove access. Also updates the\ncompany details of an existing Business account. There is no\nbusiness -> personal switch here (handled by email support).","operationId":"api_switch_to_business_auth_account_type_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/password":{"post":{"summary":"Api Change Password","description":"Change password for authenticated user.","operationId":"api_change_password_auth_password_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/forgot-password":{"post":{"summary":"Api Forgot Password","description":"Send password reset email. Always returns 200 to prevent email enumeration.","operationId":"api_forgot_password_auth_forgot_password_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/reset-password":{"post":{"summary":"Api Reset Password","description":"Complete password reset using token from email.","operationId":"api_reset_password_auth_reset_password_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/magic-login":{"get":{"summary":"Api Magic Login","description":"One-time magic-login link (no password required). Used for account-recovery\nflows where we need to give a paying member access without making them deal\nwith a password reset.\n\nThe token is a JWT signed by JWT_SECRET with `type='magic_login'`. On success\nwe issue a fresh standard auth JWT (same kind /auth/login returns) and set\nthe `dba_token` cookie, then redirect to `/`. On failure we redirect to\n`/login?error=...` rather than returning a JSON 401, because the user is\ncoming from a click in chat / Telegram and a redirect feels cleaner.","operationId":"api_magic_login_auth_magic_login_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/verify-email":{"get":{"summary":"Api Verify Email","description":"Verify email address using token from verification email.","operationId":"api_verify_email_auth_verify_email_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/activate-trial":{"get":{"summary":"Activate Trial","description":"Activate a 7-day Alpha trial via a signed JWT link.\n\nUsed for existing verified free users who signed up before the trial\nfeature launched. The link is sent via a one-time email blast. The JWT\ncontains {user_id, type: 'activate_trial'} and expires in 30 days.","operationId":"activate_trial_auth_activate_trial_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pricing":{"get":{"summary":"Api Pricing","description":"Return available tiers and pricing.\n\nOnly PUBLIC (active) tiers are exposed. Leviathan is an internal-only tier\n(active:False) and must never leak via this endpoint — filtering on `active`\nkeeps it out of the public JSON. This changes disclosure only; it does not\ntouch prices, entitlements, or any checkout/billing logic.","operationId":"api_pricing_api_pricing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/founding-waitlist":{"post":{"summary":"Api Founding Waitlist","description":"Collect email for founding member waitlist — sends drip sequence.","operationId":"api_founding_waitlist_api_founding_waitlist_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/email/unsubscribe":{"get":{"summary":"Email Unsubscribe","description":"One-click unsubscribe for marketing emails (CAN-SPAM compliant).","operationId":"email_unsubscribe_email_unsubscribe_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subscribe/stripe":{"post":{"summary":"Api Subscribe Stripe","description":"Create a Stripe checkout session.","operationId":"api_subscribe_stripe_api_subscribe_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/subscribe/crypto":{"post":{"summary":"Api Subscribe Crypto","description":"Create a crypto payment invoice.","operationId":"api_subscribe_crypto_api_subscribe_crypto_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/subscribe/cancel":{"post":{"summary":"Api Cancel Subscription","description":"Cancel the current subscription.\n\nOptionally accepts {\"reason\": \"<code>\"} so we learn WHY people leave.\nReason capture and the confirmation email are both best-effort: a failure\nin either must never block or reverse the cancellation itself.","operationId":"api_cancel_subscription_api_subscribe_cancel_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/subscribe/cancel-feedback":{"post":{"summary":"Api Cancel Feedback","description":"Bookkeeping only (2026-10-13): keep the reason when someone opens the cancel\nflow, picks a reason, and then does NOT cancel — they switched to a lower plan\n(\"downgraded\") or kept their subscription (\"stayed\"). The cancel itself is\nrecorded by /api/subscribe/cancel. Writes only cancellation_feedback; never\ntouches the subscription, the tier or the payment provider.","operationId":"api_cancel_feedback_api_subscribe_cancel_feedback_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/billing/portal":{"post":{"summary":"Api Billing Portal","description":"Create a Stripe Customer Portal session for payment method management.","operationId":"api_billing_portal_api_billing_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/billing/switch-yearly":{"post":{"summary":"Api Billing Switch Yearly","description":"One-click monthly -> yearly (same tier, founding yearly price) via Stripe's\nhosted confirm page (2026-10-13). Never charges by itself — the customer sees\nthe prorated amount and confirms on Stripe; existing webhooks sync the result.","operationId":"api_billing_switch_yearly_api_billing_switch_yearly_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/subscribe/downgrade":{"post":{"summary":"Api Downgrade Subscription","description":"Downgrade to a lower tier. Cancels current sub (access retained until period end);\nuser re-subscribes at the target tier after expiry.","operationId":"api_downgrade_subscription_api_subscribe_downgrade_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/crypto/currencies":{"get":{"summary":"Api Crypto Currencies","description":"Get available crypto currencies for payment.","operationId":"api_crypto_currencies_api_crypto_currencies_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/stripe":{"post":{"summary":"Webhook Stripe","description":"Stripe webhook receiver.","operationId":"webhook_stripe_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/nowpayments":{"post":{"summary":"Webhook Nowpayments","description":"NOWPayments IPN webhook receiver.","operationId":"webhook_nowpayments_webhooks_nowpayments_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/keys/create":{"post":{"summary":"Api Create Key","description":"Create a new API key.","operationId":"api_create_key_api_keys_create_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/keys":{"get":{"summary":"Api List Keys","description":"List user's API keys (prefix only, not full key).","operationId":"api_list_keys_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/keys/revoke":{"post":{"summary":"Api Revoke Key","description":"Revoke an API key by prefix.","operationId":"api_revoke_key_api_keys_revoke_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/legal":{"get":{"summary":"Legal Redirect","operationId":"legal_redirect_legal_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/terms":{"get":{"summary":"Terms Page","operationId":"terms_page_terms_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/business-terms":{"get":{"summary":"Business Terms Page","operationId":"business_terms_page_business_terms_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/privacy":{"get":{"summary":"Privacy Page","operationId":"privacy_page_privacy_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/disclaimer":{"get":{"summary":"Disclaimer Page","operationId":"disclaimer_page_disclaimer_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/cookies":{"get":{"summary":"Cookies Redirect","operationId":"cookies_redirect_cookies_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/cookie-policy":{"get":{"summary":"Cookie Policy Page","operationId":"cookie_policy_page_cookie_policy_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/billing":{"get":{"summary":"Billing Page","operationId":"billing_page_billing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/email":{"get":{"summary":"Email Dashboard","operationId":"email_dashboard_email_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/email/message/{msg_id}/body":{"get":{"summary":"Email Message Body","description":"Return a single message's body_html on demand (lazy load).","operationId":"email_message_body_email_message__msg_id__body_get","parameters":[{"name":"msg_id","in":"path","required":true,"schema":{"type":"integer","title":"Msg Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/attachment/{att_id}":{"get":{"summary":"Email Attachment Download","description":"Serve an email attachment as a downloadable file or inline image.","operationId":"email_attachment_download_email_attachment__att_id__get","parameters":[{"name":"att_id","in":"path","required":true,"schema":{"type":"integer","title":"Att Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/inbox/{msg_id}/read":{"post":{"summary":"Email Inbox Mark Read","operationId":"email_inbox_mark_read_email_inbox__msg_id__read_post","parameters":[{"name":"msg_id","in":"path","required":true,"schema":{"type":"integer","title":"Msg Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/messages/{msg_id}/delete":{"post":{"summary":"Email Message Delete","operationId":"email_message_delete_email_messages__msg_id__delete_post","parameters":[{"name":"msg_id","in":"path","required":true,"schema":{"type":"integer","title":"Msg Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/inbox/mark-all-read":{"post":{"summary":"Email Inbox Mark All Read","operationId":"email_inbox_mark_all_read_email_inbox_mark_all_read_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/email/compose/{contact_id}":{"get":{"summary":"Email Compose","operationId":"email_compose_email_compose__contact_id__get","parameters":[{"name":"contact_id","in":"path","required":true,"schema":{"type":"integer","title":"Contact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/send":{"post":{"summary":"Email Send","operationId":"email_send_email_send_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_email_send_email_send_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/contact":{"post":{"summary":"Email Add Contact","operationId":"email_add_contact_email_contact_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_email_add_contact_email_contact_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/quick-send":{"post":{"summary":"Email Quick Send","description":"Send an email to any address. Auto-creates contact if they don't exist.","operationId":"email_quick_send_email_quick_send_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_email_quick_send_email_quick_send_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/batch-send":{"post":{"summary":"Email Batch Send","description":"Send emails to all contacts that haven't been emailed yet (status='pending').","operationId":"email_batch_send_email_batch_send_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/email/contact/{contact_id}/status":{"post":{"summary":"Email Update Status","description":"Manually update a contact's status (replied, bounced, etc.).","operationId":"email_update_status_email_contact__contact_id__status_post","parameters":[{"name":"contact_id","in":"path","required":true,"schema":{"type":"integer","title":"Contact Id"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_email_update_status_email_contact__contact_id__status_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/contact/{contact_id}/delete":{"post":{"summary":"Email Delete Contact","operationId":"email_delete_contact_email_contact__contact_id__delete_post","parameters":[{"name":"contact_id","in":"path","required":true,"schema":{"type":"integer","title":"Contact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/x-outreach/add":{"post":{"summary":"X Outreach Add","operationId":"x_outreach_add_email_x_outreach_add_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_x_outreach_add_email_x_outreach_add_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/x-outreach/{target_id}/delete":{"post":{"summary":"X Outreach Delete","operationId":"x_outreach_delete_email_x_outreach__target_id__delete_post","parameters":[{"name":"target_id","in":"path","required":true,"schema":{"type":"integer","title":"Target Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/email/x-outreach/{target_id}/toggle-sent":{"post":{"summary":"X Outreach Toggle Sent","operationId":"x_outreach_toggle_sent_email_x_outreach__target_id__toggle_sent_post","parameters":[{"name":"target_id","in":"path","required":true,"schema":{"type":"integer","title":"Target Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/webhooks/email-inbound":{"post":{"summary":"Email Inbound Webhook","description":"Receive inbound emails from the Cloudflare Email Worker.\n\nExpected JSON payload:\n    {\n      \"from\": \"sender@example.com\",\n      \"to\":   \"replies+<token>@replies.deepbluealpha.io\",\n      \"raw_b64\": \"<base64 of full RFC822 message>\"\n    }\n\nAuthentication: shared secret in `X-Inbound-Secret` header (env var\nINBOUND_EMAIL_SECRET on the server).","operationId":"email_inbound_webhook_webhooks_email_inbound_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/resend":{"post":{"summary":"Resend Webhook","description":"Handle Resend delivery events: delivered, opened, bounced, complained.","operationId":"resend_webhook_webhooks_resend_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/backtest/run":{"post":{"summary":"Api Backtest Run","description":"Run a real backtest. Alpha tier or higher required.","operationId":"api_backtest_run_api_backtest_run_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/backtest/sample":{"get":{"summary":"Api Backtest Sample","description":"Public summary for the preview UI — LIVE, from signal_outcomes (graded\nnightly by scripts/compute_scorecard.py) over the last 90 days, on the same\n7-day-close rule as the paid run. Individual fires are NOT included (those\nare Alpha content). Replaced a hardcoded April 2026 peak-graded snapshot\n(\"MOMENTUM 94.7%, 0 losses\") on 2026-09-25.","operationId":"api_backtest_sample_api_backtest_sample_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/custom-wallets":{"get":{"summary":"List Custom Wallets","description":"The caller's own custom wallets + their cap. Returns 200 with cap=0 for\nsub-Whale tiers so the page can render the locked state, never an error.","operationId":"list_custom_wallets_api_alerts_custom_wallets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Add Custom Wallet","operationId":"add_custom_wallet_api_alerts_custom_wallets_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/custom-wallets/{wallet_id}":{"delete":{"summary":"Delete Custom Wallet","operationId":"delete_custom_wallet_api_alerts_custom_wallets__wallet_id__delete","parameters":[{"name":"wallet_id","in":"path","required":true,"schema":{"type":"integer","title":"Wallet Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/custom-wallet-tx":{"post":{"summary":"Custom Wallet Tx Endpoint","description":"Internal endpoint — called by the all-trades processor when a swap involves\nan address some Whale user is monitoring. Protected by ALERTS_BOT_SECRET.","operationId":"custom_wallet_tx_endpoint_api_alerts_custom_wallet_tx_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/process-tx":{"post":{"summary":"Process Tx Endpoint","description":"Internal endpoint — called by main.py alert_scanner every 30s.\n\nReceives one raw transaction dict and fans it out to all matching user\nalert subscriptions via dispatch_alert(). Protected by ALERTS_BOT_SECRET.","operationId":"process_tx_endpoint_api_alerts_process_tx_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alerts":{"get":{"summary":"Alerts Page","operationId":"alerts_page_alerts_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/alerts/stats":{"get":{"summary":"Alert Stats","description":"Return platform-level stats for KPI display (tracked wallet count, etc.).","operationId":"alert_stats_api_alerts_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/wallet-search":{"get":{"summary":"Wallet Search","description":"Search tracked wallets by address prefix or label. Used by the wallet alert modal.","operationId":"wallet_search_api_alerts_wallet_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts":{"get":{"summary":"List Alerts","operationId":"list_alerts_api_alerts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Create Alert","operationId":"create_alert_api_alerts_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/channels":{"get":{"summary":"Get Channels","operationId":"get_channels_api_alerts_channels_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"put":{"summary":"Update Channels","operationId":"update_channels_api_alerts_channels_put","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/channels/telegram":{"post":{"summary":"Telegram Connect","description":"Generate a one-time 6-digit code. User sends /connect CODE to @DeepBlueAlphaBot.","operationId":"telegram_connect_api_alerts_channels_telegram_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/channels/telegram/verify":{"post":{"summary":"Telegram Verify","description":"Called internally by the Telegram bot after /connect is processed.","operationId":"telegram_verify_api_alerts_channels_telegram_verify_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/{alert_id}":{"put":{"summary":"Update Alert","operationId":"update_alert_api_alerts__alert_id__put","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Alert","operationId":"delete_alert_api_alerts__alert_id__delete","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/{alert_id}/snooze":{"post":{"summary":"Snooze Alert","description":"Snooze a specific alert for N hours (pass hours=0 to un-snooze).","operationId":"snooze_alert_api_alerts__alert_id__snooze_post","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/mute":{"post":{"summary":"Mute Alerts","description":"Globally mute all alerts for the user for N hours (hours=0 to un-mute).","operationId":"mute_alerts_api_alerts_mute_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/test":{"post":{"summary":"Test Alert","description":"Send a test notification on a specific channel.","operationId":"test_alert_api_alerts_test_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/test-type":{"post":{"summary":"Test Alert Type","description":"Send a realistic sample notification for a specific alert type.","operationId":"test_alert_type_api_alerts_test_type_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alerts/history":{"get":{"summary":"Alert History","description":"Return recent delivery history for the authenticated user.","operationId":"alert_history_api_alerts_history_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/dispatch":{"post":{"summary":"Dispatch Endpoint","description":"Internal endpoint — called by block_listener/WHaiLE. Protected by ALERTS_BOT_SECRET.","operationId":"dispatch_endpoint_api_alerts_dispatch_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/playbook":{"get":{"summary":"Playbook Page","description":"Whale Playbook — event reaction dashboard. Whale-tier gated.","operationId":"playbook_page_playbook_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/playbook/events":{"get":{"summary":"Api Playbook Events","description":"List events, optionally filtered by category or status.","operationId":"api_playbook_events_api_playbook_events_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Api Create Event","description":"Create a new whale event. Admin-only.","operationId":"api_create_event_api_playbook_events_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/playbook/past-events":{"get":{"summary":"Api Playbook Past Events","description":"All past events sorted newest-first. Includes SCHEDULED events whose date has\nalready passed AND all COMPLETED events. Used by the Past Events tab.","operationId":"api_playbook_past_events_api_playbook_past_events_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}":{"get":{"summary":"Api Playbook Event","description":"Single event with computed flow metrics for its time window.","operationId":"api_playbook_event_api_playbook_events__event_id__get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"summary":"Api Update Event","description":"Update an existing event. Admin-only.","operationId":"api_update_event_api_playbook_events__event_id__put","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}/flow":{"get":{"summary":"Api Playbook Event Flow","description":"Flow data bucketed by time for the event window. bucket=60 (hourly) or 5 (5-min).","operationId":"api_playbook_event_flow_api_playbook_events__event_id__flow_get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}},{"name":"bucket","in":"query","required":false,"schema":{"type":"integer","default":60,"title":"Bucket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/live":{"get":{"summary":"Api Playbook Live","description":"Current live event with real-time accumulated metrics. Returns null if no live event.","operationId":"api_playbook_live_api_playbook_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/playbook/patterns":{"get":{"summary":"Api Playbook Patterns","description":"Aggregated whale reaction patterns by event category.","operationId":"api_playbook_patterns_api_playbook_patterns_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/playbook/impact":{"get":{"summary":"Api Playbook Impact","description":"Top COMPLETED events ranked by absolute net flow magnitude.\nUsed by the Analytics tab Impact Leaderboard panel.","operationId":"api_playbook_impact_api_playbook_impact_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/positioning":{"get":{"summary":"Api Playbook Positioning","description":"Pre-positioning gauge for the Upcoming tab.\nShows how whale activity compares to the 7-day baseline ahead of each\nupcoming SCHEDULED event.","operationId":"api_playbook_positioning_api_playbook_positioning_get","parameters":[{"name":"days_ahead","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days Ahead"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/confluence":{"get":{"summary":"Api Playbook Confluence","description":"Detect event confluence — multiple high-severity events within a short\nwindow. High confluence = higher whale volatility expected.\nUsed by the Upcoming tab Confluence panel.","operationId":"api_playbook_confluence_api_playbook_confluence_get","parameters":[{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","default":14,"title":"Window Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}/status":{"post":{"summary":"Api Event Status","description":"Transition event status: SCHEDULED→LIVE→COMPLETED. Admin-only.\nWhen transitioning to COMPLETED, auto-computes and caches final metrics.","operationId":"api_event_status_api_playbook_events__event_id__status_post","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/search":{"get":{"summary":"Api Playbook Search","description":"Search events by freetext, category, and flow direction. READ-ONLY.","operationId":"api_playbook_search_api_playbook_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"flow","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"date","title":"Sort"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/compare":{"get":{"summary":"Api Playbook Compare","description":"Compare two events side by side with full metrics and differences. READ-ONLY.","operationId":"api_playbook_compare_api_playbook_compare_get","parameters":[{"name":"a","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"A"}},{"name":"b","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"B"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}/recovery":{"get":{"summary":"Api Playbook Recovery","description":"Compute hourly net flow AFTER event timestamp to find recovery point. READ-ONLY.","operationId":"api_playbook_recovery_api_playbook_events__event_id__recovery_get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}/signals":{"get":{"summary":"Api Playbook Signals","description":"Pre-event whale positioning: real transactions in the 6h before the event.\nUses the transactions table — shows buy/sell volume by 30-min bucket,\nthe biggest individual trades, and the most active wallets. READ-ONLY.","operationId":"api_playbook_signals_api_playbook_events__event_id__signals_get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}/fastest":{"get":{"summary":"Api Playbook Fastest","description":"Find the first N whale transactions AFTER the event timestamp. READ-ONLY.","operationId":"api_playbook_fastest_api_playbook_events__event_id__fastest_get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/playbook/events/{event_id}/recompute":{"post":{"summary":"Api Playbook Recompute","description":"Admin-only: recompute final metrics for any COMPLETED event from the\nlive transactions table. Use this to fix hardcoded seed data.","operationId":"api_playbook_recompute_api_playbook_events__event_id__recompute_post","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"integer","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/whale-accumulation":{"get":{"summary":"Public Whale Accumulation","operationId":"public_whale_accumulation_api_v1_public_whale_accumulation_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/positioning":{"get":{"summary":"Positioning Page","description":"Whale Accumulation Trend — built to the approved mockups (spec §11).\n\nTiering is enforced HERE, server-side, not just in the template:\n  anon  → majors + score + divergence public; asset table is a signup teaser\n  free  → asset table top FREE_TABLE_ROWS, then a Pro teaser\n  pro+  → full table + size cohorts\n  alpha+→ named accumulator wallets\nCache keys are split by tier so an anon render never reaches a logged-in\nvisitor (the existing _page_cache pattern, per the 2026-08-17 anon gate).","operationId":"positioning_page_positioning_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/accumulation":{"get":{"summary":"Accumulation Legacy Redirect","operationId":"accumulation_legacy_redirect_accumulation_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/picks2/summary":{"get":{"summary":"Picks2 Summary","description":"Headline counts, runner distribution, peak-vs-close and follow-through.","operationId":"picks2_summary_api_picks2_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks2/distributions":{"get":{"summary":"Picks2 Distributions","description":"Histograms of highest reading and 7-day close, horizon medians, monthly series.","operationId":"picks2_distributions_api_picks2_distributions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks2/bands":{"get":{"summary":"Picks2 Bands","description":"Outcome by number of flagging addresses, and by conviction score.","operationId":"picks2_bands_api_picks2_bands_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks2/tokens":{"get":{"summary":"Picks2 Tokens","description":"One row per token — the fix for 7 near-identical rows per token.","operationId":"picks2_tokens_api_picks2_tokens_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":250,"minimum":1,"default":60,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/picks2/token/{symbol}":{"get":{"summary":"Picks2 Token Detail","description":"The individual dated picks behind one token.","operationId":"picks2_token_detail_api_picks2_token__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/picks2/picks":{"get":{"summary":"Picks2 All Picks","description":"Every graded pick as one row each — the set the on-page filters run over.\n\nThe page filters (token / address band / funnel stage) are predicates over\nper-pick records. Fetching those per token left the default \"all tokens\"\nview with an empty set, so the filters had nothing to act on and appeared\ndead. This serves the whole record in one call.\n\nThe cap is deliberately NOT applied here: the funnel's \"outside range\" stage\nis defined as the rows above it, so the client needs them to draw that node.\nEvery consumer applies the cap itself via capOK().","operationId":"picks2_all_picks_api_picks2_picks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks2/recent":{"get":{"summary":"Picks2 Recent","description":"Recently flagged tokens for the 'Recently flagged' panel — INCLUDES\nstill-PENDING picks (not yet graded at their 7-day close). The graded-only\ndatasets above power every stat/funnel; this one exists so the panel's\n'flagged N days ago' reflects the true latest flag (including today's picks),\nnot just picks old enough to have graded. Feeds the panel's dates/dots only.","operationId":"picks2_recent_api_picks2_recent_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks2/behaviour":{"get":{"summary":"Picks2 Behaviour","description":"What tracked whales did after a pick: how long they held, what move they\nexited into, by which route. Past-tense observation only.","operationId":"picks2_behaviour_api_picks2_behaviour_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks2/wallets":{"get":{"summary":"Picks2 Wallets","description":"Wallet activity on picks they EXITED.\n\nExit-side only: whale_picks stores how many whales entered, never which, so\nnothing here may imply a wallet selected or called a pick. Rows carry a\ntruncated address; the caller links to /wallet/<address>.\n\nCURRENTLY-TRACKED ONLY: every wallet here is INNER-JOINed to tracked_wallets, so\na wallet the reranker has since evicted (exchange / market-maker / churned-out,\nsub-threshold) does not appear even though its historical pick-exits remain in\nwhale_pick_exits. Before this, the LEFT JOIN let evicted wallets through — their\nNULL churn passed the `churn <= 250` guard — and they dominated the list because\nhigh-churn addresses have the most exits (93% of the old list was untracked).","operationId":"picks2_wallets_api_picks2_wallets_get","parameters":[{"name":"order","in":"query","required":false,"schema":{"type":"string","default":"picks","title":"Order"}},{"name":"min_picks","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":1,"title":"Min Picks"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/picks2/exit-timing/{pick_id}":{"get":{"summary":"Picks2 Exit Timing","description":"Every dated whale exit on one pick: day offset and move vs entry.\n\nOne entry marker (the pick) and many exit markers — the record never states\nwhich wallets entered, so per-wallet entry timing does not exist.","operationId":"picks2_exit_timing_api_picks2_exit_timing__pick_id__get","parameters":[{"name":"pick_id","in":"path","required":true,"schema":{"type":"integer","title":"Pick Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/picks2/top-runners":{"get":{"summary":"Picks2 Top Runners","description":"Highest recorded readings, in the sane 10-300% band (the cap excludes the\nthree known bad-entry-price records).","operationId":"picks2_top_runners_api_picks2_top_runners_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":60,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/picks2/exit-timing":{"get":{"summary":"Picks2 Exit Timing Index","description":"Index of picks that carry enough dated exits to chart, for the picker.\nCapped at two per token so one token cannot fill the list.","operationId":"picks2_exit_timing_index_api_picks2_exit_timing_get","parameters":[{"name":"min_exits","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":2,"default":8,"title":"Min Exits"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/echo":{"get":{"summary":"Echo Page","description":"Echo Simulator page. Whale-tier gated (ECHO_FREE_PREVIEW overrides).\nAlso gated by echo_live setting — set to 0 in admin to show coming-soon without redeploy.","operationId":"echo_page_echo_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/echo/portfolio":{"get":{"summary":"Echo Portfolio","description":"Return current portfolio: cash, holdings with live prices, total value, P&L.","operationId":"echo_portfolio_api_echo_portfolio_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/feed":{"get":{"summary":"Echo Feed","operationId":"echo_feed_api_echo_feed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/trade":{"post":{"summary":"Echo Trade","description":"Execute a manual simulated trade (BUY or SELL).","operationId":"echo_trade_api_echo_trade_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/copy":{"post":{"summary":"Echo Copy","description":"One-click copy a specific whale transaction into the simulator.","operationId":"echo_copy_api_echo_copy_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/trades":{"get":{"summary":"Echo Trades","description":"Paginated trade history for the current user.","operationId":"echo_trades_api_echo_trades_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/echo/leaderboard":{"get":{"summary":"Echo Leaderboard","operationId":"echo_leaderboard_api_echo_leaderboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/analytics":{"get":{"summary":"Echo Analytics","description":"Portfolio analytics: win rate, realized/unrealized P&L, profit factor, best/worst trade.","operationId":"echo_analytics_api_echo_analytics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/hot-tokens":{"get":{"summary":"Echo Hot Tokens","description":"Top tokens by whale volume in the last 24h — used for the Hot Tokens tab.","operationId":"echo_hot_tokens_api_echo_hot_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/token/{address}/chart-data":{"get":{"summary":"Echo Token Chart Data","description":"Return price history + market stats for the chart panel.\n\ntf values: 1H | 1D | 1W | 1M | ALL\nPrice history comes from CoinGecko (contract address lookup).\nStats (mcap, volume, 24h change, liquidity) come from DexScreener.\nATH + 24h high/low come from CoinGecko market data endpoint.\nCached server-side for 5 minutes to respect CoinGecko rate limits.","operationId":"echo_token_chart_data_api_echo_token__address__chart_data_get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}},{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"1D","title":"Tf"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/echo/tokens":{"get":{"summary":"Echo Tokens","description":"All tokens DBA has ever tracked — for the trade panel search.\n\nReturns every distinct (token_address, token_symbol) pair from the\ntransactions table, minus stablecoins/ETH-derivatives/blacklisted addresses.\nSorted by total trade count DESC so the most-active tokens appear first.\nResponse is cached server-side for 5 minutes.\nAnonymous users allowed through (read-only).","operationId":"echo_tokens_api_echo_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/echo/token-lookup":{"get":{"summary":"Echo Token Lookup","description":"Look up a token by contract address — returns symbol and current price.\nUsed by the trade panel search box when the user pastes a 0x address.\nAnonymous users allowed through (read-only).","operationId":"echo_token_lookup_api_echo_token_lookup_get","parameters":[{"name":"address","in":"query","required":false,"schema":{"type":"string","default":"","title":"Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/echo/token/{address}/flow":{"get":{"summary":"Echo Token Flow","description":"24h whale buy/sell flow for a specific token — shown in the trade panel.","operationId":"echo_token_flow_api_echo_token__address__flow_get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/echo/reset":{"post":{"summary":"Echo Reset","description":"Reset portfolio to starting balance. Wipes holdings and trade history.","operationId":"echo_reset_api_echo_reset_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/watchlist":{"get":{"summary":"Watchlist Page","operationId":"watchlist_page_watchlist_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/watchlist":{"get":{"summary":"Api Watchlist List","operationId":"api_watchlist_list_api_watchlist_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Api Watchlist Add","operationId":"api_watchlist_add_api_watchlist_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/watchlist/quick-add":{"get":{"summary":"Watchlist Quick Add","description":"Landing for one-click picks in emails: shows a one-tap confirm page.","operationId":"watchlist_quick_add_watchlist_quick_add_get","parameters":[{"name":"ref","in":"query","required":false,"schema":{"type":"string","default":"","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Watchlist Quick Add Post","operationId":"watchlist_quick_add_post_watchlist_quick_add_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/watchlist/pending":{"post":{"summary":"Api Watchlist Pending","description":"Remember a token to watch for a just-signed-up (usually unverified) user.","operationId":"api_watchlist_pending_api_watchlist_pending_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/watchlist/interest":{"get":{"summary":"Watchlist Interest","description":"Remember a category picked in an email (meta interest:<uid>), then show it.","operationId":"watchlist_interest_watchlist_interest_get","parameters":[{"name":"s","in":"query","required":false,"schema":{"type":"string","default":"","title":"S"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlist/{item_id}":{"delete":{"summary":"Api Watchlist Remove","operationId":"api_watchlist_remove_api_watchlist__item_id__delete","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"integer","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"summary":"Api Watchlist Edit","operationId":"api_watchlist_edit_api_watchlist__item_id__patch","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"integer","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlist/feed":{"get":{"summary":"Api Watchlist Feed","operationId":"api_watchlist_feed_api_watchlist_feed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/watchlist/digest":{"get":{"summary":"Api Watchlist Digest","description":"Today's digest for the signed-in user, plus their email-delivery preference.\n\nRead-only. Sub-Pro accounts get `allowed:false` + an empty payload so the page\ncan render an upgrade teaser — never an error, and never any digest content.","operationId":"api_watchlist_digest_api_watchlist_digest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/watchlist/digest/email":{"post":{"summary":"Api Watchlist Digest Email","description":"Turn daily-digest EMAIL/Telegram delivery on or off. Default is off; the\non-site panel is unaffected either way. Pro+ only.","operationId":"api_watchlist_digest_email_api_watchlist_digest_email_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/watchlist/digest/unsubscribe":{"get":{"summary":"Watchlist Digest Unsubscribe","description":"One-click unsubscribe from the watchlist digest email (Pro+ daily AND the\nfree weekly digest, which is default-on). The link token is\nHMAC(JWT_SECRET, 'wl_digest:<uid>'); on match we set meta['wl_digest_optout:<uid>']=1\n(the digest script skips opted-out users on both passes). Always returns a\nfriendly 200 page.","operationId":"watchlist_digest_unsubscribe_watchlist_digest_unsubscribe_get","parameters":[{"name":"u","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"U"}},{"name":"t","in":"query","required":false,"schema":{"type":"string","default":"","title":"T"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlist/alerts":{"get":{"summary":"Api Watchlist Alerts","operationId":"api_watchlist_alerts_api_watchlist_alerts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Api Watchlist Alerts Set","description":"Turn free coin alerts on/off ({\"enabled\": bool}). Turning them on never\noverrides a global unsubscribe; those still block every alert.","operationId":"api_watchlist_alerts_set_api_watchlist_alerts_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/watchlist/alerts/telegram":{"post":{"summary":"Api Watchlist Alerts Telegram","description":"Free coin alerts: issue the same one-time /connect code the Pro alerts page\nuses (the Pro /api/alerts/channels/telegram route stays Pro-gated). Any\nsigned-in account, only while free coin alerts are switched on; 5 codes/hour.","operationId":"api_watchlist_alerts_telegram_api_watchlist_alerts_telegram_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/watchlist/alerts/telegram/disconnect":{"post":{"summary":"Api Watchlist Alerts Telegram Disconnect","description":"Unlink Telegram for the signed-in account (same columns the Pro page uses).","operationId":"api_watchlist_alerts_telegram_disconnect_api_watchlist_alerts_telegram_disconnect_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/watchlist/alerts/off":{"get":{"summary":"Watchlist Alerts Off","description":"One-click \"turn off coin alerts\" from an alert email.\nToken = HMAC(JWT_SECRET, 'free_alerts:<uid>'). Always a friendly 200 page.","operationId":"watchlist_alerts_off_watchlist_alerts_off_get","parameters":[{"name":"u","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"U"}},{"name":"t","in":"query","required":false,"schema":{"type":"string","default":"","title":"T"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlist/coins":{"get":{"summary":"Api Watchlist Coins","operationId":"api_watchlist_coins_api_watchlist_coins_get","parameters":[{"name":"suggest","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Suggest"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/whale-index":{"get":{"summary":"V1 Whale Index","description":"Daily 0–100 whale sentiment score + components.","operationId":"v1_whale_index_api_v1_whale_index_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/top-tokens":{"get":{"summary":"V1 Top Tokens","description":"Per-token net whale flow over the timeframe (1H | 24H | 7D). Stablecoins excluded.","operationId":"v1_top_tokens_api_v1_top_tokens_get","parameters":[{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"24H","title":"Tf"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/top-wallets":{"get":{"summary":"V1 Top Wallets","description":"Whale leaderboard — address, tracked volume, rank, label.","operationId":"v1_top_wallets_api_v1_top_wallets_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/transactions":{"get":{"summary":"V1 Transactions","description":"Recent whale transactions, newest first. Paginate with before_id.","operationId":"v1_transactions_api_v1_transactions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"before_id","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Before Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/token/{symbol}/flow":{"get":{"summary":"V1 Token Flow","description":"Single-token whale flow summary over 24h / 7d / 30d.","operationId":"v1_token_flow_api_v1_token__symbol__flow_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/watchlist":{"get":{"summary":"V1 Watchlist","description":"The key owner's saved watchlist + 7d live metrics per item.","operationId":"v1_watchlist_api_v1_watchlist_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/signals":{"get":{"summary":"V1 Signals","description":"Business: graded whale signals, oldest first. Page with after_id (= next_after_id).","operationId":"v1_signals_api_v1_signals_get","parameters":[{"name":"start","in":"query","required":false,"schema":{"type":"string","title":"Start"}},{"name":"end","in":"query","required":false,"schema":{"type":"string","title":"End"}},{"name":"signal_type","in":"query","required":false,"schema":{"type":"string","title":"Signal Type"}},{"name":"token","in":"query","required":false,"schema":{"type":"string","title":"Token"}},{"name":"graded_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Graded Only"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":500,"title":"Limit"}},{"name":"after_id","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"After Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/signals/summary":{"get":{"summary":"V1 Signals Summary","description":"Business: backtest summary of graded signals over a window (7-day close).","operationId":"v1_signals_summary_api_v1_signals_summary_get","parameters":[{"name":"start","in":"query","required":false,"schema":{"type":"string","title":"Start"}},{"name":"end","in":"query","required":false,"schema":{"type":"string","title":"End"}},{"name":"signal_type","in":"query","required":false,"schema":{"type":"string","title":"Signal Type"}},{"name":"token","in":"query","required":false,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/whale-index":{"get":{"summary":"Public Whale Index","description":"Public, unauthenticated Whale Sentiment Index. CORS-enabled, cached 60s.","operationId":"public_whale_index_api_v1_public_whale_index_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/whale-index/badge.svg":{"get":{"summary":"Whale Index Badge","description":"Embeddable SVG badge with the live score. Cached 5 min.","operationId":"whale_index_badge_whale_index_badge_svg_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/og/whale-index.png":{"get":{"summary":"Og Wsi Banner","description":"Dynamic OG banner for /whale-index — shows live WSI score.","operationId":"og_wsi_banner_og_whale_index_png_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/whale-index":{"get":{"summary":"Whale Index Page","description":"Whale Sentiment Index page. Free tier — no gate. Score and history are\nserver-rendered so crawlers and AI engines see the live numbers in HTML.","operationId":"whale_index_page_whale_index_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/widget/whale-index":{"get":{"summary":"Widget Whale Index","description":"Self-contained embeddable widget — designed to be loaded in an iframe.","operationId":"widget_whale_index_widget_whale_index_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/widget":{"get":{"summary":"Widget Configurator","description":"Widget embed-code configurator page.","operationId":"widget_configurator_widget_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/mcp":{"get":{"summary":"Mcp Get","operationId":"mcp_get_mcp_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"summary":"Mcp Post","operationId":"mcp_post_mcp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"delete":{"summary":"Mcp Delete","operationId":"mcp_delete_mcp_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"options":{"summary":"Mcp Options","operationId":"mcp_options_mcp_options","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/mcp-registry-auth":{"get":{"summary":"Mcp Registry Auth","operationId":"mcp_registry_auth__well_known_mcp_registry_auth_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/openai-apps-challenge":{"get":{"summary":"Openai Apps Challenge","operationId":"openai_apps_challenge__well_known_openai_apps_challenge_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/glama.json":{"get":{"summary":"Glama Connector Json","operationId":"glama_connector_json__well_known_glama_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/token/{symbol}/whale-week":{"get":{"summary":"Api Whale Week","operationId":"api_whale_week_api_token__symbol__whale_week_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og/whale-week/{symbol}.png":{"get":{"summary":"Og Whale Week","operationId":"og_whale_week_og_whale_week__symbol__png_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og/whale-week/{symbol}/square.png":{"get":{"summary":"Og Whale Week Square","operationId":"og_whale_week_square_og_whale_week__symbol__square_png_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/whale-cards":{"get":{"summary":"Whale Cards Page","operationId":"whale_cards_page_whale_cards_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/telegram-bot":{"get":{"summary":"Telegram Bot Page","description":"'Add the whale bot to your Telegram group' page (2026-10-09 growth push).","operationId":"telegram_bot_page_telegram_bot_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/whale-cards":{"get":{"summary":"Api Whale Cards","description":"This week's top tokens by |net| whale exchange flow — used by the weekly X post script.","operationId":"api_whale_cards_api_whale_cards_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/discord/interactions":{"post":{"summary":"Discord Interactions","operationId":"discord_interactions_discord_interactions_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/smart-money":{"get":{"summary":"Smart Money Page","operationId":"smart_money_page_smart_money_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/smart-money/leaderboard":{"get":{"summary":"Smart Money Api","operationId":"smart_money_api_api_v1_smart_money_leaderboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/smart-money/buying-now":{"get":{"summary":"Smart Money Buying Now","operationId":"smart_money_buying_now_api_v1_smart_money_buying_now_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/newsletter/subscribe":{"post":{"summary":"Newsletter Subscribe","description":"Capture an email for the weekly newsletter.","operationId":"newsletter_subscribe_api_newsletter_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"delete":{"summary":"Newsletter Unsubscribe By Email","description":"Unsubscribe by email — auth required (used by account toggle).","operationId":"newsletter_unsubscribe_by_email_api_newsletter_subscribe_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/newsletter/unsubscribe":{"get":{"summary":"Newsletter Unsubscribe","description":"One-click unsubscribe via emailed link.","operationId":"newsletter_unsubscribe_newsletter_unsubscribe_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/newsletter/status":{"get":{"summary":"Newsletter Status","description":"Check if an email is subscribed (used by account toggle).\n\nOnly answers for the signed-in caller's own address. Anonymous callers and\nlookups of any other address get {\"subscribed\": false} — the same shape the\naccount page already handles — so subscription state can't be enumerated.","operationId":"newsletter_status_api_newsletter_status_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/newsletter/send-test":{"post":{"summary":"Newsletter Send Test","description":"Admin-only: send a test newsletter to team@deepbluealpha.io.","operationId":"newsletter_send_test_api_newsletter_send_test_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/newsletter/send-test-drip":{"post":{"summary":"Newsletter Send Test Drip","description":"Admin-only: send a specific drip email to team@deepbluealpha.io for preview.","operationId":"newsletter_send_test_drip_api_newsletter_send_test_drip_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/attention":{"get":{"summary":"Admin Attention","operationId":"admin_attention_admin_attention_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"7d","title":"Window"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/content-brief":{"get":{"summary":"Admin Content Brief","description":"Private editorial brief: turns the attention signal into a what-to-make plan.\nAdmin-only (same gate as /admin/attention). The source signal must NEVER be\npublished — it only decides which PUBLIC whale/on-chain content to produce.","operationId":"admin_content_brief_admin_content_brief_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"7d","title":"Window"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/track/cta":{"post":{"summary":"Track Cta","operationId":"track_cta_api_track_cta_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/track/convert":{"post":{"summary":"Track Convert","operationId":"track_convert_api_track_convert_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/trialbar":{"get":{"summary":"Trialbar State","operationId":"trialbar_state_api_trialbar_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/trialbar/done":{"post":{"summary":"Trialbar Done","operationId":"trialbar_done_api_trialbar_done_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/business/overview":{"get":{"summary":"Business Overview","operationId":"business_overview_api_business_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/business/webhooks":{"post":{"summary":"Webhook Create","operationId":"webhook_create_api_business_webhooks_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/business/webhooks/{hook_id}/update":{"post":{"summary":"Webhook Update","operationId":"webhook_update_api_business_webhooks__hook_id__update_post","parameters":[{"name":"hook_id","in":"path","required":true,"schema":{"type":"integer","title":"Hook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/business/webhooks/{hook_id}/rotate-secret":{"post":{"summary":"Webhook Rotate","operationId":"webhook_rotate_api_business_webhooks__hook_id__rotate_secret_post","parameters":[{"name":"hook_id","in":"path","required":true,"schema":{"type":"integer","title":"Hook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/business/webhooks/{hook_id}/test":{"post":{"summary":"Webhook Test","operationId":"webhook_test_api_business_webhooks__hook_id__test_post","parameters":[{"name":"hook_id","in":"path","required":true,"schema":{"type":"integer","title":"Hook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/business/webhooks/{hook_id}/delete":{"post":{"summary":"Webhook Delete","operationId":"webhook_delete_api_business_webhooks__hook_id__delete_post","parameters":[{"name":"hook_id","in":"path","required":true,"schema":{"type":"integer","title":"Hook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/business/webhooks/{hook_id}/deliveries":{"get":{"summary":"Webhook Deliveries","operationId":"webhook_deliveries_api_business_webhooks__hook_id__deliveries_get","parameters":[{"name":"hook_id","in":"path","required":true,"schema":{"type":"integer","title":"Hook Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/data/files":{"get":{"summary":"Data Files List","operationId":"data_files_list_data_files_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/data/files/{name}":{"get":{"summary":"Data Files Download","operationId":"data_files_download_data_files__name__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/business/plans":{"get":{"summary":"Business Plans","description":"Public: prices + whether checkout is open; plus the caller's buyer state.","operationId":"business_plans_api_business_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/business/checkout/stripe":{"post":{"summary":"Business Checkout Stripe","operationId":"business_checkout_stripe_api_business_checkout_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/business/checkout/crypto":{"post":{"summary":"Business Checkout Crypto","operationId":"business_checkout_crypto_api_business_checkout_crypto_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/business/portal":{"post":{"summary":"Business Portal","operationId":"business_portal_api_business_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/watchdog":{"get":{"summary":"Health Watchdog","description":"Watch-the-watcher. 200 if the payment + pipeline monitors have run recently,\n503 if any went silent. Point a FREE UptimeRobot HTTP monitor at this URL — if a\nmonitor (or the whole server) dies, this flips to 503 and UptimeRobot emails you.\n(The July 2 incident: a monitor died and nothing noticed. This closes that gap.)","operationId":"health_watchdog_health_watchdog_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/alerts":{"get":{"summary":"Health Alerts","description":"Alert-engine liveness watchdog. 200 if the alert-evaluation loop AND Telegram\ndeliverability are both fresh; 503 otherwise. Point a FREE UptimeRobot HTTP\nmonitor here — if alerts silently stop delivering (as they did for 11 days in\nAug 2026 with nobody noticing), this flips to 503 and UptimeRobot emails you\nwithin minutes.\n\nHeartbeats (unix-ts in meta, written by routes_alerts):\n  hb_alert_dispatch — the per-tx alert-evaluation path ran (stale >15min = stalled engine)\n  hb_alert_canary   — Telegram sendChatAction/getMe succeeded (stale >20min = delivery broken)\nhb_alert_delivery (last real user delivery) is reported for visibility only — it is\nlegitimately sparse when few subscriptions match, so it is NEVER an alarm condition.","operationId":"health_alerts_health_alerts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Returns 200 if the tracker backend is alive and making progress.\nDocker healthcheck and external monitors hit this endpoint.\n\nDuring backfill/catch-up after a restart, data timestamps will be old\nbut the system IS working. We check that the backend process is alive\nAND that new rows are being inserted (last_id is advancing), rather\nthan only checking timestamp freshness. This prevents Docker from\nrestarting the container during normal catch-up.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/favicon.ico":{"get":{"summary":"Favicon Ico","description":"Serve favicon at root /favicon.ico for browsers that request it directly.","operationId":"favicon_ico_favicon_ico_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/manifest.webmanifest":{"get":{"summary":"Pwa Manifest","description":"PWA manifest — served at root so browsers honor the Add-to-Home-Screen prompt.","operationId":"pwa_manifest_manifest_webmanifest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/sw.js":{"get":{"summary":"Service Worker","description":"PWA service worker — MUST be served from root scope (not /static/) so it\ncan intercept requests for /feed, /wallets, /api/* etc.\n\nAuto-bumps CACHE_VERSION based on the latest mtime across critical static\nassets (CSS + dashboard JS + sw.js itself). Each deploy updates those mtimes,\nso the cache key changes on every deploy → users get fresh assets on the next\npage load instead of one-page-stale CSS/JS. Falls back to the file's hardcoded\n\"v6\" if anything goes wrong, so the SW always works.","operationId":"service_worker_sw_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/offline.html":{"get":{"summary":"Offline Fallback","description":"Fallback page shown by the service worker when the user has no network.","operationId":"offline_fallback_offline_html_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/robots.txt":{"get":{"summary":"Robots Txt","operationId":"robots_txt_robots_txt_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/sitemap.xml":{"get":{"summary":"Sitemap Xml","operationId":"sitemap_xml_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/research/rss.xml":{"get":{"summary":"Research Rss","description":"RSS 2.0 feed of research posts. Referenced via <link rel=\"alternate\"> in\nbase.html — helps search engines and AI crawlers discover and index new content.","operationId":"research_rss_research_rss_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/6bcc3833e213e89be621101bb35d0f17.txt":{"get":{"summary":"Indexnow Key File","description":"Serve IndexNow key verification file.","operationId":"indexnow_key_file_6bcc3833e213e89be621101bb35d0f17_txt_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/og/token/{symbol}.png":{"get":{"summary":"Og Token Banner","operationId":"og_token_banner_og_token__symbol__png_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og/card/{symbol}.png":{"get":{"summary":"Og Card Banner","operationId":"og_card_banner_og_card__symbol__png_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og/wallet/{address}.png":{"get":{"summary":"Og Wallet Banner","operationId":"og_wallet_banner_og_wallet__address__png_get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og/report/{report_date}.png":{"get":{"summary":"Og Report Banner","operationId":"og_report_banner_og_report__report_date__png_get","parameters":[{"name":"report_date","in":"path","required":true,"schema":{"type":"string","title":"Report Date"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/llms.txt":{"get":{"summary":"Llms Txt","description":"Machine-readable site description optimized for AI crawlers.","operationId":"llms_txt_llms_txt_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/llms-full.txt":{"get":{"summary":"Llms Full Txt","description":"/llms.txt plus a longer data reference for AI crawlers (2026-10-16).","operationId":"llms_full_txt_llms_full_txt_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/research":{"get":{"summary":"Research Index","operationId":"research_index_research_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/research/{path}":{"get":{"summary":"Research Dispatch","operationId":"research_dispatch_research__path__get","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/blog":{"get":{"summary":"Blog Index Redirect","operationId":"blog_index_redirect_blog_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/blog/rss.xml":{"get":{"summary":"Blog Rss Redirect","operationId":"blog_rss_redirect_blog_rss_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/guides/{slug}":{"get":{"summary":"Guide Page","operationId":"guide_page_guides__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/blog/{slug}":{"get":{"summary":"Blog Post Redirect","description":"Legacy /blog/{slug} → /research/{slug} — permanent 301 for all old URLs.","operationId":"blog_post_redirect_blog__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/push/vapid-public-key":{"get":{"summary":"Push Vapid Key","operationId":"push_vapid_key_api_push_vapid_public_key_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/push/subscribe":{"post":{"summary":"Push Subscribe","operationId":"push_subscribe_api_push_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"delete":{"summary":"Push Unsubscribe","operationId":"push_unsubscribe_api_push_subscribe_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/report-subscribe":{"post":{"summary":"Report Subscribe","description":"Subscribe an email to daily report delivery.","operationId":"report_subscribe_api_report_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/reports/unsubscribe":{"get":{"summary":"Report Unsubscribe","description":"Unsubscribe from daily report emails.","operationId":"report_unsubscribe_reports_unsubscribe_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Dashboard","operationId":"dashboard__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/feed":{"get":{"summary":"Whale Feed","operationId":"whale_feed_feed_get","parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"min","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/trends":{"get":{"summary":"Trends","operationId":"trends_trends_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/news":{"get":{"summary":"News","operationId":"news_news_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/whaile":{"get":{"summary":"Whaile","operationId":"whaile_whaile_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/whaile/chat":{"post":{"summary":"Whaile Chat","description":"WHaiLE chat endpoint — natural-language interface to on-chain whale data.\n\nSAFETY: every response goes through the guardrails in website/whaile.py:\n  1. Input advice-pattern pre-check → canned refusal if triggered\n  2. Claude call with a hard-rules system prompt + descriptive tools\n  3. Output filter for banned advice language → safe fallback if triggered\n  4. Disclaimer appended to the reply (also rendered persistently in UI)\n\nQuota tiers:\n  - Anonymous / free / pro → 2 questions/day per IP (teaser)\n  - Alpha → 25 questions/day per user\n  - Whale → 100 questions/day per user\n  - Leviathan → 250 questions/day per user","operationId":"whaile_chat_api_whaile_chat_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/whale/{symbol}":{"get":{"summary":"Whale Symbol Redirect","operationId":"whale_symbol_redirect_whale__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/whale-intelligence":{"get":{"summary":"Whale Intelligence Alias","operationId":"whale_intelligence_alias_whale_intelligence_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/compare":{"get":{"summary":"Compare Hub","operationId":"compare_hub_compare_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/compare/{slug}":{"get":{"summary":"Compare Detail","operationId":"compare_detail_compare__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/alternatives":{"get":{"summary":"Alternatives Hub","operationId":"alternatives_hub_alternatives_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/glossary":{"get":{"summary":"Glossary Page","operationId":"glossary_page_glossary_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/tools":{"get":{"summary":"Tools Page","operationId":"tools_page_tools_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/free-crypto-whale-tracker":{"get":{"summary":"Free Whale Tracker","operationId":"free_whale_tracker_free_crypto_whale_tracker_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/how-to-track-ethereum-smart-money":{"get":{"summary":"How To Track Smart Money","operationId":"how_to_track_smart_money_how_to_track_ethereum_smart_money_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/umami":{"get":{"summary":"Umami Redirect","operationId":"umami_redirect_umami_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/picks-v2":{"get":{"summary":"Whale Picks Old Urls","description":"Retired 2026-09-23: the rebuild has been live at /picks since 2026-08-14.\n301 so old links and any crawled copies consolidate onto /picks.","operationId":"whale_picks_old_urls_picks_v2_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/picks-legacy":{"get":{"summary":"Whale Picks Old Urls","description":"Retired 2026-09-23: the rebuild has been live at /picks since 2026-08-14.\n301 so old links and any crawled copies consolidate onto /picks.","operationId":"whale_picks_old_urls_picks_legacy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/picks":{"get":{"summary":"Whale Picks Page","description":"Whale Pick Record (Alpha tier) — the rebuilt page.\n\nSwapped forward 2026-08-14 to picks_preview_v3.html once the rebuild gained a\ndesigned locked view (the earlier revert was because its gated state rendered\nas a page-length em-dash skeleton that read as broken). Alpha gating is applied\nexactly as /picks-v2 does: _check_tier decides entitlement, picks_entitled\ndrives which branch the template renders, and every figure the page draws still\ncomes from the Alpha-gated /api/picks2/* endpoints — a non-Alpha caller gets the\nstatic locked landing and no data in the HTML.\n\nThe previous page stays reachable at /picks-legacy for one-route rollback.","operationId":"whale_picks_page_picks_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/proof-row":{"get":{"summary":"Api Proof Row","description":"Public endpoint — returns best pick for display + founder seat count.\n\nUsed by:\n- index_v2.html (SSR fallback via _ctx)\n- base.html JS: fetches for every blog/research page to inject the proof block","operationId":"api_proof_row_api_proof_row_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/picks-summary":{"get":{"summary":"Api Picks Summary","description":"Summary stats for the /picks scoreboard bar. Requires Alpha tier or higher.","operationId":"api_picks_summary_api_picks_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/top-runners":{"get":{"summary":"Api Top Runners","description":"PUBLIC preview: the top whale-pick runners (winning tokens) — shown to free\nusers on /picks as a taste of the Alpha scoreboard. Curated highlight only\n(winning ticker + 7d return + peak + whale count); the full scoreboard, exits,\nand methodology stay Alpha-gated. Returns at their PEAK within window, not exit\nprice. Cached 120s.","operationId":"api_top_runners_api_top_runners_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":12,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/profitable-whales":{"get":{"summary":"Api Profitable Whales","description":"Most-profitable whales + what each is holding and buying now.\n\nRanks tracked whales (holdings >= $250k) by TOTAL PnL (realized +\nunrealized). Every displayed position is RECONCILED against the whale's\nlive on-chain balance so the feature never shows a sold/ghost position or a\nstale value — accuracy is verified at request time. Requires Alpha tier+.","operationId":"api_profitable_whales_api_profitable_whales_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/pick-detail/{pick_id}":{"get":{"summary":"Api Pick Detail","description":"Expandable deep-dive for one pick (Alpha+). Present-tense facts only:\nwhich whales exited (each linked to its /wallet/<addr> page), still-holding\nvs exited counts, entry price vs realized follow-through. No recommendations.","operationId":"api_pick_detail_api_pick_detail__pick_id__get","parameters":[{"name":"pick_id","in":"path","required":true,"schema":{"type":"integer","title":"Pick Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/winning-wallets":{"get":{"summary":"Api Winning Wallets","description":"Winning-Wallets board (Alpha+) — the hero of the /picks exploration hub.\n\nRanks tracked whales (holdings >= $250k, net-positive P/L) by a TRANSPARENT\nblend of past/present on-chain FACTS — never a forecast (NFA):\n  blend = 50% P/L (realized+unrealized) + 30% win-rate (% of open positions\n          currently in profit) + 20% recency (how recently active).\nTwo lenses via `mode`:\n  - performance : rank by blend score (best-performing first)\n  - active      : rank by recency (most-active-now first)\nEvery wallet carries its address so the UI links to /wallet/<addr>.","operationId":"api_winning_wallets_api_winning_wallets_get","parameters":[{"name":"mode","in":"query","required":false,"schema":{"type":"string","default":"performance","title":"Mode"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/current":{"get":{"summary":"Api Signals Current","description":"Current (recent) live fires for one signal family.\n\nPowers the click-through from the /backtest \"By signal family\" table:\na family with a strong historical hit rate is only actionable if you can\nimmediately see what it is firing on RIGHT NOW. Read-only over ai_signals,\nserved off the existing (created_at, signal_type) index.\nRequires: Alpha tier or higher (same gate as the rest of the picks data).","operationId":"api_signals_current_api_signals_current_get","parameters":[{"name":"family","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":40,"title":"Family"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":14,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/whales":{"get":{"summary":"Api Signals Whales","description":"Which tracked whales actually traded this token in the window.\n\nThe drill-down behind a signal: a signal names a TOKEN, and this answers\n\"who was behind it\" so a subscriber can go from a fired signal all the way\nto an individual whale's wallet page.\n\nDeliberately joins tracked_wallets (INNER): /wallet/{address} serves a 410\n\"not tracked\" page for anything outside the tracked set, so linking an\nuntracked address would walk the user into a dead end. Only whales with a\nreal page are returned.\nRequires: Alpha tier or higher.","operationId":"api_signals_whales_api_signals_whales_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":32,"title":"Token"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":2160,"minimum":1,"default":168,"title":"Hours"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":12,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/picks-full":{"get":{"summary":"Api Picks Full","description":"Full picks dataset for the /picks page.\nReturns up to 90 days of picks with all timeframes, whale exits,\ntoken leaderboard, and equity-curve data.\nRequires: Alpha tier or higher.","operationId":"api_picks_full_api_picks_full_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/trades":{"get":{"summary":"Trades Redirect","operationId":"trades_redirect_trades_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/about":{"get":{"summary":"About Redirect","operationId":"about_redirect_about_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alternative-to-nansen":{"get":{"summary":"Alt Nansen","operationId":"alt_nansen_alternative_to_nansen_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alternative-to-arkham":{"get":{"summary":"Alt Arkham","operationId":"alt_arkham_alternative_to_arkham_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alternative-to-arkham-intelligence":{"get":{"summary":"Alt Arkham Full","operationId":"alt_arkham_full_alternative_to_arkham_intelligence_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alternative-to-whale-alert":{"get":{"summary":"Alt Whale Alert","operationId":"alt_whale_alert_alternative_to_whale_alert_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alternative-to-dexcheck":{"get":{"summary":"Alt Dexcheck","operationId":"alt_dexcheck_alternative_to_dexcheck_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/alternative-to-glassnode":{"get":{"summary":"Alt Glassnode","operationId":"alt_glassnode_alternative_to_glassnode_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/glassnode-alternative":{"get":{"summary":"Glassnode Alt","operationId":"glassnode_alt_glassnode_alternative_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/nansen-alternative":{"get":{"summary":"Nansen Alt","operationId":"nansen_alt_nansen_alternative_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/arkham-alternative":{"get":{"summary":"Arkham Alt","operationId":"arkham_alt_arkham_alternative_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/whale-alert-api-alternative":{"get":{"summary":"Whale Alert Api Alt","operationId":"whale_alert_api_alt_whale_alert_api_alternative_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/free-ethereum-whale-tracker":{"get":{"summary":"Free Whale Redirect","operationId":"free_whale_redirect_free_ethereum_whale_tracker_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/intelligence":{"get":{"summary":"Intelligence","operationId":"intelligence_intelligence_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":168,"title":"Hours"}},{"name":"h_cex","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Cex"}},{"name":"h_cluster","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Cluster"}},{"name":"h_approval","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Approval"}},{"name":"h_drawdown","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Drawdown"}},{"name":"h_contrarian","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Contrarian"}},{"name":"h_cexflow","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Cexflow"}},{"name":"h_drypowder","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Drypowder"}},{"name":"h_exit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Exit"}},{"name":"h_consensus","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Consensus"}},{"name":"h_rotation","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Rotation"}},{"name":"h_momentum","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"H Momentum"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/faq":{"get":{"summary":"Faq","operationId":"faq_faq_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api-docs":{"get":{"summary":"Api Docs Page","operationId":"api_docs_page_api_docs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/whale-api":{"get":{"summary":"Whale Api Page","operationId":"whale_api_page_whale_api_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/data/sample.csv":{"get":{"summary":"Data Sample Csv","operationId":"data_sample_csv_data_sample_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/business":{"get":{"summary":"Business Page","operationId":"business_page_business_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/data/methodology":{"get":{"summary":"Data Methodology Page","operationId":"data_methodology_page_data_methodology_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/data":{"get":{"summary":"Data Sample Redirect","operationId":"data_sample_redirect_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/data/sample":{"get":{"summary":"Data Sample Redirect","operationId":"data_sample_redirect_data_sample_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/roadmap":{"get":{"summary":"Roadmap","operationId":"roadmap_roadmap_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/featured-in-preview":{"get":{"summary":"Featured In Preview","operationId":"featured_in_preview_featured_in_preview_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/reports/latest":{"get":{"summary":"Latest Report","operationId":"latest_report_reports_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/reports/ethereum-whale-report-{date}":{"get":{"summary":"Daily Report","operationId":"daily_report_reports_ethereum_whale_report__date__get","parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","title":"Date"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/reports":{"get":{"summary":"Report Archive","operationId":"report_archive_reports_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/generate-report":{"post":{"summary":"Admin Generate Report","operationId":"admin_generate_report_admin_generate_report_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_generate_report_admin_generate_report_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account":{"get":{"summary":"Account Page","operationId":"account_page_account_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/login":{"get":{"summary":"Login Page","operationId":"login_page_login_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/register":{"get":{"summary":"Register Page","operationId":"register_page_register_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/welcome":{"get":{"summary":"Welcome Page","operationId":"welcome_page_welcome_get","parameters":[{"name":"verified","in":"query","required":false,"schema":{"type":"string","title":"Verified"}},{"name":"trial","in":"query","required":false,"schema":{"type":"string","title":"Trial"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/signup":{"get":{"summary":"Signup Redirect","operationId":"signup_redirect_signup_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/forgot-password":{"get":{"summary":"Forgot Password Page","operationId":"forgot_password_page_forgot_password_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/reset-password":{"get":{"summary":"Reset Password Page","operationId":"reset_password_page_reset_password_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/subscribe":{"get":{"summary":"Subscribe Page","operationId":"subscribe_page_subscribe_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/pricing":{"get":{"summary":"Pricing Page","operationId":"pricing_page_pricing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/alpha-plan":{"get":{"summary":"Paid Intent Redirect","operationId":"paid_intent_redirect_alpha_plan_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/upgrade":{"get":{"summary":"Paid Intent Redirect","operationId":"paid_intent_redirect_upgrade_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/pro":{"get":{"summary":"Paid Intent Redirect","operationId":"paid_intent_redirect_pro_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/wallets":{"get":{"summary":"Api Wallets","description":"Part B browse endpoint: value-ordered keyset pagination + address/label\nsearch across ALL tracked wallets. Returns rendered <tr> rows (single source:\n_wallets_rows.html) + an opaque next_cursor. Public, DB-only, zero Alchemy.","operationId":"api_wallets_api_wallets_get","parameters":[{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wallets":{"get":{"summary":"Wallets","operationId":"wallets_wallets_get","parameters":[{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wallet/{address}":{"get":{"summary":"Wallet Detail","operationId":"wallet_detail_wallet__address__get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/screener":{"get":{"summary":"Screener Page","description":"Whale Screener — Alpha-gated token filter tool.","operationId":"screener_page_screener_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/whales-buying-today":{"get":{"summary":"Whales Buying Today","description":"What Are Whales Buying Today — live ranked board of net whale flow by token.","operationId":"whales_buying_today_whales_buying_today_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/whales":{"get":{"summary":"Whales Index","description":"Whale Sectors index page — shows all categories with aggregate stats.","operationId":"whales_index_whales_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/whales/{category}":{"get":{"summary":"Whales Sector","description":"Category-level whale flow hub page. Aggregates whale activity across\nall tracked tokens in a sector (RWA, DeFi, Memecoins, AI, L2, etc.).","operationId":"whales_sector_whales__category__get","parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/holdings":{"get":{"summary":"Api Holdings","description":"Current whale holdings by token. Free sees a teaser, Pro+ the full board.","operationId":"api_holdings_api_holdings_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/holdings/{symbol}":{"get":{"summary":"Api Holdings Token","description":"Which whales hold this token, and at what basis. Alpha tier or higher.","operationId":"api_holdings_token_api_holdings__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/holdings":{"get":{"summary":"Holdings Page","description":"What Whales Hold — current holdings board across the tracked whale base.","operationId":"holdings_page_holdings_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/tokens":{"get":{"summary":"Tokens Index","description":"Index page listing all tokens with tracked whale activity. Internal hub\nthat links out to every /token/{symbol} landing page.","operationId":"tokens_index_tokens_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/token/{symbol}/clusters":{"get":{"summary":"Api Token Clusters","description":"Pro+: the wallets and timing behind each whale cluster on this token (7 days).","operationId":"api_token_clusters_api_token__symbol__clusters_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/token/{symbol}":{"get":{"summary":"Token Detail","description":"Per-token whale activity landing page. Targets long-tail queries like\n'{TOKEN} whale activity', '{TOKEN} smart money', 'who is buying {TOKEN}'.","operationId":"token_detail_token__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/price/{symbol}":{"get":{"summary":"Api Price","description":"Return CoinGecko price series + whale trade markers for a token.","operationId":"api_price_api_price__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Tf"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/market-data/{symbol}":{"get":{"summary":"Api Market Data","description":"Return market data (mcap, volume, supply, ATH) for a token.\n\nPrimary source is the CoinGecko prewarm cache (_market_data_prewarm_loop, every 10 min).\nOn a true miss — a token with a page but no CoinGecko-ID coverage — fall back to a\ncached, contract-resolved DexScreener lookup so the panel is never blank for a\nDEX-traded token. Fallback entries are 3-tuples (data, expires_at, \"fb\") so the\nprewarm's 2-tuple entries keep their exact original behavior.","operationId":"api_market_data_api_market_data__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transactions":{"get":{"summary":"Api Transactions","operationId":"api_transactions_api_transactions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","maximum":1000000,"minimum":0,"default":0,"title":"Offset"}},{"name":"direction","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Direction"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"min_usd","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Usd"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stats":{"get":{"summary":"Api Stats","operationId":"api_stats_api_stats_get","parameters":[{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"24H","title":"Tf"}},{"name":"hours","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":168},{"type":"null"}],"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/major-flows":{"get":{"summary":"Api Major Flows","description":"Whale pressure for ETH, ETH_DERIV, BTC, BTC_DERIV.\n\nIf asset is omitted, returns all four categories in one response.\nRequires: Pro tier or higher (Intelligence Suite).","operationId":"api_major_flows_api_major_flows_get","parameters":[{"name":"asset","in":"query","required":false,"schema":{"type":"string","title":"Asset"}},{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"24H","title":"Tf"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/exchange-flows":{"get":{"summary":"Api Exchange Flows","description":"Per-exchange CEX inflow/outflow breakdown.\n\nCEX_DEPOSIT = tokens sent TO exchange by whale = bearish (inflow)\nCEX_WITHDRAW = tokens received FROM exchange by whale = bullish (outflow)\nReturns exchanges sorted by total volume descending.\nRequires: Pro tier or higher (Intelligence Suite).","operationId":"api_exchange_flows_api_exchange_flows_get","parameters":[{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"24H","title":"Tf"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/summary":{"get":{"summary":"Api Summary","operationId":"api_summary_api_summary_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/top-tokens":{"get":{"summary":"Api Top Tokens","operationId":"api_top_tokens_api_top_tokens_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":168},{"type":"null"}],"title":"Hours"}},{"name":"tf","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tf"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screener":{"get":{"summary":"Api Screener","operationId":"api_screener_api_screener_get","parameters":[{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"24H","title":"Tf"}},{"name":"min_buy_ratio","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100,"minimum":0},{"type":"null"}],"title":"Min Buy Ratio"}},{"name":"max_buy_ratio","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100,"minimum":0},{"type":"null"}],"title":"Max Buy Ratio"}},{"name":"min_whale_count","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"Min Whale Count"}},{"name":"min_volume","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"title":"Min Volume"}},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"}},{"name":"flow_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow Type"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"net_flow","title":"Sort"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":2000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stablecoin-flows":{"get":{"summary":"Api Stablecoin Flows","operationId":"api_stablecoin_flows_api_stablecoin_flows_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/coordination-signals":{"get":{"summary":"Api Coordination Signals","description":"Multi-wallet coordinated buying signals.\nRequires: Pro tier or higher (Intelligence Suite).","operationId":"api_coordination_signals_api_coordination_signals_get","parameters":[{"name":"min_wallets","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min Wallets"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallet-scores":{"get":{"summary":"Api Wallet Scores","operationId":"api_wallet_scores_api_wallet_scores_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sector-rotation":{"get":{"summary":"Api Sector Rotation","operationId":"api_sector_rotation_api_sector_rotation_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/top-wallets":{"get":{"summary":"Api Top Wallets","operationId":"api_top_wallets_api_top_wallets_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trending":{"get":{"summary":"Api Trending","operationId":"api_trending_api_trending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/news":{"get":{"summary":"Api News","operationId":"api_news_api_news_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/daily-summary":{"get":{"summary":"Api Daily Summary","operationId":"api_daily_summary_api_daily_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/hourly-volume":{"get":{"summary":"Api Hourly Volume","operationId":"api_hourly_volume_api_hourly_volume_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/hourly-ratio":{"get":{"summary":"Api Hourly Ratio","description":"Hourly buy/sell ratio trend over the last 24h.\n\nExcludes stablecoins / wrapped assets (matches chart description).\nDrops hours with too few trades (noise) and caps the displayed ratio so a\nsingle early-hour outlier doesn't blow out the y-axis.","operationId":"api_hourly_ratio_api_hourly_ratio_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/flow-funnel":{"get":{"summary":"Api Flow Funnel","description":"Unified end-to-end whale capital flow funnel.\nRequires: Pro tier or higher (Intelligence Suite).\n\nCombines three independent data sources:\n  1. Whale stable INFLOWS from exchanges (DRY_POWDER signals — exchange OUTflow = whale INflow)\n  2. Whale stable->alt deployment (transactions.counter_token_symbol, alt-base only)\n  3. Whale alt->stable profit-taking (transactions.counter_token_symbol, alt-base only)\n  4. Whale stable OUTFLOWS to exchanges (DRY_POWDER_INFLOW signals — exchange INflow = whale OUTflow)\n\nUSD amounts are parsed from `ai_signals.headline` (format: \"$N TOKEN ...\").\n`score_impact` is a confidence score, not a dollar value.","operationId":"api_flow_funnel_api_flow_funnel_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":2160,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stable-flow":{"get":{"summary":"Api Stable Flow","description":"Classify recent whale swaps by counter-token type and aggregate.\n\nBuckets each swap as one of:\n  - STABLE -> ALT  : whale BUY of a risk asset (ETH or alt) funded by stables\n  - ALT -> STABLE  : whale SELL of a risk asset (ETH or alt) into stables\n  - ETH -> ALT     : whale BUY of an alt funded by ETH/WETH (rotation within risk)\n  - ALT -> ETH     : whale SELL of an alt into ETH/WETH    (rotation within risk)\n  - OTHER          : counter not classifiable\n\nEXCLUDES rows where the *base* token is itself a stablecoin or BTC wrap —\nthose are stable↔stable repositioning or BTC rebalancing, not risk rotation.\nETH/WETH as the base token IS included: WETH/USDC swaps are genuine risk-on\n(deploying stablecoin dry powder into ETH) or risk-off (selling ETH to cash).\nRequires: Pro tier or higher (Intelligence Suite).","operationId":"api_stable_flow_api_stable_flow_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":2160,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dry-powder":{"get":{"summary":"Api Dry Powder","description":"Aggregate whale portfolio composition over time.\n\nAccepts `hours` (preferred) or legacy `days`. Bucket granularity is\nauto-selected from the window so the chart always plots ~10–60 points:\n  - <=24h  → hourly buckets\n  - <=72h  → 4-hour buckets\n  - <=168h → 6-hour buckets\n  - >168h  → daily buckets\n\nFor each bucket, sum the *latest* snapshot per wallet within that bucket\nto get aggregate dry-powder metrics. dry_powder_ratio = stables / total.\nRequires: Pro tier or higher (Intelligence Suite).","operationId":"api_dry_powder_api_dry_powder_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":8760,"minimum":1,"default":720,"title":"Hours"}},{"name":"days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":365,"minimum":1},{"type":"null"}],"title":"Days"}},{"name":"min_wallets","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":20,"title":"Min Wallets"}},{"name":"min_avg_usd","in":"query","required":false,"schema":{"type":"number","minimum":0,"default":100000,"title":"Min Avg Usd"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/whale-picks":{"get":{"summary":"Api Whale Picks","description":"Whale picks scorecard with entry price tracking, conviction scoring,\nand 7d evaluation. Entry price = average whale buy price from the 48h-24h\ntransaction window (DexScreener fallback if unavailable).\nVerdict uses 7-day CLOSING change from entry (not peak).\nGrades: BIG WIN >10%, WIN >0% (any positive close), FLAT -5% to 0%, LOSS <-5%.\nPeak is tracked separately as a secondary 'best seen' stat.\nConviction = quality-weighted (wallet score × base formula).\nMinimum 5 whales to qualify.\nRequires: Alpha tier or higher.","operationId":"api_whale_picks_api_whale_picks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/whale-consensus":{"get":{"summary":"Api Whale Consensus","description":"Tokens actively bought by the most tracked wallets — convergence signal.\n\nFast query: counts distinct wallets with BULLISH transactions per token,\nsums their buy volume. No expensive net-position CTE needed.\nRequires: Pro tier or higher (Intelligence Suite).","operationId":"api_whale_consensus_api_whale_consensus_get","parameters":[{"name":"min_wallets","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":2,"default":2,"title":"Min Wallets"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/login":{"get":{"summary":"Admin Login Page","operationId":"admin_login_page_admin_login_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"summary":"Admin Login","operationId":"admin_login_admin_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_login_admin_login_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/logout":{"get":{"summary":"Admin Logout","operationId":"admin_logout_admin_logout_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin":{"get":{"summary":"Admin Panel","operationId":"admin_panel_admin_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/seo-snapshot":{"post":{"summary":"Admin Seo Snapshot","description":"Upsert a daily SEO snapshot. Called by the SEO audit script.","operationId":"admin_seo_snapshot_admin_seo_snapshot_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/seo-report":{"get":{"summary":"Admin Seo Report Get","operationId":"admin_seo_report_get_admin_seo_report_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Admin Seo Report Post","operationId":"admin_seo_report_post_admin_seo_report_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/settings":{"post":{"summary":"Admin Save Settings","operationId":"admin_save_settings_admin_settings_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/blacklist/token":{"post":{"summary":"Admin Add Token","operationId":"admin_add_token_admin_blacklist_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_add_token_admin_blacklist_token_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/blacklist/token/remove":{"post":{"summary":"Admin Remove Token","operationId":"admin_remove_token_admin_blacklist_token_remove_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_remove_token_admin_blacklist_token_remove_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/token-registry/set-canonical":{"post":{"summary":"Admin Set Canonical Token","description":"Admin: pin a specific contract address as canonical for a ticker symbol.\nSets admin_override=1 so it survives hourly recomputes.\nUse this to fix wrong-CA issues without waiting for the next registry refresh.","operationId":"admin_set_canonical_token_admin_token_registry_set_canonical_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_set_canonical_token_admin_token_registry_set_canonical_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/token-registry":{"get":{"summary":"Admin Token Registry","description":"Admin: list tokens that have multiple contract addresses (ambiguous tickers).","operationId":"admin_token_registry_admin_token_registry_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/blacklist/wallet":{"post":{"summary":"Admin Add Wallet","operationId":"admin_add_wallet_admin_blacklist_wallet_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_add_wallet_admin_blacklist_wallet_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/blacklist/wallet/remove":{"post":{"summary":"Admin Remove Wallet","operationId":"admin_remove_wallet_admin_blacklist_wallet_remove_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_remove_wallet_admin_blacklist_wallet_remove_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/costs/add":{"post":{"summary":"Admin Add Cost","operationId":"admin_add_cost_admin_costs_add_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/costs/update":{"post":{"summary":"Admin Update Cost","operationId":"admin_update_cost_admin_costs_update_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/costs/remove":{"post":{"summary":"Admin Remove Cost","operationId":"admin_remove_cost_admin_costs_remove_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/activate-subscription":{"post":{"summary":"Admin Activate Subscription","description":"Manual subscription activation for failed-webhook recovery.\n\nRequires X-Admin-Secret header matching ADMIN_SECRET env var.\nBody: { \"email\": \"...\", \"tier\": \"pro|alpha\", \"months\": 1 }","operationId":"admin_activate_subscription_admin_activate_subscription_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/set-user-tier":{"post":{"summary":"Admin Set User Tier","description":"Directly set a user's tier without creating a subscription record.\nUse /admin/activate-subscription for paying customers.\nThis is for comps, staff accounts, correcting mistakes.\n\nRequires X-Admin-Secret header.\nBody: { \"email\": \"...\", \"tier\": \"free|pro|alpha|whale|leviathan\" }","operationId":"admin_set_user_tier_admin_set_user_tier_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/review-log":{"get":{"summary":"Admin Review Log","operationId":"admin_review_log_admin_review_log_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/founding-waitlist.csv":{"get":{"summary":"Admin Founding Waitlist Csv","description":"Download the founding-member waitlist as CSV. Admin-only.\n\nReads from the DB (authoritative) rather than the on-disk CSV so\nduplicates / late inserts always reflect current state.","operationId":"admin_founding_waitlist_csv_admin_founding_waitlist_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/run-test":{"post":{"summary":"Admin Run Test","operationId":"admin_run_test_admin_run_test_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/test-results":{"get":{"summary":"Admin Test Results","operationId":"admin_test_results_admin_test_results_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/test-schedule":{"post":{"summary":"Admin Test Schedule","operationId":"admin_test_schedule_admin_test_schedule_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_test_schedule_admin_test_schedule_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/fix":{"post":{"summary":"Admin Fix","description":"Execute a fix action from the test results panel.","operationId":"admin_fix_admin_fix_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/scan-status":{"get":{"summary":"Admin Scan Status","description":"Get live scanner status from shared status file.","operationId":"admin_scan_status_admin_scan_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/rerank":{"post":{"summary":"Admin Rerank","description":"Trigger a wallet re-rank evaluation now.","operationId":"admin_rerank_admin_rerank_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/rerank-results":{"get":{"summary":"Admin Rerank Results","operationId":"admin_rerank_results_admin_rerank_results_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/api/wallet-stats":{"get":{"summary":"Admin Wallet Stats","operationId":"admin_wallet_stats_admin_api_wallet_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/rerank-schedule":{"post":{"summary":"Admin Rerank Schedule","operationId":"admin_rerank_schedule_admin_rerank_schedule_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_rerank_schedule_admin_rerank_schedule_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/block-number":{"get":{"summary":"Api Block Number","description":"Returns the latest block number seen in the transactions table.","operationId":"api_block_number_api_block_number_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/public/stats":{"get":{"summary":"Public Stats","description":"Public, unauthenticated stats endpoint. Lightweight. Cached 60s.","operationId":"public_stats_api_v1_public_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/public/top-tokens":{"get":{"summary":"Public Top Tokens","description":"Public, unauthenticated top-10 tokens by 24h whale volume. CORS, 60s cache.\n\nBuilt for AI assistants and external consumers (Custom GPTs, MCP clients,\nembeds). Same filters as the internal dashboard endpoint; curated shape.","operationId":"public_top_tokens_api_v1_public_top_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"Body_admin_add_token_admin_blacklist_token_post":{"properties":{"address":{"type":"string","title":"Address"},"symbol":{"type":"string","title":"Symbol","default":""}},"type":"object","required":["address"],"title":"Body_admin_add_token_admin_blacklist_token_post"},"Body_admin_add_wallet_admin_blacklist_wallet_post":{"properties":{"address":{"type":"string","title":"Address"},"label":{"type":"string","title":"Label","default":""}},"type":"object","required":["address"],"title":"Body_admin_add_wallet_admin_blacklist_wallet_post"},"Body_admin_generate_report_admin_generate_report_post":{"properties":{"date":{"type":"string","title":"Date"}},"type":"object","required":["date"],"title":"Body_admin_generate_report_admin_generate_report_post"},"Body_admin_login_admin_login_post":{"properties":{"password":{"type":"string","title":"Password"},"next":{"type":"string","title":"Next","default":""}},"type":"object","required":["password"],"title":"Body_admin_login_admin_login_post"},"Body_admin_remove_token_admin_blacklist_token_remove_post":{"properties":{"address":{"type":"string","title":"Address"}},"type":"object","required":["address"],"title":"Body_admin_remove_token_admin_blacklist_token_remove_post"},"Body_admin_remove_wallet_admin_blacklist_wallet_remove_post":{"properties":{"address":{"type":"string","title":"Address"}},"type":"object","required":["address"],"title":"Body_admin_remove_wallet_admin_blacklist_wallet_remove_post"},"Body_admin_rerank_schedule_admin_rerank_schedule_post":{"properties":{"hours":{"type":"number","title":"Hours","default":0}},"type":"object","title":"Body_admin_rerank_schedule_admin_rerank_schedule_post"},"Body_admin_set_canonical_token_admin_token_registry_set_canonical_post":{"properties":{"symbol":{"type":"string","title":"Symbol"},"address":{"type":"string","title":"Address"}},"type":"object","required":["symbol","address"],"title":"Body_admin_set_canonical_token_admin_token_registry_set_canonical_post"},"Body_admin_test_schedule_admin_test_schedule_post":{"properties":{"hours":{"type":"number","title":"Hours","default":0}},"type":"object","title":"Body_admin_test_schedule_admin_test_schedule_post"},"Body_email_add_contact_email_contact_post":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"organization":{"type":"string","title":"Organization","default":""},"article_url":{"type":"string","title":"Article Url","default":""},"category":{"type":"string","title":"Category","default":"other"},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","required":["name","email"],"title":"Body_email_add_contact_email_contact_post"},"Body_email_quick_send_email_quick_send_post":{"properties":{"to_email":{"type":"string","title":"To Email"},"to_name":{"type":"string","title":"To Name","default":""},"organization":{"type":"string","title":"Organization","default":""},"category":{"type":"string","title":"Category","default":"other"},"subject":{"type":"string","title":"Subject"},"body_html":{"type":"string","title":"Body Html"}},"type":"object","required":["to_email","subject","body_html"],"title":"Body_email_quick_send_email_quick_send_post"},"Body_email_send_email_send_post":{"properties":{"contact_id":{"type":"integer","title":"Contact Id"},"subject":{"type":"string","title":"Subject"},"body_html":{"type":"string","title":"Body Html"},"in_reply_to":{"type":"string","title":"In Reply To","default":""},"references":{"type":"string","title":"References","default":""}},"type":"object","required":["contact_id","subject","body_html"],"title":"Body_email_send_email_send_post"},"Body_email_update_status_email_contact__contact_id__status_post":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"Body_email_update_status_email_contact__contact_id__status_post"},"Body_x_outreach_add_email_x_outreach_add_post":{"properties":{"handle":{"type":"string","title":"Handle"},"name":{"type":"string","title":"Name"},"followers":{"type":"string","title":"Followers","default":""},"focus":{"type":"string","title":"Focus","default":""},"dm":{"type":"string","title":"Dm"}},"type":"object","required":["handle","name","dm"],"title":"Body_x_outreach_add_email_x_outreach_add_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}