{ "openapi": "3.1.0", "info": { "x-generated-rate-limit-policy-from": "web/src/lib/rate-limit-facts.ts via web/scripts/generate-api-policy.ts", "title": "0xinsider API", "description": "Follow provider-exposed large-trade activity from Polymarket and Kalshi. Polymarket wallet-attributed trades can add grades, P&L, strategy, and diagnostic-score context when sufficient source data exists; Kalshi public prints remain anonymous, and fields can be null or unavailable. Normal API requests use a 30-second server timeout that returns HTTP 408 Request Timeout with an empty body when exceeded. Public REST /api/v1/* endpoints, excluding /api/v1/mcp, use Bearer-token based non-credentialed browser CORS: any Origin may call with Authorization, Content-Type, If-None-Match, Idempotency-Key, and Mcp-Session-Id request headers. Remote MCP at /api/v1/mcp is non-credentialed, but still validates Origin against the 0xinsider/localhost allowlist per MCP Streamable HTTP DNS-rebinding guidance. Successful browser CORS preflight responses advertise Access-Control-Max-Age: 86400. Browser JavaScript may read X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After, ETag, X-Request-Id, X-Request-Cost, X-Batch-RateLimit-Limit, X-Batch-RateLimit-Remaining, X-Batch-RateLimit-Reset, Mcp-Session-Id, and X-Mcp-Error-Code response headers. Credentialed first-party routes such as /api/keys, /api/billing, and auth endpoints remain restricted to configured 0xinsider origins.", "version": "1.0.0", "contact": { "name": "0xinsider", "email": "support@0xinsider.com", "url": "https://0xinsider.com" } }, "servers": [ { "url": "https://api.0xinsider.com", "description": "Production (live data). Authenticate with a live key (oxi_sk_live_...); requires an active Pro subscription." } ], "security": [ { "bearerAuth": [] } ], "paths": { "/api/v1": { "get": { "operationId": "getApiDiscovery", "summary": "API discovery", "description": "Unauthenticated API-origin discovery document pointing agents to the canonical API base URL, full docs, web-origin OpenAPI spec, health check, and the COMPLETE index of authenticated data routes. data.authenticated_routes is the whole authenticated route surface, not a sample: it carries every authenticated route this spec documents, so an agent that starts here never has to guess a path. backend/src/api_v1/discovery.rs::authenticated_routes_match_the_published_spec fails if the index and this spec disagree in either direction.", "tags": [ "System" ], "security": [], "x-codeSamples": [ { "lang": "Shell", "label": "cURL", "source": "curl 'https://api.0xinsider.com/api/v1'" } ], "responses": { "200": { "description": "API discovery document", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "api_discovery" }, "data": { "$ref": "#/components/schemas/ApiDiscovery" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "example": { "object": "api_discovery", "data": { "api_base_url": "https://api.0xinsider.com", "docs_url": "https://0xinsider.com/llms-full.txt", "openapi_url": "https://0xinsider.com/api/v1/openapi.json", "health_url": "https://api.0xinsider.com/api/v1/health", "authentication": "Bearer API key required for data endpoints; discovery (/api/v1), health, and /api/v1/platforms are public.", "authenticated_routes": [ "GET /api/v1/leaderboard", "GET /api/v1/markets/search", "GET /api/v1/pick-of-the-day", "GET /api/v1/positions", "GET /api/v1/trader/{address}", "GET /api/v1/whale-trades", "POST /api/v1/traders/batch" ] }, "meta": { "request_id": "req_550e8400-e29b-41d4-a716-446655440000", "cached": false, "cache_age_s": null, "cost": 1 } } } } }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "429": { "$ref": "#/components/responses/RateLimited" } } } }, "/api/v1/openapi.json": { "get": { "operationId": "redirectApiOpenapiSpec", "summary": "Redirect to the canonical OpenAPI spec", "description": "Unauthenticated API-origin compatibility redirect to the canonical web-origin OpenAPI JSON document at https://0xinsider.com/api/v1/openapi.json.", "tags": [ "System" ], "security": [], "x-codeSamples": [ { "lang": "Shell", "label": "cURL", "source": "curl -I 'https://api.0xinsider.com/api/v1/openapi.json'" } ], "responses": { "307": { "description": "Temporary redirect to the canonical web-origin OpenAPI spec.", "headers": { "Location": { "description": "Canonical OpenAPI spec URL.", "schema": { "type": "string", "format": "uri", "const": "https://0xinsider.com/api/v1/openapi.json" }, "example": "https://0xinsider.com/api/v1/openapi.json" } } }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" } } } }, "/api/v1/trader/{address}": { "get": { "operationId": "getTrader", "summary": "Get trader intelligence", "description": "Returns a trader's grade (S through F; ranked about 95% by realized profit, with calibration, track record, and consistency as a tie-breaker and proven-trader guardrails), P&L, win rate, and optional strategy/category data. The path accepts either an Ethereum wallet address, a known trader username, or a trd_-prefixed trader ID emitted by this API. Unknown lookups return sync_status \"unknown\" instead of 404.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Ethereum wallet address (0x...), known trader username, or trd_-prefixed trader ID emitted by this API.", "schema": { "type": "string" } }, { "name": "expand[]", "in": "query", "required": false, "description": "Backward-compatible alias for expand. Repeatable: strategy, categories, quant_metrics, trust.", "schema": { "type": "array", "items": { "type": "string", "enum": [ "strategy", "categories", "quant_metrics", "trust" ] } }, "style": "form", "explode": true }, { "name": "expand", "in": "query", "required": false, "description": "Include heavy fields and trust metadata. Repeatable: strategy, categories, quant_metrics, trust.", "schema": { "type": "array", "items": { "type": "string", "enum": [ "strategy", "categories", "quant_metrics", "trust" ] } }, "style": "form", "explode": true }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Trader profile", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "trader" }, "data": { "$ref": "#/components/schemas/Trader" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "traders", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}'" } ], "x-examples": { "success": { "object": "traders", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/trader/{address}/context.md": { "get": { "operationId": "getTraderContextMarkdown", "summary": "Get trader context (Markdown)", "description": "Returns a single human- and LLM-readable Markdown briefing for one trader: identity, grade, P&L, position coverage, and freshness. The path accepts an Ethereum wallet address (0x...), a known trader username, or a trd_-prefixed trader ID emitted by this API. Unknown traders still return 200 with a degraded 'not yet synced' document (no 404). The Markdown variant does not emit an ETag and does not support conditional requests; use the JSON variant (drop the .md suffix) for ETag/If-None-Match handling.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Ethereum wallet address (0x...), known trader username, or trd_-prefixed trader ID emitted by this API.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Trader context document (Markdown)", "content": { "text/markdown": { "schema": { "type": "string" }, "example": "# Trader context: @swisstony\n\nAI-ready trader summary from 0xinsider. Reflects backend state as of the data_as_of clock below (a point-in-time snapshot, cached briefly), not request time.\n\n- Data as of: 2026-01-15T12:00:00Z\n- Sync status: synced\n" } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}/context.md'" } ] } }, "/api/v1/trader/{address}/context": { "get": { "operationId": "getTraderContext", "summary": "Get trader context (JSON)", "description": "Returns a single structured context object for one trader: the full trader profile (same shape as GET /api/v1/trader/{address}) plus a position_summary (sync coverage and realized/unrealized P&L rollups, with an as_of open-position freshness clock), the data_as_of freshness timestamp (the open-position data's latest /positions snapshot, else last completed sync; the snapshot advances only open positions, so resolved/closed aggregates still date to the last full sync), and a freshness_note describing the point-in-time snapshot semantics. The path accepts an Ethereum wallet address (0x...), a known trader username, or a trd_-prefixed trader ID emitted by this API. position_summary is omitted when the trader is not in the local database; unknown lookups return 200 with sync_status 'unknown' on the nested trader (no 404). Append .md to the path for the Markdown rendering.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Ethereum wallet address (0x...), known trader username, or trd_-prefixed trader ID emitted by this API.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Trader context", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "trader_context" }, "data": { "$ref": "#/components/schemas/TraderContext" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "trader_context", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}/context'" } ], "x-examples": { "success": { "object": "trader_context", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/traders/batch": { "post": { "operationId": "batchGetTraders", "summary": "Batch trader intelligence", "description": "Returns trader intelligence for 1-25 wallet addresses or known usernames. Results preserve request order, duplicate inputs return duplicate rows, and each item is charged one batch item unit before execution. Unknown trader lookups return data with sync_status \"unknown\" matching the single trader endpoint.", "tags": [ "Traders" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "traders" ], "properties": { "traders": { "type": "array", "minItems": 1, "maxItems": 25, "items": { "type": "string" } }, "expand": { "type": "array", "items": { "type": "string", "enum": [ "strategy", "categories", "quant_metrics", "trust" ] }, "description": "Shared expand flags applied to every trader item." } } }, "example": { "traders": [ "swisstony", "0x0000000000000000000000000000000000000000" ], "expand": [ "strategy" ] } } } }, "responses": { "200": { "description": "Ordered batch trader results", "headers": { "X-Request-Cost": { "schema": { "type": "integer" }, "description": "Number of batch item units charged for this request." }, "X-Batch-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Batch item units allowed per minute." }, "X-Batch-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Batch item units remaining in the current sliding window." }, "X-Batch-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Unix timestamp when the batch item window resets." }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "trader_batch" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/BatchTraderItem" } }, "meta": { "$ref": "#/components/schemas/BatchResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "traders", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{\"traders\":[\"swisstony\",\"0x0000000000000000000000000000000000000000\"],\"expand\":[\"strategy\"]}' \\\n 'https://api.0xinsider.com/api/v1/traders/batch'" } ], "x-examples": { "success": { "object": "traders", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/trader/{address}/position-timeline": { "get": { "operationId": "getPositionTimeline", "summary": "Get a trader's position timeline for one market", "description": "Returns stored Polymarket fills for one tracked trader in one market, newest first, with server-computed running_amount and running_avg_price. The {address} segment accepts the same four identity shapes as the plural alias: 0x... wallet, username, trd_-prefixed trader id, or bare integer traders.id, resolved with precedence wallet -> trd_ -> integer -> username. Only HOT and WARM tier traders are tracked; other traders return 404. running_avg_price is a buy-weighted entry basis (sells do not change the running average) matching Polymarket /positions avgPrice semantics. Cursor-paginated.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Trader identity: 0x... wallet address, username, trd_-prefixed trader id, or bare integer traders.id. Resolved with precedence wallet -> trd_ -> integer -> username; wallet matching is case-insensitive.", "schema": { "type": "string" } }, { "name": "condition_id", "in": "query", "required": true, "description": "Market condition_id. One timeline per (trader, market).", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response's next_cursor.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Position timeline page", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/PositionTimelineEvent" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/TraderNotTracked" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/0x1111111111111111111111111111111111111111/position-timeline?condition_id=0x2222222222222222222222222222222222222222222222222222222222222222'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/trader/{address}/pnl": { "get": { "operationId": "getTraderPnl", "summary": "Get trader P&L time series", "description": "Returns a trader's daily P&L time series and pre-derived stats from the precomputed daily_pnl read model: entries (daily cumulative P&L), period stats (all/90d/30d/7d), monthly aggregation, per-year totals, and the drawdown series. Reads the refreshed read model, not a per-request equity replay. A resolved trader with no daily P&L returns an empty structured object (HTTP 200); an unknown address returns 404. Spans both providers wherever the read model has the trader's series.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Wallet address (0x...), username, or trd_-prefixed trader id.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Trader P&L object", "headers": { "ETag": { "$ref": "#/components/headers/ETag" }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "trader_pnl" }, "data": { "$ref": "#/components/schemas/TraderPnl" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "example": { "object": "trader_pnl", "data": { "id": "trd_0xabc123", "entries": [ { "date": "2026-05-12", "markets_traded": 3, "total_volume": 10000.0, "cumulative_profit": 50000.0, "total_pnl": 50000.0, "daily_change": 250.0 } ], "stats": { "all": { "current": 50000.0, "change": 50000.0, "change_pct": 0.0, "best_day": 5000.0, "worst_day": -2000.0, "win_days": 30, "loss_days": 10, "avg_day": 250.0, "rebase_anchor": 0.0 }, "d90": { "current": 12000.0, "change": 12000.0, "change_pct": 31.5, "best_day": 5000.0, "worst_day": -2000.0, "win_days": 18, "loss_days": 6, "avg_day": 500.0, "rebase_anchor": 38000.0 }, "d30": { "current": 4000.0, "change": 4000.0, "change_pct": 8.7, "best_day": 2500.0, "worst_day": -800.0, "win_days": 9, "loss_days": 3, "avg_day": 333.0, "rebase_anchor": 46000.0 }, "d7": { "current": 900.0, "change": 900.0, "change_pct": 1.8, "best_day": 600.0, "worst_day": -150.0, "win_days": 4, "loss_days": 1, "avg_day": 180.0, "rebase_anchor": 49100.0 } }, "monthly": [ { "year": 2026, "month": 5, "pnl": 12000.0, "markets_traded": 18 } ], "year_totals": [ { "year": 2026, "pnl": 50000.0 } ], "drawdown": [ { "date": "2026-05-12", "cumulative_profit": 50000.0, "drawdown": -1500.0 } ] }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "description": "Validator for the unchanged payload.", "schema": { "type": "string" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/0xabc123/pnl'" } ] } }, "/api/v1/traders/{trader}/position-timeline": { "get": { "operationId": "getPositionTimelineById", "summary": "Get a trader's position timeline (unified identity resolver)", "description": "Unified trader-timeline route (#4975). {trader} accepts all four identity shapes - 0x... wallet, username, trd_-prefixed trader id, and bare integer id - resolved by the single shared trader-identity resolver. Returns stored Polymarket fills for one tracked trader in one market, newest first, with server-computed running_amount and running_avg_price. Only HOT and WARM tier traders are tracked; other traders return 404. Response payload matches the singular GET /api/v1/trader/{address}/position-timeline route for the same (trader, market), except for the per-request meta.request_id. The prior integer-id-only variant is preserved: the same path now accepts every identity shape.", "tags": [ "Traders" ], "parameters": [ { "name": "trader", "in": "path", "required": true, "description": "Trader identity: 0x... wallet address, username, trd_-prefixed trader id, or bare integer traders.id. Resolved with precedence wallet -> trd_ -> integer -> username. Unknown identities return 404.", "schema": { "type": "string" } }, { "name": "condition_id", "in": "query", "required": true, "description": "Market condition_id. One timeline per (trader, market).", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response's next_cursor.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Position timeline page", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/PositionTimelineEvent" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/TraderNotTracked" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/traders/trd_123/position-timeline?condition_id=0x2222222222222222222222222222222222222222222222222222222222222222'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/positions": { "get": { "operationId": "listPositions", "summary": "List current positions (positions-board feed)", "description": "Returns the current positions-board feed backed by the wallet_positions mirror. Ordered by current_value_usd DESC with deterministic (wallet, condition_id, outcome_index) tiebreakers. Pre-reconcile rows (current_value_usd IS NULL) are excluded. Cursor-paginated. Every filter pushes into SQL.", "tags": [ "Positions" ], "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response's next_cursor.", "schema": { "type": "string" } }, { "name": "min_size", "in": "query", "description": "Minimum current position value in USD.", "schema": { "type": "number", "default": 100 } }, { "name": "category", "in": "query", "description": "Exact match against provider-backed market_canonical.category.", "schema": { "type": "string" } }, { "name": "min_grade", "in": "query", "description": "Minimum trader grade allowlist. `A` matches S and A; `B` matches S, A, B; etc.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ] } }, { "name": "side", "in": "query", "description": "Filter by the binary outcome side. `yes` maps to outcome_index=0, `no` to outcome_index=1.", "schema": { "type": "string", "enum": [ "yes", "no" ] } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Page of positions", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/Position" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/positions'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/large-positions": { "get": { "operationId": "listLargePositions", "summary": "List large positions", "description": "Returns the largest current open positions from graded traders, value-descending, with opaque cursor pagination. Polymarket-only by design: the large-positions scanner filters platform = 'polymarket' (backend/crates/large-positions/src/scanner.rs), so no Kalshi rows are ever scanned and a Kalshi or unknown condition_id filter returns an empty list (never fabricated rows). The teaser cap that the internal product UI applies to anonymous viewers does not apply here: the API key already proves an active Pro subscription (wire tier `insider`), so authed API callers get full access.", "tags": [ "Large Positions" ], "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Opaque pagination cursor from a previous response.", "schema": { "type": "string" } }, { "name": "min_size", "in": "query", "description": "Minimum position value in USD.", "schema": { "type": "number", "minimum": 0 } }, { "name": "category", "in": "query", "description": "One RFC 4180 CSV record of exact current provider-backed market_canonical.category values. Legacy unquoted lists such as NBA,WNBA remain valid; values containing commas, quotes, or newlines are CSV-quoted. Matching is case-insensitive. Malformed quoted input fails closed as one unknown exact category.", "schema": { "type": "string" } }, { "name": "min_grade", "in": "query", "description": "Minimum trader grade.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ] } }, { "name": "condition_id", "in": "query", "description": "Scope to one market. Accepts the raw provider condition_id or the mkt_-prefixed market id (round-trips a value from a list response). Polymarket-only; a Kalshi or unknown id returns [].", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Large positions list", "headers": { "ETag": { "$ref": "#/components/headers/ETag" }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/LargePosition" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true, "description": "Opaque cursor for the next page; absent on the last page." }, "total": { "type": "integer", "nullable": true, "description": "Total ranked rows when the read model exposes a count; may be absent." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "description": "Validator for the unchanged payload.", "schema": { "type": "string" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/large-positions?min_grade=A&limit=10'" } ] } }, "/api/v1/whale-trades": { "get": { "operationId": "listWhaleTrades", "summary": "List whale trades", "description": "Returns recent large trades with signal scoring. Filter by size, category, or trader grade. Filters are applied before pagination, and every request uses SQL-backed limit + 1 pagination so has_more and next_cursor reflect the filtered result set. Cursor-paginated, newest first. Market categories come from provider-backed market_canonical identity.", "tags": [ "Whale Trades" ], "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response's next_cursor.", "schema": { "type": "string" } }, { "name": "min_size", "in": "query", "description": "Minimum trade size in USD.", "schema": { "type": "number", "default": 5000 } }, { "name": "category", "in": "query", "description": "Filter by market category (case-insensitive). A canonical bucket name (e.g. Basketball) matches every provider member that folds into it (NBA, WNBA, NCAAB); a raw provider value also resolves to its bucket.", "schema": { "type": "string" } }, { "name": "min_grade", "in": "query", "description": "Minimum trader grade.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ] } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of whale trades", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/WhaleTrade" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/whale-trades'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/whale-trades/history": { "get": { "operationId": "listWhaleTradeHistory", "summary": "Replay historical whale trades", "description": "Returns historical whale trades from local whale_alerts rows, not request-time provider fetches. Filter by condition_id, trader, category, minimum grade, platform, and RFC3339 from/to windows. All filters are pushed into SQL before LIMIT, every request uses SQL-backed limit + 1 pagination, and results are ordered newest first by traded_at desc, id desc. Metadata exposes local_replay source and best_effort completeness.", "tags": [ "Whale Trades" ], "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response's next_cursor. Prefix: wth_. URL-encode when replaying as a query parameter.", "schema": { "type": "string" } }, { "name": "min_size", "in": "query", "description": "Minimum trade size in USD.", "schema": { "type": "number", "default": 5000 } }, { "name": "condition_id", "in": "query", "description": "Exact raw provider condition_id. Unknown markets return an empty list.", "schema": { "type": "string" } }, { "name": "trader", "in": "query", "description": "Trader wallet address, timestamp-suffixed wallet alias, or username resolved against the traders table. Unknown traders return an empty list.", "schema": { "type": "string" } }, { "name": "category", "in": "query", "description": "Filter by market category (case-insensitive). A canonical bucket name (e.g. Basketball) matches every provider member that folds into it (NBA, WNBA, NCAAB); a raw provider value also resolves to its bucket.", "schema": { "type": "string" } }, { "name": "min_grade", "in": "query", "description": "Minimum trader grade.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ] } }, { "name": "platform", "in": "query", "description": "Filter by whale_alerts.platform. all is equivalent to omitted.", "schema": { "type": "string", "enum": [ "polymarket", "kalshi", "all" ] } }, { "name": "from", "in": "query", "description": "Inclusive RFC3339 lower bound on whale_alerts.traded_at.", "schema": { "type": "string", "format": "date-time" } }, { "name": "to", "in": "query", "description": "Exclusive RFC3339 upper bound on whale_alerts.traded_at. Must be after from when both are present.", "schema": { "type": "string", "format": "date-time" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Historical whale trade replay", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/WhaleTrade" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/WhaleTradeHistoryMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/whale-trades/history'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/whale-trades/{id}": { "get": { "operationId": "getWhaleTrade", "summary": "Get whale trade by ID", "description": "Returns one whale trade by raw whale_alerts.id or the wt_-prefixed id emitted by list and history responses.", "tags": [ "Whale Trades" ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Raw whale_alerts.id or wt_-prefixed whale trade id.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Whale trade", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "whale_trade" }, "data": { "$ref": "#/components/schemas/WhaleTrade" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "whale_trade", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/whale-trades/wt_123'" } ], "x-examples": { "success": { "object": "whale_trade", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/leaderboard": { "get": { "operationId": "listLeaderboard", "summary": "Get trader leaderboard", "description": "Returns ranked traders (grades S/A/B) sorted by score descending. Supports cursor pagination and optional category/strategy filters.", "tags": [ "Leaderboard" ], "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor (score_address format).", "schema": { "type": "string" } }, { "name": "category", "in": "query", "description": "Filter by category. Values are matched to canonical category buckets: political variants (Elections, Global Politics, U.S. Politics, ...) fold into Politics, Geopolitics stays distinct, Culture/Entertainment map to Pop Culture, Science maps to Science & Tech, and Finance/Business map to Stocks. Mapped buckets are case-insensitive; passthrough categories (Crypto, NBA, and the sports leagues) match case-sensitively against the provider-native bucket key, so use exact casing (e.g. Crypto, NBA).", "schema": { "type": "string" } }, { "name": "strategy", "in": "query", "description": "Filter by ML-detected strategy type. Values come from backend/src/trader_analysis/classification/decision_tree.rs and are matched exactly against trader_classifications.primary_type. Unknown values currently match zero rows; the handler does not return HTTP 400.", "schema": { "type": "string", "enum": [ "accumulator", "algo_trader", "arbitrageur", "directional", "event_driven", "market_maker", "momentum", "scalper", "speculator", "swing_trader" ] } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Ranked trader list", "headers": { "ETag": { "description": "Stable validator for the current leaderboard payload. Re-send it via If-None-Match for conditional GETs.", "schema": { "type": "string" } }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/LeaderboardEntry" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current leaderboard payload.", "headers": { "ETag": { "description": "Validator for the unchanged leaderboard payload.", "schema": { "type": "string" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/leaderboard'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/pick-of-the-day": { "get": { "operationId": "getPickOfTheDay", "summary": "Get today's Pick of the Day", "description": "One sourced sharp-money call a day (Pro-tier). Returns the published pick for the CURRENT product day: the backed side, the pre-game odds and $100 return, the proven smart-money holders on that side, the grade, and a required truthful thesis. With proven holder backing the thesis uses the sharp-money grammar; without it the required string names the Pick of the Day without fabricating proof. The price is snapshotted before kickoff so it does not drift. It never serves a prior day's finished pick as today's, so an automated consumer never acts on a stale, already-settled game (a prior pick stays available through the archive endpoint). When no pick is published for the current product day it returns 404 with error.code=\"not_found\" and error.reason=\"pick_not_released\" -- branch on the reason, because error.code is a frozen contract and stays \"not_found\". That 404 is a schedule, not an outage: each selected pick normally releases one hour before its provider kickoff, within the 11:00-23:00 UTC operating window; a skipped day has no release. DO NOT POLL. error.retry_at (RFC3339, always in the future) and Retry-After give the recommended next attempt: the automatic release boundary before a selected pick; normally the persisted next automatic selector attempt (~15m) while no candidate exists; or a ~60s degradation when that schedule is absent, due, or a pick is overdue. Every value is advisory under supported operator actions: manual publication, release-time override, or admin generation can make a pick available first. Schedule one request rather than sleeping a worker thread.", "tags": [ "Pick of the Day" ], "parameters": [ { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Today's Pick of the Day", "headers": { "ETag": { "description": "Stable validator for the current Pick of the Day payload. Re-send it via If-None-Match for conditional GETs.", "schema": { "type": "string" } }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "pick_of_the_day" }, "data": { "$ref": "#/components/schemas/PickOfTheDay" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Published pick whose selector recorded no qualifying category expert -- a real negative, confirmed by trust", "value": { "object": "pick_of_the_day", "data": { "state": "full", "pick_date": "2026-06-23", "matchup": "Portugal vs. Uzbekistan", "category": "Soccer", "display_category": "Soccer", "platform": "polymarket", "release_at": "2026-06-23T17:00:00Z", "is_locked": false, "outcome": "pending", "pick_outcome_label": "Portugal", "position": "Portugal to win", "side_summary": "Smart money is backing Portugal", "smart_wallet_count": 7, "top_grade": "A", "smart_usd": 48250.0, "backed_price": 0.62, "return_per_100": 161.29, "sharp_pct": 0.9, "market_pct": 0.62, "consensus_edge_pct": 0.28, "directional_confidence": 0.82, "one_way_holder_count": 3, "hedged_holder_count": 1, "one_way_graded_usd": 820.0, "total_graded_usd": 1000.0, "traders": 7, "backed_sharp_usd": 312500.0, "holders": [ { "address": "0x0000000000000000000000000000000000000000", "name": "swisstony", "grade": "A", "shares": 12500.0 } ], "holder_count": 7, "editorial_note": null, "thesis": "Proven sharp money holds Portugal, led by a grade-A trader.", "market_url": "https://0xinsider.com/event/portugal-vs-uzbekistan", "event_slug": "portugal-vs-uzbekistan", "sports_context": { "league_name": "FIFA World Cup", "league_logo": "https://polymarket.com/leagues/fifa-world-cup.png", "yes_team": { "label": "Portugal", "short_label": "POR", "full_name": "Portugal national football team", "provider_id": 1421, "logo": "https://polymarket.com/teams/portugal.png", "color": "#C8102E", "record": null, "score": null }, "no_team": { "label": "Uzbekistan", "short_label": "UZB", "full_name": "Uzbekistan national football team", "provider_id": 1738, "logo": "https://polymarket.com/teams/uzbekistan.png", "color": "#1EB53A", "record": null, "score": null }, "game_id": 884213, "event_matchup": false, "matchup_title": "Portugal \u2013 Uzbekistan" }, "disclaimer": "Not financial advice. Prediction markets carry risk; do your own research.", "trust": { "qualifying_expert": { "source": { "kind": "computed", "owner": "pick_of_the_day", "field": "qualifying_expert" }, "freshness": { "status": "not_live" }, "reconciliation": { "status": "not_applicable", "detail": "the selector evaluated this pick and no qualifying category expert was recorded on the backed side" }, "completeness": { "status": "not_applicable", "detail": "the selector evaluated this pick and no qualifying category expert was recorded on the backed side" } } } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } }, "specialist_evidence_unavailable": { "summary": "Identical absent qualifying_expert, but the stored evidence is malformed. Read trust before concluding that no specialist backed the pick.", "value": { "object": "pick_of_the_day", "data": { "state": "full", "pick_date": "2026-06-23", "matchup": "Portugal vs. Uzbekistan", "category": "Soccer", "display_category": "Soccer", "platform": "polymarket", "release_at": "2026-06-23T17:00:00Z", "is_locked": false, "outcome": "pending", "pick_outcome_label": "Portugal", "position": "Portugal to win", "side_summary": "Smart money is backing Portugal", "smart_wallet_count": 7, "top_grade": "A", "smart_usd": 48250.0, "backed_price": 0.62, "return_per_100": 161.29, "sharp_pct": 0.9, "market_pct": 0.62, "consensus_edge_pct": 0.28, "directional_confidence": 0.82, "one_way_holder_count": 3, "hedged_holder_count": 1, "one_way_graded_usd": 820.0, "total_graded_usd": 1000.0, "traders": 7, "backed_sharp_usd": 312500.0, "holders": [ { "address": "0x0000000000000000000000000000000000000000", "name": "swisstony", "grade": "A", "shares": 12500.0 } ], "holder_count": 7, "editorial_note": null, "thesis": "Proven sharp money holds Portugal, led by a grade-A trader.", "market_url": "https://0xinsider.com/event/portugal-vs-uzbekistan", "event_slug": "portugal-vs-uzbekistan", "sports_context": { "league_name": "FIFA World Cup", "league_logo": "https://polymarket.com/leagues/fifa-world-cup.png", "yes_team": { "label": "Portugal", "short_label": "POR", "full_name": "Portugal national football team", "provider_id": 1421, "logo": "https://polymarket.com/teams/portugal.png", "color": "#C8102E", "record": null, "score": null }, "no_team": { "label": "Uzbekistan", "short_label": "UZB", "full_name": "Uzbekistan national football team", "provider_id": 1738, "logo": "https://polymarket.com/teams/uzbekistan.png", "color": "#1EB53A", "record": null, "score": null }, "game_id": 884213, "event_matchup": false, "matchup_title": "Portugal \u2013 Uzbekistan" }, "disclaimer": "Not financial advice. Prediction markets carry risk; do your own research.", "trust": { "qualifying_expert": { "source": { "kind": "unavailable", "owner": "pick_of_the_day", "field": "qualifying_expert" }, "freshness": { "status": "unavailable" }, "reconciliation": { "status": "unavailable", "detail": "frozen qualifying-expert evidence does not deserialize into the published shape; the specialist that decided this pick's selection rank cannot be described" }, "completeness": { "status": "unavailable", "detail": "frozen qualifying-expert evidence does not deserialize into the published shape; the specialist that decided this pick's selection rank cannot be described" } } } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current Pick of the Day payload.", "headers": { "ETag": { "description": "Validator for the unchanged Pick of the Day payload.", "schema": { "type": "string" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/PickNotReleased" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/ReadModelWarming" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/pick-of-the-day'" } ], "x-examples": { "success": { "object": "pick_of_the_day", "data": { "state": "full", "pick_date": "2026-06-23", "matchup": "Portugal vs. Uzbekistan", "category": "Soccer", "display_category": "Soccer", "platform": "polymarket", "release_at": "2026-06-23T17:00:00Z", "is_locked": false, "outcome": "pending", "pick_outcome_label": "Portugal", "position": "Portugal to win", "side_summary": "Smart money is backing Portugal", "smart_wallet_count": 7, "top_grade": "A", "smart_usd": 48250.0, "backed_price": 0.62, "return_per_100": 161.29, "sharp_pct": 0.9, "market_pct": 0.62, "consensus_edge_pct": 0.28, "directional_confidence": 0.82, "one_way_holder_count": 3, "hedged_holder_count": 1, "one_way_graded_usd": 820.0, "total_graded_usd": 1000.0, "traders": 7, "backed_sharp_usd": 312500.0, "holders": [ { "address": "0x0000000000000000000000000000000000000000", "name": "swisstony", "grade": "A", "shares": 12500.0 } ], "holder_count": 7, "editorial_note": null, "thesis": "Proven sharp money holds Portugal, led by a grade-A trader.", "market_url": "https://0xinsider.com/event/portugal-vs-uzbekistan", "event_slug": "portugal-vs-uzbekistan", "sports_context": { "league_name": "FIFA World Cup", "league_logo": "https://polymarket.com/leagues/fifa-world-cup.png", "yes_team": { "label": "Portugal", "short_label": "POR", "full_name": "Portugal national football team", "provider_id": 1421, "logo": "https://polymarket.com/teams/portugal.png", "color": "#C8102E", "record": null, "score": null }, "no_team": { "label": "Uzbekistan", "short_label": "UZB", "full_name": "Uzbekistan national football team", "provider_id": 1738, "logo": "https://polymarket.com/teams/uzbekistan.png", "color": "#1EB53A", "record": null, "score": null }, "game_id": 884213, "event_matchup": false, "matchup_title": "Portugal \u2013 Uzbekistan" }, "disclaimer": "Not financial advice. Prediction markets carry risk; do your own research.", "trust": { "qualifying_expert": { "source": { "kind": "computed", "owner": "pick_of_the_day", "field": "qualifying_expert" }, "freshness": { "status": "unknown" }, "reconciliation": { "status": "not_applicable", "detail": "this pick was never evaluated for a qualifying category expert: it predates the field or was replaced by a manual off-slate takeover" }, "completeness": { "status": "not_computed", "detail": "this pick was never evaluated for a qualifying category expert: it predates the field or was replaced by a manual off-slate takeover" } } } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/pick-of-the-day/archive": { "get": { "operationId": "getPickOfTheDayArchive", "summary": "Get the Pick of the Day track record", "description": "Every published Pick of the Day with its real outcome, plus the rolling hit rate (wins / decided; void and pending excluded). Resolved picks are public; a still-pending pick's backed side is included for the authenticated Pro key.", "tags": [ "Pick of the Day" ], "parameters": [ { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Pick of the Day track record", "headers": { "ETag": { "description": "Stable validator for the current Pick of the Day archive payload. Re-send it via If-None-Match for conditional GETs.", "schema": { "type": "string" } }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "pick_of_the_day_archive" }, "data": { "$ref": "#/components/schemas/PickOfTheDayArchive" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "pick_of_the_day_archive", "data": { "picks": [ { "pick_date": "2026-06-23", "matchup": "Portugal vs. Uzbekistan", "category": "Soccer", "display_category": "Soccer", "pick_outcome_label": "Portugal", "top_grade": "A", "outcome": "pending" }, { "pick_date": "2026-06-22", "matchup": "Spain vs. France", "category": "Soccer", "display_category": "Soccer", "image_url": "https://polymarket-upload.s3.us-east-2.amazonaws.com/soccer%20ball-bba4025f77.png", "pick_outcome_label": "Spain", "top_grade": "A", "outcome": "win", "return_per_100": 200.0 } ], "hit_rate": { "wins": 1, "losses": 0, "decided": 1, "pct": 100.0, "void": 0, "pending": 1, "net_profit_usd": 100.0, "staked_usd": 100.0, "roi_pct": 100.0, "net_profit_display": "+$100", "roi_display": "+100.0%", "win_rate_display": "100.0%", "series": [ { "date": "2026-06-22", "net_profit_usd": 100.0, "hit_rate_pct": 100.0 } ] } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current Pick of the Day archive payload.", "headers": { "ETag": { "description": "Validator for the unchanged Pick of the Day archive payload.", "schema": { "type": "string" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/pick-of-the-day/archive'" } ] } }, "/api/v1/leaderboard/trending": { "get": { "operationId": "listTrendingWallets", "summary": "List trending wallets", "description": "Returns wallets ranked by Polymarket weekly/monthly P&L (Polymarket-only discovery), with opaque page-cursor pagination. trending_pnl_usd and the by-PNL row order come from Polymarket's canonical leaderboard (data-api.polymarket.com/v1/leaderboard?timePeriod=week|month&orderBy=PNL), not a locally summed realized-leaf total. Each row also carries window volume, distinct markets, grade, hot-streak tier, and a shape-only daily P&L sparkline derived from the Polymarket user-pnl cumulative curve (per-day deltas; not guaranteed to sum to trending_pnl_usd). The underlying read model is warmed into Redis; a cold read returns 503 (warming, retry-after), never a 500 or a fabricated ranking. Polymarket-only: the read model filters platform = 'polymarket'.", "tags": [ "Leaderboard" ], "parameters": [ { "name": "limit", "in": "query", "description": "Polymarket's weekly leaderboard caps the ranked set at 50 wallets; requests above 50 still return at most 50.", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Opaque pagination cursor from a previous response.", "schema": { "type": "string" } }, { "name": "window", "in": "query", "description": "Trailing window.", "schema": { "type": "string", "enum": [ "7d", "30d" ], "default": "7d" } } ], "responses": { "200": { "description": "Trending wallets list", "headers": { "ETag": { "$ref": "#/components/headers/ETag" }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/TrendingWallet" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true, "description": "Opaque cursor for the next page; absent on the last page." }, "total": { "type": "integer", "nullable": true, "description": "Total ranked rows when the read model exposes a count; may be absent." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "description": "Validator for the unchanged payload.", "schema": { "type": "string" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/ReadModelWarming" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/leaderboard/trending?window=7d&limit=10'" } ] } }, "/api/v1/markets/search": { "get": { "operationId": "searchMarkets", "summary": "Search markets", "description": "Search prediction markets by keyword. Returns representative market matches with status, category, and platform metadata. Cursor pagination advances over grouped market results rather than raw sub-market rows.", "tags": [ "Markets" ], "parameters": [ { "name": "q", "in": "query", "required": true, "description": "Search query. Must be 1-512 characters before whitespace trimming and non-empty after trimming.", "schema": { "type": "string", "minLength": 1, "maxLength": 512 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response's next_cursor.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "description": "Filter by market status.", "schema": { "type": "string", "enum": [ "active", "closed", "all" ], "default": "all" } }, { "name": "category", "in": "query", "description": "Filter by category.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Search results", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/MarketSearchResult" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/markets/search'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/markets/explore": { "get": { "operationId": "exploreMarkets", "summary": "Explore markets", "description": "Browse whale-active titled markets with category, platform, status, and keyword filters. Explore is Polymarket-only: the platform parameter is accepted for backward-compatibility but every request returns Polymarket markets. Paginates visible discovery entries rather than raw market rows, returns live category/platform facets alongside grouped event clusters or standalone markets, and includes total on the first page only. Categories come straight from provider metadata (Polymarket Gamma) and facets are flat value/label/count rows.", "tags": [ "Markets" ], "parameters": [ { "name": "category", "in": "query", "description": "Filter by market category (case-insensitive). A canonical bucket name (e.g. Basketball) matches every provider member that folds into it (NBA, WNBA, NCAAB); a raw provider value also resolves to its bucket. Facet values are returned as the canonical bucket.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "description": "Filter by market status.", "schema": { "type": "string", "enum": [ "active", "closed", "all" ], "default": "all" } }, { "name": "platform", "in": "query", "description": "Filter by source platform. Explore is Polymarket-only; polymarket is the only supported value and the parameter is accepted for backward-compatibility but does not change the result set.", "schema": { "type": "string", "enum": [ "polymarket" ], "default": "polymarket" } }, { "name": "sort", "in": "query", "description": "Sort order for the discovery feed.", "schema": { "type": "string", "enum": [ "trending", "hot", "expiring", "whales", "volume", "newest" ], "default": "trending" } }, { "name": "cursor", "in": "query", "description": "Opaque pagination cursor from the previous response.", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Page size.", "schema": { "type": "integer", "minimum": 1, "maximum": 48, "default": 24 } }, { "name": "q", "in": "query", "description": "Keyword search against market titles.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Grouped market discovery results", "headers": { "ETag": { "description": "Stable validator for the current explore payload. Re-send it via If-None-Match for conditional GETs.", "schema": { "type": "string" } }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "facets", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/ExploreEntry" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching visible entries after grouping. Present on the first page and omitted on cursor pages." }, "facets": { "$ref": "#/components/schemas/ExploreFacets" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current explore payload.", "headers": { "ETag": { "description": "Validator for the unchanged explore payload.", "schema": { "type": "string" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/markets/explore'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/markets/smart-money-flows": { "get": { "operationId": "listSmartMoneyFlows", "summary": "List ranked smart-money flows", "description": "Ranks markets by absolute net S/A/B-grade whale flow over a requested timeframe. Use this discovery endpoint to answer where smart money is flowing before drilling into a specific market with /api/v1/market/{condition_id}/intel. Pagination is anchored by an opaque cursor carrying the first page as_of timestamp so new whale trades do not reorder page 2.", "tags": [ "Markets" ], "parameters": [ { "name": "timeframe", "in": "query", "description": "Lookback window for grade-filtered whale flow aggregation.", "schema": { "type": "string", "enum": [ "1h", "4h", "24h", "7d" ], "default": "24h" } }, { "name": "limit", "in": "query", "description": "Page size.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Opaque cursor from previous response's next_cursor. Encodes the first-page as_of timestamp plus the last row's absolute net flow and condition_id.", "schema": { "type": "string" } }, { "name": "category", "in": "query", "description": "Filter by market category (case-insensitive). A canonical bucket name (e.g. Basketball) matches every provider member that folds into it (NBA, WNBA, NCAAB); a raw provider value also resolves to its bucket.", "schema": { "type": "string" } }, { "name": "platform", "in": "query", "description": "Filter by source platform. all is a request-side no-op.", "schema": { "type": "string", "enum": [ "polymarket", "kalshi", "all" ], "default": "all" } }, { "name": "min_grade", "in": "query", "description": "Minimum latest trader grade included in the flow. Default B means S/A/B only; unranked traders are excluded.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ], "default": "B" } }, { "name": "direction", "in": "query", "description": "Optional post-aggregate flow direction filter.", "schema": { "type": "string", "enum": [ "YES", "NO" ] } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Ranked market smart-money flows", "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/SmartMoneyFlowMarket" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [ { "market": { "id": "mkt_0x123", "condition_id": "0x123", "title": "Will BTC close above $100k this week?", "slug": "btc-close-above-100k-this-week", "category": "Crypto", "platform": "polymarket" }, "sharp_money": { "net_flow_usd": 12345.67, "direction": "YES", "whale_trade_count": 7, "buy_volume_usd": 20000, "sell_volume_usd": 7654.33 }, "smart_money": { "net_flow_usd": 12345.67, "direction": "YES", "whale_trade_count": 7, "buy_volume_usd": 20000, "sell_volume_usd": 7654.33 }, "timeframe": "24h" } ], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 3 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/CursorExpired" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/markets/smart-money-flows?timeframe=7d&min_grade=B&limit=10'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 3 } } } } }, "/api/v1/markets/sharp-money-flows": { "get": { "operationId": "listSharpMoneyFlows", "summary": "List ranked sharp-money flows", "description": "Canonical alias of /api/v1/markets/smart-money-flows, which remains live but deprecated. Ranks markets by absolute net S/A/B-grade whale flow over a requested timeframe. Use this discovery endpoint to answer where sharp money is flowing before drilling into a specific market with /api/v1/market/{condition_id}/intel. Pagination is anchored by an opaque cursor carrying the first page as_of timestamp so new whale trades do not reorder page 2.", "tags": [ "Markets" ], "parameters": [ { "name": "timeframe", "in": "query", "description": "Lookback window for grade-filtered whale flow aggregation.", "schema": { "type": "string", "enum": [ "1h", "4h", "24h", "7d" ], "default": "24h" } }, { "name": "limit", "in": "query", "description": "Page size.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Opaque cursor from previous response's next_cursor. Encodes the first-page as_of timestamp plus the last row's absolute net flow and condition_id.", "schema": { "type": "string" } }, { "name": "category", "in": "query", "description": "Filter by market category (case-insensitive). A canonical bucket name (e.g. Basketball) matches every provider member that folds into it (NBA, WNBA, NCAAB); a raw provider value also resolves to its bucket.", "schema": { "type": "string" } }, { "name": "platform", "in": "query", "description": "Filter by source platform. all is a request-side no-op.", "schema": { "type": "string", "enum": [ "polymarket", "kalshi", "all" ], "default": "all" } }, { "name": "min_grade", "in": "query", "description": "Minimum latest trader grade included in the flow. Default B means S/A/B only; unranked traders are excluded.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ], "default": "B" } }, { "name": "direction", "in": "query", "description": "Optional post-aggregate flow direction filter.", "schema": { "type": "string", "enum": [ "YES", "NO" ] } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Ranked market sharp-money flows", "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/SmartMoneyFlowMarket" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [ { "market": { "id": "mkt_0x123", "condition_id": "0x123", "title": "Will BTC close above $100k this week?", "slug": "btc-close-above-100k-this-week", "category": "Crypto", "platform": "polymarket" }, "sharp_money": { "net_flow_usd": 12345.67, "direction": "YES", "whale_trade_count": 7, "buy_volume_usd": 20000, "sell_volume_usd": 7654.33 }, "smart_money": { "net_flow_usd": 12345.67, "direction": "YES", "whale_trade_count": 7, "buy_volume_usd": 20000, "sell_volume_usd": 7654.33 }, "timeframe": "24h" } ], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 3 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/CursorExpired" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/markets/sharp-money-flows?timeframe=7d&min_grade=B&limit=10'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 3 } } } } }, "/api/v1/sports-edge-signals": { "get": { "operationId": "listSportsEdgeSignals", "summary": "List ranked pre-game sports-edge signals", "description": "Pro-tier. Ranked list of upcoming pre-game sports markets (moneyline + props) where graded (S/A/B) smart money is piled on one side, each row carrying the piled side, its grade distribution, kickoff, piled-side Polymarket CLOB token id, and required shadow-only category_skill evidence. Eligibility and ranking remain the funded FLOW/HOLDER contract; category skill cannot change membership, order, rank, cursor, routing, or sizing. meta exposes explicit category source/model/status plus independently computed pre/post SHA-256 base-vector hashes that must match. Served from a shared server-side snapshot cache (healthy TTL ~180s, degraded ~30s) computed once per category at the maximum 48h horizon and filtered at request time; the cursor pins to that snapshot and a stale cursor is rejected. Polymarket only; source coverage is partial first-observed post-launch Goldsky primary taker BUY fills admitted by the canonical whale-alert thresholds, never reconstructed history. Deliberately not the editorial Pick of the Day ranker.", "tags": [ "Markets" ], "parameters": [ { "name": "category", "in": "query", "description": "Optional canonical sport bucket filter (e.g. Basketball, Tennis, Soccer). A raw provider value (NBA) resolves to its canonical bucket. A non-sport category returns an empty list.", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Page size.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Opaque cursor from a previous response's next_cursor. Encodes the snapshot anchor plus the last row's directional_rank_score, conviction_score, smart_score and condition_id. A cursor from an expired snapshot returns 400.", "schema": { "type": "string" } }, { "name": "horizon_hours", "in": "query", "description": "Kickoff ceiling in hours from now; the floor is now (only games not yet started). Clamped to 1..48.", "schema": { "type": "integer", "minimum": 1, "maximum": 48, "default": 12 } }, { "name": "min_grade", "in": "query", "description": "Minimum trader grade required on the piled side. Only S, A, B are accepted (the piled-side grade distribution is S/A/B only; C, D, F return 400). Default B means at least one S/A/B holder is piled; S requires an S holder, A requires an S or A holder.", "schema": { "type": "string", "enum": [ "S", "A", "B" ], "default": "B" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Ranked pre-game sports-edge signals", "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/SportsEdgeSignal" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 5 } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/CursorExpired" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/sports-edge-signals?category=Basketball&horizon_hours=12&min_grade=B&limit=10'" } ] } }, "/api/v1/sports-edge-observations": { "get": { "operationId": "listSportsEdgeObservations", "summary": "List observation-only sports-edge cohorts", "description": "Pro-tier. Measures two explicitly observation-only Polymarket sports cohorts without changing or feeding GET /api/v1/sports-edge-signals: wider_holder measures pre-game holder piles outside the funded route's exact raw slate admission, including recent-flow rows rejected by its event, bucket, or total caps; in_play admits only provider-confirmed live games and fails closed when the provider live-board snapshot is stale or unavailable or holder/directional evidence is stale or unavailable. Every row carries observation_only=true, provider/holder freshness and completeness fields, and the response carries a required snapshot-wide operational/unknown-completeness degraded boolean plus an accountable per-sport funnel over a closed 25-value terminal-reason vocabulary. Omitted or blank category selects all 14 registered observation sport buckets, including Table Tennis and Pickleball; those two remain outside the funded sports projection. All category and all-sports cache scopes share one global observation provider-work admission, so distinct scope keys cannot multiply concurrent provider fanout. One absolute ~25s compute deadline covers cache coordination, board/universe and primary-slate membership reads, holder cache/provider work, price/metadata evaluation, and directional reads, leaving ~5s below the public router timeout for funnel reconciliation, cleanup, and response transport. A shared pre-holder stage deadline jointly bounds those database reads and board reconciliation to the smaller of 12s or half of the absolute budget remaining when that stage starts, preserving holder/post-holder opportunity; board reads use bounded fair waves and cold holder admission gives each represented canonical sport one row before any sport repeats. Single-flight refresh contention, global provider-work admission contention, absolute deadline exhaustion before a usable cache, or pre-holder stage expiry before a usable stored universe or primary-slate membership result returns 503 with error.reason=read_model_warming. Category-resolution SQL errors, Redis coordination failures, observation-universe SQL errors, and primary-slate membership query failures return 500 internal_error instead. Once a usable universe exists, later operational or unknown-completeness board, holder, or price/metadata failures are retained as explicit terminal reasons in a degraded 200 response with degraded=true: board_source_unavailable is a completed board-source failure, board_deadline_unavailable means live-board work missed either an internal configured-scope deadline or the outer fair-wave deadline; both classify only already-started rows, so for the upcoming source read funnel.sports[].board_upcoming_status instead; provider_unavailable is an attempted holder-provider failure, and holder_deadline_unavailable is holder-stage deadline exhaustion. Directional incompleteness is cohort-specific: a wider_holder row remains emitted with terminal wider_holder_emitted and directional_status=unavailable, while an in_play row fails closed with terminal in_play_directional_unavailable. capacity_limited records intentional bounded provider-work admission in the funnel and does not by itself set degraded=true. Healthy wider_holder requests may reuse a snapshot for ~180s; in_play never serves a cached observation snapshot older than ~30s, and degraded snapshots use ~30s. The ETag is a weak semantic validator over the stable page payload, including next_cursor, with request-specific meta excluded.", "tags": [ "Markets" ], "parameters": [ { "name": "cohort", "in": "query", "required": true, "description": "Observation cohort. wider_holder measures pre-game holder piles outside the funded route's exact raw slate admission. in_play admits only provider-confirmed live games and excludes stale or unavailable provider live-board, holder, or directional evidence.", "schema": { "type": "string", "enum": [ "wider_holder", "in_play" ] } }, { "name": "category", "in": "query", "description": "Optional canonical sport bucket. Omitted or blank selects all registered sports. Raw provider categories resolve through the canonical taxonomy, including table-tennis or table tennis to Table Tennis and pickleball to Pickleball; a non-sport category returns an empty list.", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Page size.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Opaque seo_ cursor from next_cursor. Pins snapshot_as_of, cohort, rank, and condition_id. It cannot cross cohorts; a refreshed snapshot invalidates it with 400.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET using a previous weak semantic ETag. Matching stable payloads return 304 Not Modified with an empty body; request-specific meta is excluded from validation.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Observation-only sports cohort with a snapshot-wide operational/unknown-completeness degraded verdict and accountable funnel", "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" }, "Cache-Control": { "description": "Client caches may store the private response but must revalidate it before every reuse, independently of the server-side snapshot TTL.", "schema": { "type": "string", "const": "private, no-cache" } } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "next_cursor", "snapshot_as_of", "degraded", "funnel", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/SportsEdgeObservation" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "snapshot_as_of": { "type": "string", "format": "date-time", "description": "Completion time of the shared observation snapshot pinned by the cursor." }, "degraded": { "type": "boolean", "description": "True when an operational failure or unknown provider-board, holder, directional, reconciliation, or internal completeness state made this snapshot partial. This is snapshot-wide and can retain degradation that the funnel's one-terminal-per-input accounting cannot represent. Intentional bounded capacity_limited rows remain fully accounted in the funnel and do not by themselves set this field." }, "funnel": { "$ref": "#/components/schemas/SportsEdgeFunnelReport" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current sports-edge observation payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" }, "Cache-Control": { "description": "Client caches may store the private response but must revalidate it before every reuse, independently of the server-side snapshot TTL.", "schema": { "type": "string", "const": "private, no-cache" } } } }, "400": { "$ref": "#/components/responses/CursorExpired" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/ReadModelWarming" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/sports-edge-observations?cohort=wider_holder&category=Tennis&limit=20'" } ] } }, "/api/v1/platforms": { "get": { "operationId": "getPlatforms", "summary": "Get platform capability matrix", "description": "Unauthenticated discovery endpoint that declares which V1 intelligence surfaces are supported, partial, or unsupported per provider platform.", "tags": [ "System" ], "security": [], "responses": { "200": { "description": "Platform capability matrix", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "platforms" }, "data": { "$ref": "#/components/schemas/Platforms" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "platforms", "data": { "platforms": { "polymarket": { "grade": "supported", "pnl": "supported", "strategy": "supported", "timeline": "supported", "whale_signal": "supported", "insider_radar": "supported", "market_snapshot": "supported" }, "kalshi": { "grade": "unsupported", "pnl": "partial", "strategy": "unsupported", "timeline": "partial", "whale_signal": "unsupported", "insider_radar": "unsupported", "market_snapshot": "partial" } } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS 'https://api.0xinsider.com/api/v1/platforms'" } ], "x-examples": { "success": { "object": "platforms", "data": { "platforms": { "polymarket": { "grade": "supported", "pnl": "supported", "strategy": "supported", "timeline": "supported", "whale_signal": "supported", "insider_radar": "supported", "market_snapshot": "supported" }, "kalshi": { "grade": "unsupported", "pnl": "partial", "strategy": "unsupported", "timeline": "partial", "whale_signal": "unsupported", "insider_radar": "unsupported", "market_snapshot": "partial" } } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/market/{condition_id}/intel": { "get": { "operationId": "getMarketIntel", "summary": "Get market intelligence", "description": "Smart money flow analysis for a specific market \u2014 net flow direction, whale trade count, buy/sell volumes, and top graded trader positions.", "tags": [ "Markets" ], "parameters": [ { "name": "condition_id", "in": "path", "required": true, "description": "Market condition ID. Accepts the raw provider-backed condition_id returned by /api/v1/markets/search or the mkt_-prefixed market.id emitted by V1 responses.", "schema": { "type": "string" } }, { "name": "timeframe", "in": "query", "description": "Lookback window for whale flow aggregation.", "schema": { "type": "string", "enum": [ "1h", "4h", "24h", "7d" ], "default": "24h" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Market intelligence", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "market_intel" }, "data": { "$ref": "#/components/schemas/MarketIntel" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "markets", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/market/{condition_id}/intel'" } ], "x-examples": { "success": { "object": "markets", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/markets/intel/batch": { "post": { "operationId": "batchGetMarketIntel", "summary": "Batch market intelligence", "description": "Returns smart-money market intelligence for 1-25 raw provider condition_id values. Results preserve request order, duplicate inputs return duplicate rows, and each item is charged one batch item unit before execution. Do not pass prefixed mkt_ IDs; use market.condition_id from search or explore.", "tags": [ "Markets" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "condition_ids" ], "properties": { "condition_ids": { "type": "array", "minItems": 1, "maxItems": 25, "items": { "type": "string" } }, "timeframe": { "type": "string", "enum": [ "1h", "4h", "24h", "7d" ], "default": "24h" } } }, "example": { "condition_ids": [ "0x1234567890abcdef" ], "timeframe": "24h" } } } }, "responses": { "200": { "description": "Ordered batch market intelligence results", "headers": { "X-Request-Cost": { "schema": { "type": "integer" }, "description": "Number of batch item units charged for this request." }, "X-Batch-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Batch item units allowed per minute." }, "X-Batch-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Batch item units remaining in the current sliding window." }, "X-Batch-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Unix timestamp when the batch item window resets." }, "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "market_intel_batch" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/BatchMarketIntelItem" } }, "meta": { "$ref": "#/components/schemas/BatchResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{\"condition_ids\":[\"0x1234567890abcdef\"],\"timeframe\":\"24h\"}' \\\n 'https://api.0xinsider.com/api/v1/markets/intel/batch'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/market/{condition_id}/snapshot": { "get": { "operationId": "getMarketSnapshot", "summary": "Get market live snapshot", "description": "Provider-first market card snapshot with canonical identity, outcome labels, cached top-of-book when available, liquidity, live sports context, and explicit freshness/unavailable states.", "tags": [ "Markets" ], "parameters": [ { "name": "condition_id", "in": "path", "required": true, "description": "Market condition ID. Accepts the raw provider-backed condition_id returned by /api/v1/markets/search or /api/v1/markets/explore, or the mkt_-prefixed market.id emitted by V1 responses.", "schema": { "type": "string" } }, { "name": "expand[]", "in": "query", "required": false, "description": "Backward-compatible alias for expand. Repeatable: trust.", "schema": { "type": "array", "items": { "type": "string", "enum": [ "trust" ] } }, "style": "form", "explode": true }, { "name": "expand", "in": "query", "required": false, "description": "Include trust metadata for current_price and spread_bps. Repeatable: trust.", "schema": { "type": "array", "items": { "type": "string", "enum": [ "trust" ] } }, "style": "form", "explode": true }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Provider-first market snapshot", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "market_snapshot" }, "data": { "$ref": "#/components/schemas/MarketSnapshot" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "markets", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 2 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/market/{condition_id}/snapshot'" } ], "x-examples": { "success": { "object": "markets", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 2 } } } } }, "/api/v1/market/{condition_id}/candles": { "get": { "operationId": "getMarketCandles", "summary": "Get market OHLC price candles", "description": "Provider-first bucketed OHLC price candles for a market's outcome tokens, derived from the stored token_price_snapshots series (the same series the market-detail chart renders; covers open and resolved markets). Because the stored data is daily, a 1d bucket typically carries one point so its open/high/low/close all equal that day's close; 1w aggregates real OHLC across the observed daily closes. No intraday fidelity is fabricated.", "tags": [ "Markets" ], "parameters": [ { "name": "condition_id", "in": "path", "required": true, "description": "Market condition ID. Accepts the raw provider-backed condition_id returned by /api/v1/markets/search or /api/v1/markets/explore, or the mkt_-prefixed market.id emitted by V1 responses.", "schema": { "type": "string" } }, { "name": "resolution", "in": "query", "required": false, "description": "Bucketing granularity. 1d aggregates by UTC calendar day, 1w by ISO week (Monday 00:00 UTC start). Defaults to 1d.", "schema": { "type": "string", "enum": [ "1d", "1w" ], "default": "1d" } }, { "name": "from", "in": "query", "required": false, "description": "Exclusive lower bound as a unix timestamp in seconds; points at or before this timestamp are omitted (the underlying daily snapshot read filters bucket_start > from). Note: for resolution=1w a surviving mid-week point can yield a weekly candle whose t (Monday 00:00 UTC) precedes from.", "schema": { "type": "integer", "format": "int64" } }, { "name": "to", "in": "query", "required": false, "description": "Inclusive upper bound as a unix timestamp in seconds; points after this timestamp are omitted.", "schema": { "type": "integer", "format": "int64" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Provider-first market candles", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "market_candles" }, "data": { "$ref": "#/components/schemas/MarketCandles" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "market_candles", "data": { "condition_id": "0xcond", "resolution": "1d", "outcomes": [ { "token_id": "111111", "outcome": "YES", "candles": [ { "t": 1700000000, "o": 0.42, "h": 0.45, "l": 0.41, "c": 0.44 } ] } ] }, "meta": { "request_id": "req_example", "cached": false, "cost": 2 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/market/{condition_id}/candles?resolution=1d'" } ] } }, "/api/v1/insider-radar": { "get": { "operationId": "listInsiderRadar", "summary": "Get insider radar flags", "description": "Suspicious trading patterns \u2014 pre-resolution accumulation, coordinated wallets, unusual timing. Cursor-paginated by suspicion score.", "tags": [ "Insider Radar" ], "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor from previous response.", "schema": { "type": "string" } }, { "name": "min_suspicion", "in": "query", "description": "Minimum suspicion score (0-100).", "schema": { "type": "number", "default": 0 } }, { "name": "severity", "in": "query", "description": "Filter by severity level.", "schema": { "type": "string", "enum": [ "flag", "watch" ] } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Radar flags list", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/RadarFlag" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true, "description": "Total matching rows when the read model exposes a count; absent (or null) when it does not." }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "insider_radar", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/insider-radar'" } ], "x-examples": { "success": { "object": "insider_radar", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/insider-radar/{id}": { "get": { "operationId": "getInsiderRadarFlag", "summary": "Get insider radar flag by ID", "description": "Returns one suspicious-trading radar flag by raw radar_flags.id or the rf_-prefixed id emitted by list responses.", "tags": [ "Insider Radar" ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Raw radar_flags.id or rf_-prefixed radar flag id.", "schema": { "type": "string" } }, { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Radar flag", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "radar_flag" }, "data": { "$ref": "#/components/schemas/RadarFlag" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "radar_flag", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" }, "ETag": { "$ref": "#/components/headers/ETag" } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current payload.", "headers": { "ETag": { "$ref": "#/components/headers/ETag" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/insider-radar/rf_123'" } ], "x-examples": { "success": { "object": "radar_flag", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/stream": { "get": { "operationId": "getStream", "summary": "Resumable real-time event stream (SSE)", "description": "Server-Sent Events stream of the live feed envelopes the platform already broadcasts (whale-trade pulses and other public/Pro feed events). Forwards the same backend-owned envelope shape as the internal feed; no provider data is recomputed. Authenticated via the oxi_sk Bearer key like every other /api/v1 endpoint, and limited to a small number of concurrent connections per API key and a cluster-wide ceiling across all keys (HTTP 429 with Retry-After when either cap is exceeded; HTTP 503 with Retry-After if the admission backend is briefly unavailable). Each delivered frame carries an SSE id equal to the envelope sequence; reconnect with the Last-Event-ID header (or the last_event_id / seq query fallback) to replay the missed window before resuming live. When the requested resume point predates the retained window the stream emits one resync marker event (event: resync) instead of silently skipping frames. Idle connections receive periodic ': keep-alive' comment lines. This is a long-lived response: keep the connection open and read frames as they arrive.", "tags": [ "Streaming" ], "parameters": [ { "name": "Last-Event-ID", "in": "header", "required": false, "description": "Sequence id of the last frame the client successfully processed. The stream replays the strictly-newer window before resuming live. Browser EventSource clients send this automatically on reconnect. Omit to attach live from now.", "schema": { "type": "string" } }, { "name": "last_event_id", "in": "query", "required": false, "description": "Query-string fallback for the Last-Event-ID resume cursor when the client cannot set the request header. Numeric sequence id; non-numeric or absent attaches live with no replay.", "schema": { "type": "string" } }, { "name": "seq", "in": "query", "required": false, "description": "Alias for last_event_id. Numeric sequence id to resume after; non-numeric or absent attaches live with no replay.", "schema": { "type": "string" } }, { "name": "event", "in": "query", "required": false, "description": "Optional per-connection subscribe-time filter. Comma-separated list of frame wire types (the SSE 'type' discriminator, e.g. WhaleTradesInserted,wallet_grade_changed); a frame passes only when its type is in the set. An unknown token returns HTTP 400 naming the offending value. An empty/all-whitespace value is treated as absent (no constraint). Applied to BOTH the replay window and live frames, and always AFTER the per-subscriber privacy gate, so it can never widen visibility beyond what the key may already see. Combines with condition_id and min_grade as a logical AND; an absent param adds no constraint.", "schema": { "type": "string" } }, { "name": "condition_id", "in": "query", "required": false, "description": "Optional per-connection subscribe-time filter. Raw provider condition_id or mkt_-prefixed market id (normalized the same way the other v1 market endpoints normalize). A frame passes only when it carries a matching condition_id field; frames that carry no condition_id (e.g. whale-pulse events) are EXCLUDED while this is set. An empty value after normalization returns HTTP 400. Combines with event and min_grade as a logical AND; an absent param adds no constraint.", "schema": { "type": "string" } }, { "name": "min_grade", "in": "query", "required": false, "description": "Optional per-connection subscribe-time filter. A frame passes only when it carries a grade field whose grade is better-or-equal to this minimum (S is best). Frames that carry no grade field (every frame except wallet_grade_changed) are EXCLUDED while this is set. An invalid grade returns HTTP 400. Combines with event and condition_id as a logical AND; an absent param adds no constraint.", "schema": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ] } } ], "responses": { "200": { "description": "Open Server-Sent Events stream. The body is an unbounded text/event-stream of frames; each data frame is a JSON feed envelope (with seq, published_at, type, and event-specific fields) and carries an SSE id equal to seq. resync marker frames use event: resync.", "content": { "text/event-stream": { "schema": { "type": "string", "description": "Newline-delimited SSE frames: 'id: \\ndata: \\n\\n' for events, 'event: resync\\nid: \\ndata: \\n\\n' for resync markers, and ': keep-alive' comment lines while idle." }, "examples": { "whaleEvent": { "summary": "One live whale-trade event frame", "value": "id: 142\ndata: {\"seq\":142,\"published_at\":\"2026-06-04T12:00:00Z\",\"type\":\"WhaleTradesInserted\",\"count\":3}\n\n" }, "resyncMarker": { "summary": "Resync marker after a too-old resume point", "value": "event: resync\nid: 9001\ndata: {\"type\":\"resync\",\"completeness\":{\"status\":\"truncated\",\"reason\":\"The requested Last-Event-ID predates the retained replay window; treat this as a full resync and refetch current state.\"},\"from_sequence\":12,\"to_sequence\":9001}\n\n" } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -N -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/stream'" }, { "lang": "curl", "label": "cURL (resume)", "source": "curl -N -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Last-Event-ID: 100' \\\n 'https://api.0xinsider.com/api/v1/stream'" } ] } }, "/api/v1/events/feed/since": { "get": { "operationId": "getEventReplaySince", "summary": "Replay public whale-trade intelligence events", "description": "Returns durable public whale-trade intelligence events strictly after an opaque cursor backed by whale_alerts.id. This is a separate API-key contract from the browser/session /api/events/feed stream: browser-only and private alert, following, radar, and position patch events are excluded until they have a durable public outbox.", "tags": [ "Events" ], "parameters": [ { "name": "cursor", "in": "query", "required": false, "description": "Opaque event replay cursor returned as next_cursor by a prior response. The cursor maps to whale_alerts.id and is valid across backend replicas. Omit to fetch the latest durable public suffix.", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum durable public whale-trade events to return.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } } ], "responses": { "200": { "description": "Public event replay window", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "next_cursor", "meta" ], "properties": { "object": { "type": "string", "const": "event_replay" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/EventReplayEvent" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string" }, "meta": { "$ref": "#/components/schemas/EventReplayMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "event_replay", "data": [], "has_more": false, "next_cursor": "ZWZfMA", "meta": { "request_id": "req_example", "cached": false, "cost": 1, "replay": { "from_cursor": "ZWZfMA", "to_cursor": "ZWZfMA", "from_sequence": 0, "to_sequence": 0, "ordering": "whale_alerts_id_asc" }, "retention": { "status": "durable_database", "retained_events": 0, "cursor_expired": false }, "completeness": { "status": "caught_up", "reason": "No durable public whale-trade events were found after the requested cursor." } } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/events/feed/since'" } ], "x-examples": { "success": { "object": "events", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/webhooks": { "get": { "operationId": "listWebhooks", "summary": "List builder webhook destinations", "description": "Returns webhook destinations owned by the authenticated API key user. Disabled endpoints are omitted. Subscribable event_types and their payload shapes are described by GET /api/v1/webhooks/events. Four subscribable event types are Pro-only and only deliver to API keys on an active Pro subscription. whale_trades_inserted is one of them, gated by the same SubscriberScope::InsiderOnly mechanism as the other three (each type carries its own LiveEventContract entry; they share the scope value). The other three: wallet_grade_changed (data: wallet, trader_id, old_grade, new_grade, direction (upgrade|downgrade), skill_index, final_score, date) fires on a Pass-2 grade transition; insider_radar_flag_raised (data: trade_id, wallet, trader_id, condition_id, suspicion_score, track, side (yes|no), size, price) fires the first time a trade's suspicion score crosses the radar flag threshold; smart_money_flow_detected (data: condition_id, net_flow_usd, abs_net_flow_usd, dominant_side (yes|no), grade_floor (S|A|B|C|D|F), whale_trade_count, window) fires when a scheduled scanner detects ranked-trader net flow crossing a threshold (up or down) on a market.", "tags": [ "Webhooks" ], "responses": { "200": { "$ref": "#/components/responses/WebhookList" }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/webhooks'" } ], "x-examples": { "success": { "object": "list", "data": [ { "id": 1, "object": "webhook", "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ], "status": "pending_verification" } ], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } }, "post": { "operationId": "createWebhook", "summary": "Create a builder webhook destination", "description": "Creates a pending HTTPS webhook destination. The response includes one-time signing_secret and verification.token values. Deliveries are not sent until the endpoint is verified. The subscribable event_types and their data payload shapes are described by GET /api/v1/webhooks/events; the per-endpoint delivery log is GET /api/v1/webhooks/{id}/deliveries. Four subscribable event types are Pro-only and only deliver to API keys on an active Pro subscription. whale_trades_inserted is one of them, gated by the same SubscriberScope::InsiderOnly mechanism as the other three (each type carries its own LiveEventContract entry; they share the scope value). The other three: wallet_grade_changed (data: wallet, trader_id, old_grade, new_grade, direction (upgrade|downgrade), skill_index, final_score, date) fires on a Pass-2 grade transition; insider_radar_flag_raised (data: trade_id, wallet, trader_id, condition_id, suspicion_score, track, side (yes|no), size, price) fires the first time a trade's suspicion score crosses the radar flag threshold; smart_money_flow_detected (data: condition_id, net_flow_usd, abs_net_flow_usd, dominant_side (yes|no), grade_floor (S|A|B|C|D|F), whale_trade_count, window) fires when a scheduled scanner detects ranked-trader net flow crossing a threshold (up or down) on a market. Delivery signing: each delivery request carries an HMAC-SHA256 signature in the x-0xinsider-signature header formatted as v1=, where is HMAC-SHA256(signing_secret, \".\"). The signed is sent separately as x-0xinsider-timestamp (unix seconds). To verify a delivery: read x-0xinsider-timestamp, reject it if it differs from the current time by more than 300 seconds, recompute v1= over \".\" with your signing_secret, and compare against x-0xinsider-signature using a constant-time comparison. Each delivery also carries x-0xinsider-event-id, x-0xinsider-event-type, x-0xinsider-delivery-id, and x-0xinsider-delivery-attempt headers.", "tags": [ "Webhooks" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookRequest" }, "example": { "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ] } } } }, "responses": { "200": { "$ref": "#/components/responses/WebhookObject" }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "409": { "$ref": "#/components/responses/IdempotencyInProgress" }, "422": { "$ref": "#/components/responses/IdempotencyConflict" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\":\"Production webhook\",\"url\":\"https://example.com/0xinsider/webhook\",\"event_types\":[\"whale_trades_inserted\"]}' \\\n 'https://api.0xinsider.com/api/v1/webhooks'" } ], "x-examples": { "success": { "object": "webhook", "data": { "id": 1, "object": "webhook", "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ], "status": "pending_verification" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } }, "parameters": [ { "$ref": "#/components/parameters/IdempotencyKey" } ] } }, "/api/v1/webhooks/events": { "get": { "operationId": "listWebhookEvents", "summary": "List webhook event catalog", "description": "Self-describing catalog of every webhook event type: its description, data payload shape, and whether it is active (has a firing producer) or dormant (subscribable but not yet delivered). The catalog is identical for every authenticated key and exposes no owner-scoped data. Pro-only event types (whale_trades_inserted, wallet_grade_changed, insider_radar_flag_raised, smart_money_flow_detected) appear in the catalog but only deliver to API keys on an active Pro subscription.", "tags": [ "Webhooks" ], "responses": { "200": { "description": "Webhook event catalog", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEventDescriptor" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [ { "id": "whale_trades_inserted", "description": "Fires when new whale-sized trades are ingested.", "payload_shape": "{ count: integer }", "status": "active" } ], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/webhooks/events'" } ] } }, "/api/v1/webhooks/{id}/deliveries": { "get": { "operationId": "listWebhookDeliveries", "summary": "List webhook delivery log", "description": "Recent delivery attempts for one webhook destination owned by the authenticated API key user, newest first, with opaque cursor pagination. Returns 404 (identical to an unknown id) when the endpoint is not owned by the caller, so a non-owner cannot tell an owned-but-empty log apart from someone else's endpoint. Delivery rows omit the request body and signing secret.", "tags": [ "Webhooks" ], "parameters": [ { "$ref": "#/components/parameters/WebhookId" }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque pagination cursor returned as next_cursor by a prior response. Omit to fetch the newest page.", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum delivery rows to return per page.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } } ], "responses": { "200": { "description": "Webhook delivery log page", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookDelivery" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [ { "id": 1, "object": "webhook_delivery", "event_id": "evt_whale_trades_inserted_1700000000_3", "event_type": "whale_trades_inserted", "status": "delivered", "attempt_count": 1, "last_response_status": 200, "delivered_at": "2026-06-04T12:00:00Z", "created_at": "2026-06-04T12:00:00Z" } ], "has_more": false, "next_cursor": null, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/webhooks/123/deliveries'" } ] } }, "/api/v1/webhooks/{id}": { "get": { "operationId": "getWebhook", "summary": "Get one builder webhook destination", "description": "Returns one webhook destination owned by the authenticated API key user.", "tags": [ "Webhooks" ], "parameters": [ { "$ref": "#/components/parameters/WebhookId" } ], "responses": { "200": { "$ref": "#/components/responses/WebhookObject" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/webhooks/{id}'" } ], "x-examples": { "success": { "object": "webhook", "data": { "id": 1, "object": "webhook", "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ], "status": "pending_verification" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } }, "patch": { "operationId": "updateWebhook", "summary": "Update a builder webhook destination", "description": "Updates name, HTTPS URL, event types, or enabled state. URL changes force pending_verification and return a new verification token. A URL change returns 409 with error.reason=webhook_delivery_in_progress while this destination has an active delivery; retry the same mutation after that request completes.", "tags": [ "Webhooks" ], "parameters": [ { "$ref": "#/components/parameters/WebhookId" }, { "$ref": "#/components/parameters/IdempotencyKey" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWebhookRequest" }, "example": { "name": "Updated webhook", "enabled": true } } } }, "responses": { "200": { "$ref": "#/components/responses/WebhookObject" }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "409": { "description": "The same idempotent mutation is still running, or this destination has an active delivery whose frozen URL cannot change until its request completes. Branch on error.reason.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" }, "examples": { "idempotency_in_progress": { "summary": "Idempotent mutation still in progress", "value": { "object": "error", "error": { "code": "bad_request", "message": "Your previous request is still processing. Retry in a moment.", "param": "Idempotency-Key", "reason": "idempotency_in_progress" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } }, "delivery_in_progress": { "summary": "Destination URL is frozen for an active delivery", "value": { "object": "error", "error": { "code": "bad_request", "message": "webhook URL cannot change while a delivery is processing; retry after the active request completes", "param": "endpoint", "reason": "webhook_delivery_in_progress" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "422": { "$ref": "#/components/responses/IdempotencyConflict" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X PATCH \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\":\"Updated webhook\",\"enabled\":true}' \\\n 'https://api.0xinsider.com/api/v1/webhooks/{id}'" } ], "x-examples": { "success": { "object": "webhook", "data": { "id": 1, "object": "webhook", "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ], "status": "pending_verification" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } }, "delete": { "operationId": "deleteWebhook", "summary": "Disable a builder webhook destination", "description": "Soft-deletes a webhook destination owned by the authenticated API key user. Existing delivery audit rows remain retained.", "tags": [ "Webhooks" ], "parameters": [ { "$ref": "#/components/parameters/WebhookId" }, { "$ref": "#/components/parameters/IdempotencyKey" } ], "responses": { "200": { "$ref": "#/components/responses/WebhookObject" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "409": { "$ref": "#/components/responses/IdempotencyInProgress" }, "422": { "$ref": "#/components/responses/IdempotencyConflict" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X DELETE \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/webhooks/{id}'" } ], "x-examples": { "success": { "object": "webhook", "data": { "id": 1, "object": "webhook", "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ], "status": "pending_verification" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/webhooks/{id}/verify": { "post": { "operationId": "verifyWebhook", "summary": "Verify a builder webhook destination", "description": "Activates a pending webhook destination when the one-time verification token matches and has not expired.", "tags": [ "Webhooks" ], "parameters": [ { "$ref": "#/components/parameters/WebhookId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyWebhookRequest" }, "example": { "verification_token": "whv_example" } } } }, "responses": { "200": { "$ref": "#/components/responses/WebhookObject" }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{\"verification_token\":\"whv_example\"}' \\\n 'https://api.0xinsider.com/api/v1/webhooks/{id}/verify'" } ], "x-examples": { "success": { "object": "webhooks", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/webhooks/{id}/rotate-secret": { "post": { "operationId": "rotateWebhookSecret", "summary": "Rotate a builder webhook signing secret", "description": "Rotates the endpoint signing secret and returns the new signing_secret once in the response. Returns 409 with error.reason=webhook_delivery_in_progress while a live delivery freezes the current signing nonce; retry after it completes.", "tags": [ "Webhooks" ], "parameters": [ { "$ref": "#/components/parameters/WebhookId" }, { "$ref": "#/components/parameters/IdempotencyKey" } ], "responses": { "200": { "$ref": "#/components/responses/WebhookObject" }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "409": { "description": "The same idempotent mutation is still running, or this destination has an active delivery whose signing secret cannot rotate until its request completes. Branch on error.reason.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" }, "examples": { "idempotency_in_progress": { "summary": "Idempotent mutation still in progress", "value": { "object": "error", "error": { "code": "bad_request", "message": "Your previous request is still processing. Retry in a moment.", "param": "Idempotency-Key", "reason": "idempotency_in_progress" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } }, "delivery_in_progress": { "summary": "Destination signing secret is frozen for an active delivery", "value": { "object": "error", "error": { "code": "bad_request", "message": "webhook signing secret cannot rotate while a delivery is processing; retry after the active request completes", "param": "endpoint", "reason": "webhook_delivery_in_progress" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "422": { "$ref": "#/components/responses/IdempotencyConflict" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{}' \\\n 'https://api.0xinsider.com/api/v1/webhooks/{id}/rotate-secret'" } ], "x-examples": { "success": { "object": "webhook", "data": { "id": 1, "object": "webhook", "name": "Production webhook", "url": "https://example.com/0xinsider/webhook", "event_types": [ "whale_trades_inserted" ], "status": "pending_verification" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/health": { "get": { "operationId": "getHealth", "summary": "Health check", "description": "Returns API health status. No authentication required. Limited to 60 requests per minute per IP.", "tags": [ "System" ], "security": [], "parameters": [ { "name": "If-None-Match", "in": "header", "required": false, "description": "Conditional GET validator from a previous ETag. Matching values return 304 Not Modified with an empty body.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Health status", "headers": { "ETag": { "description": "Stable validator for the current health payload. Re-send it via If-None-Match for conditional GETs.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "health" }, "data": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok", "degraded", "down", "maintenance" ] }, "db": { "type": "boolean" }, "cache": { "type": "boolean" }, "subsystems": { "type": "object", "required": [ "background_jobs" ], "properties": { "background_jobs": { "type": "object", "required": [ "status", "checked", "total", "healthy", "stale", "missing", "invalid", "unconfigured", "paused" ], "description": "Public-safe aggregate status for expected background job successful-completion heartbeats. Does not expose Redis keys, job names, raw errors, provider payloads, wallet addresses, or condition IDs.", "properties": { "status": { "type": "string", "enum": [ "ok", "degraded", "down", "not_checked" ] }, "checked": { "type": "boolean" }, "total": { "type": "integer", "minimum": 0 }, "healthy": { "type": "integer", "minimum": 0 }, "stale": { "type": "integer", "minimum": 0 }, "missing": { "type": "integer", "minimum": 0 }, "invalid": { "type": "integer", "minimum": 0 }, "unconfigured": { "type": "integer", "minimum": 0 }, "paused": { "type": "integer", "minimum": 0, "description": "Heavy-periodic jobs that are stale/missing/invalid while the heavy executor is disabled (heavy_pipeline_control.executor_mode != 'active'), so this binary does not dispatch them. Observable but expected; they never drive status to 'down' (paused > 0 yields 'degraded')." } } } } } } }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "health", "data": { "status": "ok" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "304": { "description": "Not Modified. Returned when If-None-Match matches the current health payload.", "headers": { "ETag": { "description": "Validator for the unchanged health payload.", "schema": { "type": "string" } } } }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "429": { "$ref": "#/components/responses/RateLimited" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/health'" } ], "x-examples": { "success": { "object": "health", "data": { "status": "ok" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/mcp": { "post": { "operationId": "createMcpJsonRpcResponse", "summary": "Remote MCP endpoint (JSON-RPC)", "description": "Model Context Protocol (MCP) Streamable HTTP transport. Accepts a JSON-RPC 2.0 request and returns a JSON-RPC response. Supported methods: initialize, notifications/initialized, ping, tools/list, tools/call. Remote MCP exposes 30 read-only tools for public V1 read operations: get_leaderboard, get_trader, batch_get_traders, get_whale_trades, get_whale_trade, get_whale_trades_history, get_market_intel, batch_get_market_intel, get_smart_money_flows, get_sharp_money_flows, get_market_snapshot, get_insider_radar, get_insider_radar_flag, get_positions, get_position_timeline, get_position_timeline_by_id, search_markets, explore_markets, get_event_replay_since, list_webhooks, get_webhook, get_daily_report_snapshot, get_weekly_report_snapshot, get_monthly_report_snapshot, get_report, get_trader_export_snapshot, get_platforms, get_large_positions, get_trending_wallets, get_trader_pnl. Webhook create/update/delete/verify/rotate operations are intentionally not exposed as remote MCP tools. The remote endpoint advertises tools only; it does not implement resources/list, resources/read, prompts/list, or prompts/get. Each tool dispatches to the matching /api/v1/* handler in-process so auth, rate limits, and payload shape match. Auth should use Authorization: Bearer . ?token= remains a legacy compatibility path for URL-only MCP clients, but URL secrets can land in shell history, browser history, and logs, so prefer headers or the stdio package. Mcp-Session-Id is minted on initialize and echoed on every response. Origin header, when present, is validated against the 0xinsider + localhost allowlist.", "tags": [ "MCP" ], "parameters": [ { "name": "token", "in": "query", "required": false, "description": "Deprecated compatibility API-key query parameter for remote MCP clients that cannot send Authorization headers. Prefer Authorization: Bearer or the stdio package because URL secrets are easier to leak through logs and history.", "schema": { "type": "string" } }, { "name": "Mcp-Session-Id", "in": "header", "required": false, "description": "Session ID minted by the server on initialize; echoed on every subsequent request.", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "jsonrpc", "method" ], "properties": { "jsonrpc": { "type": "string", "const": "2.0" }, "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "null" } ] }, "method": { "type": "string", "enum": [ "initialize", "notifications/initialized", "ping", "tools/list", "tools/call" ] }, "params": { "type": "object" } } }, "example": {} } } }, "responses": { "200": { "description": "JSON-RPC response", "content": { "application/json": { "schema": { "type": "object", "required": [ "jsonrpc", "id" ], "properties": { "jsonrpc": { "type": "string", "const": "2.0" }, "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "null" } ] }, "result": { "type": "object" }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "integer" }, "message": { "type": "string" } } } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "mcp", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "202": { "description": "Notification acknowledged (no body)", "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "description": "JSON-RPC parse or invalid-request error" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "description": "Origin rejected or tier forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n -H 'Content-Type: application/json' \\\n -d '{}' \\\n 'https://api.0xinsider.com/api/v1/mcp'" } ], "x-examples": { "success": { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2025-11-25" } } } }, "get": { "operationId": "openMcpEventStream", "summary": "Open MCP server-to-client stream", "description": "Opens a text/event-stream connection for server-initiated notifications as described in the MCP Streamable HTTP transport. The endpoint currently sends no notifications \u2014 clients that only care about request/response use POST.", "tags": [ "MCP" ], "parameters": [ { "name": "token", "in": "query", "required": false, "description": "API key as query parameter (same contract as POST).", "schema": { "type": "string" } }, { "name": "Mcp-Session-Id", "in": "header", "required": false, "description": "Session ID minted by the server on initialize.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "SSE stream", "content": { "text/event-stream": { "schema": { "type": "string" } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "description": "Origin rejected" }, "429": { "$ref": "#/components/responses/RateLimited" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/mcp'" } ], "x-examples": { "success": { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2025-11-25" } } } } }, "/api/v1/reports": { "get": { "operationId": "getReports", "summary": "Unified report snapshot (granularity selector)", "description": "Unified convenience route (#4975) that consolidates the three singular report routes. Dispatches to the exact per-granularity cap (daily 50, weekly 100, monthly 200) and date window the legacy /api/v1/reports/{daily,weekly,monthly} routes use, so the response body is byte-identical to the matching legacy route for the same period. The three legacy routes stay live. Also reachable via the MCP get_report selector.", "tags": [ "Reports" ], "parameters": [ { "name": "granularity", "in": "query", "required": true, "description": "Report granularity selector.", "schema": { "type": "string", "enum": [ "daily", "weekly", "monthly" ] } }, { "name": "period", "in": "query", "required": true, "description": "Period token for the granularity. daily: UTC date YYYY-MM-DD. weekly: ISO week YYYY-WW, or a from,to YYYY-MM-DD pair. monthly: UTC month YYYY-MM.", "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Daily report snapshot", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "report_snapshot" }, "data": { "$ref": "#/components/schemas/ReportSnapshot" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/reports?granularity=daily&period=2026-02-17'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } }, "x-mcp-tool": "get_report" } }, "/api/v1/reports/daily": { "get": { "operationId": "getDailyReportSnapshot", "summary": "Daily report snapshot", "description": "Returns a dated daily whale-activity report snapshot with source_range, snapshot.status, completeness, and reconciliation metadata. Report whale volume is local whale-alert activity volume, not provider lifetime trader volume.", "tags": [ "Reports" ], "parameters": [ { "name": "date", "in": "query", "required": true, "description": "UTC report date in YYYY-MM-DD format.", "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } } ], "responses": { "200": { "description": "Daily report snapshot", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "report_snapshot" }, "data": { "$ref": "#/components/schemas/ReportSnapshot" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/reports/daily'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/reports/weekly": { "get": { "operationId": "getWeeklyReportSnapshot", "summary": "Weekly report snapshot", "description": "Returns a weekly whale-activity report snapshot. Pass either from/to UTC dates or an ISO YYYY-WW week token. The response identifies closed ranges as final and current ranges as rolling.", "tags": [ "Reports" ], "parameters": [ { "name": "from", "in": "query", "required": false, "description": "UTC source-range start in YYYY-MM-DD format; required with to.", "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "name": "to", "in": "query", "required": false, "description": "UTC source-range end in YYYY-MM-DD format; required with from.", "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "name": "week", "in": "query", "required": false, "description": "ISO week selector in YYYY-WW format; alternative to from/to.", "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}$" } } ], "responses": { "200": { "description": "Weekly report snapshot", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "report_snapshot" }, "data": { "$ref": "#/components/schemas/ReportSnapshot" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/reports/weekly'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/reports/monthly": { "get": { "operationId": "getMonthlyReportSnapshot", "summary": "Monthly report snapshot", "description": "Returns a UTC monthly whale-activity report snapshot with source_range, completeness, and reconciliation metadata.", "tags": [ "Reports" ], "parameters": [ { "name": "month", "in": "query", "required": true, "description": "UTC report month in YYYY-MM format.", "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}$" } } ], "responses": { "200": { "description": "Monthly report snapshot", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "report_snapshot" }, "data": { "$ref": "#/components/schemas/ReportSnapshot" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/reports/monthly'" } ], "x-examples": { "success": { "object": "list", "data": [], "has_more": false, "next_cursor": null, "total": 0, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } }, "/api/v1/trader/{address}/export": { "get": { "operationId": "getTraderExportSnapshot", "summary": "Trader export snapshot metadata", "description": "Returns export source-range, completeness, volume reconciliation, row-count estimate, and large-export policy for one trader. To download the full dataset programmatically, POST to this same path to submit an async export job (json | ndjson | csv), then poll the status route and follow the download route once ready.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Trader wallet address (0x...), known trader username-style lookup, or trd_-prefixed trader ID emitted by this API. Bare integer database IDs are not accepted.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Trader export snapshot metadata", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "trader_export_snapshot" }, "data": { "$ref": "#/components/schemas/TraderExportSnapshot" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "examples": { "success": { "summary": "Successful response", "value": { "object": "traders", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}/export'" } ], "x-examples": { "success": { "object": "traders", "data": {}, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } }, "post": { "operationId": "submitTraderExport", "summary": "Submit a trader dataset export job", "description": "Queues an async export of the trader's full dataset in the requested format (json default, ndjson, or csv) and returns the job. Poll the status route, then follow the download route once status is 'ready'. Quotas are the per-user daily and per-address hourly export caps, keyed on the API key owner so an API key never widens its owner's quota.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Trader wallet address (0x...), known trader username-style lookup, or trd_-prefixed trader ID emitted by this API.", "schema": { "type": "string" } }, { "name": "format", "in": "query", "required": false, "description": "Output serialization. json = full envelope document (default); ndjson = full envelope as line 1 then one trade object per line; csv = flat trades rows only.", "schema": { "type": "string", "enum": [ "json", "ndjson", "csv" ], "default": "json" } } ], "responses": { "200": { "description": "An in-flight or ready job for this trader+format already exists and was reused", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TraderExportJob" }, "examples": { "reused": { "summary": "Existing in-flight job reused (no new quota consumed)", "value": { "object": "trader_export_job", "data": { "job_id": 123, "status": "running", "format": "csv", "total_trades": 4821, "processed_trades": 1200, "file_size": null, "error": null }, "meta": { "request_id": "req_example", "cached": false, "cost": 0 } } } } } } }, "202": { "description": "New export job accepted and queued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TraderExportJob" }, "examples": { "queued": { "summary": "New CSV export job queued", "value": { "object": "trader_export_job", "data": { "job_id": 123, "status": "queued", "format": "csv", "total_trades": 4821, "processed_trades": 0, "file_size": null, "error": null }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS -X POST \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}/export?format=csv'" } ] } }, "/api/v1/trader/{address}/export/status": { "get": { "operationId": "getTraderExportStatus", "summary": "Poll a trader export job", "description": "Returns the current state of a submitted export job (queued | running | ready | failed) for the authenticated API key.", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Trader wallet address (0x...), known trader username-style lookup, or trd_-prefixed trader ID emitted by this API.", "schema": { "type": "string" } }, { "name": "job_id", "in": "query", "required": true, "description": "Export job id returned by the submit route.", "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Export job state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TraderExportJob" }, "examples": { "ready": { "summary": "Finished export ready to download", "value": { "object": "trader_export_job", "data": { "job_id": 123, "status": "ready", "format": "csv", "total_trades": 4821, "processed_trades": 4821, "file_size": 184320, "error": null }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}/export/status?job_id=123'" } ] } }, "/api/v1/trader/{address}/export/download": { "get": { "operationId": "downloadTraderExport", "summary": "Download a finished trader export", "description": "Redirects (302) to a short-lived presigned URL for the finished export file once the job status is 'ready'. The file is gzip-compressed and served with the format's Content-Type (application/json, application/x-ndjson, or text/csv). Returns 400 while the job is not yet ready (poll the status route first).", "tags": [ "Traders" ], "parameters": [ { "name": "address", "in": "path", "required": true, "description": "Trader wallet address (0x...), known trader username-style lookup, or trd_-prefixed trader ID emitted by this API.", "schema": { "type": "string" } }, { "name": "job_id", "in": "query", "required": true, "description": "Export job id returned by the submit route.", "schema": { "type": "integer", "format": "int64" } } ], "responses": { "302": { "description": "Redirect to the presigned download URL", "headers": { "Location": { "description": "Short-lived presigned URL for the export file.", "schema": { "type": "string" }, "example": "https://r2.0xinsider.com/exports/0xabc.../123.csv?X-Amz-Expires=3600&X-Amz-Signature=..." } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "408": { "$ref": "#/components/responses/RequestTimeout" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sSL --compressed -o trader-dataset.csv \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/trader/{address}/export/download?job_id=123'" } ] } }, "/api/v1/usage": { "get": { "tags": [ "Usage" ], "operationId": "getUsage", "summary": "Inspect current API usage without spending primary request quota", "description": "Returns the authenticated caller sliding-window request budget and UTC-day usage. This endpoint is authenticated and does not increment the primary Redis rate-limit counter or log itself into the API usage table; it is separately throttled at 100 reads/minute per user to protect the usage-count query.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Usage budget and counters for the authenticated API key owner.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Usage" }, "examples": { "success": { "summary": "Successful response", "value": { "object": "usage", "data": { "rate_limit": { "used": 7, "limit": 100, "remaining": 93, "reset_at": 1710772860, "window_seconds": 60 }, "daily_usage": { "used": 42, "limit": null, "remaining": null, "reset_at": 1710806400, "window_seconds": 86400 } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "headers": { "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" }, "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }, "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }, "X-Request-Id": { "$ref": "#/components/headers/X-Request-Id" } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "402": { "$ref": "#/components/responses/SubscriptionRequired" }, "403": { "$ref": "#/components/responses/Forbidden" }, "423": { "$ref": "#/components/responses/Locked" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/RateLimitUnavailable" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -sS \\\n -H 'Authorization: Bearer $OXI_SK' \\\n 'https://api.0xinsider.com/api/v1/usage'" } ], "x-examples": { "success": { "object": "usage", "data": { "rate_limit": { "used": 7, "limit": 100, "remaining": 93, "reset_at": 1710772860, "window_seconds": 60 }, "daily_usage": { "used": 42, "limit": null, "remaining": null, "reset_at": 1710806400, "window_seconds": 86400 } }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "description": "API key authentication. Send your key in the Authorization header as `Bearer oxi_sk_live_...`. Live keys require an active Pro subscription and return live data." } }, "parameters": { "WebhookId": { "name": "id", "in": "path", "required": true, "description": "Webhook endpoint id owned by the authenticated API key user.", "schema": { "type": "integer", "format": "int64" } }, "IdempotencyKey": { "name": "Idempotency-Key", "in": "header", "required": false, "description": "Optional safe-retry key. Reuse the same value only when retrying the exact same mutation request body; a different body returns 422 and an in-flight matching request returns 409.", "schema": { "type": "string", "minLength": 1, "maxLength": 255 }, "example": "wh_idem_01HX7Y9ZQ4K7Z0Q2E4N6A8C1BF" } }, "schemas": { "WebhookEventType": { "type": "string", "enum": [ "whale_trades_inserted", "live_sports_updated", "whale_trader_synced", "large_positions_updated", "wallet_grade_changed", "insider_radar_flag_raised", "smart_money_flow_detected" ] }, "WebhookStatus": { "type": "string", "enum": [ "pending_verification", "active", "disabled" ] }, "WebhookRetryPolicy": { "type": "object", "required": [ "max_attempts", "terminal_status" ], "properties": { "max_attempts": { "type": "integer", "const": 8 }, "terminal_status": { "type": "string", "const": "dead_letter" } } }, "WebhookVerification": { "type": "object", "required": [ "token", "expires_at" ], "properties": { "token": { "type": "string", "description": "One-time verification token returned only on create or URL change." }, "expires_at": { "type": "string", "format": "date-time" } } }, "WebhookEventDescriptor": { "type": "object", "description": "Self-describing entry in the webhook event catalog: the event type a subscriber lists in event_types, when it fires, the data payload shape, and whether it currently fires (active) or is reserved (dormant, subscribable but not yet delivered). Pro-only event types (whale_trades_inserted, wallet_grade_changed, insider_radar_flag_raised, smart_money_flow_detected) only deliver to API keys on an active Pro subscription.", "required": [ "id", "description", "payload_shape", "status" ], "properties": { "id": { "$ref": "#/components/schemas/WebhookEventType" }, "description": { "type": "string", "description": "One-line description of when the event fires." }, "payload_shape": { "type": "string", "description": "Short description of the data payload object's shape." }, "status": { "type": "string", "enum": [ "active", "dormant" ], "description": "active: the event has a firing producer callsite. dormant: advertised and subscribable, but does not yet enqueue any delivery." } } }, "WebhookDelivery": { "type": "object", "description": "Owner-scoped view of one webhook delivery attempt. Deliberately omits the request body and the endpoint signing secret: a delivery log never re-exposes the payload or any secret material.", "required": [ "id", "object", "event_id", "event_type", "status", "attempt_count", "created_at" ], "properties": { "id": { "type": "integer", "format": "int64" }, "object": { "type": "string", "const": "webhook_delivery" }, "event_id": { "type": "string", "description": "Stable event id for this delivery; identical across retries of the same logical event." }, "event_type": { "$ref": "#/components/schemas/WebhookEventType" }, "status": { "type": "string", "description": "Delivery lifecycle state (e.g. pending, delivered, dead_letter)." }, "attempt_count": { "type": "integer", "description": "Number of delivery attempts made so far." }, "last_response_status": { "type": "integer", "description": "HTTP status code of the most recent delivery attempt. Omitted until a response (or transport error) has been recorded." }, "last_error": { "type": "string", "description": "Short description of the most recent delivery failure. Omitted when the last attempt succeeded or none has failed." }, "delivered_at": { "type": "string", "format": "date-time", "description": "When the delivery was first accepted by the destination. Omitted until a delivery succeeds." }, "created_at": { "type": "string", "format": "date-time" } } }, "WebhookEndpoint": { "type": "object", "required": [ "id", "object", "name", "url", "event_types", "status", "verification_token_expires_at", "failure_count", "created_at", "updated_at", "retry_policy" ], "properties": { "id": { "type": "integer", "format": "int64" }, "object": { "type": "string", "const": "webhook" }, "name": { "type": "string" }, "url": { "type": "string", "format": "uri" }, "event_types": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEventType" } }, "status": { "$ref": "#/components/schemas/WebhookStatus" }, "verified_at": { "type": "string", "format": "date-time", "nullable": true }, "verification_token_expires_at": { "type": "string", "format": "date-time" }, "failure_count": { "type": "integer" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "retry_policy": { "$ref": "#/components/schemas/WebhookRetryPolicy" }, "signing_secret": { "type": "string", "description": "Returned only on create or rotate-secret." }, "verification": { "$ref": "#/components/schemas/WebhookVerification" } } }, "CreateWebhookRequest": { "type": "object", "required": [ "name", "url", "event_types" ], "properties": { "name": { "type": "string", "maxLength": 100 }, "url": { "type": "string", "format": "uri", "description": "Public HTTPS callback URL. Local/private/internal targets are rejected." }, "event_types": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/WebhookEventType" } } } }, "UpdateWebhookRequest": { "type": "object", "properties": { "name": { "type": "string", "maxLength": 100 }, "url": { "type": "string", "format": "uri" }, "event_types": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/WebhookEventType" } }, "enabled": { "type": "boolean" } } }, "VerifyWebhookRequest": { "type": "object", "required": [ "verification_token" ], "properties": { "verification_token": { "type": "string" } } }, "Candle": { "type": "object", "description": "One bucketed OHLC price candle. Prices are in provider [0, 1] units, truncated to 4 decimals at the rendering edge.", "required": [ "t", "o", "h", "l", "c" ], "properties": { "t": { "type": "integer", "format": "int64", "description": "Bucket-start unix epoch (seconds): UTC midnight for 1d, the ISO-week Monday's UTC midnight for 1w." }, "o": { "type": "number", "description": "Open price in provider [0, 1] units (first observed point in the bucket)." }, "h": { "type": "number", "description": "High price in provider [0, 1] units (max observed in the bucket)." }, "l": { "type": "number", "description": "Low price in provider [0, 1] units (min observed in the bucket)." }, "c": { "type": "number", "description": "Close price in provider [0, 1] units (last observed point in the bucket)." } } }, "OutcomeCandles": { "type": "object", "description": "One outcome token's bucketed candle series.", "required": [ "token_id", "outcome", "candles" ], "properties": { "token_id": { "type": "string", "description": "Provider CLOB token id the candles were read for." }, "outcome": { "type": "string", "description": "Canonical side label.", "enum": [ "YES", "NO" ] }, "candles": { "type": "array", "description": "OHLC candles for this outcome token, ascending by bucket start.", "items": { "$ref": "#/components/schemas/Candle" } } } }, "MarketCandles": { "type": "object", "description": "Provider-first bucketed OHLC price candles for a market's outcome tokens, derived from the stored token_price_snapshots series (covers open and resolved markets).", "required": [ "condition_id", "resolution", "outcomes" ], "properties": { "condition_id": { "type": "string", "description": "Market condition id the candles were read for." }, "resolution": { "type": "string", "description": "Bucketing granularity that produced these candles.", "enum": [ "1d", "1w" ] }, "outcomes": { "type": "array", "description": "One entry per present provider token (YES first, then NO); empty when no tokens have been fetched yet.", "items": { "$ref": "#/components/schemas/OutcomeCandles" } } } }, "ResponseMeta": { "type": "object", "required": [ "request_id", "cached", "cost" ], "properties": { "request_id": { "type": "string", "description": "Unique request ID (req_ prefix)." }, "cached": { "type": "boolean" }, "cache_age_s": { "type": "integer", "nullable": true, "description": "Cache age in seconds, null if not cached." }, "cost": { "type": "integer", "description": "Advisory request weight (relative compute cost). 1 for simple reads; higher for heavier endpoints. Not a credit/price." }, "directional_source": { "type": "string", "enum": [ "live", "degraded" ], "description": "Which path produced the team-directional read on this response. Only present on endpoints that compute one (today: GET /api/v1/sports-edge-signals). \"live\" means the read RAN. \"degraded\" means it FAILED, so nothing was measured and the ranking fell back to raw conviction. The flag describes the READ, not its consequence: a read that ran and found nothing groupable also leaves the directional fields null, and that is honestly \"live\" -- the per-signal nulls already say \"nothing to enrich here\", so this snapshot-level flag carries only what they cannot, namely whether the read ran at all. A degraded response is cached on the shorter degraded TTL so it self-heals. Reported SEPARATELY from ranking_source because the two degradations are independent -- a smart-money DB miss weakens the ranking DATA, a directional failure removes a ranking WEIGHT -- and a consumer down-weighting a degraded response needs to know which input it lost. Omitted on endpoints that compute no directional read." }, "ranking_source": { "type": "string", "enum": [ "live", "db_only" ], "description": "Which ranking-data path produced this response. Only present on endpoints that can degrade a ranking (today: GET /api/v1/sports-edge-signals). \"live\" is the normal path (the current holder pile from the provider batch); \"db_only\" is the degraded fallback (a truthful but weaker trader_markets ranking) served when the live sharp-money ranking batch is unavailable (a smart-money DB read failure, not a Polymarket outage) and cached on a shorter TTL, so a consumer can down-weight or skip it. Omitted on endpoints that never degrade." }, "category_skill_source": { "type": "string", "enum": ["live", "partial", "degraded", "unavailable"], "description": "Whole filtered snapshot category-evidence status before pagination. Operational live always remains partial source coverage." }, "category_skill_model_version": { "type": "string" }, "category_skill_taxonomy_version": { "type": "string" }, "category_skill_platform": { "type": "string", "const": "polymarket" }, "category_skill_scope": { "type": "string", "const": "observed_goldsky_primary_taker_fill" }, "category_skill_source_coverage": { "type": "string", "const": "partial_whale_threshold_fills" }, "category_skill_observation_started_at": { "type": "string", "format": "date-time" }, "category_skill_model_operationally_degraded": { "type": "boolean", "description": "Whole-model operational readiness captured with the category model snapshot. Present on category-enriched responses even when the filtered signal slate is empty. When true, category_skill_source is degraded and sports-edge-signals uses the shorter degraded cache TTL." }, "category_skill_status_counts": { "type": "object", "required": ["live", "insufficient", "stale", "unknown", "degraded"], "properties": { "live": { "type": "integer", "minimum": 0 }, "insufficient": { "type": "integer", "minimum": 0 }, "stale": { "type": "integer", "minimum": 0 }, "unknown": { "type": "integer", "minimum": 0 }, "degraded": { "type": "integer", "minimum": 0 } } }, "category_skill_base_payload_hash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 of the funded signal membership/order/rank/cursor vector immediately before category-skill enrichment. Sports-edge-signals only." }, "category_skill_enriched_base_payload_hash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "Independent SHA-256 recomputation over the same base fields immediately after category-skill enrichment. Equality with category_skill_base_payload_hash proves shadow enrichment did not change funded inputs. Sports-edge-signals only." } } }, "ApiDiscovery": { "type": "object", "required": [ "api_base_url", "docs_url", "openapi_url", "health_url", "authentication", "authenticated_routes" ], "properties": { "api_base_url": { "type": "string", "format": "uri", "description": "Canonical API origin for public V1 requests." }, "docs_url": { "type": "string", "format": "uri", "description": "Full agent-readable API reference." }, "openapi_url": { "type": "string", "format": "uri", "description": "Canonical web-origin OpenAPI JSON document." }, "health_url": { "type": "string", "format": "uri", "description": "Unauthenticated API health endpoint." }, "authentication": { "type": "string", "const": "Bearer API key required for data endpoints; discovery (/api/v1), health, and /api/v1/platforms are public." }, "authenticated_routes": { "type": "array", "description": "The complete authenticated route index: one entry per authenticated route this spec documents, in \" \" form, not a representative subset. GET /api/v1 is the unauthenticated entrypoint an agent hits first, so it hands back the whole authenticated surface rather than a sample the caller would have to guess around. The example on GET /api/v1 is abridged for readability -- the live response returns all of them. Kept in lockstep with this spec by backend/src/api_v1/discovery.rs::authenticated_routes_match_the_published_spec, which fails in both directions.", "items": { "type": "string" } } } }, "WhaleTradeHistoryMeta": { "type": "object", "required": [ "request_id", "cached", "source", "completeness" ], "properties": { "request_id": { "type": "string", "description": "Unique request ID (req_ prefix)." }, "cached": { "type": "boolean" }, "cache_age_s": { "type": "integer", "nullable": true, "description": "Cache age in seconds, null if not cached." }, "source": { "type": "object", "required": [ "kind", "table", "provider_fetch_at_request_time" ], "properties": { "kind": { "type": "string", "const": "local_replay" }, "table": { "type": "string", "const": "whale_alerts" }, "provider_fetch_at_request_time": { "type": "boolean", "const": false } } }, "completeness": { "type": "object", "required": [ "status", "reason" ], "properties": { "status": { "type": "string", "const": "best_effort" }, "reason": { "type": "string", "description": "Explains that local replay completeness can vary by market and time window." } } } } }, "EventReplayEvent": { "type": "object", "required": [ "id", "type", "cursor", "sequence", "published_at", "payload", "source", "freshness" ], "properties": { "id": { "type": "string", "description": "Opaque event ID; currently identical to cursor for the whale_alerts.id sequence." }, "type": { "type": "string", "enum": [ "whale_trades_inserted" ] }, "cursor": { "type": "string", "description": "Cursor positioned at this event." }, "sequence": { "type": "integer", "minimum": 1, "description": "Global whale_alerts.id sequence." }, "published_at": { "type": "string", "format": "date-time" }, "payload": { "type": "object", "additionalProperties": true }, "source": { "$ref": "#/components/schemas/EventReplaySource" }, "freshness": { "$ref": "#/components/schemas/EventReplayFreshness" } } }, "EventReplaySource": { "type": "object", "required": [ "kind", "producer_family", "owner", "provider_fetch_at_request_time" ], "properties": { "kind": { "type": "string", "const": "local_durable_replay" }, "producer_family": { "type": "string", "enum": [ "whale_trades" ] }, "owner": { "type": "string", "const": "whale_alerts" }, "provider_fetch_at_request_time": { "type": "boolean", "const": false } } }, "EventReplayFreshness": { "type": "object", "required": [ "status", "observed_at" ], "properties": { "status": { "type": "string", "const": "observed" }, "observed_at": { "type": "string", "format": "date-time" } } }, "EventReplayMeta": { "type": "object", "required": [ "request_id", "cached", "cost", "replay", "retention", "completeness" ], "properties": { "request_id": { "type": "string", "description": "Unique request ID (req_ prefix)." }, "cached": { "type": "boolean" }, "cache_age_s": { "type": "integer", "nullable": true }, "cost": { "type": "integer", "description": "Advisory request weight (relative compute cost). 1 for simple reads; higher for heavier endpoints. Not a credit/price." }, "replay": { "type": "object", "required": [ "from_cursor", "to_cursor", "from_sequence", "to_sequence", "ordering" ], "properties": { "from_cursor": { "type": "string" }, "to_cursor": { "type": "string" }, "from_sequence": { "type": "integer", "minimum": 0 }, "to_sequence": { "type": "integer", "minimum": 0 }, "ordering": { "type": "string", "const": "whale_alerts_id_asc" } } }, "retention": { "type": "object", "required": [ "status", "retained_events", "cursor_expired" ], "properties": { "status": { "type": "string", "enum": [ "durable_database" ] }, "retained_events": { "type": "integer", "minimum": 0 }, "cursor_expired": { "type": "boolean", "const": false } } }, "completeness": { "type": "object", "required": [ "status", "reason" ], "properties": { "status": { "type": "string", "enum": [ "complete", "caught_up" ] }, "reason": { "type": "string" } } } } }, "TrustSource": { "type": "object", "description": "Source metadata for a trust-critical value. Providers and DB/read models own business truth; clients should not infer missing provider facts from titles, slugs, zeros, or empty arrays.", "required": [ "kind", "owner" ], "properties": { "kind": { "type": "string", "enum": [ "provider", "database", "cache", "computed", "client_input", "unavailable" ] }, "owner": { "type": "string", "description": "Provider, table/read-model, cache, or service that owns the value." }, "field": { "type": "string", "nullable": true, "description": "Provider field, DB column, or computed field name when applicable." } } }, "TrustFreshness": { "type": "object", "description": "Freshness metadata for a trust-critical value. This is separate from transport cache fields in ResponseMeta.", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "fresh", "refreshing", "stale", "not_live", "unknown", "unavailable" ] }, "as_of": { "type": "string", "format": "date-time", "nullable": true }, "max_age_s": { "type": "integer", "nullable": true, "minimum": 0 } } }, "TrustReconciliation": { "type": "object", "description": "How provider-owned facts were reconciled with stored/read-model values.", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "provider_backed", "db_mirror", "computed", "partial", "not_applicable", "unavailable" ] }, "detail": { "type": "string", "nullable": true } } }, "TrustCompleteness": { "type": "object", "description": "Whether the described value or result set is complete for its stated contract.", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "complete", "partial", "not_computed", "not_applicable", "unavailable" ] }, "detail": { "type": "string", "nullable": true } } }, "TrustMetadata": { "type": "object", "description": "Shared source/freshness/reconciliation/completeness metadata for public API values that may be cached, stale, partial, computed, or provider-unavailable. Unavailable provider values must be represented with explicit metadata instead of fabricated zeros or empty arrays.", "required": [ "source", "freshness", "reconciliation", "completeness" ], "properties": { "source": { "$ref": "#/components/schemas/TrustSource" }, "freshness": { "$ref": "#/components/schemas/TrustFreshness" }, "reconciliation": { "$ref": "#/components/schemas/TrustReconciliation" }, "completeness": { "$ref": "#/components/schemas/TrustCompleteness" } } }, "PickTrust": { "type": "object", "description": "Field-level trust metadata for the full Pick of the Day payload. Present on the full shape only (omitted on the teaser and the no-pick state, because whether a specialist backs the pick is itself backed-side evidence). Unlike TraderTrust it is not gated behind expand=trust: it carries one member on an endpoint that returns a single object per day.", "required": [ "qualifying_expert" ], "properties": { "qualifying_expert": { "allOf": [ { "$ref": "#/components/schemas/TrustMetadata" } ], "description": "Provenance of the frozen qualifying category expert. source.kind=database with reconciliation.status=db_mirror means the evidence deserialized, still satisfies every frozen selection gate, and is being served. On that arm freshness.status is always not_live and never fresh, because this evidence is frozen at selection and never refreshed, so on an archived pick the as_of (the expert's own stats_computed_at) can be days or months old by design. source.kind=computed with reconciliation.status=not_applicable means the selector evaluated the backed side and nobody qualified -- a real negative. source.kind=computed with freshness.status=unknown and completeness.status=not_computed means the selector never evaluated this field, as on a pre-feature pick or manual off-slate takeover. source.kind=unavailable means the payload is malformed, violates a selection gate, or conflicts with its persisted status: a contract defect, NOT a negative, on a pick whose selection rank that evidence decided. Do not read an omitted qualifying_expert as 'no specialist' without checking this field." } } }, "TraderTrust": { "type": "object", "description": "Field-level trust metadata returned only when GET /api/v1/trader/{address} includes expand=trust.", "required": [ "total_pnl", "realized_pnl", "unrealized_pnl", "markets_traded", "win_rate", "daily_win_rate", "total_volume", "grade", "score", "rank", "streak_tier", "strategy", "category_strengths", "quant_metrics", "last_active", "synced_at", "sync_status" ], "properties": { "total_pnl": { "$ref": "#/components/schemas/TrustMetadata" }, "realized_pnl": { "$ref": "#/components/schemas/TrustMetadata" }, "unrealized_pnl": { "$ref": "#/components/schemas/TrustMetadata" }, "markets_traded": { "$ref": "#/components/schemas/TrustMetadata" }, "win_rate": { "$ref": "#/components/schemas/TrustMetadata" }, "daily_win_rate": { "$ref": "#/components/schemas/TrustMetadata" }, "total_volume": { "$ref": "#/components/schemas/TrustMetadata" }, "grade": { "$ref": "#/components/schemas/TrustMetadata" }, "score": { "$ref": "#/components/schemas/TrustMetadata" }, "rank": { "$ref": "#/components/schemas/TrustMetadata" }, "streak_tier": { "$ref": "#/components/schemas/TrustMetadata" }, "strategy": { "$ref": "#/components/schemas/TrustMetadata" }, "category_strengths": { "$ref": "#/components/schemas/TrustMetadata" }, "quant_metrics": { "$ref": "#/components/schemas/TrustMetadata" }, "last_active": { "$ref": "#/components/schemas/TrustMetadata" }, "synced_at": { "$ref": "#/components/schemas/TrustMetadata" }, "sync_status": { "$ref": "#/components/schemas/TrustMetadata" } } }, "PlatformCapabilityStatus": { "type": "string", "enum": [ "supported", "partial", "unsupported" ] }, "PlatformCapabilities": { "type": "object", "required": [ "grade", "pnl", "strategy", "timeline", "whale_signal", "insider_radar", "market_snapshot" ], "properties": { "grade": { "$ref": "#/components/schemas/PlatformCapabilityStatus" }, "pnl": { "$ref": "#/components/schemas/PlatformCapabilityStatus" }, "strategy": { "$ref": "#/components/schemas/PlatformCapabilityStatus" }, "timeline": { "$ref": "#/components/schemas/PlatformCapabilityStatus" }, "whale_signal": { "$ref": "#/components/schemas/PlatformCapabilityStatus" }, "insider_radar": { "$ref": "#/components/schemas/PlatformCapabilityStatus" }, "market_snapshot": { "$ref": "#/components/schemas/PlatformCapabilityStatus" } } }, "Platforms": { "type": "object", "required": [ "platforms" ], "properties": { "platforms": { "type": "object", "required": [ "kalshi", "polymarket" ], "properties": { "kalshi": { "$ref": "#/components/schemas/PlatformCapabilities" }, "polymarket": { "$ref": "#/components/schemas/PlatformCapabilities" } } } } }, "PositionTimelineEvent": { "type": "object", "required": [ "id", "event_timestamp", "action", "outcome_side", "amount_delta", "price", "usdc_notional", "tx_hash", "running_amount", "running_avg_price" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (pe_...)." }, "event_timestamp": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp of the on-chain fill." }, "action": { "type": "string", "enum": [ "buy", "sell" ], "description": "From the taker's perspective." }, "outcome_side": { "type": "string", "enum": [ "yes", "no" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for this outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "amount_delta": { "type": "number", "description": "Signed share delta (+ on buy, \u2212 on sell)." }, "price": { "type": "number", "description": "Fill price in USDC per share, in [0,1]." }, "usdc_notional": { "type": "number", "description": "Positive USDC notional of the fill." }, "tx_hash": { "type": "string", "description": "Polygon transaction hash of the fill." }, "running_amount": { "type": "number", "description": "Cumulative signed share balance after this fill." }, "running_avg_price": { "type": "number", "description": "Buy-weighted entry basis (matches Polymarket /positions avgPrice semantics). Sells do not change this value. 0 when no buys have occurred yet." } } }, "Trader": { "type": "object", "required": [ "id", "address", "pnl", "stats" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (trd_...)." }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ], "nullable": true }, "streak_tier": { "type": "string", "enum": [ "hot", "rising", "neutral", "cooling", "cold" ], "nullable": true, "description": "Hot-streak tier (trailing-7d cross-sectional percentile); a separate axis from the all-time grade. Null when no recent activity." }, "score": { "type": "number", "nullable": true }, "rank": { "type": "integer", "nullable": true }, "pnl": { "type": "object", "properties": { "total": { "type": "number", "nullable": true }, "realized": { "type": "number", "nullable": true }, "unrealized": { "type": "number", "nullable": true }, "last_7d": { "type": "number", "nullable": true, "description": "DEPRECATED, always null. The local pnl_7d rollup over-counted P&L (#5416 class) and is no longer emitted. Read the provider-native weekly window from GET /api/trader/{address}/profile-summary instead." }, "last_30d": { "type": "number", "nullable": true, "description": "DEPRECATED, always null. The local pnl_30d rollup over-counted P&L (#5416 class) and is no longer emitted. Read the provider-native monthly window from GET /api/trader/{address}/profile-summary instead." } } }, "stats": { "type": "object", "properties": { "markets_traded": { "type": "integer", "nullable": true }, "win_rate": { "type": "number", "nullable": true }, "daily_win_rate": { "type": "number", "nullable": true }, "total_volume": { "type": "number", "nullable": true } } }, "strategy": { "type": "object", "nullable": true, "properties": { "strategy_type": { "type": "string" }, "description": { "type": "string", "nullable": true }, "confidence": { "type": "number", "nullable": true } } }, "category_strengths": { "type": "object", "nullable": true, "additionalProperties": true, "description": "Per-category performance breakdown (expand=categories or expand[]=categories). Omitted unless expanded. Object keyed by category name; each value is the precomputed trader_rankings.category_ranks payload (rank, total_in_category, total_pnl, scaled_total_pnl, n_markets, wins, losses, win_rate; scaled_total_pnl is a legacy alias that currently equals total_pnl). Pass-through DB JSON: keys and value shape are DB-owned, so the inner shape is intentionally unconstrained and may carry additional compatibility fields." }, "quant_metrics": { "type": "object", "nullable": true, "additionalProperties": false, "required": [ "smart_score", "copy_score", "sharpe_30d", "sharpe_7d", "profit_factor", "edge_consistency", "sharpe_percentile", "pf_percentile", "consistency_percentile" ], "description": "Curated advanced risk/performance metrics (expand=quant_metrics or expand[]=quant_metrics). Omitted unless expanded and backed by a computed row strictly under six hours old; a missing row, NULL computed_at, or age of exactly six hours or more is stale and omitted. Provider-input changes may intentionally lag inside the bounded six-hour window. When present, all listed fields are present (each is a number or null); null means insufficient trade history and must not be treated as 0. The fixed field shape is unchanged.", "properties": { "smart_score": { "type": "number", "nullable": true, "description": "Composite skill score, 0-100. smart_score = clamp(0, 100, 30*sharpe_percentile_fraction + 20*profit_factor_percentile_fraction + 20*edge_consistency_percentile_fraction + 10*min(1, return_on_capital/2) + 10*equity_smoothness + 10*(1 - min(1, asset_concentration))). Higher is better. null when insufficient history." }, "copy_score": { "type": "number", "nullable": true, "description": "Copyability score, 0-100. Same base as smart_score minus penalties for traits that make a strategy hard to replicate: -20 if fewer than 50 markets traded, -15 if positions are highly concentrated, -15 if position sizing exceeds about 2x Kelly, -10 if the worst single-trade loss exceeds 30%, -10 if edge is inconsistent; result clamped to 0-100. Higher means easier to follow. null when insufficient history." }, "sharpe_30d": { "type": "number", "nullable": true, "description": "Sharpe ratio over the trailing 30 days (risk-adjusted return; higher is better). Magnitude can be large for small samples. null when insufficient history." }, "sharpe_7d": { "type": "number", "nullable": true, "description": "Sharpe ratio over the trailing 7 days (risk-adjusted return; higher is better). null when insufficient history." }, "profit_factor": { "type": "number", "nullable": true, "description": "Gross profit divided by gross loss; greater than 1 is profitable. Capped at 1000 when there are effectively no losses. null when insufficient history." }, "edge_consistency": { "type": "number", "nullable": true, "description": "Stability of the trader's edge over time, 0-1 (higher is more consistent). null when insufficient history." }, "sharpe_percentile": { "type": "number", "nullable": true, "description": "Cross-sectional percentile rank of the trader's Sharpe ratio versus all traders, 0-100. null when insufficient history." }, "pf_percentile": { "type": "number", "nullable": true, "description": "Cross-sectional percentile rank of profit factor versus all traders, 0-100. null when insufficient history." }, "consistency_percentile": { "type": "number", "nullable": true, "description": "Cross-sectional percentile rank of edge consistency versus all traders, 0-100. null when insufficient history." } } }, "last_active": { "type": "string", "format": "date-time", "nullable": true }, "synced_at": { "type": "string", "format": "date-time", "nullable": true }, "sync_status": { "type": "string", "nullable": true, "description": "synced, unknown, or pending." }, "trust": { "$ref": "#/components/schemas/TraderTrust", "description": "Field-level trust metadata. Present only when expand=trust or expand[]=trust is requested." } } }, "TraderContext": { "type": "object", "required": [ "trader", "data_as_of", "freshness_note" ], "properties": { "trader": { "$ref": "#/components/schemas/Trader" }, "position_summary": { "type": "object", "description": "Aggregate position and P&L coverage for the trader. Omitted entirely (key absent, never null) when the trader is not in the local database.", "required": [ "markets_total", "markets_synced", "markets_resolved", "markets_open", "sync_coverage", "synced_realized_pnl", "total_realized_pnl", "unrealized_mtm", "cost_basis_locked", "resolved_win_rate", "as_of" ], "properties": { "markets_total": { "type": "integer", "nullable": true, "description": "Provider markets_traded count when known; null when the provider total is unavailable." }, "markets_synced": { "type": "integer", "description": "Markets with locally synced position rows." }, "markets_resolved": { "type": "integer", "description": "Synced markets that have resolved." }, "markets_open": { "type": "integer", "description": "Synced markets still open with residual value (open positions with current value > 0)." }, "sync_coverage": { "type": "number", "description": "markets_synced divided by markets_total when the provider total is known (capped at 1.0); 0.0-1.0. When markets_total is unknown or not positive (null, 0, or negative), this is 1.0 if any markets are synced (else 0.0), so cross-check markets_total before treating 1.0 as full coverage." }, "synced_realized_pnl": { "type": "number", "description": "Realized P&L (USD) across synced markets only." }, "total_realized_pnl": { "type": "number", "description": "Realized P&L (USD) across synced markets: closed-leg realized plus realized gains booked on still-open positions; not provider all-time realized when sync_coverage < 1.0 -- cross-check sync_coverage." }, "unrealized_mtm": { "type": "number", "description": "Mark-to-market unrealized P&L (USD) on open positions." }, "cost_basis_locked": { "type": "number", "description": "Cost basis (USD) currently tied up in open positions." }, "resolved_win_rate": { "type": "number", "nullable": true, "description": "Win rate as a percentage (0-100) over resolved markets; null when there is no resolved sample." }, "as_of": { "type": "string", "format": "date-time", "nullable": true, "description": "RFC3339 freshness of the served OPEN-position data: the trader's latest /positions snapshot, else the last completed sync. The snapshot advances ONLY open positions, so read this as the open-position freshness clock -- the resolved/closed aggregates on this same summary (markets_resolved, synced_realized_pnl, resolved_win_rate) advance only on a full sync. The value is the /positions snapshot instant when one exists, so it is typically at or just before the trader-level last sync on a normal sync, and can be AFTER it while the active-view loop refreshes open positions between full syncs. Always present on the wire (serialized as JSON null when the trader has neither a snapshot nor a sync); never omitted." } } }, "data_as_of": { "type": "string", "format": "date-time", "nullable": true, "description": "RFC3339 freshness of the OPEN-position-level data: when a position_summary is present this mirrors its as_of byte-for-byte (latest /positions snapshot, else last completed sync) -- the open-position freshness clock, since the snapshot advances only open positions; otherwise the trader's last completed sync. null only when the trader has neither a snapshot nor a sync." }, "freshness_note": { "type": "string", "description": "Human-readable statement of the point-in-time snapshot semantics (data_as_of is the open-position clock -- the latest /positions snapshot, else the last completed sync; the snapshot advances only open positions, so resolved/closed aggregates date to the last full sync -- not a live feed; re-fetch for fresher data)." } } }, "Position": { "type": "object", "required": [ "id", "platform", "wallet", "side", "shares", "current_value_usd", "freshness", "trader", "market" ], "properties": { "id": { "type": "string", "description": "Composite prefixed ID `pos_::`." }, "platform": { "type": "string", "enum": [ "polymarket", "kalshi" ], "description": "Provider discriminator. Slice 5 ships Polymarket only; the field stays in the response shape so Kalshi positions can land without a breaking change." }, "wallet": { "type": "string", "description": "Lowercased proxy wallet address." }, "side": { "type": "string", "enum": [ "YES", "NO" ], "description": "Binary outcome side. Non-binary positions are not surfaced on V1." }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for this outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "shares": { "type": "number", "description": "Live share count from the wallet_positions mirror." }, "avg_price": { "type": "number", "nullable": true, "description": "Volume-weighted entry price for this leg." }, "current_value_usd": { "type": "number", "description": "Current mark-to-market value in USD (always non-null on V1 \u2014 pre-reconcile rows are excluded)." }, "initial_value_usd": { "type": "number", "nullable": true }, "cash_pnl": { "type": "number", "nullable": true, "description": "Unrealized P&L for the open position (Polymarket `cashPnl`)." }, "realized_pnl": { "type": "number", "nullable": true, "description": "Closed-leg P&L rolled up (Polymarket `realizedPnl`)." }, "last_reconciled_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Max updated_at across mirror legs for this pair." }, "freshness": { "type": "string", "enum": [ "fresh", "refreshing", "stale", "unknown" ], "description": "Backend-computed staleness bucket derived from last_reconciled_at." }, "trader": { "type": "object", "required": [ "id", "address", "is_new_wallet" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (`trd_...`)." }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ], "nullable": true }, "win_rate": { "type": "number", "nullable": true, "description": "Percentage 0-100." }, "pnl": { "type": "number", "nullable": true }, "markets": { "type": "integer", "nullable": true }, "wallet_age_days": { "type": "number", "nullable": true }, "is_new_wallet": { "type": "boolean", "description": "Wallet is younger than the new-wallet threshold (30 days)." } } }, "market": { "type": "object", "required": [ "id", "condition_id", "title" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (`mkt_...`)." }, "condition_id": { "type": "string" }, "title": { "type": "string" }, "slug": { "type": "string", "nullable": true }, "event_slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true, "description": "Provider-backed market_canonical category." }, "outcome_label": { "type": "string", "nullable": true, "description": "Provider-reported outcome label (e.g. team name for sports). Separate from `side` because provider labels can diverge from the binary Yes/No axis." }, "end_date": { "type": "string", "format": "date-time", "nullable": true } } } } }, "WhaleTrade": { "type": "object", "required": [ "id", "traded_at", "size_usd", "side", "price", "signal_score", "trader", "market" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (wt_...)." }, "traded_at": { "type": "string", "format": "date-time" }, "size_usd": { "type": "number" }, "side": { "type": "string", "enum": [ "BUY", "SELL" ] }, "outcome": { "type": "string", "nullable": true, "description": "Traded outcome label (e.g. \"Yes\"/\"No\"/team name), resolved provider-first from the trade's outcome_index against market_canonical (index 0 -> yes, 1 -> no). Distinct axis from side (BUY/SELL): side is the trade direction, outcome is which leg was traded. null for multi-outcome (outcome_index >= 2) or unsynced markets; a Kalshi row carries its provider label here (only token_id is null for Kalshi, since there is no CLOB token)." }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the traded outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "price": { "type": "number" }, "signal_score": { "type": "number", "description": "0.0\u20131.0 normalized signal score." }, "trader": { "type": "object", "required": [ "id", "address" ], "properties": { "id": { "type": "string" }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "nullable": true } } }, "market": { "type": "object", "required": [ "id", "condition_id", "title" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "title": { "type": "string" }, "slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true, "description": "Provider-backed market_canonical category." } } } } }, "PickHolder": { "type": "object", "required": [ "address", "shares" ], "properties": { "address": { "type": "string" }, "name": { "type": "string", "nullable": true }, "grade": { "type": "string", "nullable": true, "description": "All-time trader grade (S, A, B, C, D, F)." }, "shares": { "type": "number" } } }, "PickOfTheDay": { "type": "object", "required": [ "state", "pick_date", "matchup", "category", "platform", "release_at", "is_locked", "outcome", "pick_outcome_label", "position", "side_summary", "smart_wallet_count", "thesis", "disclaimer" ], "properties": { "state": { "type": "string", "enum": [ "full" ], "description": "Always 'full' for an authenticated Pro key." }, "pick_date": { "type": "string", "format": "date", "description": "The pick's local publication date (YYYY-MM-DD)." }, "matchup": { "type": "string", "description": "Human-readable matchup (e.g. \"Portugal vs. Uzbekistan\")." }, "category": { "type": "string", "description": "Frozen canonical calibration/report bucket (e.g. \"Basketball\", \"MMA\", or \"Soccer\"). Existing semantics are unchanged; presentation consumers should prefer display_category when present." }, "display_category": { "type": "string", "description": "Frozen public presentation category. For supported Polymarket sports this is the exact verified official event league (e.g. \"WNBA\" or \"UFC\"); otherwise it equals category. Additive and optional for mixed-version client compatibility." }, "platform": { "type": "string", "description": "Provider platform (e.g. \"polymarket\")." }, "release_at": { "type": "string", "format": "date-time", "description": "The pick's stored release instant. Normally the current provider kickoff minus one hour; an operator may override it. The actual publish instant can trail it because of worker or claim delay." }, "is_locked": { "type": "boolean", "description": "True only before the pick's stored release instant (a pre-release embargo flag); effectively always false on a served, already-published pick. To detect that the backed game has kicked off, use `game_started`." }, "game_started": { "type": "boolean", "description": "True once the backed game's kickoff has passed (kickoff <= now). When true the snapshotted pre-game price is no longer actionable. Absent for a legacy pick with no stored kickoff (treat as not-started)." }, "outcome": { "type": "string", "enum": [ "pending", "win", "loss", "void" ], "description": "Settlement outcome of the backed side; 'pending' until the market resolves." }, "outcome_display": { "type": "string", "description": "Pre-formatted SETTLEMENT STATUS for display: \"Win\" / \"Loss\" / \"Void\" / \"Pending\" -- the outcome enum above as a label. Convenience only; outcome is the source value. NOTE: this is the win/loss STATUS, not the backed side. The backed side is pick_outcome_label (\"Belgium (-2.5)\") -- a different field answering a different question." }, "pick_outcome_label": { "type": "string", "description": "The backed side phrased as a bet: a team for a moneyline (e.g. \"Portugal\"), the handicap line for a spread (e.g. \"Belgium (-2.5)\"), or \"{team} to advance\" for a knockout advancement market (e.g. \"Spain to advance\")." }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the backed outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "position": { "type": "string", "description": "The backed side phrased as a bet (e.g. \"Portugal to win\")." }, "side_summary": { "type": "string", "description": "One-line summary of which side smart money is backing. Any current-day published pick whose required holder proof is not safely readable returns 503 read_model_warming instead of a partial success shape." }, "smart_wallet_count": { "type": "integer", "description": "Number of proven smart-money wallets on the backed side. Any current-day published pick whose required holder proof is not safely readable returns 503 read_model_warming instead of fabricating zero or omitting this required field." }, "top_grade": { "type": "string", "nullable": true, "description": "Best (highest) grade among the PROVEN smart-money (S/A-graded) wallets on the backed side. Scoped to S and A only: a backing whose graded holders are all sub-S/A (B) reports null, so a grade is never shown next to a zero proven-wallet count. null when no S/A wallet backs a current-policy pick. A current-day published pick with pending legacy proof, unknown-future proof, or structurally invalid current-policy proof returns 503 before this success schema is served. Resolved legacy proof remains readable on both current-day and archive/history responses." }, "category_edge_pct": { "type": "number", "nullable": true, "description": "Deprecated (#7170): no longer populated for picks selected on/after the calibration-edge change; omitted (absent) for new picks (the field uses skip_serializing_if, so a null value is dropped from the JSON rather than serialized as null). Permanently frozen-legacy -- retained for historical picks, with no removal or replacement planned, so no v2 is implied. Historical picks may still carry a value. Legacy meaning: category win-rate edge as a fraction (the backed-side cohort's win rate in this category minus the non-market-maker category baseline, e.g. 0.09 = +9 points), paired with category_edge_sample." }, "category_edge_sample": { "type": "integer", "nullable": true, "description": "Deprecated (#7170): no longer populated for picks selected on/after the calibration-edge change; omitted (absent) for new picks (the field uses skip_serializing_if, so a null value is dropped from the JSON rather than serialized as null). Permanently frozen-legacy -- retained for historical picks, with no removal or replacement planned, so no v2 is implied. Historical picks may still carry a value. Legacy meaning: pooled count of resolved markets behind category_edge_pct (the headline's n)." }, "smart_usd": { "type": "number", "nullable": true, "description": "Recency-weighted graded-flow magnitude in USD; omitted when <= 0." }, "backed_price": { "type": "number", "nullable": true, "description": "Pre-game snapshot probability (0..1) for the backed side." }, "odds_display": { "type": "string", "nullable": true, "description": "Pre-formatted backed_price as cents-on-the-dollar odds, to ONE decimal: \"62.0c\" / \"99.9c\". Never rounded to a whole cent -- a 99.9c favorite is not a 100c certainty. Convenience only; backed_price is the source value. Omitted when backed_price is." }, "return_per_100": { "type": "number", "nullable": true, "description": "Gross return on a $100 stake at the snapshotted price (100 / backed_price)." }, "payout_display": { "type": "string", "nullable": true, "description": "Pre-formatted return_per_100 as USD with cents and thousands separators: \"$161.29\" / \"$1,250.00\". The GROSS return (the $100 stake included), so it carries no sign. Convenience only; return_per_100 is the source value. Omitted when return_per_100 is." }, "profit_display": { "type": "string", "nullable": true, "description": "Pre-formatted PROFIT on the $100 stake -- return_per_100 minus the 100 stake, i.e. the payout net of what you put in -- as a signed USD string: \"+$61.29\". Distinct from payout_display, which is gross. Omitted when return_per_100 is." }, "sharp_pct": { "type": "number", "nullable": true, "description": "Backed-side smart-money dollar consensus as a fraction 0..1: the share of the sharp dollars on the backed side. A conviction signal, NOT a probability or expected-value claim. Frozen at generation." }, "market_pct": { "type": "number", "nullable": true, "description": "Market-implied probability of the backed side as a fraction 0..1 (equals backed_price), re-exposed alongside sharp_pct for the WHY breakdown." }, "consensus_edge_pct": { "type": "number", "nullable": true, "description": "Consensus edge = sharp_pct - market_pct, the conviction-vs-price gap (how much more of the smart money sits on this side than the price implies). This is NOT an expected-value or guaranteed edge. Null when either input is null." }, "directional_confidence": { "type": "number", "nullable": true, "description": "Team-directional commitment read at selection time: the fraction (0..1) of the backed side's graded smart-money DOLLARS held by wallets that are genuinely one-way on this game, rather than hedged across its markets. A high value means the graded pile is really committed to this side; a low one means much of it is hedged or unreadable. Omitted when the read was not computed (a pick selected before the field existed, an ungroupable game, or an empty graded pile) -- which is NOT the same as 0.0, a computed reading that nothing was confidently one-way." }, "one_way_holder_count": { "type": "integer", "nullable": true, "description": "Graded backed-side holders read as one-way-committed on this game." }, "hedged_holder_count": { "type": "integer", "nullable": true, "description": "Graded backed-side holders read as HEDGED across the game's markets." }, "one_way_graded_usd": { "type": "number", "nullable": true, "description": "The one-way holders' share of the backed-side graded dollars (the confidence's numerator)." }, "total_graded_usd": { "type": "number", "nullable": true, "description": "Backed-side graded dollars the confidence is measured against (its denominator)." }, "qualifying_expert": { "type": "object", "nullable": true, "description": "The qualifying category expert whose sport-specific record and real position earned this pick its top selection tier: a candidate backed by one outranks every candidate without one. Present only on the full payload. Omitted when no wallet qualified on the backed side, on picks generated before the field existed, and on the first-party web teaser, which withholds all backed-side evidence. Frozen at SELECTION time \u2014 the wallet's position can move before the pick renders.", "properties": { "address": { "type": "string", "description": "Wallet address of the qualifying expert." }, "name": { "type": "string", "nullable": true, "description": "Provider display name, or null for an unnamed wallet." }, "grade": { "type": "string", "nullable": true, "description": "0xinsider grade letter. Always S or A: Pick of the Day only counts S/A wallets as proven." }, "canonical_category": { "type": "string", "description": "The canonical sport bucket the win rate was measured over (for example Basketball). Can be BROADER than the pick's display_category, which names an exact league such as NBA \u2014 label the rate with this field, never with display_category." }, "win_rate": { "type": "number", "description": "Share of this wallet's resolved markets in canonical_category whose realized P&L came out positive, as a 0..1 fraction. Above 0.60 by construction. Deliberately NOT phrased as \"closed profitable\": the metric counts realized P&L above zero, so a resolved winner the wallet never redeemed sits at zero and counts against it." }, "n_resolved": { "type": "integer", "description": "Resolved markets in canonical_category behind win_rate. At least 10 by construction." }, "position_usd": { "type": "number", "description": "Polymarket's own currentValue for this wallet on the backed outcome, in USD, as of selection. At least 1000 by construction." }, "stats_computed_at": { "type": "string", "format": "date-time", "description": "When the category read model behind win_rate was last rebuilt." } }, "required": [ "address", "canonical_category", "win_rate", "n_resolved", "position_usd", "stats_computed_at" ] }, "trust": { "$ref": "#/components/schemas/PickTrust" }, "traders": { "type": "integer", "nullable": true, "description": "Count of proven smart-money wallets on the backed side (equals smart_wallet_count)." }, "backed_sharp_usd": { "type": "number", "nullable": true, "description": "Raw backed-side smart-money USD frozen at generation (the 'Sharp $'), NOT the recency-weighted smart_usd which decays." }, "holders": { "type": "array", "nullable": true, "description": "Frozen smart-money holders on the backed side. Newly captured backing snapshots use a complete provider-confirmed S/A-only cohort; historical rows can retain their earlier frozen shape.", "items": { "$ref": "#/components/schemas/PickHolder" } }, "holder_count": { "type": "integer", "nullable": true, "description": "True pre-cap total for the frozen holders cohort on the backed side (may exceed the holders array length). Newly captured backing snapshots count the complete provider-confirmed S/A-only cohort." }, "editorial_note": { "type": "string", "nullable": true, "description": "Optional editorial note attached to the pick." }, "thesis": { "type": "string", "description": "Required truthful thesis. With at least one proven holder: Proven sharp money holds {pick_outcome_label}[, led by a grade-{top_grade} trader]. Without proven holder backing: 0xInsider's Pick of the Day is {pick_outcome_label}. Wallet counts are not appended." }, "market_url": { "type": "string", "nullable": true, "description": "Canonical web market URL." }, "event_slug": { "type": "string", "nullable": true, "description": "The canonical /event game-page slug (one neutral page per game), null when the game has no neutral event page." }, "sports_context": { "allOf": [ { "$ref": "#/components/schemas/PickSportsContext" } ], "nullable": true, "description": "Provider-first sports context for the pick's market (team logos, league branding, live score). Full-state only; omitted when the pick is not a team-sports market." }, "disclaimer": { "type": "string", "description": "Risk disclaimer shown with every pick." } } }, "PickSportsContext": { "type": "object", "required": [ "event_matchup" ], "description": "Provider-first sports context for a Pick of the Day market: team crests, league branding, and live score. Team logos and league logo are provider-owned (Polymarket /teams crests for clubs, country flags for national teams and tennis players); no local derivation.", "properties": { "league_name": { "type": "string", "nullable": true, "description": "League or competition display name (e.g. \"Premier League\")." }, "league_logo": { "type": "string", "nullable": true, "description": "League logo URL (provider-owned)." }, "yes_team": { "allOf": [ { "$ref": "#/components/schemas/PickSportsTeam" } ], "nullable": true, "description": "The team mapped to the market's YES outcome, or the parent-event home/first team when event_matchup is true." }, "no_team": { "allOf": [ { "$ref": "#/components/schemas/PickSportsTeam" } ], "nullable": true, "description": "The team mapped to the market's NO outcome, or the parent-event away/second team when event_matchup is true." }, "game_id": { "type": "integer", "nullable": true, "description": "Provider game identifier (Polymarket Gamma gameId); omitted when null." }, "event_matchup": { "type": "boolean", "description": "Always present. True when the two teams are the parent-event match identity for a teamless binary leg (e.g. a draw, totals, or prop market), not the market's own outcomes." }, "event_subject_team": { "allOf": [ { "$ref": "#/components/schemas/PickSportsTeam" } ], "nullable": true, "description": "Present only alongside event_matchup: the event team the binary leg is about (provider group_item_title matched to a matchup team, e.g. Belgium for \"Will Belgium win?\"), i.e. the winner on a Yes resolution. Omitted for teamless legs (draw, totals, prop)." }, "matchup_title": { "type": "string", "nullable": true, "description": "The two teams as a single whole-game label, joined \" \u2013 \" (en-dash) in provider display order (e.g. \"Portugal \u2013 Uzbekistan\"). Composed server-side from the provider team names (no title/slug parsing). Present when both teams resolve a name; omitted for single-subject, teamless, or non-two-team contexts." } } }, "PickSportsTeam": { "type": "object", "description": "A single sports team or competitor in a Pick of the Day market's sports context. Every field is provider-owned and nullable.", "properties": { "label": { "type": "string", "nullable": true, "description": "Team display label as it appears on the market outcome (e.g. \"Portugal\")." }, "short_label": { "type": "string", "nullable": true, "description": "Abbreviated team label (e.g. \"POR\")." }, "full_name": { "type": "string", "nullable": true, "description": "Full team or competitor name (e.g. \"Portugal national football team\")." }, "provider_id": { "type": "integer", "nullable": true, "description": "Provider team identifier (Polymarket /teams id)." }, "logo": { "type": "string", "nullable": true, "description": "Team crest or flag URL (provider-owned: Polymarket /teams crest for clubs, country flag for national teams and tennis players)." }, "color": { "type": "string", "nullable": true, "description": "Team brand color as a hex string (provider-owned)." }, "record": { "type": "string", "nullable": true, "description": "Win-loss record as a display string (e.g. \"12-4\")." }, "score": { "type": "string", "nullable": true, "description": "Live or final score as a display string when the game is in play or settled." } } }, "PickOfTheDayArchive": { "type": "object", "required": [ "picks", "hit_rate" ], "properties": { "picks": { "type": "array", "description": "Every published Pick of the Day, newest first by pick_date.", "items": { "$ref": "#/components/schemas/PickOfTheDayArchiveEntry" } }, "hit_rate": { "$ref": "#/components/schemas/PickOfTheDayHitRate" } } }, "PickOfTheDayArchiveEntry": { "type": "object", "required": [ "pick_date", "matchup", "category", "outcome" ], "properties": { "pick_date": { "type": "string", "format": "date", "description": "The pick's local publication date (YYYY-MM-DD)." }, "matchup": { "type": "string", "description": "Human-readable matchup (e.g. \"Portugal vs. Uzbekistan\")." }, "category": { "type": "string", "description": "Frozen canonical calibration/report bucket (e.g. \"Basketball\", \"MMA\", or \"Soccer\"). Existing semantics are unchanged; presentation consumers should prefer display_category when present." }, "display_category": { "type": "string", "description": "Frozen public presentation category. For supported Polymarket sports this is the exact verified official event league (e.g. \"WNBA\" or \"UFC\"); otherwise it equals category. Additive and optional for mixed-version client compatibility." }, "image_url": { "type": "string", "description": "Provider (Polymarket Gamma) market thumbnail URL (markets.image); omitted (not null) when the market has no image. Public regardless of the backed-side gate, so present for pending rows too." }, "pick_outcome_label": { "type": "string", "nullable": true, "description": "The backed side's outcome label. Omitted for a still-pending pick when the request is not from an authenticated Pro key." }, "top_grade": { "type": "string", "nullable": true, "description": "Best (highest) grade among the PROVEN smart-money (S/A-graded) wallets on the backed side. Scoped to S and A only: a backing whose graded holders are all sub-S/A (B) reports null, so a grade is never shown next to a zero proven-wallet count. null when no S/A wallet backs the pick, when a pending legacy proof has not yet upgraded, or when the stored holder policy is unknown-future or structurally invalid. Resolved legacy history remains supported." }, "outcome": { "type": "string", "enum": [ "pending", "win", "loss", "void" ], "description": "Settlement outcome of the backed side; 'pending' until the market resolves." }, "outcome_display": { "type": "string", "description": "Pre-formatted settlement status for display: \"Win\" / \"Loss\" / \"Void\" / \"Pending\" -- the outcome enum above as a label, from the same formatter the pick payload's outcome_display uses. Convenience only; outcome is the source value." }, "return_per_100": { "type": "number", "description": "Gross return on a $100 stake on this resolved pick: a win returns 100 / backed_price, a loss returns 0, a void refunds 100. A loss always returns 0 (the whole stake is lost regardless of price). Omitted (not null) only for a still-pending pick or a resolved WIN with no frozen price (a win's payout needs the price); mirrors the backend skip-when-absent behavior and the route-client optional (non-nullable) schema." }, "payout_display": { "type": "string", "description": "Pre-formatted return_per_100 as USD with cents: \"$200.00\". Present exactly when return_per_100 is -- it is formatted from that already-gated value -- so it is omitted for a still-pending pick, an unpriced win, and any pick whose backed side is withheld. Convenience only; return_per_100 is the source value." } } }, "PickOfTheDayHitRate": { "type": "object", "required": [ "wins", "losses", "decided", "pct", "void", "pending", "net_profit_usd", "staked_usd", "roi_pct", "net_profit_display", "roi_display", "win_rate_display" ], "properties": { "wins": { "type": "integer", "description": "Number of decided picks that won." }, "losses": { "type": "integer", "description": "Number of decided picks that lost." }, "decided": { "type": "integer", "description": "Number of decided picks (wins + losses); excludes void and pending." }, "pct": { "type": "number", "description": "Rolling hit rate as a percentage (wins / decided * 100, to 1 decimal); 0 when none are decided." }, "void": { "type": "integer", "description": "Number of picks that resolved void (excluded from the hit rate)." }, "pending": { "type": "integer", "description": "Number of picks still pending resolution (excluded from the hit rate)." }, "net_profit_usd": { "type": "number", "description": "Cumulative profit (USD) of a $100/pick strategy over decided picks with a valuation: a win pays 100/backed_price - 100, a loss pays -100 (always, price-independent), a void pays 0. Only a resolved WIN with no frozen price is excluded (its payout is unknowable); a priceless loss still books -100." }, "staked_usd": { "type": "number", "description": "Total staked (USD) = 100 * count of decided picks with a valuation: every loss (always) plus every priced win. Void (refunds the stake) and a priceless win (unknowable payout) are excluded." }, "roi_pct": { "type": "number", "description": "Return on the staked amount as a percentage (net_profit_usd / staked_usd * 100, to 1 decimal); 0 when nothing is staked." }, "net_profit_display": { "type": "string", "description": "Pre-formatted net profit for display, e.g. \"+$100\" / \"-$40\". Whole dollars, signed, round-then-signed so a rounds-to-zero record reads \"+$0\" (never \"-$0\"). Convenience only; net_profit_usd is the source value." }, "roi_display": { "type": "string", "description": "Pre-formatted ROI for display, e.g. \"+8.3%\" / \"-20.0%\". One decimal, signed, round-then-signed so a rounds-to-zero record reads \"+0.0%\" (never \"-0.0%\"). Convenience only; roi_pct is the source value." }, "win_rate_display": { "type": "string", "description": "Pre-formatted win rate for display, e.g. \"92.3%\". One decimal, unsigned. Convenience only; pct is the source value." }, "series": { "type": "array", "description": "Cumulative track-record series, one point per decided (win/loss) pick in ascending pick_date order (void and pending add no point). The last point's net_profit_usd and hit_rate_pct equal the headline net_profit_usd and pct by construction. Empty when nothing is decided.", "items": { "type": "object", "required": [ "date", "net_profit_usd", "hit_rate_pct" ], "properties": { "date": { "type": "string", "format": "date", "description": "The decided pick's publish date (YYYY-MM-DD)." }, "net_profit_usd": { "type": "number", "description": "Running cumulative $100/pick profit (USD) through this pick (every loss and every priced win are booked; only an unpriced WIN carries it forward unchanged)." }, "hit_rate_pct": { "type": "number", "description": "Running rolling hit rate (wins / decided * 100, to 1 decimal) through this pick." } } } } } }, "LeaderboardEntry": { "type": "object", "required": [ "id", "address", "platform" ], "properties": { "id": { "type": "string" }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "nullable": true }, "streak_tier": { "type": "string", "enum": [ "hot", "rising", "neutral", "cooling", "cold" ], "nullable": true, "description": "Hot-streak tier (trailing-7d cross-sectional percentile); a separate axis from the all-time grade. Null when no recent activity." }, "score": { "type": "number", "nullable": true }, "pnl": { "type": "number", "nullable": true, "description": "All-time P&L in USD (total_pnl), including unrealized open positions. Kept for back-compat; prefer realized_pnl for the banked figure." }, "realized_pnl": { "type": "number", "nullable": true, "description": "All-time banked realized P&L in USD (total_pnl - open_pnl), excluding unrealized open positions. Matches the realized-P&L-dominant grade/board." }, "volume": { "type": "number", "nullable": true }, "markets_traded": { "type": "integer", "nullable": true }, "win_rate": { "type": "number", "nullable": true }, "strategy_type": { "type": "string", "nullable": true }, "platform": { "type": "string" }, "last_active": { "type": "string", "format": "date-time", "nullable": true } } }, "MarketSearchResult": { "type": "object", "required": [ "id", "condition_id", "title", "status" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "title": { "type": "string" }, "slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true }, "platform": { "type": "string", "nullable": true }, "status": { "type": "string", "enum": [ "active", "closed" ] } } }, "ExploreMarket": { "type": "object", "required": [ "id", "condition_id", "title", "status" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "title": { "type": "string", "minLength": 1, "description": "Non-empty market title." }, "slug": { "type": "string", "nullable": true, "description": "Provider-native market slug." }, "url_slug": { "type": "string", "nullable": true, "description": "First-party market page slug used for internal links." }, "image": { "type": "string", "nullable": true }, "icon": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true }, "platform": { "type": "string", "nullable": true }, "status": { "type": "string", "enum": [ "active", "closed" ] }, "volume": { "type": "number", "nullable": true }, "liquidity": { "type": "number", "nullable": true }, "whale_trade_count": { "type": "integer", "nullable": true }, "whale_distinct_wallets": { "type": "integer", "nullable": true }, "whale_total_usd": { "type": "number", "nullable": true }, "whale_last_trade_at": { "type": "string", "format": "date-time", "nullable": true }, "end_date": { "type": "string", "format": "date-time", "nullable": true }, "created_at": { "type": "string", "format": "date-time", "nullable": true }, "outcome_yes": { "type": "string", "nullable": true }, "token_id_yes": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the YES outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "outcome_no": { "type": "string", "nullable": true }, "token_id_no": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the NO outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "event_slug": { "type": "string", "nullable": true }, "kalshi_series_slug": { "type": "string", "nullable": true }, "smart_score": { "type": "number", "nullable": true }, "smart_count": { "type": "integer", "nullable": true }, "smart_label": { "type": "string", "nullable": true }, "outcome_yes_label": { "type": "string", "nullable": true, "description": "Display label for the YES/outcome_index=0 side, enriched from provider outcome metadata when available." }, "outcome_no_label": { "type": "string", "nullable": true, "description": "Display label for the NO/outcome_index=1 side, enriched from provider outcome metadata when available." }, "outcome_yes_provider_id": { "type": "integer", "nullable": true, "description": "Provider-owned YES/outcome_index=0 identifier when available for trade-ticket wiring." }, "outcome_no_provider_id": { "type": "integer", "nullable": true, "description": "Provider-owned NO/outcome_index=1 identifier when available for trade-ticket wiring." }, "open_interest": { "type": "number", "nullable": true }, "oi_change_pct": { "type": "number", "nullable": true }, "price_points": { "type": "array", "nullable": true, "items": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "number" } } }, "no_price_points": { "type": "array", "nullable": true, "items": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "number" } } }, "last_price": { "type": "number", "nullable": true }, "no_last_price": { "type": "number", "nullable": true }, "change_pct_24h": { "type": "number", "nullable": true }, "no_change_pct_24h": { "type": "number", "nullable": true }, "discover_score": { "type": "number", "nullable": true, "description": "Backend-owned deterministic market discovery score used by the hot sort." }, "score_components": { "type": "object", "required": [ "missing_price_penalty" ], "properties": { "volume_signal": { "type": "number", "nullable": true }, "whale_signal": { "type": "number", "nullable": true }, "liquidity_signal": { "type": "number", "nullable": true }, "recency_signal": { "type": "number", "nullable": true }, "smart_money_signal": { "type": "number", "nullable": true }, "price_move_signal": { "type": "number", "nullable": true }, "missing_price_penalty": { "type": "number" } } }, "freshness": { "type": "object", "required": [ "enrichment_status", "price_status" ], "properties": { "enrichment_status": { "type": "string", "enum": [ "available", "unavailable" ] }, "price_status": { "type": "string", "enum": [ "available", "unavailable" ] } } } } }, "ExploreGroup": { "type": "object", "required": [ "type", "event_slug", "parent_title", "markets" ], "properties": { "type": { "type": "string", "const": "group" }, "event_slug": { "type": "string" }, "parent_title": { "type": "string" }, "image": { "type": "string", "nullable": true }, "platform": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true }, "markets": { "type": "array", "items": { "$ref": "#/components/schemas/ExploreMarket" } }, "rep_volume": { "type": "number", "nullable": true }, "rep_whales": { "type": "integer", "nullable": true } } }, "ExploreStandalone": { "type": "object", "required": [ "type", "market" ], "properties": { "type": { "type": "string", "const": "standalone" }, "market": { "$ref": "#/components/schemas/ExploreMarket" } } }, "ExploreFacetValue": { "type": "object", "required": [ "value", "label", "count" ], "properties": { "value": { "type": "string" }, "label": { "type": "string" }, "count": { "type": "integer" } } }, "ExploreFacets": { "type": "object", "required": [ "categories", "platforms" ], "properties": { "categories": { "type": "array", "items": { "$ref": "#/components/schemas/ExploreFacetValue" } }, "platforms": { "type": "array", "items": { "$ref": "#/components/schemas/ExploreFacetValue" } } } }, "ExploreEntry": { "oneOf": [ { "$ref": "#/components/schemas/ExploreGroup" }, { "$ref": "#/components/schemas/ExploreStandalone" } ], "discriminator": { "propertyName": "type", "mapping": { "group": "#/components/schemas/ExploreGroup", "standalone": "#/components/schemas/ExploreStandalone" } } }, "MarketIntel": { "type": "object", "required": [ "market", "sharp_money", "smart_money", "timeframe" ], "properties": { "market": { "type": "object", "required": [ "id", "condition_id", "title" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "title": { "type": "string" }, "slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true }, "platform": { "type": "string", "nullable": true } } }, "sharp_money": { "type": "object", "description": "Sharp-money flow aggregate for the market (canonical; smart_money is a deprecated byte-identical alias).", "required": [ "net_flow_usd", "direction", "whale_trade_count", "buy_volume_usd", "sell_volume_usd", "top_positions" ], "properties": { "net_flow_usd": { "type": "number" }, "direction": { "type": "string", "enum": [ "YES", "NO" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the net-flow direction outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "whale_trade_count": { "type": "integer" }, "buy_volume_usd": { "type": "number" }, "sell_volume_usd": { "type": "number" }, "top_positions": { "type": "array", "items": { "type": "object", "required": [ "id", "address", "side", "size_usd" ], "properties": { "id": { "type": "string" }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "nullable": true }, "side": { "type": "string", "enum": [ "YES", "NO" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for this outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "size_usd": { "type": "number" } } } } } }, "smart_money": { "type": "object", "description": "Deprecated alias of sharp_money; byte-identical and retained for backward compatibility.", "required": [ "net_flow_usd", "direction", "whale_trade_count", "buy_volume_usd", "sell_volume_usd", "top_positions" ], "properties": { "net_flow_usd": { "type": "number" }, "direction": { "type": "string", "enum": [ "YES", "NO" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the net-flow direction outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "whale_trade_count": { "type": "integer" }, "buy_volume_usd": { "type": "number" }, "sell_volume_usd": { "type": "number" }, "top_positions": { "type": "array", "items": { "type": "object", "required": [ "id", "address", "side", "size_usd" ], "properties": { "id": { "type": "string" }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "nullable": true }, "side": { "type": "string", "enum": [ "YES", "NO" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for this outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "size_usd": { "type": "number" } } } } } }, "timeframe": { "type": "string" } } }, "SmartMoneyFlowMarket": { "type": "object", "required": [ "market", "sharp_money", "smart_money", "timeframe" ], "properties": { "market": { "type": "object", "required": [ "id", "condition_id", "title", "slug", "category", "platform" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "title": { "type": "string", "nullable": true }, "slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true }, "platform": { "type": "string", "nullable": true } } }, "sharp_money": { "type": "object", "description": "Sharp-money flow aggregate for the market (canonical; smart_money is a deprecated byte-identical alias).", "required": [ "net_flow_usd", "direction", "whale_trade_count", "buy_volume_usd", "sell_volume_usd" ], "properties": { "net_flow_usd": { "type": "number" }, "direction": { "type": "string", "enum": [ "YES", "NO" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the net-flow direction outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "whale_trade_count": { "type": "integer" }, "buy_volume_usd": { "type": "number" }, "sell_volume_usd": { "type": "number" } } }, "smart_money": { "type": "object", "description": "Deprecated alias of sharp_money; byte-identical and retained for backward compatibility.", "required": [ "net_flow_usd", "direction", "whale_trade_count", "buy_volume_usd", "sell_volume_usd" ], "properties": { "net_flow_usd": { "type": "number" }, "direction": { "type": "string", "enum": [ "YES", "NO" ] }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the net-flow direction outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "whale_trade_count": { "type": "integer" }, "buy_volume_usd": { "type": "number" }, "sell_volume_usd": { "type": "number" } } }, "timeframe": { "type": "string" } } }, "SportsEdgeSignalCategorySkill": { "type": "object", "description": "Shadow-only category evidence over the full uncapped piled-side S/A/B holder allocation. It never changes signal membership, ordering, routing, or sizing.", "required": [ "status", "model_version", "taxonomy_version", "platform", "scope", "source_coverage", "observation_started_at", "as_of", "canonical_category", "eligible_holders", "covered_holders", "backed_sharp_usd", "covered_backed_usd", "coverage_pct", "weighted_edge_mean", "weighted_holder_lower_mean", "specialist_backed_usd", "specialist_backed_usd_pct", "largest_holder_backed_usd_pct", "minimum_holder_event_count" ], "properties": { "status": { "type": "string", "enum": ["live", "insufficient", "stale", "unknown", "degraded"] }, "model_version": { "type": "string" }, "taxonomy_version": { "type": "string", "nullable": true }, "platform": { "type": "string", "const": "polymarket" }, "scope": { "type": "string", "const": "observed_goldsky_primary_taker_fill" }, "source_coverage": { "type": "string", "const": "partial_whale_threshold_fills" }, "observation_started_at": { "type": "string", "format": "date-time" }, "as_of": { "type": "string", "format": "date-time" }, "canonical_category": { "type": "string", "nullable": true }, "eligible_holders": { "type": "integer", "minimum": 0 }, "covered_holders": { "type": "integer", "minimum": 0 }, "backed_sharp_usd": { "type": "number", "nullable": true, "minimum": 0 }, "covered_backed_usd": { "type": "number", "nullable": true, "minimum": 0 }, "coverage_pct": { "type": "number", "nullable": true, "minimum": 0, "maximum": 1 }, "weighted_edge_mean": { "type": "number", "nullable": true, "minimum": -1, "maximum": 1 }, "weighted_holder_lower_mean": { "type": "number", "nullable": true }, "specialist_backed_usd": { "type": "number", "nullable": true, "minimum": 0 }, "specialist_backed_usd_pct": { "type": "number", "nullable": true, "minimum": 0, "maximum": 1 }, "largest_holder_backed_usd_pct": { "type": "number", "nullable": true, "minimum": 0, "maximum": 1 }, "minimum_holder_event_count": { "type": "integer", "nullable": true, "minimum": 0 } } }, "SportsEdgeSignal": { "type": "object", "description": "One ranked pre-game sports market where graded smart money is piled on one side, with required-status shadow category evidence from partial forward-observed Polymarket fills.", "required": [ "condition_id", "piled_outcome_index", "backed_sharp_usd", "s_count", "a_count", "b_count", "graded_holders", "conviction_score", "directional_rank_score", "category_skill", "rank" ], "properties": { "condition_id": { "type": "string", "description": "Polymarket condition id." }, "token_id": { "type": "string", "nullable": true, "description": "Polymarket CLOB token id (ERC1155 asset id, decimal string) for the PILED outcome; null when unavailable." }, "category": { "type": "string", "nullable": true, "description": "Canonical sport bucket (e.g. Basketball, Tennis); null when the raw category has no canonical mapping." }, "raw_category": { "type": "string", "nullable": true, "description": "Raw provider category as stored (e.g. NBA, EPL)." }, "title": { "type": "string", "nullable": true }, "event_slug": { "type": "string", "nullable": true }, "game_start_time": { "type": "string", "format": "date-time", "nullable": true, "description": "Kickoff (UTC). In the future at SNAPSHOT time and within the requested horizon; because the response is served from a shared snapshot cached up to the ~180s TTL, a served kickoff can be up to ~180s in the past relative to the response time. Not a live guarantee that the game has not yet started." }, "piled_side": { "type": "string", "nullable": true, "description": "Nullable provider-backed piled-outcome display label. When provider group context is unavailable, it may remain a bare Yes/No/Over/Under; do not use it alone as participant identity." }, "piled_outcome_index": { "type": "integer", "description": "Provider binary-column selector: 0 selects outcome_yes/token_id_yes; 1 selects outcome_no/token_id_no. It does not identify home/away or a participant. Use piled_side together with title/event context for display." }, "sharp_pct": { "type": "number", "nullable": true, "description": "Piled-side dollar concentration backed_usd / (yes_usd + no_usd), in (0.5, 1] for a real pile; null when there is no sharp USD." }, "backed_sharp_usd": { "type": "number", "description": "Raw piled-side smart-money USD." }, "s_count": { "type": "integer", "description": "S-grade graded holders on the piled side." }, "a_count": { "type": "integer", "description": "A-grade graded holders on the piled side." }, "b_count": { "type": "integer", "description": "B-grade graded holders on the piled side." }, "graded_holders": { "type": "integer", "description": "Piled-side graded holder count (s_count + a_count + b_count)." }, "top_grade": { "type": "string", "nullable": true, "enum": [ "S", "A", "B" ], "description": "Best grade present on the piled side; null when none." }, "smart_score": { "type": "number", "nullable": true, "description": "Canonical sharp-money score (yes_usd - no_usd)/(yes_usd + no_usd) in [-1, 1] (piled-yes positive, piled-no negative); a lower-order ranking tiebreak (after directional_rank_score and conviction_score)." }, "volume": { "type": "number", "nullable": true, "description": "Market volume (USD)." }, "net_side": { "type": "string", "nullable": true, "enum": [ "BUY", "SELL" ], "description": "Aggregate recent flow direction on the market; null when unavailable." }, "conviction_score": { "type": "number", "description": "Grade-weighted pile score (5*s + 4*a + 3*b) * sharp_pct; the raw conviction input to the ranking (see directional_rank_score)." }, "one_way_holder_count": { "type": "integer", "nullable": true, "description": "Piled-side graded holders whose open legs across the signal game's markets (cross-market within the one game; moneyline+spread family only) all back the same team; counted only when the wallet's leg set is fresh and groupable. Null when the directional read was not computed (no groupable game, no holder-level data on this ranking path, or the enrichment read failed)." }, "hedged_holder_count": { "type": "integer", "nullable": true, "description": "Piled-side graded holders classified HEDGED across the game (they back two or more distinct teams). Null when the directional read was not computed." }, "one_way_graded_usd": { "type": "number", "nullable": true, "description": "Piled-side graded USD held by genuinely one-way wallets (share-weighted allocation of backed_sharp_usd). Null when the directional read was not computed." }, "directional_confidence": { "type": "number", "nullable": true, "description": "One-way fraction of the piled graded dollars, in [0, 1] -- the metric orthogonal to sharp_pct. Stale/unknown/hedged dollars dilute it toward zero (conservative). Null when the directional read was not computed." }, "directional_rank_score": { "type": "number", "description": "The ranking key, descending: conviction_score * (1 + 0.25 * directional_confidence). Equals conviction_score when the directional read is null/zero, so signals without the read rank exactly as before." }, "category_skill": { "$ref": "#/components/schemas/SportsEdgeSignalCategorySkill" }, "rank": { "type": "integer", "description": "1-based rank within the (min_grade-filtered) ranked result." } } }, "SportsEdgeObservationTerminalReason": { "type": "string", "description": "Closed 25-value terminal-reason vocabulary for the accountable sports-edge observation funnel. capacity_limited is intentional bounded provider-work admission and does not itself set the snapshot degraded. board_source_unavailable is a completed board-source failure; board_deadline_unavailable means live-board work missed either an internal configured-scope deadline or the outer fair-wave deadline; both classify only already-started rows, so for the upcoming source read funnel.sports[].board_upcoming_status instead; provider_unavailable is reserved for an attempted holder-provider failure; holder_deadline_unavailable is holder cache/provider absolute-deadline exhaustion.", "enum": [ "outside_horizon", "resolved", "provider_closed", "provider_excluded", "invalid_market", "missing_token", "missing_stored_market", "not_provider_live", "board_source_unavailable", "board_deadline_unavailable", "primary_slate_candidate", "zero_indexed_holder_research", "capacity_limited", "provider_unavailable", "holder_deadline_unavailable", "holder_computation_unavailable", "holder_scan_incomplete", "no_current_graded_holder", "split_holder_pile", "price_unavailable", "wider_holder_emitted", "in_play_emitted", "in_play_stale_observed", "in_play_directional_unavailable", "internal_unclassified" ] }, "SportsEdgeObservation": { "type": "object", "description": "One explicitly observation-only holder-pile measurement. It is evidence for cohort evaluation, not an execution instruction, and is isolated from the funded sports-edge-signals route.", "required": [ "condition_id", "token_id", "category", "raw_category", "title", "event_slug", "event_id", "parent_event_id", "game_start_time", "observed_at", "cohort", "observation_only", "piled_side", "piled_outcome_index", "backed_price", "sharp_pct", "backed_sharp_usd", "s_count", "a_count", "b_count", "graded_holders", "top_grade", "smart_score", "volume", "conviction_score", "provider_read_source", "holder_scan_complete", "holder_snapshot_at", "directional_status", "one_way_holder_count", "hedged_holder_count", "one_way_graded_usd", "directional_confidence", "directional_rank_score", "rank" ], "properties": { "condition_id": { "type": "string", "description": "Raw Polymarket condition id." }, "token_id": { "type": "string", "description": "Provider-backed Polymarket CLOB token id for the piled outcome. Rows without a verified token terminate before emission." }, "category": { "type": "string", "enum": [ "Basketball", "Football", "Baseball", "Hockey", "MMA", "Boxing", "Soccer", "Cricket", "Golf", "Tennis", "Esports", "Racing", "Table Tennis", "Pickleball" ], "description": "Canonical sport bucket." }, "raw_category": { "type": "string", "nullable": true, "description": "Raw provider category as stored." }, "title": { "type": "string", "description": "Provider-backed market title." }, "event_slug": { "type": "string", "nullable": true }, "event_id": { "type": "string", "nullable": true, "description": "Provider event id when available." }, "parent_event_id": { "type": "string", "nullable": true, "description": "Provider parent-event id used as the first event-cap identity when available." }, "game_start_time": { "type": "string", "format": "date-time", "description": "Provider-backed kickoff time in UTC." }, "observed_at": { "type": "string", "format": "date-time", "description": "UTC instant when this row finished provider/holder evaluation." }, "cohort": { "type": "string", "enum": [ "wider_holder", "in_play" ] }, "observation_only": { "type": "boolean", "const": true, "description": "Always true. This row must not be routed to an order executor." }, "piled_side": { "type": "string", "nullable": true, "description": "Nullable provider-backed piled-outcome display label. When provider group context is unavailable, it may remain a bare Yes/No/Over/Under; do not use it alone as participant identity." }, "piled_outcome_index": { "type": "integer", "enum": [ 0, 1 ], "description": "Provider binary-column selector: 0 selects outcome_yes/token_id_yes; 1 selects outcome_no/token_id_no. It does not identify home/away or a participant. Use piled_side together with title/event context for display." }, "backed_price": { "type": "number", "minimum": 0, "maximum": 1, "description": "Provider-backed implied price for the piled outcome at observation time." }, "sharp_pct": { "type": "number", "minimum": 0, "maximum": 1, "description": "Piled-side graded-holder dollar concentration." }, "backed_sharp_usd": { "type": "number", "minimum": 0, "description": "Raw graded-holder USD on the piled outcome." }, "s_count": { "type": "integer", "minimum": 0 }, "a_count": { "type": "integer", "minimum": 0 }, "b_count": { "type": "integer", "minimum": 0 }, "graded_holders": { "type": "integer", "minimum": 1, "description": "Piled-side S/A/B holder count." }, "top_grade": { "type": "string", "enum": [ "S", "A", "B" ] }, "smart_score": { "type": "number", "minimum": -1, "maximum": 1, "description": "Canonical signed holder-pile score." }, "volume": { "type": "number", "exclusiveMinimum": 0, "description": "Strictly positive stored market volume in USD. Missing, zero, or non-finite volume terminates as invalid_market and is never emitted as an observation." }, "conviction_score": { "type": "number", "minimum": 0, "description": "Grade-weighted holder-pile score before directional enrichment." }, "provider_read_source": { "type": "string", "enum": [ "cached", "live" ], "description": "Whether the provider holder page came from the shared cache or a live provider read." }, "holder_scan_complete": { "type": "boolean", "description": "True only when neither provider outcome holder page hit the top-100 scan bound. False means the pile is a positive lower bound and cannot satisfy a future capital-promotion gate." }, "holder_snapshot_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Proven provider holder observation time. A warm cache hit uses only the original provider completion time from its companion metadata, never cache-read time. Null, malformed, future, or stale holder time fails in-play closed." }, "directional_status": { "type": "string", "enum": [ "available", "unknown_ungrouped", "unknown_stale", "unavailable" ], "description": "Truthful state of the cross-market directional read. A wider_holder row can remain emitted with unavailable and terminal wider_holder_emitted; in_play fails closed instead and terminates as in_play_directional_unavailable." }, "one_way_holder_count": { "type": "integer", "minimum": 0, "nullable": true }, "hedged_holder_count": { "type": "integer", "minimum": 0, "nullable": true }, "one_way_graded_usd": { "type": "number", "minimum": 0, "nullable": true }, "directional_confidence": { "type": "number", "minimum": 0, "maximum": 1, "nullable": true }, "directional_rank_score": { "type": "number", "minimum": 0, "description": "Default cohort ordering key: conviction_score * (1 + 0.25 * directional_confidence), or conviction_score when confidence is null." }, "rank": { "type": "integer", "minimum": 1, "description": "1-based rank within this observation cohort and snapshot." } } }, "SportsEdgeFunnelReport": { "type": "object", "description": "Per-sport accountable funnel for the full observation snapshot, returned on every page.", "required": [ "sports" ], "properties": { "sports": { "type": "array", "items": { "$ref": "#/components/schemas/SportsEdgeSportFunnelReport" } } } }, "SportsEdgeSportFunnelReport": { "type": "object", "description": "Independent sports-board supply plus stored-universe terminal accounting for one canonical sport.", "required": [ "sport", "board_input", "board_live_available", "board_upcoming_configured", "board_upcoming_available", "board_upcoming_status", "input", "terminals", "terminal_total", "reconciled" ], "properties": { "sport": { "type": "string", "enum": [ "Basketball", "Football", "Baseball", "Hockey", "MMA", "Boxing", "Soccer", "Cricket", "Golf", "Tennis", "Esports", "Racing", "Table Tennis", "Pickleball" ] }, "board_input": { "type": "integer", "minimum": 0, "description": "Unique condition ids independently visible on the provider-first sports board." }, "board_live_available": { "type": "boolean", "description": "Whether the always-applicable live-board source completed as available. False can mean a completed source failure (board_source_unavailable) or live-board work missing an internal configured-scope deadline or the outer fair-wave deadline (board_deadline_unavailable); inspect terminals to distinguish them." }, "board_upcoming_configured": { "type": "boolean", "description": "Whether a provider-backed upcoming-board source is configured and applicable for this sport. False means not applicable, not provider failure." }, "board_upcoming_available": { "type": "boolean", "description": "Whether every configured upcoming-board scope completed as available. False with board_upcoming_configured=false means not applicable. When board_upcoming_configured is true and this flag is false, read board_upcoming_status for the cause (it reads unknown, i.e. no recorded cause, only on a snapshot cached before that field existed, which self-clears within one TTL): the board_source_unavailable and board_deadline_unavailable terminals are assigned only to already-started rows (the live half) and are structurally 0 for the upcoming source, so they never explain this flag." }, "board_upcoming_status": { "type": "string", "enum": [ "unknown", "not_configured", "available", "source_unavailable", "cold_unavailable", "deadline_unavailable" ], "description": "Why the upcoming-board source is (un)available. Board supply is one canonical-sport union: the bare category owns live truth and every routable league scope contributes upcoming rows; folded leagues without a configured board (currently NCAAB, NCAAF, and CFL) are not in the upcoming union. available: every configured scope completed truthfully (a successful empty schedule still counts). source_unavailable: composition failed before a truthful union; resolved scope readers turn half failures into cold_unavailable, so fresh producers are whole-union identity reconciliation or a registry contract failure and carry zero rows. cold_unavailable: every scope completed but at least one reported its upcoming half unavailable because no servable entry was inside the stale-serve bound and the background warm did not land in time; it is not by itself proof of a provider outage. deadline_unavailable: an internal configured-scope deadline or the outer bounded fair wave expired. An internal deadline may retain healthy bare-category or sibling-scope rows; the outer wave records zero rows. These upcoming fields do not describe league live-membership availability. If the bare-category live scope fails, all live rows are dropped even when a league scope completed, because the bare category is the sole live-truth owner. not_configured: no upcoming scope applies to the sport. unknown: exactly one cause -- a snapshot cached before this field existed whose legacy flags recorded an unavailable-but-configured half without saying why. Every freshly computed snapshot reports a concrete status, and a legacy available or not-configured row is reconstructed exactly, so unknown self-clears within one TTL. board_upcoming_available is exactly board_upcoming_status == available." }, "board_upcoming_unavailable_scopes": { "type": "array", "description": "Configured upcoming scopes that did not complete as available. Values are category, a provider league tag slug (nfl, nba, wnba, nhl, or mls), registry when the compiled scope/projection contract drifted, union when cross-scope identity reconciliation failed, or wave when the outer fair-wave deadline expired before scope-level evidence returned. Empty means no unavailable upcoming scope was identified; this includes healthy/not-configured rows and a legacy cached row. Observation league scopes are upcoming-only and perform no live-membership read.", "items": { "type": "string", "enum": [ "category", "nfl", "nba", "wnba", "nhl", "mls", "registry", "union", "wave" ] }, "uniqueItems": true }, "input": { "type": "integer", "minimum": 0, "description": "Stored-universe rows plus provider-board rows missing from storage." }, "terminals": { "type": "object", "description": "Sparse counts over the closed 25-value terminal vocabulary: outside_horizon, resolved, provider_closed, provider_excluded, invalid_market, missing_token, missing_stored_market, not_provider_live, board_source_unavailable, board_deadline_unavailable, primary_slate_candidate, zero_indexed_holder_research, capacity_limited, provider_unavailable, holder_deadline_unavailable, holder_computation_unavailable, holder_scan_incomplete, no_current_graded_holder, split_holder_pile, price_unavailable, wider_holder_emitted, in_play_emitted, in_play_stale_observed, in_play_directional_unavailable, or internal_unclassified. primary_slate_candidate means exact admission by the funded route's raw shared slate query before provider/holder enrichment; recent-flow rows rejected by its event, bucket, or total caps remain eligible for wider_holder measurement. capacity_limited is intentional bounded provider-work admission, is fully accounted here, and does not itself set degraded=true. board_source_unavailable means a completed board source was unavailable; board_deadline_unavailable means live-board work missed either an internal configured-scope deadline or the outer fair-wave deadline; provider_unavailable means an attempted holder-provider read failed; holder_deadline_unavailable means holder cache/provider work missed the absolute request deadline; holder_computation_unavailable means post-holder provider or DB-backed price/metadata evaluation was unavailable.", "propertyNames": { "$ref": "#/components/schemas/SportsEdgeObservationTerminalReason" }, "additionalProperties": { "type": "integer", "minimum": 0 } }, "terminal_total": { "type": "integer", "minimum": 0, "description": "Sum of every sparse terminal count." }, "reconciled": { "type": "boolean", "description": "True exactly when input equals terminal_total." } } }, "MarketSnapshotFreshness": { "type": "object", "required": [ "status", "source" ], "properties": { "status": { "type": "string", "enum": [ "fresh", "stale", "available", "not_live", "unavailable" ] }, "source": { "type": "string" }, "as_of": { "type": "string", "format": "date-time", "nullable": true }, "stale_after_s": { "type": "integer", "nullable": true }, "reason": { "type": "string", "nullable": true } } }, "MarketSnapshotTopOfBook": { "type": "object", "required": [ "status", "source" ], "properties": { "status": { "type": "string", "enum": [ "available", "unavailable" ] }, "source": { "type": "string" }, "best_bid": { "type": "number", "nullable": true }, "best_ask": { "type": "number", "nullable": true }, "spread_bps": { "type": "integer", "nullable": true }, "bid_depth_usdc": { "type": "number", "nullable": true }, "ask_depth_usdc": { "type": "number", "nullable": true }, "reason": { "type": "string", "nullable": true } } }, "MarketSnapshotTrust": { "type": "object", "description": "Price and spread trust metadata returned only when GET /api/v1/market/{condition_id}/snapshot includes expand=trust.", "required": [ "current_price", "spread_bps" ], "properties": { "current_price": { "$ref": "#/components/schemas/TrustMetadata" }, "spread_bps": { "$ref": "#/components/schemas/TrustMetadata" } } }, "MarketSnapshot": { "type": "object", "required": [ "market", "outcomes", "liquidity", "sports", "freshness" ], "properties": { "market": { "type": "object", "required": [ "id", "condition_id", "provider", "status" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "provider": { "type": "string" }, "title": { "type": "string", "nullable": true }, "slug": { "type": "string", "nullable": true }, "page_slug": { "type": "string", "nullable": true }, "event_slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true }, "status": { "type": "string", "enum": [ "active", "closed" ] }, "description": { "type": "string", "nullable": true }, "image": { "type": "string", "nullable": true }, "series_slug": { "type": "string", "nullable": true }, "kalshi_series_slug": { "type": "string", "nullable": true }, "market_type": { "type": "string", "nullable": true }, "market_result": { "type": "string", "nullable": true }, "created_at": { "type": "string", "format": "date-time", "nullable": true }, "end_date": { "type": "string", "format": "date-time", "nullable": true }, "resolved_at": { "type": "string", "format": "date-time", "nullable": true } } }, "outcomes": { "type": "array", "items": { "type": "object", "required": [ "side", "label", "top_of_book" ], "properties": { "side": { "type": "string", "enum": [ "yes", "no" ] }, "label": { "type": "string" }, "token_id": { "type": "string", "nullable": true }, "current_price": { "type": "number", "nullable": true }, "top_of_book": { "$ref": "#/components/schemas/MarketSnapshotTopOfBook" } } } }, "liquidity": { "type": "object", "required": [ "source" ], "properties": { "source": { "type": "string" }, "volume_usd": { "type": "number", "nullable": true }, "liquidity_usd": { "type": "number", "nullable": true }, "volume_24h_usd": { "type": "number", "nullable": true }, "last_price": { "type": "number", "nullable": true } } }, "sports": { "type": "object", "required": [ "status", "source" ], "properties": { "status": { "type": "string", "enum": [ "fresh", "stale", "not_live", "unavailable" ] }, "source": { "type": "string" }, "live_match_key": { "type": "string", "nullable": true }, "live_league_key": { "type": "string", "nullable": true }, "live_score": { "type": "object", "nullable": true }, "reason": { "type": "string", "nullable": true } } }, "freshness": { "type": "object", "required": [ "market_data", "top_of_book", "live_sports" ], "properties": { "market_data": { "$ref": "#/components/schemas/MarketSnapshotFreshness" }, "top_of_book": { "$ref": "#/components/schemas/MarketSnapshotFreshness" }, "live_sports": { "$ref": "#/components/schemas/MarketSnapshotFreshness" } } }, "trust": { "$ref": "#/components/schemas/MarketSnapshotTrust", "description": "Price and spread trust metadata. Present only when expand=trust or expand[]=trust is requested." } } }, "RadarFlag": { "type": "object", "required": [ "id", "suspicion_score", "severity", "trader", "market", "scores", "evidence", "created_at" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (rf_...)." }, "suspicion_score": { "type": "number" }, "severity": { "type": "string", "enum": [ "flag", "watch" ] }, "trader": { "type": "object", "required": [ "id", "address" ], "properties": { "id": { "type": "string" }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true } } }, "market": { "type": "object", "required": [ "id", "condition_id", "title" ], "properties": { "id": { "type": "string" }, "condition_id": { "type": "string" }, "title": { "type": "string" } } }, "scores": { "type": "object", "properties": { "timing": { "type": "number", "nullable": true }, "edge": { "type": "number", "nullable": true }, "size": { "type": "number", "nullable": true }, "fresh_wallet": { "type": "number", "nullable": true } } }, "evidence": { "description": "Structured evidence JSON." }, "created_at": { "type": "string", "format": "date-time" } } }, "ApiErrorBody": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "bad_request", "invalid_api_key", "subscription_required", "forbidden", "not_found", "account_locked", "rate_limited", "rate_limit_unavailable", "internal_error" ] }, "message": { "type": "string" }, "doc_url": { "type": "string", "nullable": true }, "param": { "type": "string", "nullable": true }, "retry_at": { "type": "string", "format": "date-time", "nullable": true, "description": "The recommended next retry instant (RFC3339). Present on every retryable error (reason=pick_not_released, code=rate_limited, code=rate_limit_unavailable, reason=read_model_warming) and omitted otherwise. Always in the future. For pick_not_released: before the 11:00 UTC operating-window start, before a selected pick's stored release, or after a skipped day, it names the automatic system's next boundary. While no candidate exists in the live window it normally names the persisted next automatic selector attempt (~15m). Every value is advisory under supported operator actions: manual publication, release-time override, or admin generation can make a pick available first. When the automatic schedule is absent/due or a pick is overdue it degrades to ~60s. Schedule one request and do not poll. Prefer Retry-After for the duration because it is immune to client clock skew." }, "reason": { "type": "string", "enum": [ "cursor_expired", "unknown_endpoint", "pick_not_released", "trader_not_tracked", "read_model_warming", "idempotency_in_progress", "webhook_delivery_in_progress" ], "nullable": true, "description": "ADDITIVE (#7209). The specific, actionable cause behind `code`, when there is one more specific than the code itself. `code` keeps its published values, so existing clients are unaffected; new clients branch on `reason`. Omitted when the code already says everything we know. pick_not_released: no Pick of the Day is published for the current product day; schedule one request against retry_at instead of polling. unknown_endpoint: the PATH is not a route on this API -- read GET /api/v1, do not retry. trader_not_tracked: the wallet is real and the URL is right, but the trader is outside the HOT/WARM sync tiers -- stop asking for this wallet. cursor_expired: pagination went stale mid-walk -- re-request the first page and continue. read_model_warming: the requested endpoint cannot serve its read model yet; exact causes are endpoint-specific and can include a cold or contended refresh or a dependency that prevented refresh. idempotency_in_progress: retain the exact Idempotency-Key and request body, then retry shortly. webhook_delivery_in_progress: retry the URL or signing-secret configuration change after the destination's active request completes." } } }, "BatchRateLimitMeta": { "type": "object", "required": [ "basis", "limit", "remaining", "reset" ], "properties": { "basis": { "type": "string", "const": "batch_items_per_minute" }, "limit": { "type": "integer" }, "remaining": { "type": "integer" }, "reset": { "type": "integer", "description": "Unix timestamp when the batch item window resets." } } }, "BatchResponseMeta": { "type": "object", "required": [ "request_id", "cached", "total_items", "successful_items", "failed_items", "request_cost", "rate_limit" ], "properties": { "request_id": { "type": "string" }, "cached": { "type": "boolean" }, "total_items": { "type": "integer" }, "successful_items": { "type": "integer" }, "failed_items": { "type": "integer" }, "request_cost": { "type": "integer", "description": "Number of batch item units reserved before execution." }, "rate_limit": { "$ref": "#/components/schemas/BatchRateLimitMeta" } } }, "BatchTraderItem": { "type": "object", "required": [ "index", "input", "status" ], "properties": { "index": { "type": "integer", "description": "Zero-based request index. Duplicate inputs keep separate result rows." }, "input": { "type": "string" }, "status": { "type": "string", "enum": [ "ok", "error" ] }, "data": { "$ref": "#/components/schemas/Trader" }, "error": { "$ref": "#/components/schemas/ApiErrorBody" } } }, "BatchMarketIntelItem": { "type": "object", "required": [ "index", "input", "status" ], "properties": { "index": { "type": "integer", "description": "Zero-based request index. Duplicate inputs keep separate result rows." }, "input": { "type": "string" }, "status": { "type": "string", "enum": [ "ok", "error" ] }, "data": { "$ref": "#/components/schemas/MarketIntel" }, "error": { "$ref": "#/components/schemas/ApiErrorBody" } } }, "ApiError": { "type": "object", "required": [ "object", "error", "meta" ], "properties": { "object": { "type": "string", "const": "error" }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "bad_request", "invalid_api_key", "subscription_required", "forbidden", "not_found", "account_locked", "rate_limited", "rate_limit_unavailable", "internal_error" ] }, "message": { "type": "string" }, "doc_url": { "type": "string", "nullable": true }, "param": { "type": "string", "nullable": true }, "retry_at": { "type": "string", "format": "date-time", "nullable": true, "description": "The recommended next retry instant (RFC3339). Present on every retryable error (reason=pick_not_released, code=rate_limited, code=rate_limit_unavailable, reason=read_model_warming) and omitted otherwise. Always in the future. For pick_not_released: before the 11:00 UTC operating-window start, before a selected pick's stored release, or after a skipped day, it names the automatic system's next boundary. While no candidate exists in the live window it normally names the persisted next automatic selector attempt (~15m). Every value is advisory under supported operator actions: manual publication, release-time override, or admin generation can make a pick available first. When the automatic schedule is absent/due or a pick is overdue it degrades to ~60s. Schedule one request and do not poll. Prefer Retry-After for the duration because it is immune to client clock skew." }, "reason": { "type": "string", "enum": [ "cursor_expired", "unknown_endpoint", "pick_not_released", "trader_not_tracked", "read_model_warming", "idempotency_in_progress", "webhook_delivery_in_progress" ], "nullable": true, "description": "ADDITIVE (#7209). The specific, actionable cause behind `code`, when there is one more specific than the code itself. `code` keeps its published values, so existing clients are unaffected; new clients branch on `reason`. Omitted when the code already says everything we know. pick_not_released: no Pick of the Day is published for the current product day; schedule one request against retry_at instead of polling. unknown_endpoint: the PATH is not a route on this API -- read GET /api/v1, do not retry. trader_not_tracked: the wallet is real and the URL is right, but the trader is outside the HOT/WARM sync tiers -- stop asking for this wallet. cursor_expired: pagination went stale mid-walk -- re-request the first page and continue. read_model_warming: the requested endpoint cannot serve its read model yet; exact causes are endpoint-specific and can include a cold or contended refresh or a dependency that prevented refresh. idempotency_in_progress: retain the exact Idempotency-Key and request body, then retry shortly. webhook_delivery_in_progress: retry the URL or signing-secret configuration change after the destination's active request completes." } } }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "ReportSnapshot": { "type": "object", "required": [ "kind", "generated_at", "source_range", "snapshot", "completeness", "reconciliation", "report" ], "properties": { "kind": { "type": "string", "enum": [ "daily", "weekly", "monthly" ] }, "generated_at": { "type": "string", "format": "date-time" }, "source_range": { "$ref": "#/components/schemas/ReportSourceRange" }, "snapshot": { "$ref": "#/components/schemas/SnapshotState" }, "completeness": { "$ref": "#/components/schemas/SnapshotCompleteness" }, "reconciliation": { "$ref": "#/components/schemas/ReportReconciliation" }, "report": { "$ref": "#/components/schemas/ReportPayload" } } }, "ReportSourceRange": { "type": "object", "required": [ "start_date", "end_date", "timezone" ], "properties": { "start_date": { "type": "string", "format": "date" }, "end_date": { "type": "string", "format": "date" }, "timezone": { "type": "string", "const": "UTC" } } }, "SnapshotState": { "type": "object", "required": [ "status", "generated_at" ], "properties": { "status": { "type": "string", "enum": [ "final", "rolling" ] }, "generated_at": { "type": "string", "format": "date-time" }, "mutable_until": { "type": "string", "format": "date", "nullable": true } } }, "SnapshotCompleteness": { "type": "object", "required": [ "status", "reason", "expected_days", "covered_days_with_whale_activity" ], "properties": { "status": { "type": "string", "enum": [ "complete", "partial", "empty" ] }, "reason": { "type": "string" }, "expected_days": { "type": "integer" }, "covered_days_with_whale_activity": { "type": "integer" } } }, "ReportReconciliation": { "type": "object", "required": [ "volume_kind", "whale_volume_source", "notes" ], "properties": { "volume_kind": { "type": "string", "const": "local_whale_activity_volume" }, "whale_volume_source": { "type": "string", "const": "whale_alerts.usdc_notional_num" }, "notes": { "type": "string" } } }, "ReportPayload": { "type": "object", "properties": { "total_whale_trades": { "type": "integer", "nullable": true }, "total_whale_volume": { "type": "number", "nullable": true }, "biggest_trade_size": { "type": "number", "nullable": true }, "active_traders": { "type": "integer", "nullable": true }, "top_whale_trades": { "type": "array", "items": { "type": "object", "properties": { "outcome": { "type": "string", "nullable": true, "description": "Provider outcome label for the traded side." }, "side": { "type": "string", "nullable": true, "description": "Trade direction (BUY or SELL), not the outcome side." }, "title": { "type": "string", "nullable": true, "description": "Market title." }, "size": { "type": "number", "nullable": true, "description": "Trade size in USD." }, "price": { "type": "number", "nullable": true, "description": "Trade price in provider [0, 1] units." }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for the traded outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "id": { "type": "integer", "format": "int64", "nullable": true, "description": "Whale trade id." }, "trade_time": { "type": "string", "format": "date-time", "nullable": true, "description": "Trade timestamp (UTC)." }, "market_category": { "type": "string", "nullable": true, "description": "Provider market category." }, "platform": { "type": "string", "nullable": true, "description": "Venue: polymarket or kalshi." }, "name": { "type": "string", "nullable": true, "description": "Trader display name, when known." }, "pseudonym": { "type": "string", "nullable": true, "description": "Trader pseudonym, when no display name is known." }, "trader_grade": { "type": "string", "nullable": true, "description": "Trader grade (S-F) at snapshot time." } } }, "nullable": true }, "categories": { "type": "array", "items": { "type": "object" }, "nullable": true }, "grade_distribution": { "type": "array", "items": { "type": "object" }, "nullable": true } } }, "TraderExportSnapshot": { "type": "object", "required": [ "address", "generated_at", "source_range", "completeness", "reconciliation", "counts", "large_export_policy" ], "properties": { "address": { "type": "string" }, "generated_at": { "type": "string", "format": "date-time" }, "source_range": { "$ref": "#/components/schemas/ExportSourceRange" }, "completeness": { "$ref": "#/components/schemas/ExportCompleteness" }, "reconciliation": { "$ref": "#/components/schemas/ExportVolumeReconciliation" }, "counts": { "$ref": "#/components/schemas/ExportCounts" }, "large_export_policy": { "$ref": "#/components/schemas/LargeExportPolicy" } } }, "ExportSourceRange": { "type": "object", "properties": { "first_pnl_date": { "type": "string", "format": "date", "nullable": true }, "last_pnl_date": { "type": "string", "format": "date", "nullable": true }, "latest_trade_at": { "type": "string", "format": "date-time", "nullable": true }, "latest_market_activity_at": { "type": "string", "format": "date-time", "nullable": true } } }, "ExportCompleteness": { "type": "object", "required": [ "status", "reason", "sync_coverage" ], "properties": { "status": { "type": "string", "enum": [ "complete", "partial", "empty" ] }, "reason": { "type": "string" }, "sync_coverage": { "type": "number", "minimum": 0 } } }, "ExportVolumeReconciliation": { "type": "object", "required": [ "exported_activity_volume", "exported_market_cost_basis" ], "properties": { "provider_lifetime_volume": { "type": "number", "nullable": true }, "exported_activity_volume": { "type": "number" }, "exported_market_cost_basis": { "type": "number" }, "provider_activity_volume_gap": { "type": "number", "nullable": true }, "activity_volume_coverage": { "type": "number", "nullable": true } } }, "ExportCounts": { "type": "object", "required": [ "pnl_days", "exported_markets", "estimated_trade_rows", "estimated_size_mb" ], "properties": { "pnl_days": { "type": "integer" }, "exported_markets": { "type": "integer" }, "estimated_trade_rows": { "type": "integer" }, "estimated_size_mb": { "type": "number" } } }, "TraderExportJob": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "trader_export_job" }, "data": { "type": "object", "required": [ "job_id", "status", "format" ], "properties": { "job_id": { "type": "integer", "format": "int64" }, "status": { "type": "string", "enum": [ "queued", "running", "ready", "failed" ] }, "format": { "type": "string", "enum": [ "json", "ndjson", "csv" ] }, "total_trades": { "type": "integer", "format": "int64", "nullable": true }, "processed_trades": { "type": "integer", "format": "int64", "nullable": true }, "file_size": { "type": "integer", "format": "int64", "nullable": true }, "error": { "type": "string", "nullable": true } } }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "LargeExportPolicy": { "type": "object", "required": [ "mode", "current_internal_route", "v1_async", "direct_streaming", "async_job", "rate_limit" ], "properties": { "mode": { "type": "string", "const": "v1_async_export" }, "current_internal_route": { "type": "string" }, "v1_async": { "type": "object", "description": "Programmatic API-key-gated export routes (submit/status/download) and supported formats (json, ndjson, csv).", "properties": { "submit_route": { "type": "string", "description": "POST route template to submit an export job." }, "status_route": { "type": "string", "description": "GET route template to poll job status." }, "download_route": { "type": "string", "description": "GET route template that 302-redirects to the file." }, "formats": { "type": "array", "items": { "type": "string", "enum": [ "json", "ndjson", "csv" ] }, "description": "Supported ?format= values." }, "status_values": { "type": "array", "items": { "type": "string", "enum": [ "queued", "running", "ready", "failed" ] }, "description": "Possible job status values." }, "retention": { "type": "string", "description": "How long a finished export is retained before expiry." } } }, "direct_streaming": { "type": "object" }, "async_job": { "type": "object" }, "rate_limit": { "type": "object" } } }, "Usage": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "usage" }, "data": { "type": "object", "required": [ "rate_limit", "daily_usage" ], "properties": { "rate_limit": { "type": "object", "required": [ "used", "limit", "remaining", "reset_at", "window_seconds" ], "properties": { "used": { "type": "integer", "example": 7 }, "limit": { "type": "integer", "example": 100 }, "remaining": { "type": "integer", "example": 93 }, "reset_at": { "type": "integer", "example": 1710772860 }, "window_seconds": { "type": "integer", "example": 60 } } }, "daily_usage": { "type": "object", "required": [ "used", "limit", "remaining", "reset_at", "window_seconds" ], "properties": { "used": { "type": "integer", "example": 42 }, "limit": { "type": [ "integer", "null" ], "example": null }, "remaining": { "type": [ "integer", "null" ], "example": null }, "reset_at": { "type": "integer", "example": 1710806400 }, "window_seconds": { "type": "integer", "example": 86400 } }, "description": "UTC-day usage count. Current V1 has no daily hard cap, so limit and remaining are null rather than synthesized." } } }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } }, "LargePosition": { "type": "object", "required": [ "id", "platform", "share_count", "event_leg_count", "first_seen_at", "last_updated_at", "trader", "market" ], "properties": { "id": { "type": "string", "description": "Composite prefixed ID `pos_::`." }, "platform": { "type": "string", "enum": [ "polymarket", "kalshi" ], "description": "Provider discriminator. Always polymarket today (scanner is Polymarket-only); kept in the shape so Kalshi can land without a breaking change." }, "total_size_usd": { "type": "number", "nullable": true, "description": "Aggregate provider currentValue for this position leg in USD." }, "position_unrealized_pnl": { "type": "number", "nullable": true, "description": "Provider per-position unrealized P&L (trader_markets.unrealized_pnl_num, from Polymarket cashPnl)." }, "share_count": { "type": "number", "description": "Live share count for this position." }, "avg_entry_price": { "type": "number", "nullable": true, "description": "Volume-weighted entry price." }, "current_price": { "type": "number", "nullable": true, "description": "Latest provider mark price for the position's token." }, "outcome_label": { "type": "string", "nullable": true, "description": "Backend-resolved outcome label (provider outcome, else Yes/No from the binary index)." }, "token_id": { "type": "string", "nullable": true, "description": "The Polymarket CLOB token id (ERC1155 asset id, decimal string) for this outcome; null when unavailable (e.g. Kalshi markets, unsynced markets)." }, "event_leg_count": { "type": "integer", "description": "Legs collapsed into this representative row for one (wallet, event, outcome side) group. 1 means standalone." }, "event_total_value_usd": { "type": "number", "nullable": true, "description": "Aggregate provider currentValue across collapsed sibling legs; equals total_size_usd when event_leg_count = 1." }, "first_seen_at": { "type": "string", "format": "date-time" }, "last_updated_at": { "type": "string", "format": "date-time" }, "trader": { "type": "object", "required": [ "id", "address" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (`trd_...`)." }, "address": { "type": "string" }, "username": { "type": "string", "nullable": true }, "grade": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ], "nullable": true }, "win_rate": { "type": "number", "nullable": true }, "pnl": { "type": "number", "nullable": true, "description": "Trader lifetime realized P&L across all markets." }, "markets_traded": { "type": "integer", "nullable": true } } }, "market": { "type": "object", "required": [ "id", "condition_id" ], "properties": { "id": { "type": "string", "description": "Prefixed ID (`mkt_...`)." }, "condition_id": { "type": "string" }, "title": { "type": "string", "nullable": true }, "slug": { "type": "string", "nullable": true }, "event_slug": { "type": "string", "nullable": true }, "category": { "type": "string", "nullable": true } } } } }, "TrendingWallet": { "type": "object", "required": [ "id", "address", "rank", "platform", "trending_pnl_usd", "window_volume_usd", "window_markets_traded", "window_trade_days", "daily_pnl_series" ], "properties": { "id": { "type": "string", "description": "Prefixed trader ID (`trd_...`)." }, "address": { "type": "string" }, "rank": { "type": "integer", "description": "1-based rank within the full ranked set (stable across pages)." }, "username": { "type": "string", "nullable": true }, "profile_image_url": { "type": "string", "nullable": true, "description": "Official Polymarket avatar URL (profileImage)." }, "platform": { "type": "string", "enum": [ "polymarket", "kalshi" ], "description": "Real provider platform; surfaced, never coerced. Polymarket-only today." }, "trending_pnl_usd": { "type": "number", "description": "Polymarket weekly/monthly P&L for the wallet in USD, taken from Polymarket's canonical leaderboard (data-api.polymarket.com/v1/leaderboard?timePeriod=week|month&orderBy=PNL). This is the ranking axis and the rows are returned in Polymarket's by-PNL order; it is the provider's number, not a locally summed realized-leaf total." }, "window_volume_usd": { "type": "number" }, "window_markets_traded": { "type": "integer" }, "window_trade_days": { "type": "integer", "description": "Distinct in-window UTC trade days from our trades (0 if the winner is not in our DB)." }, "grade": { "type": "string", "enum": [ "S", "A", "B", "C", "D", "F" ], "description": "All-time trader grade; a separate axis from streak_tier. Led by realized profit (the money actually banked, about 95 percent of the grade), with forecasting calibration, risk-adjusted returns, and consistency as the tie-breaker and proven-trader guardrails: any grade above C requires verified net-positive realized profit, and the top grades also require a real resolved-market track record plus a survivable drawdown. Relative, so it drifts as the cohort moves. Omitted when the trader is Unranked (fewer than 5 markets, insufficient track record to cohort-rank)." }, "streak_tier": { "type": "string", "enum": [ "hot", "rising", "neutral", "cooling", "cold" ], "nullable": true, "description": "Hot-streak tier (trailing-7d cross-sectional percentile). Null when no recent activity." }, "all_time_pnl_usd": { "type": "number", "nullable": true }, "all_time_score": { "type": "number", "nullable": true }, "last_synced": { "type": "string", "format": "date-time", "nullable": true }, "daily_pnl_series": { "type": "array", "description": "Shape-only daily P&L sparkline across the window, derived from Polymarket's user-pnl cumulative curve (user-pnl-api.polymarket.com) converted to per-day deltas. It conveys the trend of the curve only and is NOT guaranteed to sum to trending_pnl_usd, which is the canonical leaderboard total.", "items": { "type": "object", "required": [ "date", "pnl_usd" ], "properties": { "date": { "type": "string", "format": "date" }, "pnl_usd": { "type": "number" } } } } } }, "TraderPnl": { "type": "object", "required": [ "id", "entries", "stats", "monthly", "year_totals", "drawdown" ], "properties": { "id": { "type": "string", "description": "Prefixed trader ID (`trd_...`)." }, "freshness_at": { "type": "string", "format": "date-time", "nullable": true, "description": "RFC3339 served-freshness clock for this trader's PnL history = traders.daily_pnl_recomputed_at, when the daily_pnl read model this response is served from was last rebuilt; null when it has never been recomputed for the trader. Additive optional (not in `required`)." }, "entries": { "type": "array", "description": "Daily cumulative-P&L series (oldest-first).", "items": { "type": "object", "required": [ "date", "daily_change" ], "properties": { "date": { "type": "string", "format": "date" }, "markets_traded": { "type": "integer", "nullable": true }, "total_volume": { "type": "number", "nullable": true }, "cumulative_profit": { "type": "number", "nullable": true }, "total_pnl": { "type": "number", "nullable": true }, "daily_change": { "type": "number" } } } }, "stats": { "type": "object", "required": [ "all", "d90", "d30", "d7" ], "properties": { "all": { "type": "object", "required": [ "current", "change", "change_pct", "best_day", "worst_day", "win_days", "loss_days", "avg_day", "rebase_anchor" ], "properties": { "current": { "type": "number" }, "change": { "type": "number" }, "change_pct": { "type": "number" }, "best_day": { "type": "number" }, "best_day_date": { "type": "string", "format": "date", "nullable": true }, "worst_day": { "type": "number" }, "worst_day_date": { "type": "string", "format": "date", "nullable": true }, "win_days": { "type": "integer" }, "loss_days": { "type": "integer" }, "avg_day": { "type": "number" }, "rebase_anchor": { "type": "number" } } }, "d90": { "type": "object", "required": [ "current", "change", "change_pct", "best_day", "worst_day", "win_days", "loss_days", "avg_day", "rebase_anchor" ], "properties": { "current": { "type": "number" }, "change": { "type": "number" }, "change_pct": { "type": "number" }, "best_day": { "type": "number" }, "best_day_date": { "type": "string", "format": "date", "nullable": true }, "worst_day": { "type": "number" }, "worst_day_date": { "type": "string", "format": "date", "nullable": true }, "win_days": { "type": "integer" }, "loss_days": { "type": "integer" }, "avg_day": { "type": "number" }, "rebase_anchor": { "type": "number" } } }, "d30": { "type": "object", "required": [ "current", "change", "change_pct", "best_day", "worst_day", "win_days", "loss_days", "avg_day", "rebase_anchor" ], "properties": { "current": { "type": "number" }, "change": { "type": "number" }, "change_pct": { "type": "number" }, "best_day": { "type": "number" }, "best_day_date": { "type": "string", "format": "date", "nullable": true }, "worst_day": { "type": "number" }, "worst_day_date": { "type": "string", "format": "date", "nullable": true }, "win_days": { "type": "integer" }, "loss_days": { "type": "integer" }, "avg_day": { "type": "number" }, "rebase_anchor": { "type": "number" } } }, "d7": { "type": "object", "required": [ "current", "change", "change_pct", "best_day", "worst_day", "win_days", "loss_days", "avg_day", "rebase_anchor" ], "properties": { "current": { "type": "number" }, "change": { "type": "number" }, "change_pct": { "type": "number" }, "best_day": { "type": "number" }, "best_day_date": { "type": "string", "format": "date", "nullable": true }, "worst_day": { "type": "number" }, "worst_day_date": { "type": "string", "format": "date", "nullable": true }, "win_days": { "type": "integer" }, "loss_days": { "type": "integer" }, "avg_day": { "type": "number" }, "rebase_anchor": { "type": "number" } } } } }, "monthly": { "type": "array", "description": "Per-month P&L aggregation.", "items": { "type": "object", "required": [ "year", "month", "pnl", "markets_traded" ], "properties": { "year": { "type": "integer" }, "month": { "type": "integer" }, "pnl": { "type": "number" }, "markets_traded": { "type": "integer" } } } }, "year_totals": { "type": "array", "description": "Per-year P&L totals (ascending by year).", "items": { "type": "object", "required": [ "year", "pnl" ], "properties": { "year": { "type": "integer" }, "pnl": { "type": "number" } } } }, "drawdown": { "type": "array", "description": "Underwater (drawdown) series.", "items": { "type": "object", "required": [ "date", "cumulative_profit", "drawdown" ], "properties": { "date": { "type": "string", "format": "date" }, "cumulative_profit": { "type": "number" }, "drawdown": { "type": "number" } } } } } } }, "responses": { "WebhookObject": { "description": "Webhook destination", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "meta" ], "properties": { "object": { "type": "string", "const": "webhook" }, "data": { "$ref": "#/components/schemas/WebhookEndpoint" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } }, "WebhookList": { "description": "Webhook destination list", "content": { "application/json": { "schema": { "type": "object", "required": [ "object", "data", "has_more", "meta" ], "properties": { "object": { "type": "string", "const": "list" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEndpoint" } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": "string", "nullable": true }, "total": { "type": "integer", "nullable": true }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } }, "BadRequest": { "description": "Invalid request parameter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "Unauthorized": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "SubscriptionRequired": { "description": "Active Pro subscription required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "Forbidden": { "description": "Account access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "Locked": { "description": "Account is locked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "NotFound": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "RequestTimeout": { "description": "Request exceeded the server's 30-second transport timeout. The timeout response has an empty body because it is generated before handler-level JSON error shaping." }, "RateLimited": { "description": "Rate limit exceeded. Two independent budgets. (1) 100 requests/minute per user (sliding window), on every authenticated route. (2) On the BATCH routes only: 2500 batch item units/minute per user, reserved before any item is executed. A batch with N requested items costs N item units, including duplicate and invalid items. 2500 = 100 requests x 25 items per batch, which is the most item work a key can buy through the request limiter at all: a caller may spend their entire 100-request minute on full 25-item batches without the item budget being what stops them. The REQUEST budget is the effective ceiling, and batching is never the more expensive choice. The item budget can still deny at a sliding-window boundary (both counters carry the previous window forward with a floor, and the item counter runs 25x the request counter), so honor a 429 from either. Over-quota batches return 429 with Retry-After before any item work is done.", "headers": { "Retry-After": { "description": "Seconds until rate limit resets.", "schema": { "type": "integer" } }, "X-RateLimit-Limit": { "schema": { "type": "integer" } }, "X-RateLimit-Remaining": { "schema": { "type": "integer" } }, "X-RateLimit-Reset": { "schema": { "type": "integer" } }, "X-Request-Id": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "RateLimitUnavailable": { "description": "Redis-backed authenticated rate limiter unavailable; retry after the per-process outage cooldown", "headers": { "Retry-After": { "description": "Seconds until the middleware will probe the Redis-backed rate limiter again.", "schema": { "type": "integer" } }, "X-Request-Id": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "InternalError": { "description": "Unexpected server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "IdempotencyInProgress": { "description": "An Idempotency-Key request with the same body is still in progress. Retry shortly with the same key and body.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" }, "examples": { "in_progress": { "summary": "Idempotency request still in progress", "value": { "object": "error", "error": { "code": "bad_request", "message": "Your previous request is still processing. Retry in a moment.", "param": "Idempotency-Key", "reason": "idempotency_in_progress" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "IdempotencyConflict": { "description": "The Idempotency-Key was already used with a different request body.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" }, "examples": { "different_body": { "summary": "Idempotency key reused with a different body", "value": { "object": "error", "error": { "code": "bad_request", "message": "Idempotency-Key already used with a different request body", "param": "Idempotency-Key" }, "meta": { "request_id": "req_example", "cached": false, "cost": 1 } } } } } } }, "PickNotReleased": { "description": "No Pick of the Day is published for the current product day. This is expected before the selected pick's kickoff-relative release; each selected pick normally releases one hour before kickoff within the 11:00-23:00 UTC operating window, and on a skipped day no pick is published at all. The body carries error.code=\"not_found\" with error.reason=\"pick_not_released\" (branch on the reason -- the code stays \"not_found\" because error.code is a frozen contract) plus error.retry_at (RFC3339, always in the future), and the response sets Retry-After. Schedule against those instead of polling -- polling this window is what makes a schedule look like an outage.", "headers": { "Retry-After": { "description": "Seconds until the recommended next retry. Before the operating-window start, before a selected pick's stored release, or after a skipped day it names the automatic system's next boundary. While no candidate exists it normally names the persisted next automatic selector attempt (~15m). Supported operator actions can make a pick available before any recommendation. An absent/due schedule or overdue pick degrades to ~60s. Always >= 1. Schedule one request (error.retry_at is its absolute RFC3339 twin); do not poll or block a worker thread.", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "ReadModelWarming": { "description": "Service unavailable. On this route a 503 has TWO distinct causes; branch on error.reason. (1) error.reason=\"read_model_warming\": the requested endpoint cannot serve its read model yet. Exact causes are endpoint-specific and can include a cold or contended refresh or a dependency that prevented refresh; consult that endpoint's contract and do not infer dependency health from this shared reason. This is endpoint-local unavailability, not rate limiting: retry only this route after Retry-After (or error.retry_at), and do not feed it into a rate-limit backoff shared with other endpoints. (2) no error.reason: the Redis-backed authenticated rate limiter is unavailable and the middleware failed closed; Retry-After is the seconds until it probes Redis again. Both carry error.code=\"rate_limit_unavailable\" (a FROZEN contract value, so it cannot be split per cause) and X-Request-Id -- which is why error.reason, not error.code, is the discriminator.", "headers": { "Retry-After": { "description": "Seconds until retrying is worth doing. With error.reason=\"read_model_warming\" this is the endpoint-local read-model retry interval; without a reason it is the rate-limiter outage cooldown. Always >= 1.", "schema": { "type": "integer" } }, "X-Request-Id": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "CursorExpired": { "description": "Bad request. On this cursor-paginated route a 400 has TWO distinct causes; branch on error.reason. (1) error.reason=\"cursor_expired\" (with error.param=\"cursor\"): the pagination cursor was invalidated by an upstream data change mid-walk (e.g. the ranking snapshot behind the page refreshed). It is NOT a malformed parameter and NOT a reason to stop: recovery is mechanical -- re-request the first page and walk forward again. There is deliberately no Retry-After and no error.retry_at, because waiting changes nothing. (2) no error.reason: an ordinary invalid request parameter -- check error.param when present, otherwise error.message. Both carry error.code=\"bad_request\" (a FROZEN contract value), so error.reason is the discriminator.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "TraderNotTracked": { "description": "Not found. On this route a 404 has TWO distinct causes; branch on error.reason. (1) error.reason=\"trader_not_tracked\": the wallet is real and the URL is right, but the trader sits outside the HOT/WARM sync tiers, so we capture no timeline for them. This is TERMINAL -- there is no Retry-After and no error.retry_at, because neither retrying nor re-spelling the path will ever succeed. Stop requesting this wallet. (2) no error.reason: the trader id or address does not resolve at all. Both carry error.code=\"not_found\" (a FROZEN contract value), so error.reason is the discriminator -- and since this endpoint has singular and plural path spellings, \"I used the wrong URL\" is a plausible enough wrong guess that the distinction is worth branching on.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "headers": { "X-RateLimit-Limit": { "description": "Authenticated V1 per-user request limit for the current sliding window.", "schema": { "type": "integer", "example": 100 } }, "X-RateLimit-Remaining": { "description": "Authenticated V1 requests remaining in the current sliding window after this response.", "schema": { "type": "integer", "example": 84 } }, "X-RateLimit-Reset": { "description": "Unix timestamp when the authenticated V1 request window resets.", "schema": { "type": "integer", "example": 1710772860 } }, "X-Request-Id": { "description": "Server-generated request identifier for support and tracing.", "schema": { "type": "string", "example": "req_550e8400" } }, "ETag": { "description": "Weak semantic validator for conditional GET. Request-specific response metadata is excluded; send as If-None-Match to receive 304 when the stable payload is unchanged.", "schema": { "type": "string", "example": "W/\"8f14e45fceea167a5a36dedd4bea2543\"" } } } }, "tags": [ { "name": "Traders", "description": "Trader intelligence, batch lookups, timelines, and export readiness." }, { "name": "Positions", "description": "Current prediction-market position snapshots from backend-owned mirrors." }, { "name": "Large Positions", "description": "Largest current open positions from graded traders (Polymarket-only)." }, { "name": "Whale Trades", "description": "Recent and historical large trade intelligence." }, { "name": "Leaderboard", "description": "Ranked trader discovery and category/strategy leaderboards." }, { "name": "Pick of the Day", "description": "One sourced sharp-money call a day: the side proven smart money is backing, with pre-game odds, the proven holders, and the track record." }, { "name": "Markets", "description": "Market search, discovery, snapshots, and smart-score flow." }, { "name": "Insider Radar", "description": "Suspicious trading pattern detection." }, { "name": "Events", "description": "Durable public event replay streams." }, { "name": "Streaming", "description": "Resumable real-time Server-Sent Events stream of live feed envelopes." }, { "name": "Webhooks", "description": "Signed builder webhook destinations and delivery controls." }, { "name": "Usage", "description": "Developer API budget and usage introspection." }, { "name": "System", "description": "Health and operational status checks." }, { "name": "MCP", "description": "Remote Model Context Protocol transport." }, { "name": "Reports", "description": "Daily, weekly, monthly, and trader export report snapshots." } ] }