{"openapi":"3.1.0","info":{"title":"$GRADUATE","description":"Live graduation probability + smart-money intelligence for pump.fun. Public API requires a free or paid key.","contact":{"name":"$GRADUATE","url":"https://graduateoracle.fun/"},"version":"1.0.0"},"paths":{"/api/v1/live":{"get":{"tags":["v1"],"summary":"Live graduation probabilities","description":"Returns currently-tracked non-mayhem pump.fun mints with k-NN graduation probability scores. Updates every ~5 seconds.","operationId":"live_api_v1_live_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":60,"title":"Limit"}},{"name":"min_prob","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Filter to mints with at least this graduation probability.","default":0.0,"title":"Min Prob"},"description":"Filter to mints with at least this graduation probability."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/probe/{mint}":{"get":{"tags":["v1"],"summary":"Score a single mint","description":"Returns the same enriched mint payload as /api/v1/live (grad probability, k-NN context, all bot/quality/activity signals, top buyers list). Bypasses the dashboard's auto-hide filter — even mints we'd hide from the dashboard are returned, with a `hide_reason` field set so callers can decide for themselves.","operationId":"probe_api_v1_probe__mint__get","parameters":[{"name":"mint","in":"path","required":true,"schema":{"type":"string","description":"Full Solana mint address","title":"Mint"},"description":"Full Solana mint address"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/smart_money_active":{"get":{"tags":["v1"],"summary":"Live mints with smart-money wallets currently positioned","description":"Filtered view of /live: only mints where one or more leaderboard wallets (min_total≥8, smart_score≥0.30) are *currently* in the top buyers. Sorted by smart-money count (most wallets first), tie-broken by graduation probability. Useful for tail-trading proven wallets in real time.","operationId":"smart_money_active_api_v1_smart_money_active_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"min_smart","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Minimum smart-money wallet count for a mint to surface.","default":1,"title":"Min Smart"},"description":"Minimum smart-money wallet count for a mint to surface."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runners":{"get":{"tags":["v1"],"summary":"Live mints with high runner odds from current price","description":"Filtered view of /live ranked by `runner_prob_5x_from_now` — i.e. probability the mint reaches ≥5× ITS CURRENT PRICE (not its launch price). This is the trader-relevant sort: highest expected upside if you buy at the price you see.","operationId":"runners_api_v1_runners_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}},{"name":"tier","in":"query","required":false,"schema":{"type":"string","pattern":"^(2x|3x|5x|10x|20x)$","description":"Which runner tier to rank by (from-now semantics).","default":"5x","title":"Tier"},"description":"Which runner tier to rank by (from-now semantics)."},{"name":"min_prob","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum from-now probability for the chosen tier.","default":0.05,"title":"Min Prob"},"description":"Minimum from-now probability for the chosen tier."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/wallet/{address}":{"get":{"tags":["v1"],"summary":"Wallet pump.fun history","description":"Returns lifetime stats for a wallet (using observed first-12-char prefix) including graduation/runner/rug counts and smart score.","operationId":"wallet_api_v1_wallet__address__get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","description":"Full wallet address (we match by 12-char prefix)","title":"Address"},"description":"Full wallet address (we match by 12-char prefix)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/wallets/leaderboard":{"get":{"tags":["v1"],"summary":"Smart money / sniper leaderboard","description":"Top wallets ranked by smart_score (graduation rate − rug rate, sample-size weighted) or sniper-rug rate.","operationId":"leaderboard_api_v1_wallets_leaderboard_get","parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string","pattern":"^(smart|sniper|graduate)$","default":"smart","title":"Kind"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"min_total","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":8,"title":"Min Total"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks":{"post":{"tags":["v1"],"summary":"Register a webhook subscription (Pro tier)","description":"Register a URL we'll POST signed event payloads to. Each delivery includes an `X-Graduate-Signature` header containing HMAC-SHA256(secret, body). The `secret` field is returned ONCE on creation — store it; we don't expose it on subsequent reads. Use `events=\"*\"` to subscribe to every event kind, or a comma-separated list (e.g. `runner_dev,smart_money_in`).","operationId":"webhooks_register_api_v1_webhooks_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"},"example":{"url":"https://your.app/hook","events":"*"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["v1"],"summary":"List your webhook subscriptions","operationId":"webhooks_list_api_v1_webhooks_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/{webhook_id}":{"delete":{"tags":["v1"],"summary":"Deactivate a webhook subscription","operationId":"webhooks_delete_api_v1_webhooks__webhook_id__delete","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"title":"Webhook Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/deliveries":{"get":{"tags":["v1"],"summary":"Recent delivery attempts (debugging)","description":"Last N delivery attempts across all your webhooks, including status code and any error.","operationId":"webhooks_deliveries_api_v1_webhooks_deliveries_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/composite_predictions":{"get":{"tags":["v1"],"summary":"Composite-signal predictions log","description":"Returns rows from the composite_predictions table — every time the hot-launch composite signal (smart_money_in × max_mult × freshness) crossed the rolling-24h P90 threshold AND market cap was above the $5,000 floor, dedupe-by-mint first-cross. Outcome columns (did_graduate, peak_mult_24h, did_sustain_30m) are NULL until 24h post-cross, then populated by the background resolver from existing outcome tables. Paired with /api/v1/composite_ledger for tamper-evident merkle root verification.","operationId":"composite_predictions_list_api_v1_composite_predictions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"only_resolved","in":"query","required":false,"schema":{"type":"boolean","description":"If true, return only crosses with outcomes resolved.","default":false,"title":"Only Resolved"},"description":"If true, return only crosses with outcomes resolved."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/composite_ledger":{"get":{"tags":["v1"],"summary":"Composite predictions merkle commits","description":"Returns hourly merkle root commits over composite_predictions rows. Same tamper-evident discipline as /api/ledger/commits (grad_prob track), applied to the composite track. Leaves use a composite-specific format starting at version 1.","operationId":"composite_ledger_commits_api_v1_composite_ledger_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats":{"get":{"tags":["v1"],"summary":"Platform-wide aggregate stats","operationId":"stats_api_v1_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/live":{"get":{"summary":"Api Live","description":"Hot path. Reads entirely from the precomputed score cache — no\nsnapshot file I/O, no scoring loop, no DB writes. Bootstrap path\n(cache empty at boot) falls back to a one-time inline read+compute.","operationId":"api_live_api_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/wallets":{"get":{"summary":"Api Wallets","operationId":"api_wallets_api_wallets_get","parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string","default":"smart","title":"Kind"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"min_total","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min Total"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/paper":{"get":{"tags":["paper"],"summary":"Paper-trading P&L","description":"Live performance of the paper-trading harness running three thresholds\n(70/80/90% grad probability). No auth — public proof-of-signal.","operationId":"api_paper_api_paper_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/postmortems":{"get":{"tags":["paper"],"summary":"Closed trades with catastrophic loss + full entry context","description":"Returns paper trades that closed with a loss ≥ `min_loss_pct` (default\n−30%), most-recent first, including the full enriched-mint snapshot we\nhad at entry time.\n\nDefault surfaces only rows that have entry_context_json populated (i.e.\ntrades opened after 2026-04-28 when the column was added). Pass\n`require_context=false` to include older context-less rows.\n\nUseful for:\n- Understanding which mints fooled all our filters at entry\n- Aggregating which bot_flags fired (or didn't) on losing trades\n- Driving future entry-filter improvements based on real failures\n\nNo auth — full transparency.","operationId":"api_postmortems_api_postmortems_get","parameters":[{"name":"min_loss_pct","in":"query","required":false,"schema":{"type":"number","default":0.3,"title":"Min Loss Pct"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"require_context","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Require Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/accuracy":{"get":{"tags":["calibration"],"summary":"Model calibration · proven accuracy","description":"Two-tier proof of the oracle's accuracy.\n\n`lifetime` — leave-one-out k-NN cross-validation on the full historical\ncurve index. Every sampled mint is predicted using all OTHER mints as\nneighbors (never itself). Recomputed every 6h.\n\n`forward` — every live prediction we've made since launch, joined against\nactual graduation outcomes once each mint resolves. Bulletproof: every\nprediction was recorded BEFORE we knew the outcome.\n\nFor new deployments `forward` will have few resolved samples; lifetime\ncarries the marketing weight until forward catches up (~30 days).","operationId":"api_accuracy_api_accuracy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/scope":{"get":{"tags":["calibration"],"summary":"Product scope · what we predict and at what age","description":"Documents what predictions we make, the age window we make them at,\nthe corpus they're calibrated against, and what we explicitly DO NOT\nclaim. Honest scope = defensible product.","operationId":"api_scope_api_scope_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/predictor/health":{"get":{"tags":["calibration"],"summary":"Rug-prob predictor health · sample counts, status, corpus cross-check","description":"Live state of the rug_prob k-NN predictor: sample counts, warming/live\nstatus, calibration freshness, and a corpus-wide cross-check of distinct\nrugged mints across all checkpoint ages (not just the 60s training set).\n\nUse this to decide whether the predictor has graduated from \"warming\" to\n\"live\" and whether MIN_SAMPLES / MIN_POSITIVE_SAMPLES thresholds should\nmove.","operationId":"api_predictor_health_api_predictor_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/ledger/commits":{"get":{"tags":["calibration"],"summary":"Tamper-evident hourly merkle commits over predictions","description":"Returns recent hourly merkle commitments. Each commit locks in every\nprediction made during one hour — its merkle_root_hex is a function of\nthe (mint, age_bucket, predicted_prob, ...) of every covered prediction.\nSnapshot this endpoint regularly. If a past root ever changes, we\nrewrote history.","operationId":"api_ledger_commits_api_ledger_commits_get","parameters":[{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Since"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ledger/proof/{prediction_id}":{"get":{"tags":["calibration"],"summary":"Merkle proof that a prediction was committed in its hour-root","description":"Given a prediction id, returns its leaf hash, the merkle path of\nsibling hashes from leaf to root, and the committed root for that hour.\nVerify locally: hash the leaf payload, walk the path applying\nsha256(left || right) at each step, confirm the result equals\nmerkle_root_hex of the commit.","operationId":"api_ledger_proof_api_ledger_proof__prediction_id__get","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"integer","title":"Prediction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/audit":{"get":{"tags":["calibration"],"summary":"Recent TG alert fires joined with the actual outcome of each called mint","description":"For each TG alert we fired in the last `hours`, return the call details\n(kind, threshold, predicted_prob at fire time) and the actual outcome\n(max_mult achieved, did_graduate, resolved_at). The receipt for \"did\nyour alerts actually catch winners?\" — readable by anyone.\n\nFiltered to the currently-active grad_prob rule and fires logged at or\nafter that rule's activation. Without this floor, fires from older rules\n(different thresholds, different criteria) leak in and contaminate the\naggregate hit rates with traffic that no longer represents the product.","operationId":"api_alerts_audit_api_alerts_audit_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gate_validation":{"get":{"tags":["calibration"],"summary":"Pre-registered sustains-gate criterion · mechanical execution","description":"Returns the most recent gate-validation run (set `history` for more).\nThe criterion is pre-registered in BACKLOG.md ('Sustains-gate validation\ncriterion'); this endpoint executes it mechanically against the live\ndata on an hourly tick. The decision field is one of:\n\n- \"warming\"   — n < 15 in either bucket; not enough data yet\n- \"fails\"     — ratio < 1.5×; sustains doesn't discriminate, gate stays display-only\n- \"hold\"      — 1.5× ≤ ratio < 2×; collect 30 more fires before deciding\n- \"validates\" — ratio ≥ 2× AND n ≥ 15 each; gate ships as a hard suppression\n\nTwo side stratifications are computed alongside the primary criterion:\nby `manufactured_pump` and by `bundle_detected`. These were flagged\n2026-05-04 as label-leak hypotheses — if 100% of post-bond runners are\nbundled/manufactured, the model has effectively learned \"bundled scam =\nrunner\" rather than a real signal. Same population, different bucketing.\nNo decision rule applied to the side analyses; they're observational.","operationId":"api_gate_validation_api_gate_validation_get","parameters":[{"name":"history","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"History"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/predictions/by_mint/{mint}":{"get":{"tags":["calibration"],"summary":"What we predicted on a specific mint, at the moment we predicted it","description":"Look up our forward-logged predictions for a single mint. Returns\nevery (age_bucket × predicted_prob) row we logged + the resolved outcome\nif available. This is the receipt for \"what did you say about THIS\ncoin?\" — every prediction is timestamped and locked in via the merkle\nledger before the outcome was known.","operationId":"api_predictions_by_mint_api_predictions_by_mint__mint__get","parameters":[{"name":"mint","in":"path","required":true,"schema":{"type":"string","title":"Mint"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallet/{short}":{"get":{"summary":"Api Wallet Lookup","description":"Lookup by 12-char short prefix — used internally by the bot to avoid\nloading its own copy of the wallet index. Public, no auth needed.","operationId":"api_wallet_lookup_api_wallet__short__get","parameters":[{"name":"short","in":"path","required":true,"schema":{"type":"string","title":"Short"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/status":{"get":{"tags":["status"],"summary":"System status JSON","description":"Live system health: uptime, recent /api/live latency, daemon\nheartbeats. Polled every 10s by /status. No auth — public artifact.","operationId":"api_status_api_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/sol_price":{"get":{"tags":["status"],"summary":"Live SOL/USD price (5-min cached)","description":"Cached Jupiter SOL→USD quote, used by the marketing page to render\ndollar-equivalent prices that don't go stale when SOL moves. Refreshes\nserver-side every 5 minutes; clients can poll freely.","operationId":"api_sol_price_api_sol_price_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/upgrade":{"post":{"tags":["payments"],"summary":"Create a SOL payment intent","description":"One-shot signup. If no existing API key is supplied, this endpoint will\nissue a fresh one and link the payment intent to it — no two-step \"get\nfree key, then upgrade\" flow needed.\n\nBody: {\n  \"tier\": \"pro\",                           // default \"pro\"\n  \"plan\": \"monthly\" | \"yearly\",            // default \"monthly\"\n  \"key\": \"<existing api key>\",             // optional · upgrades that key\n  \"email\": \"you@example.com\",              // optional · for renewal reminders\n  \"telegram_id\": <int>                     // optional · binds to a TG user\n}\n\nReturns memo + amount + Phantom deeplinks AND (if a new key was minted)\nthe plaintext key shown ONCE. Send SOL with the memo to auto-activate.","operationId":"create_upgrade_intent_api_upgrade_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/upgrade/{memo}":{"get":{"tags":["payments"],"summary":"Check intent status","operationId":"check_intent_api_upgrade__memo__get","parameters":[{"name":"memo","in":"path","required":true,"schema":{"type":"string","title":"Memo"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/new":{"post":{"tags":["keys"],"summary":"Issue a free API key","description":"Body (all optional): { \"email\": \"you@example.com\", \"label\": \"my-bot\" }\n\nReturns the plaintext key ONCE — store it, we don't keep a copy.\n\nEmail is optional. Skipping it gives you a fully anonymous key; the\nonly downside is that we can't email you renewal reminders or recover\na lost key. IP-based rate limit (5/hr) prevents abuse.","operationId":"issue_free_key_api_keys_new_post","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/me":{"get":{"tags":["keys"],"summary":"Inspect your current API key","operationId":"me_api_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Index","operationId":"index__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"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"}}}}