# Pegana > The peg-risk oracle for Solana. Real-time monitoring of LSTs, stablecoins, yield-bearing assets and synthetics. Read via REST, WebSocket, MCP, Webhook, Telegram. ## Docs - [Get v1alerts](https://pegana.xyz/docs/api-reference/alerts/get-v1alerts.md) - [Get v1assets](https://pegana.xyz/docs/api-reference/assets/get-v1assets.md) - [Get v1assets 1](https://pegana.xyz/docs/api-reference/assets/get-v1assets-1.md) - [Get v1assets history](https://pegana.xyz/docs/api-reference/assets/get-v1assets-history.md) - [Get v1assets state](https://pegana.xyz/docs/api-reference/assets/get-v1assets-state.md) - [`GET /v1/audit/{alert_id}` — single receipt with ADR-0006 four-state discrimination.](https://pegana.xyz/docs/api-reference/audit/`get-v1audit-`-—-single-receipt-with-adr-0006-four-statediscrimination.md): Returns `Response` (not `Json`) so each status path can carry distinct headers and body without fighting axum's `Result` → IntoResponse conversion (which forces non-2xx into the `Err` arm). - [Get v1audit](https://pegana.xyz/docs/api-reference/audit/get-v1audit.md) - [Get v1audit onchain](https://pegana.xyz/docs/api-reference/audit/get-v1audit-onchain.md) - [Get v1audit replay bundle](https://pegana.xyz/docs/api-reference/audit/get-v1audit-replay-bundle.md) - [Get v1auditcsv](https://pegana.xyz/docs/api-reference/audit/get-v1auditcsv.md) - [`POST /v1/auth/logout` — revoke the caller's session JWT (by `jti`). Accepts even an already-expired token so a stale tab can still log out.](https://pegana.xyz/docs/api-reference/auth/`post-v1authlogout`-—-revoke-the-callers-session-jwt-by-`jti`accepts-even-an-already-expired-token-so-a-stale-tab-can-still-log-out.md) - [`POST /v1/auth/magic/consume` — public endpoint the web client calls when it lands on `/auth/magic?nonce=…`. Atomically marks the nonce consumed AND returns the telegram_id in a single UPDATE … RETURNING (race-free; two concurrent consumers can't both succeed). On hit, mints a 7-day session JWT — same path as Login Widget.](https://pegana.xyz/docs/api-reference/auth/`post-v1authmagicconsume`-—-public-endpoint-the-web-client-callswhen-it-lands-on-`authmagic?nonce=…`-atomically-marks-the-nonceconsumed-and-returns-the-telegram_id-in-a-single-update-…-returningrace-free;-two-concurrent-consumers-cant-both-succeed-on-hit-mintsa-7-day-session-jwt-—-same-path-as-login-widget.md): Failure modes: - 400 if the body fails to parse. - 401 if the nonce is unknown, already consumed, or expired. - 500 if the JWT insert fails (DB issue). - [`POST /v1/auth/magic/mint` — internal endpoint the bot calls when a user runs `/web`. Authenticates via `x-internal-secret` (constant-time compare against `BOT_INTERNAL_SECRET`). Inserts a fresh nonce row and returns it. No JWT is issued here — that happens on consume.](https://pegana.xyz/docs/api-reference/auth/`post-v1authmagicmint`-—-internal-endpoint-the-bot-calls-when-a-userruns-`web`-authenticates-via-`x-internal-secret`-constant-timecompare-against-`bot_internal_secret`-inserts-a-fresh-nonce-row-andreturns-it-no-jwt-is-issued-here-—-that-happens-on-consume.md): Failure modes: - 401 if the header is missing or wrong. - 400 if the body fails to parse. - 500 if the DB insert fails. - [`POST /v1/auth/telegram` — exchange a verified Telegram Login Widget payload for a 7-day session JWT. Unauthenticated; the HMAC over the payload (signed with SHA256(BOT_TOKEN)) is the credential.](https://pegana.xyz/docs/api-reference/auth/`post-v1authtelegram`-—-exchange-a-verified-telegram-login-widgetpayload-for-a-7-day-session-jwt-unauthenticated;-the-hmac-over-thepayload-signed-with-sha256bot_token-is-the-credential.md) - [Get ](https://pegana.xyz/docs/api-reference/health/get-.md) - [Get healthz](https://pegana.xyz/docs/api-reference/health/get-healthz.md) - [Get readyz](https://pegana.xyz/docs/api-reference/health/get-readyz.md) - [GET /v1/meta/webhook-ips — IP allowlist hint for webhook subscribers.](https://pegana.xyz/docs/api-reference/health/get-v1metawebhook-ips-—-ip-allowlist-hint-for-webhook-subscribers.md): Pattern lifted from Linear (`6 static IPs` page) and GitHub (`GET /meta` with `hooks` field). Subscribers behind enterprise firewalls need to know which source IPs to trust; without this they either disable signature-based trust or refuse our deliveries. - [GET /v1/meta/webhook-keys — active Ed25519 public keys for verifying inbound webhook signatures.](https://pegana.xyz/docs/api-reference/health/get-v1metawebhook-keys-—-active-ed25519-public-keys-for-verifyinginbound-webhook-signatures.md): Lifted from the GitHub pattern (`GET /meta` with `ssh_keys`). During key rotation we publish BOTH the outgoing primary AND the incoming secondary here, so receivers can pre-trust the new key before we cut over. See `pegana_common::webhook_sign` for the full rotation playbook. - [`GET /v1/me` — the authenticated user's profile + digest preferences.](https://pegana.xyz/docs/api-reference/me/`get-v1me`-—-the-authenticated-users-profile-+-digest-preferences.md) - [`GET /v1/me/alerts` — alerts delivered to the caller's subscriptions, newest first. Optional `asset`, `limit` (1..500), and `since` filters.](https://pegana.xyz/docs/api-reference/me/`get-v1mealerts`-—-alerts-delivered-to-the-callers-subscriptionsnewest-first-optional-`asset`-`limit`-1500-and-`since`-filters.md) - [`PATCH /v1/me/preferences` — update locale (`en`|`pt-BR`) and/or daily digest settings. Omitted fields are left unchanged.](https://pegana.xyz/docs/api-reference/me/`patch-v1mepreferences`-—-update-locale-`en`|`pt-br`-andor-dailydigest-settings-omitted-fields-are-left-unchanged.md) - [Get v1methodologycurrent](https://pegana.xyz/docs/api-reference/methodology/get-v1methodologycurrent.md) - [Get v1stats](https://pegana.xyz/docs/api-reference/stats/get-v1stats.md) - [`GET /v1/me/subs` — the caller's alert subscriptions (active first).](https://pegana.xyz/docs/api-reference/subscriptions/`get-v1mesubs`-—-the-callers-alert-subscriptions-active-first.md) - [`PATCH /v1/me/subs/{asset}` — update threshold / active state for an asset's subscription(s). `?only_id=N` scopes to a single row.](https://pegana.xyz/docs/api-reference/subscriptions/`patch-v1mesubs-`-—-update-threshold-active-state-for-anassets-subscriptions-`?only_id=n`-scopes-to-a-single-row.md) - [`POST /v1/me/subs` — create (or re-activate) an alert subscription for an asset at a bps threshold. Idempotent on (asset, threshold, channel).](https://pegana.xyz/docs/api-reference/subscriptions/`post-v1mesubs`-—-create-or-re-activate-an-alert-subscription-for-anasset-at-a-bps-threshold-idempotent-on-asset-threshold-channel.md) - [Soft-delete by default; hard-delete with `?hard=true`. When `?only_id=N` is supplied, scopes to a single row (used by the web console where the UI knows which specific row the user clicked). Without `only_id`, all rows for this user+asset are affected (mirrors `/unsubscribe ` in bot).](https://pegana.xyz/docs/api-reference/subscriptions/soft-delete-by-default;-hard-delete-with-`?hard=true`-when-`?only_id=n`is-supplied-scopes-to-a-single-row-used-by-the-web-console-where-the-uiknows-which-specific-row-the-user-clicked-without-`only_id`-all-rowsfor-this-user+asset-are-affected-mirrors-`unsubscribe-`-in-bot.md) - [`DELETE /v1/me/webhooks/{id}` — deactivate a webhook subscription (soft-delete: is_active=false, keeping its delivery history).](https://pegana.xyz/docs/api-reference/webhooks/`delete-v1mewebhooks-`-—-deactivate-a-webhook-subscriptionsoft-delete:-is_active=false-keeping-its-delivery-history.md) - [`GET /v1/me/webhooks/{id}/deliveries?since=&limit=` — paged audit trail of every delivery attempt against this subscription, ordered newest first. Includes successes (`error = null`), failures, and `is_test = true` rows from `/test`.](https://pegana.xyz/docs/api-reference/webhooks/`get-v1mewebhooks-deliveries?since=&limit=`-—-paged-audittrail-of-every-delivery-attempt-against-this-subscription-orderednewest-first-includes-successes-`error-=-null`-failures-and`is_test-=-true`-rows-from-`test`.md): Backed by `webhook_deliveries` (migration 0023). Both the production fan-out (`dispatcher-rs`) and the single-shot `/test`+`/replay` path write here, so this is the single operator view of receiver health. - [`GET /v1/me/webhooks` — the caller's active webhook subscriptions.](https://pegana.xyz/docs/api-reference/webhooks/`get-v1mewebhooks`-—-the-callers-active-webhook-subscriptions.md) - [`PATCH /v1/me/webhooks/{id}` — partial update of a subscription keeping its `id` (and so its `webhook_deliveries` history) intact.](https://pegana.xyz/docs/api-reference/webhooks/`patch-v1mewebhooks-`-—-partial-update-of-a-subscriptionkeeping-its-`id`-and-so-its-`webhook_deliveries`-history-intact.md): The previous "delete + re-create" workflow orphaned the audit trail under a new id. This endpoint keeps continuity for dashboards and replay. - [`POST /v1/me/webhooks/{id}/replay?since=&limit=` — re-attempt delivery of the dead-letter rows for this subscription inside the window. Modeled on Svix's "Replay Missing".](https://pegana.xyz/docs/api-reference/webhooks/`post-v1mewebhooks-replay?since=&limit=`-—re-attempt-delivery-of-the-dead-letter-rows-for-this-subscriptioninside-the-window-modeled-on-svixs-"replay-missing".md): Successful re-deliveries are NOT removed from `webhook_dead_letter` — the audit trail stays put. Repeated success on the same row is harmless (the receiver's own dedup on `x-pegana-event-id` makes the second delivery a no-op). - [`POST /v1/me/webhooks/{id}/test` — send a synthetic signed payload to the registered URL and return what happened. Mirrors Stripe's "Send test webhook" button. The synthetic event carries the `x-pegana-test: true` header so subscribers can guard prod handlers (e.g. skip downstream order-fill on test deliveries).](https://pegana.xyz/docs/api-reference/webhooks/`post-v1mewebhooks-test`-—-send-a-synthetic-signed-payloadto-the-registered-url-and-return-what-happened-mirrors-stripes"send-test-webhook"-button-the-synthetic-event-carries-the`x-pegana-test:-true`-header-so-subscribers-can-guard-prod-handlerseg-skip-downstream-order-fill-on-test-deliveries.md): No retry. One POST. The caller is operator-triggered, not engine- triggered, so retries would lie about the receiver's true health. - [`POST /v1/me/webhooks` — register an Ed25519-signed webhook for an asset. URL is SSRF- and length-checked; idempotent on (url, asset).](https://pegana.xyz/docs/api-reference/webhooks/`post-v1mewebhooks`-—-register-an-ed25519-signed-webhook-for-an-asseturl-is-ssrf-and-length-checked;-idempotent-on-url-asset.md) - [`GET /v1/ws` — upgrade to a WebSocket carrying the live peg-state stream.](https://pegana.xyz/docs/api-reference/websocket/`get-v1ws`-—-upgrade-to-a-websocket-carrying-the-live-peg-state-stream.md): Not a JSON endpoint: a successful handshake returns `101 Switching Protocols`. After upgrade the server pushes `{op:"update", ...}` and `{op:"heartbeat", ts}` frames; the client may send `{op:"ping"}` (→ `pong`) and `{op:"subscribe"|"unsubscribe", assets:[...]}`. Browsers must present an allowlisted… - [Authentication](https://pegana.xyz/docs/authentication.md): Most Pegana endpoints are public — no API key, no signup. Authenticated routes use a JWT issued from Telegram Login. - [DAI took the same wave as USDC — and proved CDP-collateral isn't bullet-proof](https://pegana.xyz/docs/case-studies/dai-contagion-march-2023.md): MakerDAO's DAI traded below $0.89 alongside USDC during the SVB weekend. Half its backing was USDC; when USDC bled, DAI bled. - [GHO traded sub-$0.97 for eight months — when mint-only is the design flaw](https://pegana.xyz/docs/case-studies/gho-launch-2023.md): Aave's GHO launched July 2023 with a mint cap and no symmetric burn path. The peg stayed below parity for nearly a year before governance fixed the mechanism. - [mSOL flash-crashed to 0.85× SOL on a single oracle update](https://pegana.xyz/docs/case-studies/msol-pyth-may-2022.md): Solend's oracle priced mSOL off a thin Mango pool. One stale update + one whale exit = $21M of liquidations on otherwise-healthy collateral. - [Case studies](https://pegana.xyz/docs/case-studies/overview.md): Five real depegs across the major asset classes Pegana tracks. What broke, why, and what a peg oracle would have shown. - [USDC slipped to $0.87 — the day a stable broke on a bank, not on chain](https://pegana.xyz/docs/case-studies/usdc-svb-march-2023.md): Silicon Valley Bank held ~$3.3B of Circle's reserves. The peg held against intrinsic, but the orderbook didn't trust intrinsic for 36 hours. - [UST: how an algorithmic peg unwinds in 72 hours](https://pegana.xyz/docs/case-studies/ust-collapse-may-2022.md): Terra's UST broke from $1 on May 9 and never came back. Required reading for anyone holding any algorithmic or yield-bearing stable on Solana. - [Changelog](https://pegana.xyz/docs/changelog.md): Notable changes to the Pegana API, MCP server, webhook contract, and docs. Live mirror at pegana.xyz/changelog. - [Confidence score](https://pegana.xyz/docs/concepts/confidence-score.md): Per-asset confidence reflects market depth, source staleness, and decoder health. Below the floor, don't act on the print. - [Hylo CDP CR — the under-collateralization signal](https://pegana.xyz/docs/concepts/hylo-cdp-cr-signal.md): Hylo's hyUSD is a CDP-style stablecoin on Solana. Its peg holds as long as the collateral ratio (CR) stays above the protocol's floor. When CR drops below 130%, Stability Mode triggers — and that's the alert you actually want. - [Why hysteresis matters in peg detection](https://pegana.xyz/docs/concepts/hysteresis-fsm.md): If a stable hovers around the drift threshold, a naive monitor will fire an alert every tick. Pegana's 5-state FSM uses asymmetric enter/exit thresholds and dwell timers so a real transition emits one alert, not a hundred. - [Intrinsic vs market](https://pegana.xyz/docs/concepts/intrinsic-vs-market.md): Every Pegana signal is the gap between two numbers — what the asset's mechanism says it's worth, and what the market actually pays for it. - [What is LST peg drift?](https://pegana.xyz/docs/concepts/lst-peg-drift.md): Liquid Staking Tokens like jitoSOL and mSOL don't peg to $1. They peg to the SOL they accrue inside the stake pool. When market price diverges from that intrinsic SOL value, you're looking at peg drift — and it's a very different signal from a stablecoin depeg. - [Peg risk 101](https://pegana.xyz/docs/concepts/peg-risk-101.md): What it means for an asset to be 'pegged', why pegs break, and how peg risk shows up across the Solana asset classes Pegana tracks. - [The state machine](https://pegana.xyz/docs/concepts/state-machine.md): Pegana's 5-state finite-state machine — PEGGED, DRIFT, DEPEG, CRITICAL, UNKNOWN — and what each transition means. - [Yield-bearing NAV oracles explained](https://pegana.xyz/docs/concepts/yield-bearing-nav-oracles.md): USDY, sUSD, syrupUSDC, sUSDe, ONyc — these aren't $1 stablecoins. Their intrinsic value is a NAV (net asset value) that grows over time as the underlying strategy earns. Monitoring them requires a different formula than USDC. - [FAQ](https://pegana.xyz/docs/faq.md): Common questions about scope, sources, pricing, reliability, and how Pegana compares to other oracle products. - [Embed widget](https://pegana.xyz/docs/guides/embed-widget.md): 320 × 86 iframe badge showing live peg status for any tracked asset. No JavaScript, no API key, ~3 KB HTML. - [MCP for AI agents](https://pegana.xyz/docs/guides/mcp.md): Pegana's Model Context Protocol server gives Claude, Cursor, Cline and Continue native access to live peg state. Four free tools, two paid tools settled in USDC via x402. - [MCP — free tools](https://pegana.xyz/docs/guides/mcp-free-tools.md): Four MCP tools available with no payment, no API key. ping, getAssets, getAssetState, getMethodology. - [MCP — paid tools (x402)](https://pegana.xyz/docs/guides/mcp-paid-tools-x402.md): Two MCP tools settle on-chain in USDC via x402: getAssetHistory ($0.001/call) and subscribePegEvents ($0.0005/call). - [MCP setup — Claude / Cursor / Cline / Continue](https://pegana.xyz/docs/guides/mcp-setup-claude.md): Point your MCP host at https://mcp.pegana.xyz. No install, no clone, no API key. - [REST API](https://pegana.xyz/docs/guides/rest-api.md): JSON over HTTPS. No API key. Soft rate limit. The canonical read path for Pegana state. - [Telegram bot](https://pegana.xyz/docs/guides/telegram-bot.md): @PeganaWatchBot delivers human-readable alerts via Telegram. No wallet, no API key, English. - [Webhooks](https://pegana.xyz/docs/guides/webhooks.md): Ed25519-signed HTTP POST to your endpoint on every peg-state transition. Self-serve registration, delivery history, and replay. - [Webhook receiver — Python / FastAPI](https://pegana.xyz/docs/guides/webhooks-examples-python.md): Production-ready reference using the cryptography library. Verbatim from the repo. - [Webhook receiver — Rust / axum](https://pegana.xyz/docs/guides/webhooks-examples-rust.md): Production-ready reference using ed25519-dalek strict mode. Verbatim from the repo. - [Webhook receiver — TypeScript / Cloudflare Worker](https://pegana.xyz/docs/guides/webhooks-examples-typescript.md): Production-ready reference using the Web Crypto API. Verbatim from the repo. - [Webhook retry policy](https://pegana.xyz/docs/guides/webhooks-retry-policy.md): Failures retry 6 times over roughly 2h35m. After that, delivery is logged as failed and can be replayed. - [Webhook signing — Ed25519](https://pegana.xyz/docs/guides/webhooks-signing.md): Every webhook payload is signed with Ed25519 over a canonical timestamp.body string. Receivers verify against the active key list. - [WebSocket stream](https://pegana.xyz/docs/guides/websocket.md): Sub-second push for every peg-state change on Solana mainnet. No polling, no rate limit. - [Introduction](https://pegana.xyz/docs/introduction.md): Pegana is the peg-risk oracle for Solana. Read peg state for every LST, stablecoin, yield-bearing asset and synthetic — via REST, WebSocket, MCP, Webhook or Telegram. - [Honesty about limits](https://pegana.xyz/docs/methodology/honesty.md): What Pegana does not model. Where the signal can lie. When to mistrust an alert. - [Intrinsic value](https://pegana.xyz/docs/methodology/intrinsic-value.md): What an asset is supposed to be worth, per its own mechanism. Different formula per asset class. - [Market value](https://pegana.xyz/docs/methodology/market-value.md): What you'd actually get swapping the asset. Jupiter routed quote, USDC numeraire, repriced via Pyth. - [Methodology overview](https://pegana.xyz/docs/methodology/overview.md): One formula. Five sources. Four states. Everything Pegana does is in this page. - [The spread](https://pegana.xyz/docs/methodology/spread.md): Formula, EWMA smoothing, per-asset thresholds, and the 5-state FSM with asymmetric hysteresis. - [Pricing](https://pegana.xyz/docs/pricing.md): Free for reads. From $0.001 per call for agent tools — settled in USDC on Solana via x402. - [Quickstart](https://pegana.xyz/docs/quickstart.md): Get a real Pegana response in 5 minutes. Pick your stack. ## OpenAPI Specs - [openapi](https://api.pegana.xyz/openapi.json) ## Optional - [Dashboard](https://pegana.xyz/dashboard) - [Telegram bot](https://t.me/PeganaWatchBot) - [GitHub](https://github.com/lrafasouza/pegana)