Capacitr API Docs
Backend services powering Capacitr's market intelligence platform — turning signal into position across prediction markets, perpetuals, and options.
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).
All endpoints return JSON. Successful responses include the data directly. Error responses return { "error": "message" } with an appropriate HTTP status code.
Most market intelligence endpoints are unauthenticated. User endpoints require a Privy ID passed as a query parameter or in the request body.
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request — missing or invalid parameters |
| 401 | Unauthorized — missing or wrong auth credentials |
| 404 | Not found — resource doesn't exist |
| 500 | Internal server error — check server logs |
Core endpoint — turns any URL or text query into a full market discovery report: prediction markets, perpetuals, options, and Quotient mispricing signals.
Accepts a news URL or freetext query. Scrapes the content (URL path via Jina AI), runs LLM extraction to identify tickers, entities, keywords, and categories, then fans out to Polymarket, HyperLiquid, and Deribit to find matching markets. Results are enriched with Quotient mispricing signals and sorted by edge opportunity. Search results are logged to the market_searches Supabase table.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | optional* | A news article or web page URL to analyze. Either url or query must be provided. |
| query | string | optional* | A freetext search query (e.g. "NVIDIA earnings Q1 2025"). Used when no URL is provided. |
POST /api/analyze-link
Content-Type: application/json
{
"url": "https://reuters.com/technology/nvidia-earnings-beat-2025"
}
{
"summary": "NVIDIA reported record Q1 earnings...",
"keywords": ["NVIDIA", "earnings", "semiconductors", "AI chips"],
"entities": ["NVIDIA", "Jensen Huang"],
"tickers": ["NVDA"],
"categories": ["tech", "finance"],
"predictions": [
{
"id": "will-nvidia-hit-1000",
"question": "Will NVIDIA stock hit $1000 by Q3 2025?",
"yesPrice": 0.62,
"noPrice": 0.38,
"volume": 485000,
"mispricingScore": 0.14,
"bluf": "Market underpricing YES given recent earnings beat"
}
],
"perps": [
{
"symbol": "NVDA-USD",
"price": 872.50,
"funding": 0.0003,
"openInterest": 12400000
}
],
"options": []
}
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.
| Param | Type | Required | Description |
|---|---|---|---|
| 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) |
GET /api/quotient?action=mispriced&limit=5&min_spread=0.08
GET /api/quotient?action=lookup&slugs=will-bitcoin-hit-100k,eth-merge-by-q3
Streaming AI chat agent powered by GPT-4o-mini via OpenRouter. Has tool access to Polymarket search and Quotient mispricing data.
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.
| Field | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | required | Array of chat messages in Vercel AI SDK format: { role: "user"|"assistant", content: string } |
POST /api/chat
Content-Type: application/json
{
"messages": [
{ "role": "user", "content": "What prediction markets exist around the US election?" }
]
}
Returns a streaming text/event-stream response in Vercel AI SDK Data Stream format. Compatible with the useChat hook.
| Tool | Description |
|---|---|
| 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. |
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.
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.
| Param | Type | Required | Description |
|---|---|---|---|
| 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" |
GET /api/feed?privyId=did:privy:abc123
{
"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 profile management — get/create users, manage interests and risk profiles. All user data is stored in Supabase and keyed by Privy DID.
| Param | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | The Privy DID of the user |
{
"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"]
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | Privy DID |
| displayName | string | optional | User's display name |
| avatarUrl | string | optional | Profile image URL |
| Param | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | The Privy DID of the user |
{ "interests": ["crypto", "ai", "finance"] }
| Field | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | Privy DID |
| interests | string[] | required | Array of interest slugs. Valid: crypto, politics, ai, tech, finance, sports, pop-culture, music, food, environment |
POST /api/interests
Content-Type: application/json
{ "privyId": "did:privy:abc123", "interests": ["crypto", "ai"] }
| Param | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | Privy DID |
{
"profile": {
"tier": "aggressive",
"scores": { "riskTolerance": 8, "timeHorizon": 7, "experience": 9 },
"completed_at": "2025-03-15T10:22:00Z"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | Privy DID |
| tier | string | required | Risk tier: conservative | moderate | aggressive |
| scores | object | optional | Raw quiz scores object |
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.
| Field | Type | Required | Description |
|---|---|---|---|
| privyId | string | required | Privy DID |
| provider | string | optional | Auth provider: "twitter" | "farcaster" |
| displayName | string | optional | Display name from OAuth profile |
| avatarUrl | string | optional | Avatar URL from OAuth profile |
| twitterHandle | string | optional | Twitter/X handle (without @) |
| farcasterFid | integer | optional | Farcaster FID |
{ "user": { "id": "uuid", "privy_id": "did:privy:abc123", "display_name": "Atown", ... } }
Internal admin endpoints for monitoring usage and development tooling. Password-protected.
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.
| Param | Type | Required | Description |
|---|---|---|---|
| password | string | required | Admin password for auth |
{
"totalSearches": 142,
"uniqueUrls": 89,
"topEntities": [["Bitcoin", 34], ["NVIDIA", 21], ...],
"topTickers": [["BTC", 41], ["NVDA", 19], ...],
"topCategories": [["crypto", 67], ["tech", 44], ...],
"recentSearches": [...]
}
⚠️ Destructive. Deletes all rows from user_interests, feed_items, and users tables in sequence. For development/testing only — never run in production.
{ "success": true, "message": "All users wiped" }