{"name":"KolHub API","version":"0.4.0","base":"https://kolhub-production.up.railway.app","auth":{"session":"send the kh_session cookie issued by /api/auth/login or /api/auth/signup","cron":"send header `x-cron-secret: <CRON_SECRET>` (or use an ADMIN session)","session+role":"session cookie + the listed roles"},"counts":{"shipped":48,"future":13,"total":61},"groups":[{"name":"Auth & session","blurb":"Email/password signup with scrypt hashing, httpOnly cookie sessions, 30-day expiry.","endpoints":[{"method":"POST","path":"/api/auth/signup","auth":"public","desc":"Create account + auto-login","body":"email, password, name, handle, role","status":"shipped"},{"method":"POST","path":"/api/auth/login","auth":"public","desc":"Verify password, set session cookie","body":"email, password","status":"shipped"},{"method":"POST","path":"/api/auth/logout","auth":"session","desc":"Invalidate session row + clear cookie","status":"shipped"},{"method":"GET","path":"/api/me","auth":"session","desc":"Return current signed-in user (no passwordHash)","status":"shipped"},{"method":"PATCH","path":"/api/me/update","auth":"session","desc":"Update name / bio / avatarUrl","body":"name?, bio?, avatarUrl?","status":"shipped"},{"method":"POST","path":"/api/auth/forgot","auth":"public","desc":"Send password-reset email via Resend (no enumeration)","body":"email","status":"shipped"},{"method":"POST","path":"/api/auth/reset","auth":"public","desc":"Verify token, set new password, auto-login","body":"token, password","status":"shipped"}]},{"name":"Wallet (Solana)","blurb":"Phantom wallet connect via signed nonce challenge. Server verifies ed25519 signature.","endpoints":[{"method":"POST","path":"/api/wallet/link/nonce","auth":"session","desc":"Issue a one-time nonce to sign","status":"shipped"},{"method":"POST","path":"/api/wallet/link","auth":"session","desc":"Verify signature + bind walletAddr to user","body":"walletAddr, signature, nonce","status":"shipped"},{"method":"DELETE","path":"/api/wallet/link","auth":"session","desc":"Unlink wallet from account","status":"planned"}]},{"name":"Gigs (KOL services)","blurb":"KOL-listed promotional services. POST creates a gig, orders are tracked separately.","endpoints":[{"method":"GET","path":"/api/gigs","auth":"public","query":"q?, niche?, seller?, limit?","desc":"List open gigs (filterable)","status":"shipped"},{"method":"POST","path":"/api/gigs","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Create a gig","body":"title, description, priceCents, deliveryDays, niche?","status":"shipped"},{"method":"GET","path":"/api/gigs/[id]","auth":"public","desc":"Get gig + seller + recent orders","status":"shipped"},{"method":"PATCH","path":"/api/gigs/[id]","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Update fields (own gig only)","status":"shipped"},{"method":"DELETE","path":"/api/gigs/[id]","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Soft-cancel (with orders) or hard-delete (no orders)","status":"shipped"}]},{"name":"Orders & escrow","blurb":"Project places order → mock USDC lock → KOL delivers → project releases. State machine enforced server-side.","endpoints":[{"method":"GET","path":"/api/orders","auth":"session","query":"as=buyer|seller","desc":"List orders for the signed-in user","status":"shipped"},{"method":"POST","path":"/api/orders","auth":"session+role","roles":["PROJECT","ADMIN"],"desc":"Place order, lock mock USDC escrow, notify seller","body":"gigId","status":"shipped"},{"method":"GET","path":"/api/orders/[id]","auth":"session","desc":"Get one order (buyer/seller/admin only)","status":"shipped"},{"method":"PATCH","path":"/api/orders/[id]","auth":"session","desc":"Transition: DELIVERED / RELEASED / DISPUTED / CANCELED with role checks","body":"status, deliveryUrl?","status":"shipped"},{"method":"POST","path":"/api/escrow/fund","auth":"session","desc":"Real Solana SPL token transfer to escrow PDA","status":"v1.5"},{"method":"POST","path":"/api/escrow/release","auth":"session","desc":"Release on-chain escrow to seller","status":"v1.5"}]},{"name":"Signals (trading ideas)","blurb":"LONG/SHORT signals with TP/SL. Auto-settled by Pyth Hermes on cron.","endpoints":[{"method":"GET","path":"/api/signals","auth":"public","query":"status?, side?, author?, q?","desc":"List signals","status":"shipped"},{"method":"POST","path":"/api/signals","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Publish signal (validates R:R direction)","body":"asset, side, entry, takeProfit, stopLoss, rationale?","status":"shipped"},{"method":"GET","path":"/api/signals/[id]","auth":"public","desc":"Get signal + author","status":"shipped"},{"method":"PATCH","path":"/api/signals/[id]","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Owner can edit rationale or status","status":"shipped"},{"method":"POST","path":"/api/signals/[id]/settle","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Manual settle (owner/admin only)","body":"outcome: TP_HIT|SL_HIT|EXPIRED","status":"shipped"},{"method":"POST","path":"/api/cron/settle-signals","auth":"cron","desc":"Auto-settle ACTIVE signals via Pyth Hermes","status":"shipped"}]},{"name":"Hubs (paid communities)","blurb":"KOL-run subscription Hubs with up to 3 tiers. Tier-gated post feed.","endpoints":[{"method":"GET","path":"/api/hubs","auth":"public","query":"q?, niche?, limit?","desc":"List hubs ordered by member count","status":"shipped"},{"method":"POST","path":"/api/hubs","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Create a Hub with tier prices","body":"slug, name, tagline?, description?, niches[], tier1Price?, tier2Price?, tier3Price?","status":"shipped"},{"method":"GET","path":"/api/hubs/[slug]","auth":"public","desc":"Get hub + owner","status":"shipped"},{"method":"PATCH","path":"/api/hubs/[slug]","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Update hub (owner only)","status":"shipped"},{"method":"POST","path":"/api/hubs/[slug]/subscribe","auth":"session","desc":"Subscribe at tier (mock USDC). Upgrade/downgrade re-uses row.","body":"tier: T1|T2|T3","status":"shipped"},{"method":"DELETE","path":"/api/hubs/[slug]/subscribe","auth":"session","desc":"Cancel subscription (decrements memberCount)","status":"shipped"},{"method":"GET","path":"/api/hubs/[slug]/posts","auth":"public","desc":"List posts visible at viewer's tier","status":"shipped"},{"method":"POST","path":"/api/hubs/[slug]/posts","auth":"session+role","roles":["KOL","ADMIN"],"desc":"Owner posts to feed (with minTier gate)","body":"body, minTier?","status":"shipped"}]},{"name":"Campaigns (multi-KOL)","blurb":"Project-led campaigns with N slots. Each slot is its own escrow.","endpoints":[{"method":"GET","path":"/api/campaigns","auth":"public","query":"owner?","desc":"List OPEN/IN_PROGRESS campaigns","status":"shipped"},{"method":"POST","path":"/api/campaigns","auth":"session+role","roles":["PROJECT","ADMIN"],"desc":"Create campaign + slots in one transaction","body":"title, description, slots: [{title, niche?, priceCents, deliveryDays?}, ...]","status":"shipped"},{"method":"GET","path":"/api/campaigns/[id]","auth":"public","desc":"Get campaign + slots + applicants","status":"shipped"},{"method":"PATCH","path":"/api/campaigns/[id]","auth":"session+role","roles":["PROJECT","ADMIN"],"desc":"Owner: edit fields or close/cancel","status":"shipped"},{"method":"POST","path":"/api/campaigns/[id]/slots/[slotId]","auth":"session","desc":"Slot state machine: apply/accept/reject/deliver/release/cancel","body":"action: apply|accept|reject|deliver|release|cancel, deliveryUrl? (deliver)","status":"shipped"}]},{"name":"Chat & messages","blurb":"1:1 conversations with 4-second polling. SSE upgrade planned.","endpoints":[{"method":"GET","path":"/api/conversations","auth":"session","desc":"List threads with last message + other party","status":"shipped"},{"method":"POST","path":"/api/conversations","auth":"session","desc":"Get-or-create 1:1 with another user","body":"handle","status":"shipped"},{"method":"GET","path":"/api/conversations/[id]/messages","auth":"session","query":"since?","desc":"Fetch thread, marks read for me","status":"shipped"},{"method":"POST","path":"/api/conversations/[id]/messages","auth":"session","desc":"Send message (coalesces notifs to recipient at 60s)","body":"body","status":"shipped"},{"method":"GET","path":"/api/conversations/[id]/stream","auth":"session","desc":"Server-Sent Events for live messages","status":"v1.5"}]},{"name":"Reviews","blurb":"Reviews are gated to users with at least one RELEASED order between them.","endpoints":[{"method":"POST","path":"/api/reviews","auth":"session","desc":"Leave 1–5★ review on a counterparty","body":"handle, rating, body?","status":"shipped"},{"method":"GET","path":"/api/reviews","auth":"public","query":"handle, kind=received|left","desc":"List reviews for a user","status":"planned"}]},{"name":"Notifications","blurb":"In-app bell, polled every 30s. Auto-fired by every transactional event.","endpoints":[{"method":"GET","path":"/api/notifications","auth":"session","desc":"Last 30 + unread count","status":"shipped"},{"method":"POST","path":"/api/notifications","auth":"session","desc":"Mark all read","status":"shipped"},{"method":"POST","path":"/api/notifications/email","auth":"cron","desc":"Cron: send digest email for unread > 24h","status":"planned"}]},{"name":"Admin","blurb":"ADMIN-only platform overrides + reporting.","endpoints":[{"method":"PATCH","path":"/api/admin/users/[id]","auth":"session+role","roles":["ADMIN"],"desc":"Verify/unverify user, change role","body":"verified?, role?","status":"shipped"},{"method":"POST","path":"/api/admin/orders/[id]/force","auth":"session+role","roles":["ADMIN"],"desc":"Force-resolve disputed order","status":"planned"},{"method":"GET","path":"/api/admin/stats","auth":"session+role","roles":["ADMIN"],"desc":"Platform KPIs JSON for dashboard","status":"planned"},{"method":"POST","path":"/api/admin/users/[id]/ban","auth":"session+role","roles":["ADMIN"],"desc":"Ban a user (revokes sessions)","status":"planned"}]},{"name":"X (Twitter) integration","blurb":"OAuth claim verification + post snapshot capture for delivery proofs.","endpoints":[{"method":"GET","path":"/api/x/oauth/start","auth":"session","desc":"Begin X OAuth flow, store state cookie","status":"v1.5"},{"method":"GET","path":"/api/x/oauth/callback","auth":"session","desc":"Exchange code, store X user id, mark handle verified","status":"v1.5"},{"method":"POST","path":"/api/x/snapshot","auth":"session","desc":"Capture post text+metrics at submission/24h/7d","body":"url, orderId|slotId","status":"v1.5"}]},{"name":"Search & discovery","blurb":"Cross-entity search across users, gigs, hubs, signals, campaigns.","endpoints":[{"method":"GET","path":"/api/search","auth":"public","query":"q, kinds?","desc":"Aggregated search across the platform","status":"planned"}]},{"name":"Telegram bot (@kolhubwatcherbot)","blurb":"Posts every gig, signal, campaign, order, subscription, and signal-settlement event to a Telegram group. Bot token + chat IDs set via Railway env vars.","endpoints":[{"method":"POST","path":"/api/dev/telegram-test","auth":"session+role","roles":["ADMIN"],"desc":"Send a test message from the dev console","body":"channel?: 'public'|'admin', text?: string","status":"shipped"}]},{"name":"Spec & health","blurb":"Self-describing API spec + uptime check.","endpoints":[{"method":"GET","path":"/api/openapi","auth":"public","desc":"API_GROUPS as JSON for tooling","status":"shipped"},{"method":"GET","path":"/api/health","auth":"public","desc":"DB ping + email/pyth status (for uptime monitors)","status":"shipped"}]}]}