{"openapi":"3.1.0","info":{"title":"PolyInsight API","description":"AI-powered prediction market analysis","version":"1.0.0"},"paths":{"/api/auth/me":{"get":{"tags":["auth"],"summary":"Get Me","description":"Get current user profile with credit balance.","operationId":"get_me_api_auth_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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"}}}}}},"patch":{"tags":["auth"],"summary":"Update Me","description":"Update mutable fields on the current user's profile.","operationId":"update_me_api_auth_me_patch","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/events":{"get":{"tags":["events"],"summary":"List Events","description":"Browse all Polymarket events. No auth required.","operationId":"list_events_api_events_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Per Page"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Search"}},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","pattern":"^(volume|liquidity|end_date|created_at)$","default":"volume","title":"Sort By"}},{"name":"curated_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Curated Only"}},{"name":"hidden_gems","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Hidden Gems"}},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}},{"name":"min_volume","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Volume"}},{"name":"time_horizon","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(today|this_week|this_month|all)$"},{"type":"null"}],"title":"Time Horizon"}},{"name":"min_markets","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Min Markets"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/events/categories":{"get":{"tags":["events"],"summary":"List Categories","description":"Get available event categories.","operationId":"list_categories_api_events_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/events/last-updated":{"get":{"tags":["events"],"summary":"Last Updated","description":"Get the timestamp of the most recent event sync.","operationId":"last_updated_api_events_last_updated_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/events/{event_id}/kalshi":{"get":{"tags":["events"],"summary":"Get Event Kalshi","description":"Cross-venue check: live Kalshi price for this event's primary market.\n\nBest-effort and public. Returns {\"match\": null} when the event can't be\nconfidently resolved to a Kalshi market (or the implied gap is too large\nto trust the match — see kalshi_feed.gap_plausible).","operationId":"get_event_kalshi_api_events__event_id__kalshi_get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","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/events/{event_id}":{"get":{"tags":["events"],"summary":"Get Event","description":"Get full event detail with markets.","operationId":"get_event_api_events__event_id__get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","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/credits":{"get":{"tags":["credits"],"summary":"Get Credits","description":"Get credit balance and transaction history.","operationId":"get_credits_api_credits_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/credits/pricing":{"get":{"tags":["credits"],"summary":"Get Pricing","description":"Current report prices in credits. No auth required.\n\nOnly credit prices are exposed — the underlying provider-cost basis is\nredacted (same philosophy as ReportService._redact_costs).","operationId":"get_pricing_api_credits_pricing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/credits/packs":{"get":{"tags":["credits"],"summary":"Get Packs","description":"Get available credit packs. No auth required.","operationId":"get_packs_api_credits_packs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/credits/checkout":{"post":{"tags":["credits"],"summary":"Create Checkout","description":"Create Stripe Checkout session. Returns hosted checkout URL.","operationId":"create_checkout_api_credits_checkout_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing":{"get":{"tags":["billing"],"summary":"Get Billing","description":"Current API-billing subscription status for the logged-in user.","operationId":"get_billing_api_billing_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/billing/subscribe":{"post":{"tags":["billing"],"summary":"Subscribe","description":"Start a Checkout session for the metered API subscription.\n\nSession-only (an API key cannot subscribe on the owner's behalf).","operationId":"subscribe_api_billing_subscribe_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/billing/portal":{"post":{"tags":["billing"],"summary":"Billing Portal","description":"Stripe Customer Portal session — manage/cancel the API subscription.","operationId":"billing_portal_api_billing_portal_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/reports":{"post":{"tags":["reports"],"summary":"Generate Report","description":"Run LLM Council on an event. Deducts the current cost-indexed credit\nprice (fresh reports; cached hits charge the cached fraction).\n\nReturns report ID and status. Poll GET /api/reports/:id for completion.","operationId":"generate_report_api_reports_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["reports"],"summary":"List My Reports","description":"Get user's purchased reports.","operationId":"list_my_reports_api_reports_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/reports/check/{event_id}":{"get":{"tags":["reports"],"summary":"Check Report","description":"Check if a cached report exists for an event.\n\n`cost_credits` is what THIS user pays right now; `pricing` exposes the\nfull current quote (fresh/cached/BYOK) for the UI.","operationId":"check_report_api_reports_check__event_id__get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/reports/{report_id}":{"get":{"tags":["reports"],"summary":"Get Report","description":"Get full report (must have purchased).","operationId":"get_report_api_reports__report_id__get","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"integer","title":"Report Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/webhooks/stripe":{"post":{"tags":["webhooks"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.\n\nEvents handled:\n- checkout.session.completed: Add credits after payment\n- customer.subscription.created/updated/deleted: mirror API-billing\n  subscription state onto the profile\n- charge.dispute.created: Zero balance, flag account","operationId":"stripe_webhook_api_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/keys":{"post":{"tags":["api-keys"],"summary":"Create Api Key","description":"Mint a new API key. The plaintext `key` is shown ONCE — store it now.","operationId":"create_api_key_api_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["api-keys"],"summary":"List Api Keys","description":"List the caller's keys (redacted — never returns the secret).","operationId":"list_api_keys_api_keys_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke Api Key","description":"Revoke one of the caller's keys (soft delete).","operationId":"revoke_api_key_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/byok":{"post":{"tags":["byok"],"summary":"Store Key","description":"Store (or replace) the caller's OpenRouter key. Returns a masked hint.","operationId":"store_key_api_byok_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["byok"],"summary":"Get Key Status","description":"Return {has_key, key_hint} — never the plaintext key.","operationId":"get_key_status_api_byok_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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"}}}}}},"delete":{"tags":["byok"],"summary":"Delete Key","description":"Remove the caller's stored OpenRouter key.","operationId":"delete_key_api_byok_delete","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/stats/track-record":{"get":{"tags":["stats"],"summary":"Get Track Record","description":"Public council track record. Every graded report, nothing filtered.","operationId":"get_track_record_api_stats_track_record_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/costs":{"get":{"tags":["admin"],"summary":"Get Costs","description":"Spend + provider-health dashboard over the last `days` days of reports.","operationId":"get_costs_api_admin_costs_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Days"}},{"name":"recent_limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Recent Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","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/blog":{"get":{"tags":["blog"],"summary":"List Posts","operationId":"list_posts_api_blog_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"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":{"type":"object","additionalProperties":true,"title":"Response List Posts Api Blog Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/blog/{slug}":{"get":{"tags":["blog"],"summary":"Get Post","operationId":"get_post_api_blog__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Post Api Blog  Slug  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/email/unsubscribe":{"get":{"tags":["email"],"summary":"Unsubscribe","description":"Human click-through from the email footer — opt out, then land on a\nfriendly confirmation page.","operationId":"unsubscribe_api_email_unsubscribe_get","parameters":[{"name":"uid","in":"query","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"sig","in":"query","required":true,"schema":{"type":"string","title":"Sig"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["email"],"summary":"Unsubscribe One Click","description":"RFC 8058 one-click unsubscribe — mail clients POST to the\nList-Unsubscribe URL without rendering anything.","operationId":"unsubscribe_one_click_api_email_unsubscribe_post","parameters":[{"name":"uid","in":"query","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"sig","in":"query","required":true,"schema":{"type":"string","title":"Sig"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Unsubscribe One Click Api Email Unsubscribe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health":{"get":{"summary":"Health","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"CheckoutRequest":{"properties":{"pack_id":{"type":"integer","title":"Pack Id"}},"type":"object","required":["pack_id"],"title":"CheckoutRequest"},"CreateKeyRequest":{"properties":{"name":{"type":"string","title":"Name","default":"API key"}},"type":"object","title":"CreateKeyRequest"},"GenerateRequest":{"properties":{"event_id":{"type":"string","title":"Event Id"},"quoted_credits":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Quoted Credits"}},"type":"object","required":["event_id"],"title":"GenerateRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"StoreKeyRequest":{"properties":{"openrouter_key":{"type":"string","title":"Openrouter Key"}},"type":"object","required":["openrouter_key"],"title":"StoreKeyRequest"},"UpdateProfileBody":{"properties":{"display_name":{"type":"string","maxLength":40,"minLength":1,"title":"Display Name"}},"type":"object","required":["display_name"],"title":"UpdateProfileBody"},"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"}}}}