C Capacitr API Docs
// API Reference — v1.0

Capacitr API Docs

Backend services powering Capacitr's market intelligence platform — turning signal into position across prediction markets, perpetuals, and options.

Base URL https://app.capacitr.xyz
Stack

All APIs are Next.js 14 App Router route handlers deployed on Vercel. The backend integrates Polymarket (prediction markets via Gamma API), Quotient (mispricing intelligence), HyperLiquid (perpetuals), Deribit (options), OpenRouter GPT-4o-mini (LLM analysis), Jina AI (web scraping), and Supabase (PostgreSQL persistence).

Response format

All endpoints return JSON. Successful responses include the data directly. Error responses return { "error": "message" } with an appropriate HTTP status code.

🔐 Authentication

Most market intelligence endpoints are unauthenticated. User endpoints require a Privy ID passed as a query parameter or in the request body.

ℹ️ User-scoped endpoints (interests, risk-profile, feed, user) identify users via privyId — the DID issued by Privy on login. Auth is handled client-side via Privy.io (Twitter + Farcaster OAuth). Admin endpoints use a shared password param.
⚡ Error Codes
Code Meaning
200Success
400Bad request — missing or invalid parameters
401Unauthorized — missing or wrong auth credentials
404Not found — resource doesn't exist
500Internal server error — check server logs
GET /api/quotient Proxy to Quotient prediction intelligence API
Description

Proxies requests to the Quotient API for mispricing intelligence on Polymarket markets. Supports three actions: fetching mispriced markets, looking up specific markets by slug, and querying general market intelligence.

Query Parameters
ParamTypeRequiredDescription
action enum required One of: mispriced | lookup | intelligence
limit integer optional Max results (action=mispriced). Default: 20
min_spread float optional Minimum mispricing spread filter (action=mispriced). Default: 0.05
sort string optional Sort order (action=mispriced). Default: spread_desc
slugs string optional* Comma-separated market slugs (required for action=lookup)
query string optional* Text query (required for action=intelligence)
Example — Get Mispriced Markets
GET /api/quotient?action=mispriced&limit=5&min_spread=0.08
Example — Lookup by Slug
GET /api/quotient?action=lookup&slugs=will-bitcoin-hit-100k,eth-merge-by-q3
🤖 Research Agent

Streaming AI chat agent powered by GPT-4o-mini via OpenRouter. Has tool access to Polymarket search and Quotient mispricing data.

POST /api/chat Stream a research agent response (Vercel AI SDK)
Description

Streams a response from the Capacitr market research agent using the Vercel AI SDK (Server-Sent Events). The agent can call tools: searchMarkets (Polymarket text search), getMispricedMarkets (Quotient top opportunities), and getMarketIntelligence (Quotient intelligence for a query). Use the useChat hook from ai/react client-side.

Request Body (JSON)
FieldTypeRequiredDescription
messages Message[] required Array of chat messages in Vercel AI SDK format: { role: "user"|"assistant", content: string }
Example Request
POST /api/chat
Content-Type: application/json

{
  "messages": [
    { "role": "user", "content": "What prediction markets exist around the US election?" }
  ]
}
Response

Returns a streaming text/event-stream response in Vercel AI SDK Data Stream format. Compatible with the useChat hook.

Agent Tools
ToolDescription
searchMarkets Full-text search of Polymarket via Gamma API. Returns top 5 matching markets with prices and volume.
getMispricedMarkets Returns top mispriced markets from Quotient with spread and BLUF analysis.
getMarketIntelligence Runs a Quotient intelligence query for a specific topic, returning relevant markets and edge signals.
📰 Feed

Personalized market signal feed — fetches Reddit and Hacker News posts based on user interests, runs LLM analysis, and returns tradeable predictions enriched with Quotient mispricing data.

GET /api/feed Get personalized market signal feed for a user
Description

Fetches top posts from Reddit subreddits and Hacker News based on the user's interest categories (crypto, politics, ai, tech, finance, sports, pop-culture, music, food, environment). Each post is analyzed by LLM to extract tickers, entities, and generate a prediction card with Polymarket + HyperLiquid + Deribit markets. Results are enriched with Quotient mispricing signals.

Query Parameters
ParamTypeRequiredDescription
privyId string required The Privy DID of the authenticated user. Used to fetch their interest categories.
interests string optional Comma-separated override interest list (skips DB lookup). E.g. "crypto,ai,tech"
Example Request
GET /api/feed?privyId=did:privy:abc123
Example Response
200 OK
{
  "items": [
    {
      "id": "abc123",
      "title": "Bitcoin ETF inflows hit record $2B in single day",
      "source": "reddit",
      "subreddit": "cryptocurrency",
      "url": "https://reddit.com/r/cryptocurrency/...",
      "summary": "Bitcoin ETFs recorded record inflows...",
      "entities": ["Bitcoin", "BlackRock"],
      "tickers": ["BTC"],
      "predictions": [...],
      "perps": [...],
      "options": [],
      "categories": ["crypto", "finance"]
    }
  ]
}
👤 User

User profile management — get/create users, manage interests and risk profiles. All user data is stored in Supabase and keyed by Privy DID.

GET /api/user Get user profile with interests
Query Parameters
ParamTypeRequiredDescription
privyId string required The Privy DID of the user
Example Response
200 OK
{
  "user": {
    "id": "uuid",
    "privy_id": "did:privy:abc123",
    "privy_provider": "twitter",
    "display_name": "Atown",
    "avatar_url": "https://...",
    "twitter_handle": "capacitr_xyz",
    "farcaster_fid": null,
    "created_at": "2025-01-01T00:00:00Z",
    "interests": ["crypto", "ai", "finance"]
  }
}
POST /api/user Update user profile fields
Request Body (JSON)
FieldTypeRequiredDescription
privyIdstringrequiredPrivy DID
displayNamestringoptionalUser's display name
avatarUrlstringoptionalProfile image URL
GET /api/interests Get user's interest categories
Query Parameters
ParamTypeRequiredDescription
privyIdstringrequiredThe Privy DID of the user
Example Response
200 OK
{ "interests": ["crypto", "ai", "finance"] }
POST /api/interests Save user's interest categories
Request Body (JSON)
FieldTypeRequiredDescription
privyIdstringrequiredPrivy DID
interestsstring[]requiredArray of interest slugs. Valid: crypto, politics, ai, tech, finance, sports, pop-culture, music, food, environment
Example Request
POST /api/interests
Content-Type: application/json

{ "privyId": "did:privy:abc123", "interests": ["crypto", "ai"] }
GET /api/risk-profile Get user's risk profile tier
Query Parameters
ParamTypeRequiredDescription
privyIdstringrequiredPrivy DID
Example Response
200 OK
{
  "profile": {
    "tier": "aggressive",
    "scores": { "riskTolerance": 8, "timeHorizon": 7, "experience": 9 },
    "completed_at": "2025-03-15T10:22:00Z"
  }
}
POST /api/risk-profile Save or update user's risk profile
Request Body (JSON)
FieldTypeRequiredDescription
privyIdstringrequiredPrivy DID
tierstringrequiredRisk tier: conservative | moderate | aggressive
scoresobjectoptionalRaw quiz scores object
POST /api/auth/sync Sync Privy user to Supabase on login
Description

Called automatically on login. Upserts the Privy user record into Supabase — creates if new, updates profile fields if existing. Called from the PrivyProviderWrapper on onSuccess.

Request Body (JSON)
FieldTypeRequiredDescription
privyIdstringrequiredPrivy DID
providerstringoptionalAuth provider: "twitter" | "farcaster"
displayNamestringoptionalDisplay name from OAuth profile
avatarUrlstringoptionalAvatar URL from OAuth profile
twitterHandlestringoptionalTwitter/X handle (without @)
farcasterFidintegeroptionalFarcaster FID
Example Response
200 OK
{ "user": { "id": "uuid", "privy_id": "did:privy:abc123", "display_name": "Atown", ... } }
🔧 Admin

Internal admin endpoints for monitoring usage and development tooling. Password-protected.

GET /api/insights Usage analytics — top searches, entities, query volume
Description

Returns aggregated analytics from the market_searches table: total search volume, unique URLs, top entities, top tickers, top categories, and recent searches. Admin-only — requires password query param.

Query Parameters
ParamTypeRequiredDescription
passwordstringrequiredAdmin password for auth
Example Response
200 OK
{
  "totalSearches": 142,
  "uniqueUrls": 89,
  "topEntities": [["Bitcoin", 34], ["NVIDIA", 21], ...],
  "topTickers": [["BTC", 41], ["NVDA", 19], ...],
  "topCategories": [["crypto", 67], ["tech", 44], ...],
  "recentSearches": [...]
}
DELETE /api/admin/wipe-users ⚠️ Dev only — wipe all user data from Supabase
Description

⚠️ Destructive. Deletes all rows from user_interests, feed_items, and users tables in sequence. For development/testing only — never run in production.

Example Response
200 OK
{ "success": true, "message": "All users wiped" }