@0xinsider/mcp 3.14.0 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +30 -10
  2. package/dist/catalog.generated.d.ts +20 -0
  3. package/dist/catalog.generated.d.ts.map +1 -1
  4. package/dist/catalog.generated.js +25 -0
  5. package/dist/catalog.generated.js.map +1 -1
  6. package/dist/client.d.ts +3 -0
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js.map +1 -1
  9. package/dist/constants.d.ts +1 -1
  10. package/dist/constants.js +1 -1
  11. package/dist/product-cli/browser.d.ts +17 -0
  12. package/dist/product-cli/browser.d.ts.map +1 -0
  13. package/dist/product-cli/browser.js +72 -0
  14. package/dist/product-cli/browser.js.map +1 -0
  15. package/dist/product-cli/client.js +2 -2
  16. package/dist/product-cli/index.d.ts.map +1 -1
  17. package/dist/product-cli/index.js +27 -6
  18. package/dist/product-cli/index.js.map +1 -1
  19. package/dist/product-cli/login-prompt.d.ts +18 -0
  20. package/dist/product-cli/login-prompt.d.ts.map +1 -0
  21. package/dist/product-cli/login-prompt.js +56 -0
  22. package/dist/product-cli/login-prompt.js.map +1 -0
  23. package/dist/product-cli/oauth.d.ts +5 -1
  24. package/dist/product-cli/oauth.d.ts.map +1 -1
  25. package/dist/product-cli/oauth.js +42 -4
  26. package/dist/product-cli/oauth.js.map +1 -1
  27. package/dist/product-cli/operations.d.ts +1 -1
  28. package/dist/product-cli/operations.d.ts.map +1 -1
  29. package/dist/product-cli/operations.js +8 -2
  30. package/dist/product-cli/operations.js.map +1 -1
  31. package/dist/sdk/client.d.ts +173 -7
  32. package/dist/sdk/client.d.ts.map +1 -1
  33. package/dist/sdk/client.js +153 -6
  34. package/dist/sdk/client.js.map +1 -1
  35. package/dist/sdk/errors.d.ts +15 -2
  36. package/dist/sdk/errors.d.ts.map +1 -1
  37. package/dist/sdk/errors.js +23 -1
  38. package/dist/sdk/errors.js.map +1 -1
  39. package/dist/sdk/index.d.ts +5 -5
  40. package/dist/sdk/index.d.ts.map +1 -1
  41. package/dist/sdk/index.js +2 -2
  42. package/dist/sdk/index.js.map +1 -1
  43. package/dist/sdk/schema.d.ts +594 -107
  44. package/dist/sdk/schema.d.ts.map +1 -1
  45. package/dist/sdk/stream.d.ts +45 -5
  46. package/dist/sdk/stream.d.ts.map +1 -1
  47. package/dist/sdk/stream.js +52 -4
  48. package/dist/sdk/stream.js.map +1 -1
  49. package/dist/sdk/webhooks.d.ts +19 -6
  50. package/dist/sdk/webhooks.d.ts.map +1 -1
  51. package/dist/sdk/webhooks.js +10 -3
  52. package/dist/sdk/webhooks.js.map +1 -1
  53. package/dist/server.d.ts.map +1 -1
  54. package/dist/server.js +8 -3
  55. package/dist/server.js.map +1 -1
  56. package/dist/tools/games.d.ts +2 -0
  57. package/dist/tools/games.d.ts.map +1 -1
  58. package/dist/tools/games.js +124 -6
  59. package/dist/tools/games.js.map +1 -1
  60. package/dist/tools/get-position-timeline.js +1 -1
  61. package/dist/tools/get-whale-trades.js +2 -2
  62. package/dist/tools/get-whale-trades.js.map +1 -1
  63. package/dist/tools/market-reads.d.ts +2 -0
  64. package/dist/tools/market-reads.d.ts.map +1 -1
  65. package/dist/tools/market-reads.js +68 -0
  66. package/dist/tools/market-reads.js.map +1 -1
  67. package/dist/tools/pick-of-the-day.js +5 -5
  68. package/dist/tools/pick-of-the-day.js.map +1 -1
  69. package/dist/tools/read-parity.js +8 -8
  70. package/dist/tools/read-parity.js.map +1 -1
  71. package/dist/tools/trader-reads.d.ts +1 -0
  72. package/dist/tools/trader-reads.d.ts.map +1 -1
  73. package/dist/tools/trader-reads.js +37 -2
  74. package/dist/tools/trader-reads.js.map +1 -1
  75. package/package.json +2 -2
@@ -96,8 +96,8 @@ export type ApiError = {
96
96
  freshness?: FreshnessFailure;
97
97
  /** Where a person clears this 402 (#32592): pays the overdue invoice (reason payment_overdue) or reactivates the plan (reason subscription_inactive). Present on every 402 subscription_required, omitted on every other error. The message names the same URL; link this field instead of parsing the message. */
98
98
  billing_url?: string;
99
- /** 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 not on the warm sync tier (the wallets we sync most often) -- stop asking for this wallet. market_out_of_scope (404 not_found, #27303): the market or event is real and the URL is right, but 0xinsider serves sports and esports markets only -- stop asking for this market; neither a retry nor another URL for it can succeed. 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. database_unavailable: the API's database or its connection pool is temporarily unreachable (a connection-class failure, not a query fault); code stays rate_limit_unavailable, nothing is rate-limited, retry after Retry-After / retry_at. 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. request_accounting_unavailable: accounting capacity is unavailable before the handler executes; retry after Retry-After / retry_at. sandbox_api_key: the credential is a sandbox key (oxi_sk_test_) from POST /api/v1/agents/register, which only the sandbox server accepts -- call the sandbox base URL with it, or get a live key or OAuth access token; do not retry it here. api_key_in_query: the key was sent as a ?token= query parameter, which no route reads because URLs land in logs and history; the key itself was not checked -- resend it as Authorization: Bearer. subscription_inactive: the key is valid but the account's Pro subscription has lapsed (402 subscription_required); permanent until a person reactivates at https://0xinsider.com/billing, which the message names -- stop retrying on a schedule and surface the link. The key owner is emailed once per lapse. payment_overdue (402 subscription_required, #32592): the key is valid and the account still has its plan, but its latest subscription invoice is unpaid (Stripe past_due or unpaid), so paid access is paused; permanent until a person pays at billing_url (https://0xinsider.com/billing) -- stop retrying on a schedule and surface the link. The key works again the moment the invoice is paid. GET /api/v1/me and GET /api/v1/usage keep answering. monthly_quota_exceeded: the account has used the requests its plan includes for the UTC calendar month (429 rate_limited); retry_at and Retry-After name the first of next month, the only retry that can succeed, and the message names https://0xinsider.com/developers, where pay as you go for requests over the quota is turned on. The X-Monthly-Quota-Limit, X-Monthly-Quota-Remaining and X-Monthly-Quota-Reset headers on every authenticated response say how close the account is. invalid_query, invalid_path, invalid_body (400 bad_request, #16146): a query parameter, a path segment or the JSON body did not parse or does not fit the route's schema, so no handler ran; param names the field when the parser named one (a query key, a path segment, a JSON path such as traders[0], or body); fix the request, never retry it as sent. unsupported_media_type (415 bad_request, param content-type): send the body with Content-Type: application/json. payload_too_large (413 bad_request, param body): the body is over 1048576 bytes. method_not_allowed (405 bad_request): the path is a route but not with this method; the Allow header names the methods it serves. ip_rate_limited (429 rate_limited, #16380): the per-address budget every caller behind one IP shares, counted before authentication, is spent; not the key's own window, and the RateLimit-* headers describe that bucket. ip_throttled (429 rate_limited): the address is in a cooldown after sustained over-limit traffic; Retry-After is minutes to days, and a request before it does not shorten the cooldown. cold_read_limited (429 rate_limited, #28752): the account has used its share of cold reads on GET /api/v1/market/{condition_id}/holders, requests for a market whose roster is not cached, each of which walks Polymarket (6 a minute, in bursts of up to 400); not the per-minute window, so a cached market still answers, and the next cold read is admitted at Retry-After. max_plan_required (403 forbidden, #23085): the key is valid and its account is on Pro, but the route is part of Max (GET /api/v1/edge-hunter); every Pro route keeps working with the same key, so do not disable it. The message names https://0xinsider.com/pricing, where the account upgrades; a retry never clears it. endpoint_retired (410): this legacy sports endpoint no longer serves data. Migrate to GET /api/v1/edge-hunter; retrying the retired path cannot succeed. */
100
- reason?: "cursor_expired" | "unknown_endpoint" | "pick_not_released" | "trader_not_tracked" | "market_out_of_scope" | "read_model_warming" | "database_unavailable" | "request_accounting_unavailable" | "idempotency_in_progress" | "webhook_delivery_in_progress" | "webhook_secret_rotation_not_prepared" | "webhook_secret_rotation_overlap_active" | "sandbox_api_key" | "api_key_in_query" | "subscription_inactive" | "payment_overdue" | "monthly_quota_exceeded" | "invalid_query" | "unknown_query_parameter" | "invalid_path" | "invalid_body" | "unsupported_media_type" | "payload_too_large" | "method_not_allowed" | "ip_rate_limited" | "ip_throttled" | "cold_read_limited" | "export_expired" | "freshness_ceiling_unsatisfied" | "max_plan_required" | "endpoint_retired";
99
+ /** 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 not on the warm sync tier (the wallets we sync most often) -- stop asking for this wallet. market_out_of_scope (404 not_found, #27303): the market or event is real and the URL is right, but 0xinsider serves sports and esports markets only -- stop asking for this market; neither a retry nor another URL for it can succeed. fill_history_too_large (404 not_found, #33245): the wallet and market are tracked, but the position timeline sums every earlier fill into its running totals and this wallet has more than 20,000 fills on the market before the requested page -- stop asking for this pair; neither a retry nor another page can succeed. 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. database_unavailable: the API's database or its connection pool is temporarily unreachable (a connection-class failure, not a query fault); code stays rate_limit_unavailable, nothing is rate-limited, retry after Retry-After / retry_at. 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. request_accounting_unavailable: accounting capacity is unavailable before the handler executes; retry after Retry-After / retry_at. sandbox_api_key: the credential is a sandbox key (oxi_sk_test_) from POST /api/v1/agents/register, which only the sandbox server accepts -- call the sandbox base URL with it, or get a live key or OAuth access token; do not retry it here. api_key_in_query: the key was sent as a ?token= query parameter, which no route reads because URLs land in logs and history; the key itself was not checked -- resend it as Authorization: Bearer. subscription_inactive: the key is valid but the account's Pro subscription has lapsed (402 subscription_required); permanent until a person reactivates at https://0xinsider.com/billing, which the message names -- stop retrying on a schedule and surface the link. The key owner is emailed once per lapse. payment_overdue (402 subscription_required, #32592): the key is valid and the account still has its plan, but its latest subscription invoice is unpaid (Stripe past_due or unpaid), so paid access is paused; permanent until a person pays at billing_url (https://0xinsider.com/billing) -- stop retrying on a schedule and surface the link. The key works again the moment the invoice is paid. GET /api/v1/me and GET /api/v1/usage keep answering. monthly_quota_exceeded: the account has used the requests its plan includes for the UTC calendar month (429 rate_limited); retry_at and Retry-After name the first of next month, the only retry that can succeed, and the message names https://0xinsider.com/developers, where pay as you go for requests over the quota is turned on. The X-Monthly-Quota-Limit, X-Monthly-Quota-Remaining and X-Monthly-Quota-Reset headers on every authenticated response say how close the account is. invalid_query, invalid_path, invalid_body (400 bad_request, #16146): a query parameter, a path segment or the JSON body did not parse or does not fit the route's schema, so no handler ran; param names the field when the parser named one (a query key, a path segment, a JSON path such as traders[0], or body); fix the request, never retry it as sent. unsupported_media_type (415 bad_request, param content-type): send the body with Content-Type: application/json. payload_too_large (413 bad_request, param body): the body is over 1048576 bytes. method_not_allowed (405 bad_request): the path is a route but not with this method; the Allow header names the methods it serves. ip_rate_limited (429 rate_limited, #16380): the per-address budget every caller behind one IP shares, counted before authentication, is spent; not the key's own window, and the RateLimit-* headers describe that bucket. ip_throttled (429 rate_limited): the address is in a cooldown after sustained over-limit traffic; Retry-After is minutes to days, and a request before it does not shorten the cooldown. cold_read_limited (429 rate_limited, #28752): the account has used its share of cold reads on GET /api/v1/market/{condition_id}/holders, requests for a market whose roster is not cached, each of which walks Polymarket (6 a minute, in bursts of up to 400); not the per-minute window, so a cached market still answers, and the next cold read is admitted at Retry-After. max_plan_required (403 forbidden, #23085): the key is valid and its account is on Pro, but the route is part of Max (GET /api/v1/edge-hunter); every Pro route keeps working with the same key, so do not disable it. The message names https://0xinsider.com/pricing, where the account upgrades; a retry never clears it. endpoint_retired (410): this legacy sports endpoint no longer serves data. Migrate to GET /api/v1/edge-hunter; retrying the retired path cannot succeed. */
100
+ reason?: "cursor_expired" | "unknown_endpoint" | "pick_not_released" | "trader_not_tracked" | "market_out_of_scope" | "fill_history_too_large" | "read_model_warming" | "database_unavailable" | "request_accounting_unavailable" | "idempotency_in_progress" | "webhook_delivery_in_progress" | "webhook_secret_rotation_not_prepared" | "webhook_secret_rotation_overlap_active" | "sandbox_api_key" | "api_key_in_query" | "subscription_inactive" | "payment_overdue" | "monthly_quota_exceeded" | "invalid_query" | "unknown_query_parameter" | "invalid_path" | "invalid_body" | "unsupported_media_type" | "payload_too_large" | "method_not_allowed" | "ip_rate_limited" | "ip_throttled" | "cold_read_limited" | "export_expired" | "freshness_ceiling_unsatisfied" | "max_plan_required" | "endpoint_retired";
101
101
  };
102
102
  meta: ResponseMeta;
103
103
  };
@@ -112,8 +112,8 @@ export type ApiErrorBody = {
112
112
  freshness?: FreshnessFailure;
113
113
  /** Where a person clears this 402 (#32592): pays the overdue invoice (reason payment_overdue) or reactivates the plan (reason subscription_inactive). Present on every 402 subscription_required, omitted on every other error. The message names the same URL; link this field instead of parsing the message. */
114
114
  billing_url?: string;
115
- /** 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 not on the warm sync tier (the wallets we sync most often) -- stop asking for this wallet. market_out_of_scope (404 not_found, #27303): the market or event is real and the URL is right, but 0xinsider serves sports and esports markets only -- stop asking for this market; neither a retry nor another URL for it can succeed. 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. database_unavailable: the API's database or its connection pool is temporarily unreachable (a connection-class failure, not a query fault); code stays rate_limit_unavailable, nothing is rate-limited, retry after Retry-After / retry_at. 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. request_accounting_unavailable: accounting capacity is unavailable before the handler executes; retry after Retry-After / retry_at. sandbox_api_key: the credential is a sandbox key (oxi_sk_test_) from POST /api/v1/agents/register, which only the sandbox server accepts -- call the sandbox base URL with it, or get a live key or OAuth access token; do not retry it here. api_key_in_query: the key was sent as a ?token= query parameter, which no route reads because URLs land in logs and history; the key itself was not checked -- resend it as Authorization: Bearer. subscription_inactive: the key is valid but the account's Pro subscription has lapsed (402 subscription_required); permanent until a person reactivates at https://0xinsider.com/billing, which the message names -- stop retrying on a schedule and surface the link. The key owner is emailed once per lapse. payment_overdue (402 subscription_required, #32592): the key is valid and the account still has its plan, but its latest subscription invoice is unpaid (Stripe past_due or unpaid), so paid access is paused; permanent until a person pays at billing_url (https://0xinsider.com/billing) -- stop retrying on a schedule and surface the link. The key works again the moment the invoice is paid. GET /api/v1/me and GET /api/v1/usage keep answering. monthly_quota_exceeded: the account has used the requests its plan includes for the UTC calendar month (429 rate_limited); retry_at and Retry-After name the first of next month, the only retry that can succeed, and the message names https://0xinsider.com/developers, where pay as you go for requests over the quota is turned on. The X-Monthly-Quota-Limit, X-Monthly-Quota-Remaining and X-Monthly-Quota-Reset headers on every authenticated response say how close the account is. invalid_query, invalid_path, invalid_body (400 bad_request, #16146): a query parameter, a path segment or the JSON body did not parse or does not fit the route's schema, so no handler ran; param names the field when the parser named one (a query key, a path segment, a JSON path such as traders[0], or body); fix the request, never retry it as sent. unsupported_media_type (415 bad_request, param content-type): send the body with Content-Type: application/json. payload_too_large (413 bad_request, param body): the body is over 1048576 bytes. method_not_allowed (405 bad_request): the path is a route but not with this method; the Allow header names the methods it serves. ip_rate_limited (429 rate_limited, #16380): the per-address budget every caller behind one IP shares, counted before authentication, is spent; not the key's own window, and the RateLimit-* headers describe that bucket. ip_throttled (429 rate_limited): the address is in a cooldown after sustained over-limit traffic; Retry-After is minutes to days, and a request before it does not shorten the cooldown. cold_read_limited (429 rate_limited, #28752): the account has used its share of cold reads on GET /api/v1/market/{condition_id}/holders, requests for a market whose roster is not cached, each of which walks Polymarket (6 a minute, in bursts of up to 400); not the per-minute window, so a cached market still answers, and the next cold read is admitted at Retry-After. max_plan_required (403 forbidden, #23085): the key is valid and its account is on Pro, but the route is part of Max (GET /api/v1/edge-hunter); every Pro route keeps working with the same key, so do not disable it. The message names https://0xinsider.com/pricing, where the account upgrades; a retry never clears it. endpoint_retired (410): this legacy sports endpoint no longer serves data. Migrate to GET /api/v1/edge-hunter; retrying the retired path cannot succeed. */
116
- reason?: "cursor_expired" | "unknown_endpoint" | "pick_not_released" | "trader_not_tracked" | "market_out_of_scope" | "read_model_warming" | "database_unavailable" | "request_accounting_unavailable" | "idempotency_in_progress" | "webhook_delivery_in_progress" | "webhook_secret_rotation_not_prepared" | "webhook_secret_rotation_overlap_active" | "sandbox_api_key" | "api_key_in_query" | "subscription_inactive" | "payment_overdue" | "monthly_quota_exceeded" | "invalid_query" | "unknown_query_parameter" | "invalid_path" | "invalid_body" | "unsupported_media_type" | "payload_too_large" | "method_not_allowed" | "ip_rate_limited" | "ip_throttled" | "cold_read_limited" | "export_expired" | "freshness_ceiling_unsatisfied" | "max_plan_required" | "endpoint_retired";
115
+ /** 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 not on the warm sync tier (the wallets we sync most often) -- stop asking for this wallet. market_out_of_scope (404 not_found, #27303): the market or event is real and the URL is right, but 0xinsider serves sports and esports markets only -- stop asking for this market; neither a retry nor another URL for it can succeed. fill_history_too_large (404 not_found, #33245): the wallet and market are tracked, but the position timeline sums every earlier fill into its running totals and this wallet has more than 20,000 fills on the market before the requested page -- stop asking for this pair; neither a retry nor another page can succeed. 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. database_unavailable: the API's database or its connection pool is temporarily unreachable (a connection-class failure, not a query fault); code stays rate_limit_unavailable, nothing is rate-limited, retry after Retry-After / retry_at. 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. request_accounting_unavailable: accounting capacity is unavailable before the handler executes; retry after Retry-After / retry_at. sandbox_api_key: the credential is a sandbox key (oxi_sk_test_) from POST /api/v1/agents/register, which only the sandbox server accepts -- call the sandbox base URL with it, or get a live key or OAuth access token; do not retry it here. api_key_in_query: the key was sent as a ?token= query parameter, which no route reads because URLs land in logs and history; the key itself was not checked -- resend it as Authorization: Bearer. subscription_inactive: the key is valid but the account's Pro subscription has lapsed (402 subscription_required); permanent until a person reactivates at https://0xinsider.com/billing, which the message names -- stop retrying on a schedule and surface the link. The key owner is emailed once per lapse. payment_overdue (402 subscription_required, #32592): the key is valid and the account still has its plan, but its latest subscription invoice is unpaid (Stripe past_due or unpaid), so paid access is paused; permanent until a person pays at billing_url (https://0xinsider.com/billing) -- stop retrying on a schedule and surface the link. The key works again the moment the invoice is paid. GET /api/v1/me and GET /api/v1/usage keep answering. monthly_quota_exceeded: the account has used the requests its plan includes for the UTC calendar month (429 rate_limited); retry_at and Retry-After name the first of next month, the only retry that can succeed, and the message names https://0xinsider.com/developers, where pay as you go for requests over the quota is turned on. The X-Monthly-Quota-Limit, X-Monthly-Quota-Remaining and X-Monthly-Quota-Reset headers on every authenticated response say how close the account is. invalid_query, invalid_path, invalid_body (400 bad_request, #16146): a query parameter, a path segment or the JSON body did not parse or does not fit the route's schema, so no handler ran; param names the field when the parser named one (a query key, a path segment, a JSON path such as traders[0], or body); fix the request, never retry it as sent. unsupported_media_type (415 bad_request, param content-type): send the body with Content-Type: application/json. payload_too_large (413 bad_request, param body): the body is over 1048576 bytes. method_not_allowed (405 bad_request): the path is a route but not with this method; the Allow header names the methods it serves. ip_rate_limited (429 rate_limited, #16380): the per-address budget every caller behind one IP shares, counted before authentication, is spent; not the key's own window, and the RateLimit-* headers describe that bucket. ip_throttled (429 rate_limited): the address is in a cooldown after sustained over-limit traffic; Retry-After is minutes to days, and a request before it does not shorten the cooldown. cold_read_limited (429 rate_limited, #28752): the account has used its share of cold reads on GET /api/v1/market/{condition_id}/holders, requests for a market whose roster is not cached, each of which walks Polymarket (6 a minute, in bursts of up to 400); not the per-minute window, so a cached market still answers, and the next cold read is admitted at Retry-After. max_plan_required (403 forbidden, #23085): the key is valid and its account is on Pro, but the route is part of Max (GET /api/v1/edge-hunter); every Pro route keeps working with the same key, so do not disable it. The message names https://0xinsider.com/pricing, where the account upgrades; a retry never clears it. endpoint_retired (410): this legacy sports endpoint no longer serves data. Migrate to GET /api/v1/edge-hunter; retrying the retired path cannot succeed. */
116
+ reason?: "cursor_expired" | "unknown_endpoint" | "pick_not_released" | "trader_not_tracked" | "market_out_of_scope" | "fill_history_too_large" | "read_model_warming" | "database_unavailable" | "request_accounting_unavailable" | "idempotency_in_progress" | "webhook_delivery_in_progress" | "webhook_secret_rotation_not_prepared" | "webhook_secret_rotation_overlap_active" | "sandbox_api_key" | "api_key_in_query" | "subscription_inactive" | "payment_overdue" | "monthly_quota_exceeded" | "invalid_query" | "unknown_query_parameter" | "invalid_path" | "invalid_body" | "unsupported_media_type" | "payload_too_large" | "method_not_allowed" | "ip_rate_limited" | "ip_throttled" | "cold_read_limited" | "export_expired" | "freshness_ceiling_unsatisfied" | "max_plan_required" | "endpoint_retired";
117
117
  };
118
118
  export type BatchGameHoldersItem = {
119
119
  /** Zero-based request index. Duplicate inputs keep separate result rows. */
@@ -123,6 +123,14 @@ export type BatchGameHoldersItem = {
123
123
  data?: GameHoldersItem;
124
124
  error?: ApiErrorBody;
125
125
  };
126
+ export type BatchMarketCloseItem = {
127
+ /** Zero-based request index. Duplicate inputs keep separate result rows. */
128
+ index: number;
129
+ input: string;
130
+ status: "ok" | "error";
131
+ data?: MarketClose;
132
+ error?: ApiErrorBody;
133
+ };
126
134
  export type BatchMarketFlowItem = {
127
135
  /** Zero-based request index. Duplicate inputs keep separate result rows. */
128
136
  index: number;
@@ -489,6 +497,8 @@ export type CreateWebhookRequest = {
489
497
  url: string;
490
498
  event_types: WebhookEventType[];
491
499
  trade_filters?: LargeTradeSubscriptionFilters;
500
+ price_move_filters?: PriceMoveSubscriptionFilters;
501
+ settlement_filters?: SettlementSubscriptionFilters;
492
502
  };
493
503
  export type CreateWebhookVerificationAttemptRequest = {
494
504
  /** The original one-time token returned by webhook creation or a URL change. Sent only in the request body and signed receiver challenge. */
@@ -660,10 +670,12 @@ export type EdgeHunterObservation = {
660
670
  directional_confidence: number | null;
661
671
  /** Recorded side ordering score; higher values sort first. */
662
672
  directional_rank_score: number;
663
- /** 1-based rank within this observation cohort and snapshot. */
673
+ /** 1-based rank within this observation cohort and snapshot: directional_rank_score descending, then conviction_score descending, then category and condition_id. Admission decides which markets a response holds, not their rank, so under admission=most_held_48h or most_held_48h_by_type rank does not follow indexed_graded_holders. */
664
674
  rank: number;
665
675
  /** Required nullable frozen metadata context. Null only during the legacy-generation transition; selected reads require sidecar readiness and fail closed with 503 instead. */
666
676
  market_context: EdgeHunterMarketContext | null;
677
+ /** S, A and B graded wallets in the 0xinsider index holding either outcome of the market, as the stored market universe last counted them. Every most-held place ranks by this count: admission=most_held_48h and most_held_48h_by_type, the default selection's most_held places and in_play slots. It can be larger or smaller than graded_holders, which counts the piled side of the provider's holder page. Null only on a row of a generation computed before this field existed. */
678
+ indexed_graded_holders: number | null;
667
679
  };
668
680
  /** Measured coverage of the frozen canonical observation generation and this requested page. For sports and esports reads, the first four counts remain global through category, cohort and all selectors; with admission=most_held_48h they count that selection's generation, where every wider_holder candidate it did not take is capacity_limited. They are neither a census of all provider markets nor a count of successfully evaluated holders. Selected and returned counts describe the requested projection. An unmappable legacy category synthesizes a zero-work empty generation with all six counts zero and no degradation reasons; it does not read the all-sports cache. */
669
681
  export type EdgeHunterObservationCoverage = {
@@ -1276,7 +1288,7 @@ export type Game = {
1276
1288
  /** Kickoff in UTC, as the provider supplied it. Omitted when the provider published none; coverage.schedule then reads unavailable. */
1277
1289
  scheduled_at?: string;
1278
1290
  status: GameStatus;
1279
- /** Both sides, in the provider's own order. For a team league the provider lists the home side first. Empty when the provider identified neither side. */
1291
+ /** Both sides, in the provider's own order. That order states no home or away: Polymarket lists the away team first in US leagues and the home team first in soccer. Read a market's side for home and away. Empty when the provider identified neither side. */
1280
1292
  competitors: GameCompetitor[];
1281
1293
  /** The esports series length, for example Bo3. Omitted for everything else. */
1282
1294
  series_format?: string;
@@ -1296,7 +1308,7 @@ export type Game = {
1296
1308
  };
1297
1309
  /** One side of the game. */
1298
1310
  export type GameCompetitor = {
1299
- /** The competitor's name as the provider gives it. */
1311
+ /** The team as its moneyline outcome names it, the same before, during and after the game (Jaguars, Penn). Where no outcome names the team, for example a soccer game's Yes/No win markets, the provider's full name (FC Bayern München). To identify a team, prefer provider_id. */
1300
1312
  name: string;
1301
1313
  /** The provider's league-scoped competitor id, as a string. Omitted when the provider has not identified this side; coverage.competitors then reads labels. */
1302
1314
  provider_id?: string;
@@ -1371,7 +1383,7 @@ export type GameMarket = {
1371
1383
  slug?: string;
1372
1384
  /** The provider's own market type, for example moneyline or spread. Omitted when the provider sent none. Not an enum: the provider owns this vocabulary and adds to it. */
1373
1385
  sports_market_type?: string;
1374
- /** Which side of the game this market's YES leg pays. Soccer 1X2 legs are explicitly classified as home, draw or away by the provider projection. draw is a real value, not a competitor. Omitted when the provider projection cannot classify the leg, which is not the same as other. */
1386
+ /** Which side of the game this market's YES leg pays. home and away are the provider's own home/away designation of the team the YES leg names (Polymarket's teams[].ordering), never its place in competitors. Soccer 1X2 legs are explicitly classified as home, draw or away by the provider projection. draw is a real value, not a competitor. Omitted when the provider projection cannot classify the leg or the provider designates neither team home or away, which is not the same as other. */
1375
1387
  side?: "home" | "away" | "draw" | "other";
1376
1388
  /** The provider's label for the YES outcome. Omitted when the provider sent none. */
1377
1389
  outcome_yes?: string;
@@ -1383,7 +1395,7 @@ export type GameMarket = {
1383
1395
  prices?: GameMarketPrices;
1384
1396
  /** Polymarket's reported liquidity for this market. Omitted when the provider read carried none, and on a finished game read from its stored record; never 0 in place of a missing figure. */
1385
1397
  liquidity?: GameMarketLiquidity;
1386
- /** How Polymarket's oracle settled or is settling this market, the block GET /api/v1/games/{event_slug}/markets serves, from the same per-game store. Always present on GET /api/v1/games/{event_slug}; on GET /api/v1/games only with expand=settlement. It never waits for Polymarket: a game not read lately reads status unavailable while its read starts. */
1398
+ /** How Polymarket's oracle settled or is settling this market, the block GET /api/v1/games/{event_slug}/markets serves, from the same per-game store. Always present on GET /api/v1/games/{event_slug}; on GET /api/v1/games only with expand=settlement. It never waits for Polymarket: a settled market reads its recorded settlement on the first read, and any other market of a game not read lately reads status unavailable while its read starts. */
1387
1399
  settlement?: {
1388
1400
  expected_settlement_time: string | null;
1389
1401
  observed_at: string | null;
@@ -1397,6 +1409,7 @@ export type GameMarket = {
1397
1409
  status: "observed" | "not_posed" | "unavailable";
1398
1410
  was_disputed: boolean | null;
1399
1411
  winning_outcome_index: number | null;
1412
+ oracle_updated_at: string | null;
1400
1413
  };
1401
1414
  };
1402
1415
  /** One market's liquidity as Polymarket reports it (Gamma liquidityNum), verbatim. Polymarket documents it only as reported market liquidity, with no unit. It describes the market's resting order book, not traded volume. */
@@ -1485,7 +1498,8 @@ export type GameSharpMoney = {
1485
1498
  is_leader: boolean;
1486
1499
  label: string;
1487
1500
  pct: number;
1488
- side: "home" | "draw" | "away";
1501
+ /** The side the provider designates this outcome's team: home or away, by Polymarket's own home/away designation (teams[].ordering), never the outcome's place in this list; draw for a 1X2 draw. null when the provider designates neither team home or away; never inferred from order. */
1502
+ side: "home" | "draw" | "away" | null;
1489
1503
  usd: number;
1490
1504
  wallets: {
1491
1505
  a: number;
@@ -1536,6 +1550,10 @@ export type GameStatus = {
1536
1550
  live?: boolean;
1537
1551
  /** Whether the game is over. Always present. */
1538
1552
  ended: boolean;
1553
+ /** When the game ended (RFC 3339 UTC), as first observed. Always present. It is null unless state is ended and an end was observed. It is never inferred from the kickoff, the clock or the market's resolution. Null on an ended game means the end time is unknown, and games that ended before this field shipped carry null. ended_at_source names who observed it. */
1554
+ ended_at: string | null;
1555
+ /** Who observed ended_at. Always present, and null exactly when ended_at is null. sports_ws: the first Polymarket Sports WebSocket frame that reported the game final, at the time it was received. gamma_finished: for a game no such frame ended, Polymarket's own event finish time, served only when it is earlier than the market's resolution and never for a fight card (MMA, boxing). */
1556
+ ended_at_source: "sports_ws" | "gamma_finished" | null;
1539
1557
  };
1540
1558
  /** The tennis tournament edition a game belongs to, curated from official ATP, WTA and ITF pages (source_urls), never from Polymarket, which supplies the competition label and tour only. Selected by the game's provider competition label, the one tour both players carry, and the kickoff's day at the venue. A fact no official page states is omitted. */
1541
1559
  export type GameTournament = {
@@ -1799,6 +1817,27 @@ export type LargeTrade = {
1799
1817
  /** Provider-backed market_canonical category. */
1800
1818
  category?: string;
1801
1819
  };
1820
+ /** Closing line value against the market's stored close (GET /api/v1/market/{condition_id}/close). Always present; status says whether it is measured. */
1821
+ clv: {
1822
+ /** The CLV definition, clv@v1. */
1823
+ basis_version: string;
1824
+ /** The anchor pre_kickoff was judged against: the stored close's anchor, else the market's kickoff. */
1825
+ close_anchor_at: string | null;
1826
+ /** The traded outcome's closing price, 0 to 1, whenever a usable close is stored and the outcome is known, in play included. */
1827
+ close_price: number | null;
1828
+ /** Cents per share, positive when the trade beat the close: buy is (close_price - price) * 100, sell is (price - close_price) * 100. Gross of fees. Computed from the trade's exact stored price; price on the wire is rounded to 4 places, so a recomputation from it agrees within 0.005 cents. Set exactly when status is measured. */
1829
+ clv_cents: number | null;
1830
+ /** Whether the trade filled before close_anchor_at. null when the market has no anchor. */
1831
+ pre_kickoff: boolean | null;
1832
+ /** measured: clv_cents is set. in_play: traded at or after the close anchor (kickoff), no CLV is defined. pending: traded before kickoff and the market's close is not stored yet. unavailable: see unavailable_reason. */
1833
+ status: "measured" | "in_play" | "pending" | "unavailable";
1834
+ /** Set exactly when status is unavailable. The market's reasons (see MarketClose.unavailable_reason), plus anchor_stale (the kickoff moved after the close was captured) and outcome_unknown (the traded outcome is not known for this trade). */
1835
+ unavailable_reason: "no_observation_in_lookback" | "provider_empty_window" | "provider_invalid_contract" | "capture_window_closed" | "no_game_start_time" | "not_one_sided_resolution" | "not_captured" | "close_token_mismatch" | "anchor_stale" | "outcome_unknown" | null;
1836
+ /** clv_cents - taker_fee_cents: the CLV after the fee the fill paid, cents per share. Set exactly when both are set. */
1837
+ clv_after_fees_cents: number | null;
1838
+ /** The fee the fill paid as taker, cents per share, from the exchange's on-chain record of the fill (the OrderFilled event in its Polygon receipt); the trader is its taker. Polymarket charges only takers, so a buy's fee adds to its cost and a sell's comes out of its proceeds, and either way it lowers the CLV by this amount. Includes any builder fee an app added; excludes maker and taker rebates, which Polymarket pays later and no fill records. Set whatever status is; null until the record is decoded (about a minute after the trade) and for trades before 2026-08-16. */
1839
+ taker_fee_cents: number | null;
1840
+ };
1802
1841
  };
1803
1842
  export type LargeTradeDetail = LargeTrade & {
1804
1843
  counterparty_analysis: CounterpartyAnalysis;
@@ -2017,6 +2056,48 @@ export type MarketCandles = {
2017
2056
  /** One entry per present provider token (YES first, then NO); empty when no tokens have been fetched yet. */
2018
2057
  outcomes: OutcomeCandles[];
2019
2058
  };
2059
+ /** A market's stored closing line (#32517): Polymarket's price-history value for the last minute bucket ending at or before kickoff, read once after settlement and never recomputed. */
2060
+ export type MarketClose = {
2061
+ /** true when game_start_time has moved more than lookback_seconds from close_anchor_at since capture; large trades on the market then carry no CLV. null without a stored row. */
2062
+ anchor_stale: boolean | null;
2063
+ /** Provider response contract version the value was read under. */
2064
+ basis_version: string | null;
2065
+ /** When the close was stored. Bookkeeping only. */
2066
+ captured_at: string | null;
2067
+ /** The instant the close was measured at: the kickoff when it was captured. Write-once; null when no close row is stored. */
2068
+ close_anchor_at: string | null;
2069
+ /** The field that supplied close_anchor_at, markets.game_start_time. */
2070
+ close_anchor_source: string | null;
2071
+ /** Polymarket condition id. */
2072
+ condition_id: string;
2073
+ /** The market's kickoff as stored now. */
2074
+ game_start_time: string | null;
2075
+ /** How far before the anchor the admitted bucket may start: 21600 (6 hours). */
2076
+ lookback_seconds: number | null;
2077
+ /** Bucket width: 60 (minute grain) or 3600 (hour grain, for a market read more than about six days after kickoff). */
2078
+ observation_window_seconds: number | null;
2079
+ /** Start of the provider bucket the close is. The bucket ends at observed_at + observation_window_seconds, at or before close_anchor_at. */
2080
+ observed_at: string | null;
2081
+ /** YES then NO when status is measured; empty otherwise. */
2082
+ outcomes: ({
2083
+ /** Closing price, 0 to 1, at full stored precision. */
2084
+ close_price: number;
2085
+ /** true on the NO leg: 1 minus the stored YES price, never a second read. */
2086
+ derived_from_yes: boolean;
2087
+ /** The outcome's label. */
2088
+ outcome: string | null;
2089
+ /** 0 is the YES leg, 1 the NO leg. */
2090
+ outcome_index: number;
2091
+ /** CLOB token id of the outcome. */
2092
+ token_id: string | null;
2093
+ })[];
2094
+ /** Provider endpoint and grain, e.g. polymarket_data_v2_prices_history@minute-window-v1. */
2095
+ price_source: string | null;
2096
+ /** measured: outcomes carries the close. pending: no close is stored yet and the capture will still read the market. unavailable: no close will be served; see unavailable_reason. */
2097
+ status: "measured" | "pending" | "unavailable";
2098
+ /** Set exactly when status is unavailable. no_observation_in_lookback, provider_empty_window, provider_invalid_contract and capture_window_closed are the capture's own stored refusals; no_game_start_time: the market has no kickoff time; not_one_sided_resolution: it resolved to neither side; not_captured: the capture does not read it (no tracked buy before resolution, or kickoff over 30 days ago); close_token_mismatch: the close was read on a different YES token than the market carries now. */
2099
+ unavailable_reason: "no_observation_in_lookback" | "provider_empty_window" | "provider_invalid_contract" | "capture_window_closed" | "no_game_start_time" | "not_one_sided_resolution" | "not_captured" | "close_token_mismatch" | "anchor_stale" | "outcome_unknown" | null;
2100
+ };
2020
2101
  export type MarketFlow = {
2021
2102
  market: {
2022
2103
  id: string;
@@ -2127,7 +2208,7 @@ export type MarketHolder = {
2127
2208
  /** Why `category_win_rate` is present or absent: `measured` (rate present), `not_enough_data` (under the floor of 5 decided markets in the category), or `unavailable` (the market has no canonical category, or the read failed; retry later). Never `untracked`: this route lists S, A and B wallets only, all on file. Always present on this route. */
2128
2209
  category_win_rate_status: "measured" | "not_enough_data" | "unavailable" | "untracked";
2129
2210
  category_evidence?: HolderCategoryEvidence;
2130
- /** Whole days since this wallet's first trade, rounded down (3.6 days reads 3), so it changes once a day, not on every request. The five badge fields are present together, only for a wallet that draws at least one badge. */
2211
+ /** Whole UTC calendar days since this wallet's first trade: the number of UTC dates from the first trade's date to today, so a first trade at 23:00 UTC reads 1 an hour later. Every wallet's age changes at 00:00 UTC, once a day, not on every request. The five badge fields are present together, only for a wallet that draws at least one badge. */
2131
2212
  wallet_age_days?: number | null;
2132
2213
  /** True when the wallet's first trade was under 30 days ago. */
2133
2214
  is_new_wallet?: boolean;
@@ -2198,6 +2279,62 @@ export type MarketHoldersTotals = {
2198
2279
  /** no_usd split by grade: where the S, A and B money on NO sits. */
2199
2280
  no_grade_usd: MarketHoldersSideGradeUsd;
2200
2281
  };
2282
+ /** `market_price_moved` data, also the MarketPriceMoved frame on GET /api/v1/stream: a sports or esports market's outcome-0 midpoint moved a whole-cent level over one window. Prices are decimal strings at full precision. A missing value is null with its *_unavailable_reason. */
2283
+ export type MarketPriceMovedData = {
2284
+ best_ask: string;
2285
+ best_bid: string;
2286
+ concurrent_sharp_flow: {
2287
+ detected: boolean;
2288
+ grade_floor: "S" | "A" | "B" | "C" | "D" | "F";
2289
+ net_flow_usd: number;
2290
+ ranked_large_trades: number;
2291
+ /** Large trades on the market in the same window at any grade, ungraded wallets included. ranked_large_trades is the part of them at grade_floor or better. */
2292
+ large_trades_in_window: number | null;
2293
+ } | null;
2294
+ concurrent_sharp_flow_unavailable_reason: "read_failed" | null;
2295
+ condition_id: string;
2296
+ detected_at: string;
2297
+ direction: "up" | "down";
2298
+ event_slug: string | null;
2299
+ from_price: string;
2300
+ game_state: {
2301
+ clock: string | null;
2302
+ ended: boolean;
2303
+ live: boolean | null;
2304
+ period: string | null;
2305
+ scores: LiveSportsScoreEntry[];
2306
+ status: string | null;
2307
+ updated_at: string;
2308
+ } | null;
2309
+ game_state_unavailable_reason: "no_event_slug" | "no_game_state" | "read_failed" | null;
2310
+ gap_before: boolean;
2311
+ label: string | null;
2312
+ league: string | null;
2313
+ level_cents: number;
2314
+ market_slug: string | null;
2315
+ move_cents: string;
2316
+ observed_at: string | null;
2317
+ outcome_index: number;
2318
+ /** Where the game stood at detected_at. in_play: its live state reports it live. pre_game: its live state is neither live nor ended, or it has no live state yet and the market's scheduled start (the games endpoints' scheduled_at) is after detected_at. unknown: neither holds or the live state could not be read; game_state_unavailable_reason says why. */
2319
+ phase: "pre_game" | "in_play" | "unknown";
2320
+ previous_level_cents: number;
2321
+ source: string;
2322
+ spread_cents: string;
2323
+ to_price: string;
2324
+ window_seconds: number;
2325
+ window_start: string;
2326
+ /** Why book_depth_within_2c is null, and null when it is present. no_book: no full order book has arrived for the market since tracking began, only quotes. book_changed: the best bid or ask moved after the latest full book, so its depth belongs to another top. band_not_covered: the latest full book shows no level beyond 2 cents from the midpoint on at least one side, so that side's sum could be cut short. */
2327
+ book_depth_unavailable_reason: "no_book" | "book_changed" | "band_not_covered" | null;
2328
+ /** USD resting within 2 cents of outcome 0's midpoint on each side at detected_at, or null with book_depth_unavailable_reason. */
2329
+ book_depth_within_2c: {
2330
+ /** USD resting on asks priced at or below the midpoint plus 0.02 (price times size), as a decimal string. */
2331
+ ask_usd: string;
2332
+ /** USD resting on bids priced at or above the midpoint minus 0.02 (price times size), as a decimal string. */
2333
+ bid_usd: string;
2334
+ /** When we received the full order book the sums come from. Its best bid and ask are the event's best_bid and best_ask; deeper levels may have changed since. */
2335
+ book_observed_at: string;
2336
+ } | null;
2337
+ };
2201
2338
  export type MarketSearchResult = {
2202
2339
  id: string;
2203
2340
  condition_id: string;
@@ -2210,6 +2347,41 @@ export type MarketSearchResult = {
2210
2347
  status: "active" | "closed";
2211
2348
  event_slug?: string;
2212
2349
  };
2350
+ /** `market_settled` data, also the MarketSettled frame on GET /api/v1/stream: a sports or esports game market settled, sent once per settled state the first time 0xinsider records it. A market can settle in more than one state: a resolved UMA question row with no winner yet, the same row with the winner ConditionalTokens paid on chain, and the condition row with the provider's payouts; each is its own event with its own settlement_id, except a state naming the winner an earlier event named, which is not sent. */
2351
+ export type MarketSettledData = {
2352
+ /** Polymarket condition ID of the market, lowercase. */
2353
+ condition_id: string;
2354
+ /** The recorded state: one per market per settled state, never reused. Deduplicate on it, or on the event id. */
2355
+ settlement_id: number;
2356
+ /** Polymarket event (game) slug, or null when the market stores none. */
2357
+ event_slug: string | null;
2358
+ /** Polymarket game ID for the event as a string, the game_id of GET /api/v1/games, or null when the market stores none. */
2359
+ game_id: string | null;
2360
+ /** The event slug league prefix (nba in nba-lal-gsw-2026-11-01), lowercase, read after a polyv2 copy prefix. A PGA Tour golf slug starts with the year, so its markets are pga, from their series. null when neither names a league. */
2361
+ league: string | null;
2362
+ /** Polymarket sportsMarketType of the market (moneyline, spreads, totals, a prop type) verbatim, or null when the market stores none. */
2363
+ sports_market_type: string | null;
2364
+ /** Outcome names, each at its outcome index: settlement.payouts and settlement.winning_outcome_index index into it. Empty when the market stores none; an outcome Polymarket labels blank is an empty string. */
2365
+ outcomes: string[];
2366
+ /** Set on a Polymarket polyv2 copy of a game whose original event has a moneyline market: the original event slug, which GET /api/v1/games serves. Such a copy reaches a webhook only when its settlement_filters name its condition ID or its own event slug. */
2367
+ copy_of_event_slug: string | null;
2368
+ /** The settled state, the block GET /api/v1/games/{event_slug}/markets serves as settlement: status observed, oracle_status resolved, settled true. payouts is null on a resolved UMA question row, whose result and winning_outcome_index come from the payout ConditionalTokens reported on chain (null in an event sent before it paid), and set on the condition row that follows, sent as its own event unless it names a winner already sent. observed_at is when 0xinsider first saw this state. */
2369
+ settlement: {
2370
+ expected_settlement_time: string | null;
2371
+ observed_at: string | null;
2372
+ oracle_status: string | null;
2373
+ payouts: number[] | null;
2374
+ proposed_answer: "outcome_0" | "outcome_1" | "split" | "too_early" | null;
2375
+ resolved_at: string | null;
2376
+ result: "outcome" | "split" | null;
2377
+ settled: boolean | null;
2378
+ settlement_time_basis: string | null;
2379
+ status: "observed" | "not_posed" | "unavailable";
2380
+ was_disputed: boolean | null;
2381
+ winning_outcome_index: number | null;
2382
+ oracle_updated_at: string | null;
2383
+ };
2384
+ };
2213
2385
  export type MarketSnapshot = {
2214
2386
  market: {
2215
2387
  id: string;
@@ -2265,7 +2437,7 @@ export type MarketSnapshot = {
2265
2437
  source: string;
2266
2438
  live_match_key?: string;
2267
2439
  live_league_key?: string;
2268
- /** Live-score period and elapsed may be omitted when unavailable (older responses use null). A score entry may omit full_name when it equals team; fall back to team. Distinct aliases and score admission markers are preserved. For live esports, scores[].map_score retains an available pair through an update omitting both sides only within the same live map, series format and series totals. Map changes and final state follow current provider updates; absent detail remains unavailable. Optional tennis_points supplies independently sourced current-game points and serving side; absence means unavailable. Compatible unexpired tennis_points survives temporary supplemental snapshot unavailability or contention; expiry and set/game mismatch still clear it. */
2440
+ /** Live-score period and elapsed may be omitted when unavailable (older responses use null). A score entry may omit full_name when it equals team; fall back to team. A score entry's side (home or away) is the provider's home/away designation of that team, omitted when the provider gives none; the order of scores states no side. Distinct aliases and score admission markers are preserved. For live esports, scores[].map_score retains an available pair through an update omitting both sides only within the same live map, series format and series totals. Map changes and final state follow current provider updates; absent detail remains unavailable. Optional tennis_points supplies independently sourced current-game points and serving side; absence means unavailable. Compatible unexpired tennis_points survives temporary supplemental snapshot unavailability or contention; expiry and set/game mismatch still clear it. */
2269
2441
  live_score?: Record<string, unknown> & {
2270
2442
  tennis_points?: TennisPoints;
2271
2443
  };
@@ -2279,7 +2451,7 @@ export type MarketSnapshot = {
2279
2451
  };
2280
2452
  /** Price and spread trust metadata. Present only when expand=trust or expand[]=trust is requested. */
2281
2453
  trust?: MarketSnapshotTrust;
2282
- /** How Polymarket's oracle settled or is settling this market, the block GET /api/v1/games/{event_slug}/markets serves, read from the store of the market's event (a child event's market: its game's). It never waits for Polymarket: with nothing stored it reads status unavailable while the read starts. market.market_result stays null; read settlement.result. */
2454
+ /** How Polymarket's oracle settled or is settling this market, the block GET /api/v1/games/{event_slug}/markets serves, read from the store of the market's event (a child event's market: its game's). It never waits for Polymarket: with nothing stored a settled market reads its recorded settlement, and any other reads status unavailable while the read starts. market.market_result stays null; read settlement.result. */
2283
2455
  settlement: {
2284
2456
  expected_settlement_time: string | null;
2285
2457
  observed_at: string | null;
@@ -2293,6 +2465,7 @@ export type MarketSnapshot = {
2293
2465
  status: "observed" | "not_posed" | "unavailable";
2294
2466
  was_disputed: boolean | null;
2295
2467
  winning_outcome_index: number | null;
2468
+ oracle_updated_at: string | null;
2296
2469
  };
2297
2470
  };
2298
2471
  export type MarketSnapshotFreshness = {
@@ -2309,7 +2482,9 @@ export type MarketSnapshotTopOfBook = {
2309
2482
  best_bid?: number;
2310
2483
  best_ask?: number;
2311
2484
  spread_bps?: number;
2485
+ /** USD (price times size) on bids at or above the midpoint minus 0.02, from the whole book, rounded to the cent. The props filter min_book_usd_within_2c compares the unrounded sums, which expand=quotes serves as book_depth_within_2c. Absent when we hold no depth for the book. */
2312
2486
  bid_depth_usdc?: number;
2487
+ /** USD (price times size) on asks at or below the midpoint plus 0.02, from the whole book, rounded to the cent. The props filter min_book_usd_within_2c compares the unrounded sums, which expand=quotes serves as book_depth_within_2c. Absent when we hold no depth for the book. */
2313
2488
  ask_depth_usdc?: number;
2314
2489
  reason?: string;
2315
2490
  };
@@ -2366,7 +2541,7 @@ export type MarketTopHolder = {
2366
2541
  category_win_rate_game?: string;
2367
2542
  /** Why `category_win_rate` is present or absent: `measured` (rate present), `not_enough_data` (the wallet is on file and under the floor of 5 decided markets in the category), `untracked` (0xinsider has no record of the wallet, so nothing was measured; `grade`, `in_scope_realized_pnl` and `in_scope_volume` are null too), or `unavailable` (a read failed; retry later). Absent when the market has no canonical category. */
2368
2543
  category_win_rate_status?: "measured" | "not_enough_data" | "unavailable" | "untracked";
2369
- /** Whole days since this wallet's first trade, rounded down (3.6 days reads 3), so it changes once a day, not on every request. The five badge fields are present together, only for a wallet that draws at least one badge. */
2544
+ /** Whole UTC calendar days since this wallet's first trade: the number of UTC dates from the first trade's date to today, so a first trade at 23:00 UTC reads 1 an hour later. Every wallet's age changes at 00:00 UTC, once a day, not on every request. The five badge fields are present together, only for a wallet that draws at least one badge. */
2370
2545
  wallet_age_days?: number | null;
2371
2546
  /** True when the wallet's first trade was under 30 days ago. */
2372
2547
  is_new_wallet?: boolean;
@@ -2407,6 +2582,33 @@ export type MarketTopHoldersTotals = {
2407
2582
  /** The most holders the sample keeps per outcome (100). */
2408
2583
  sample_cap: number;
2409
2584
  };
2585
+ /** One taker fill of 100 USD or more on a market, from the exchange's on-chain fill events. */
2586
+ export type MarketTrade = {
2587
+ /** {transaction_hash}:{log_index}: one fill event, listed once. Deduplicate on it across reads. */
2588
+ id: string;
2589
+ /** The fill's block time, to the second. */
2590
+ traded_at: string;
2591
+ /** The taker's side: BUY took outcome shares, SELL gave them. */
2592
+ side: "BUY" | "SELL";
2593
+ /** The traded outcome's label; null when the market names none. */
2594
+ outcome: string | null;
2595
+ /** 0 for the first (Yes) outcome token, 1 for the second (No). */
2596
+ outcome_index: number;
2597
+ /** The traded outcome token's id (decimal string); null when the market holds none for that outcome. */
2598
+ token_id: string | null;
2599
+ /** Fill price per share, 0 to 1. */
2600
+ price: number;
2601
+ /** Outcome shares filled. */
2602
+ shares: number;
2603
+ /** USDC notional of the fill. */
2604
+ size_usd: number;
2605
+ /** The taker's wallet, lowercase. */
2606
+ taker: string;
2607
+ /** The fill's transaction, lowercase 0x hex. */
2608
+ transaction_hash: string;
2609
+ /** The fill event's log index in its transaction. */
2610
+ log_index: number;
2611
+ };
2410
2612
  /** One market's net buyers and net sellers over a 24h or 7d window, as the market page's wallets in/out panel shows a Pro viewer. */
2411
2613
  export type MarketWalletsInOut = {
2412
2614
  /** The market's raw provider condition id. */
@@ -2482,7 +2684,7 @@ export type PickHolder = {
2482
2684
  name: string | null;
2483
2685
  /** All-time trader grade (S, A, B, C, D, F). */
2484
2686
  grade: string | null;
2485
- /** The wallet's most recent recorded trade time, stamped at serve time from its current trader record rather than frozen with the pick. Always sent; null when no trade time is recorded. */
2687
+ /** The UTC day of the wallet's most recent recorded trade, served as that day's 00:00:00Z, stamped at serve time from its current trader record rather than frozen with the pick. It changes at most once a day per wallet, so the pick's ETag holds between polls. Always sent; null when no trade time is recorded. */
2486
2688
  last_traded_at: string | null;
2487
2689
  /** 0xinsider profile path segment this wallet links to: `@<username>` when that username resolves to this wallet alone, otherwise the lowercase wallet. Percent-encode the part after `@` and append to `https://0xinsider.com/profile/`. Stamped at serve time; absent on a body cached before the field shipped. */
2488
2690
  profile_segment?: string;
@@ -2498,13 +2700,15 @@ export type PickHolder = {
2498
2700
  /** Settled markets in the category that this wallet closed with a profit or a loss. A market resolved at zero realized P&L is in neither count. */
2499
2701
  decided: number;
2500
2702
  };
2501
- /** The wallet's average entry price in the pick's canonical category, as a 0..1 fraction of $1 (0.98 is 98 cents). Its sample is the wallet's markets in that category that resolved to a winning side, of $20 or more where it bought one side at a known price, so it can differ from the `category_win_record` sample. A wallet that buys near-certain outcomes wins almost every time, so read the win rate beside this price. Present only with `category_win_rate_status` = `measured`, and only when that sample has at least 5 markets. When `category_win_rate_game` is present the price is still the whole `category` bucket's: this field has no per-game or per-league price. Absent otherwise and on payloads predating the field. */
2703
+ /** The wallet's average entry price in the pick's canonical category, as a 0..1 fraction of $1 (0.98 is 98 cents). Its sample is the wallet's markets in that category that resolved to a winning side, of $20 or more where it bought one side at a known price, so it can differ from the `category_win_record` sample. A wallet that buys near-certain outcomes wins almost every time, so read the win rate beside this price. Present only with `category_win_rate_status` = `measured`, and only when that sample has at least 5 markets. When `category_win_rate_game` is present the price is still the whole `category` bucket's; the game's or league's own price is `category_scope_avg_price`. Absent otherwise and on payloads predating the field. */
2502
2704
  category_avg_price?: number;
2705
+ /** The wallet's average entry price in the game or league `category_win_rate_game` names, as a 0..1 fraction of $1: `category_avg_price` over that game's or league's markets only, under the same sample rules and the same 5-market floor. Read `category_win_rate` against this price when both are present; the difference is the wallet's edge there. Present only beside `category_win_rate_game`, and only when that sample clears the floor; recomputed at serve time, not frozen with the pick. Absent otherwise and on payloads predating the field. */
2706
+ category_scope_avg_price?: number;
2503
2707
  /** Where `category_win_rate` and `category_win_record` were measured, by the same name the pick's `display_category` uses for it: for an esports pick the game (`LoL`, `CS2`, `Dota 2`, `Valorant`, `Call of Duty`, `Honor of Kings`, `Mobile Legends: Bang Bang`, `Overwatch`, `Rainbow Six Siege`, `Rocket League` or `StarCraft II`), and for a pick in a registered league that league (`NBA`, `NFL`, `NHL`, `MLB`, `UFC`, `ATP`, `WTA`, `LaLiga`, `Premier League`, `Serie A`, `UEFA Champions League`, `MLS` and the other registered leagues). Present only when the wallet's record there clears the 5-settled-market floor, in which case the rate and record are the game's or league's rather than the whole `category` bucket's. Absent when the rate is the bucket's (the wallet's history there is under the floor, or the competition is not a registered league), on every other pick, beside every non-measured status, and on payloads predating the field. Label the rate with this when present and with `category` otherwise. */
2504
2708
  category_win_rate_game?: string;
2505
2709
  /** Why `category_win_rate` is present or absent on a `display_holders` entry: `measured` (rate present), `not_enough_data` (the wallet is below the settled-market floor of 5 in the category), or `unavailable` (the annotation read failed; retry later). Never `untracked`: every recorded holder is a graded wallet 0xinsider has on file. Absent entirely on `holders` entries, legacy rows, and payloads predating the field -- absence means the roster was never annotated, not a small sample. */
2506
2710
  category_win_rate_status?: "measured" | "not_enough_data" | "unavailable" | "untracked";
2507
- /** Whole days since this wallet's first trade, rounded down (3.6 days reads 3), so it changes once a day, not on every request, and the pick's ETag holds between requests. Stamped at serve time from the wallet's current trader record, never frozen with the pick. The five badge fields are present together, and only for a wallet that carries at least one badge; all absent means no badge, or a body cached before the fields shipped. */
2711
+ /** Whole UTC calendar days since this wallet's first trade: the number of UTC dates from the first trade's date to today, so a first trade at 23:00 UTC reads 1 an hour later. Every wallet's age changes at 00:00 UTC, once a day, not on every request, and the pick's ETag holds between requests. Stamped at serve time from the wallet's current trader record, never frozen with the pick. The five badge fields are present together, and only for a wallet that carries at least one badge; all absent means no badge, or a body cached before the fields shipped. */
2508
2712
  wallet_age_days?: number | null;
2509
2713
  /** True when the wallet's first trade was under 30 days ago. Stamped at serve time from the wallet's current trader record, never frozen with the pick. The five badge fields are present together, and only for a wallet that carries at least one badge; all absent means no badge, or a body cached before the fields shipped. */
2510
2714
  is_new_wallet?: boolean;
@@ -2514,6 +2718,32 @@ export type PickHolder = {
2514
2718
  is_bot?: boolean;
2515
2719
  /** The wallet's X handle from its Polymarket profile, normalized to 1-15 characters of [A-Za-z0-9_] with no `@`. Link it as `https://x.com/<handle>`. Stamped at serve time from the wallet's current trader record, never frozen with the pick. The five badge fields are present together, and only for a wallet that carries at least one badge; all absent means no badge, or a body cached before the fields shipped. */
2516
2720
  x_username?: string | null;
2721
+ /** The wallet's edge over the price it paid in the pick's canonical category (`category`): how often the side it bought won, minus the average price it paid, over its settled markets there of $20 or more at a known entry price. The rule the site's sport leaderboards use for their Edge column, and the figure the pick card prints on the sport's line. Not `category_win_rate` minus `category_avg_price`: the edge counts its own sample. Present only with `category_win_rate_status` = `measured`, when the edge ranks (30 or more such markets, and the share of the decided ones that made money at settlement within 10 points of the win rate) and the wallet's realized P&L over them is above zero; otherwise `category_price_edge_hold` says why. Beside `category_win_rate_game` it is still the whole category's edge; the game's or league's is `category_scope_price_edge`. Recomputed at serve time from the daily record rebuild, not frozen with the pick. Absent otherwise and on payloads predating the field. */
2722
+ category_price_edge?: PickHolderPriceEdge;
2723
+ /** The same edge over the markets of the game or league `category_win_rate_game` names alone: the edge the pick card prints beside a game or league win rate (for example `-17.1 pp` in the Premier League). Present only beside `category_win_rate_game`, under the same rule over that game's or league's markets and the wallet's realized P&L there; otherwise, beside a game or league rate, `category_scope_price_edge_hold` says why. Never the whole category's edge in its place. Recomputed at serve time, not frozen with the pick. Absent otherwise and on payloads predating the field. */
2724
+ category_scope_price_edge?: PickHolderPriceEdge;
2725
+ /** Why there is no `category_price_edge` for a wallet with a measured rate, with the rule's figures when it has them. Present only with `category_win_rate_status` = `measured`, and never beside `category_price_edge`. Absent otherwise and on payloads predating the field. */
2726
+ category_price_edge_hold?: PickHolderPriceEdgeHold;
2727
+ /** Why there is no `category_scope_price_edge` beside a game or league rate, with the rule's figures when it has them. Present only beside `category_win_rate_game`, and never beside `category_scope_price_edge`. Absent otherwise and on payloads predating the field. */
2728
+ category_scope_price_edge_hold?: PickHolderPriceEdgeHold;
2729
+ };
2730
+ /** Edge over the price paid in one category, game or league: how often the side a wallet bought won, minus the average price it paid, over its settled markets there of $20 or more at a known entry price. Probabilities throughout: edge -0.171 is -17.1 percentage points. A market bought on both sides counts by its shares: the winning side's share of the shares bought is its hit, the cost over those shares its price. Figures from the daily record rebuild. */
2731
+ export type PickHolderPriceEdge = {
2732
+ /** Settled markets of $20 or more at a known entry price that the edge is measured over. */
2733
+ markets: number;
2734
+ /** Share of those markets whose bought side won, 0-1. */
2735
+ hit_rate: number;
2736
+ /** Mean entry price paid over the same markets, 0-1. Its sample is these markets, so it can differ from `category_avg_price` and `category_scope_avg_price`. */
2737
+ avg_price: number;
2738
+ /** hit_rate minus avg_price, full precision. */
2739
+ edge: number;
2740
+ };
2741
+ /** An edge the holder row does not show, and why. */
2742
+ export type PickHolderPriceEdgeHold = {
2743
+ /** category_loss: the edge ranks, and the wallet's realized P&L over the same markets is zero or below. too_few_markets: fewer than 30 counted markets. sample_mismatch: the share of the decided markets that made money at settlement is more than 10 points from the win rate over the same markets, so these markets do not describe the wallet's record. no_markets: no settled market of $20 or more at a known entry price. */
2744
+ hold: "category_loss" | "too_few_markets" | "sample_mismatch" | "no_markets";
2745
+ /** The rule's figures, as a shown edge carries them. Omitted for no_markets, and for too_few_markets when the wallet has fewer than 5 such markets. */
2746
+ record?: PickHolderPriceEdge;
2517
2747
  };
2518
2748
  /** Recorded lead wallet facts on a full response when available. Position and category history are frozen at publication; they are not live balances or pick win probabilities. */
2519
2749
  export type PickLeadBacker = {
@@ -2576,7 +2806,7 @@ export type PickOfTheDay = {
2576
2806
  is_locked?: boolean;
2577
2807
  /** 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). */
2578
2808
  game_started?: boolean;
2579
- /** Whether the backed game is over according to the cached live scoreboard, read at serve time. Tells a finished game from one still in play before `outcome` settles. Omitted when the pick has no event slug or no scoreboard is cached for it; absence is unknown, never false. */
2809
+ /** Whether the backed game is over, from the game's scoreboard. Once the game is recorded as finished it stays true, on later reads and on past days. A pick settled `win` or `loss` reads true unless the live scoreboard shows the game still in play. Tells a finished game from one still in play before `outcome` settles. Omitted when the game's state is unknown; absence is unknown, never false. */
2580
2810
  game_ended?: boolean;
2581
2811
  /** Settlement outcome of the backed side; 'pending' until the market resolves. */
2582
2812
  outcome?: "pending" | "win" | "loss" | "void";
@@ -3056,8 +3286,6 @@ export type PickOfTheDayLedgerOpenedEntry = {
3056
3286
  supersedes_pick_id: string | null;
3057
3287
  /** Explicit proof provenance: 1 retains historic eight-field canonical JSON; 2 binds stable pick_id and version without pick_rank. */
3058
3288
  commitment_version: 1 | 2;
3059
- /** How the pick was chosen: auto by the selection algorithm, manual by an operator (102 published picks from 2026-06-23 to 2026-10-15; none since). Outside the hashed payload, so it moves no commitment. */
3060
- selected_by: "auto" | "manual";
3061
3289
  };
3062
3290
  /** An unresolved published pick. Carries only date, rank, hash, algorithm, seal instant and permalink. Kickoff and game identity are withheld; seal time remains public commitment provenance. */
3063
3291
  export type PickOfTheDayLedgerSealedEntry = {
@@ -3090,8 +3318,6 @@ export type PickOfTheDayLedgerSealedEntry = {
3090
3318
  supersedes_pick_id: string | null;
3091
3319
  /** Explicit proof provenance: 1 retains historic eight-field canonical JSON; 2 binds stable pick_id and version without pick_rank. */
3092
3320
  commitment_version: 1 | 2;
3093
- /** How the pick was chosen: auto by the selection algorithm, manual by an operator (102 published picks from 2026-06-23 to 2026-10-15; none since). Outside the hashed payload, so it moves no commitment. */
3094
- selected_by: "auto" | "manual";
3095
3321
  };
3096
3322
  /** A pick without a commitment, retained so the record cannot omit unprovable entries. Unresolved entries omit game identity; once resolved, matchup, category and payload become public. Existing opened canonical payload bytes and hashes are unchanged. */
3097
3323
  export type PickOfTheDayLedgerUncommittedEntry = {
@@ -3130,8 +3356,6 @@ export type PickOfTheDayLedgerUncommittedEntry = {
3130
3356
  * @deprecated
3131
3357
  */
3132
3358
  supersedes_pick_id: string | null;
3133
- /** How the pick was chosen: auto by the selection algorithm, manual by an operator (102 published picks from 2026-06-23 to 2026-10-15; none since). Outside the hashed payload, so it moves no commitment. */
3134
- selected_by: "auto" | "manual";
3135
3359
  };
3136
3360
  /** A successful current-day entitlement response when only unauthorized ranks have published. It carries an empty pick set, identity-free locked ranks and an upgrade message. Selection IDs, game identity, prices and unauthorized clocks are absent. Any scheduled or proof-pending rows are entitled rows. */
3137
3361
  export type PickOfTheDayNoEntitledPicks = {
@@ -3556,37 +3780,6 @@ export type PickOfTheDayStats = {
3556
3780
  pick_id: string;
3557
3781
  pick_rank: number;
3558
3782
  }[];
3559
- selections: {
3560
- canonical_category?: string;
3561
- clv_avg_display?: string;
3562
- clv_avg_pct?: number;
3563
- clv_avg_pp?: number;
3564
- clv_avg_pp_display?: string;
3565
- clv_measured: number;
3566
- edge_display?: string;
3567
- edge_pp?: number;
3568
- key: string;
3569
- label: string;
3570
- losses: number;
3571
- net_profit_display?: string;
3572
- net_profit_usd?: number;
3573
- pending: number;
3574
- picks: number;
3575
- priced_decided: number;
3576
- priced_in_display?: string;
3577
- priced_in_pct?: number;
3578
- roi_display?: string;
3579
- roi_pct?: number;
3580
- settled: number;
3581
- small_sample: boolean;
3582
- staked_usd: number;
3583
- unit_score?: number;
3584
- unit_score_display?: string;
3585
- void: number;
3586
- win_rate_display?: string;
3587
- win_rate_pct?: number;
3588
- wins: number;
3589
- }[];
3590
3783
  };
3591
3784
  /** The stats with `view=summary` or `sections`: only the named sections, listed in `sections`. `view=summary` names every section except `series`, `days`, `categories`, `months` and `voids`. */
3592
3785
  export type PickOfTheDayStatsSections = {
@@ -4027,37 +4220,6 @@ export type PickOfTheDayStatsSections = {
4027
4220
  pick_id: string;
4028
4221
  pick_rank: number;
4029
4222
  }[];
4030
- selections?: {
4031
- canonical_category?: string;
4032
- clv_avg_display?: string;
4033
- clv_avg_pct?: number;
4034
- clv_avg_pp?: number;
4035
- clv_avg_pp_display?: string;
4036
- clv_measured: number;
4037
- edge_display?: string;
4038
- edge_pp?: number;
4039
- key: string;
4040
- label: string;
4041
- losses: number;
4042
- net_profit_display?: string;
4043
- net_profit_usd?: number;
4044
- pending: number;
4045
- picks: number;
4046
- priced_decided: number;
4047
- priced_in_display?: string;
4048
- priced_in_pct?: number;
4049
- roi_display?: string;
4050
- roi_pct?: number;
4051
- settled: number;
4052
- small_sample: boolean;
4053
- staked_usd: number;
4054
- unit_score?: number;
4055
- unit_score_display?: string;
4056
- void: number;
4057
- win_rate_display?: string;
4058
- win_rate_pct?: number;
4059
- wins: number;
4060
- }[];
4061
4223
  };
4062
4224
  /** A settled uncommitted pick's market, side and price. The same eight fields as PickOfTheDayCommitmentPayload, in the same key order, so a settled pick's side and price sit under payload whatever the entry's state. It is NOT a commitment: no hash was taken over it before the game, and it proves nothing about when the pick was made. */
4063
4225
  export type PickOfTheDayUncommittedPayload = {
@@ -4257,7 +4419,7 @@ export type PositionExact = {
4257
4419
  realized_pnl?: ExactDecimal;
4258
4420
  };
4259
4421
  export type PositionTimelineEvent = {
4260
- /** Prefixed ID (pe_...). */
4422
+ /** Opaque fill id (fill_...). Responses before #33245 carried pe_... ids, which no longer match. */
4261
4423
  id: string;
4262
4424
  /** ISO 8601 timestamp of the on-chain fill. */
4263
4425
  event_timestamp: string;
@@ -4272,8 +4434,8 @@ export type PositionTimelineEvent = {
4272
4434
  price: number;
4273
4435
  /** Positive USDC notional of the fill. */
4274
4436
  usdc_notional: number;
4275
- /** Polygon transaction hash of the fill. */
4276
- tx_hash: string;
4437
+ /** Polygon transaction hash of the fill, from the large-trade alert recorded for it. null for a fill with no such alert: the fill ledger stores no transaction hash (#33245). */
4438
+ tx_hash: string | null;
4277
4439
  /** Cumulative signed stored-fill amount for this outcome after this fill, including older pages. Stable across limits/cursors for unchanged source history. Excludes split, merge, redemption and neg-risk activity; not complete holdings. Incomplete fill history can also leave a negative amount. */
4278
4440
  running_amount: number;
4279
4441
  /** Cumulative buy-weighted average of stored fills for this outcome, including older pages; not provider current-position avgPrice. Sells do not change this value. 0 when no stored buys have occurred yet. */
@@ -4302,6 +4464,25 @@ export type PotdEntryAuthorization = {
4302
4464
  /** Authorization expiry timestamp. Existing grants do not extend; an expired authorization cannot authorize a new automated entry. */
4303
4465
  expires_at: string;
4304
4466
  };
4467
+ /** Settings for market_price_moved: required when event_types includes it, refused (400) when it does not. A PATCH without it keeps the stored settings; removing the event clears them. A subscription receives at most one delivery per market per window: the one level step whose (previous_level_cents, level_cents] holds min_move_cents. */
4468
+ export type PriceMoveSubscriptionFilters = {
4469
+ /** Move threshold in whole cents of outcome 0's midpoint. */
4470
+ min_move_cents: number;
4471
+ /** The window the move is measured over. */
4472
+ window_seconds: 60 | 120 | 300 | 900;
4473
+ /** One market only. Raw or mkt_-prefixed. */
4474
+ condition_id?: string;
4475
+ /** One Polymarket event (game) only. */
4476
+ event_slug?: string;
4477
+ /** Event slug league prefixes such as nba or epl, matched case-insensitively; any one matches. */
4478
+ league?: string[];
4479
+ /** Game phase when the move was detected. any includes unknown. */
4480
+ phase: "any" | "pre_game" | "in_play";
4481
+ /** Deliver only moves with concurrent_sharp_flow.detected true. */
4482
+ require_concurrent_sharp_flow: boolean;
4483
+ /** Deliver only moves whose book_depth_within_2c is known and holds at least this many USD on each side. A move with book_depth_within_2c null does not match. */
4484
+ min_book_usd_within_2c?: number;
4485
+ };
4305
4486
  /** One PUBLISHED same-day pick whose holder proof is not readable yet: its stable slot rank, the release and kickoff instants, and the instant before which a retry cannot succeed. Every item in `picks` carries its full required shape, so a pick that cannot meet it is listed here instead of being served with missing fields or a synthetic zero. */
4306
4487
  export type ProofPendingPickSlot = {
4307
4488
  /**
@@ -4404,7 +4585,7 @@ export type ReportPayload = {
4404
4585
  grade: "S" | "A" | "B" | "C" | "D" | "F" | null;
4405
4586
  count: number | null;
4406
4587
  })[] | null;
4407
- /** Which markets the report counts. sports_and_esports for a period that ends on or after 2026-10-21: totals, categories, top trades and the grade cohort cover sports and esports markets only. all_markets for an earlier period, whose stored report keeps every Polymarket market it published. */
4588
+ /** Which markets the report counts. sports_and_esports: totals, categories, top trades and the grade cohort cover sports and esports markets only. Every period that ends on or after 2026-10-21 and every custom from/to range says so, as does an earlier stored period first built after 2026-10-24. all_markets: an earlier stored period built before then, which keeps every Polymarket market it published. A custom range can therefore count fewer trades than the stored report of the same dates. */
4408
4589
  market_scope: "all_markets" | "sports_and_esports";
4409
4590
  };
4410
4591
  export type ReportReconciliation = {
@@ -4493,6 +4674,8 @@ export type ResponseMeta = {
4493
4674
  ranking_generation?: number;
4494
4675
  /** Authoritative RFC3339 timestamp from cache_generations.updated_at for ranking_generation. It is read in the same repeatable-read snapshot as the leaderboard rows and is not request time, cache write time, or row insertion order. */
4495
4676
  ranking_as_of?: string;
4677
+ /** GET /api/v1/leaderboard only. The cursor's ranking_generation, set when this page continued a cursor from an earlier ranking that moved under it: the rows follow the cursor's boundary in the ranking named by ranking_generation, so a trader who crossed the boundary can repeat a row you already hold or be missing from the walk. De-duplicate by id, or restart from the first page for an exact walk. Omitted on a first page and on an exact continuation, including a newer generation in which nothing a page of that order reads moved. It can equal ranking_generation when the ranking moved within one generation: on the default order, sort=rank and sort=grade when the rank keys changed, and on every other sort whenever the projection republished (about once a minute; since 2026-11-07). */
4678
+ continued_from_generation?: number;
4496
4679
  /** Directional evidence provenance for Edge Hunter signals collections. The default board carries this provenance in data.directional_source and omits this optional meta field. */
4497
4680
  directional_source?: "live" | "degraded";
4498
4681
  /** Ranking evidence provenance for Edge Hunter signals collections. The default board carries this clock/provenance in data.ranking_source and omits this optional meta field. */
@@ -4551,6 +4734,17 @@ export type ScoreCell = {
4551
4734
  };
4552
4735
  /** Shape the provider score string was parsed into. `two_side` is one aggregate per side (basketball `105-98`), `multi_set` is per-set columns (tennis `6-7(5-7), 6-0, 1-0`), `esports_series` is a maps/sets/format triplet (`000-000|2-0|Bo3`). Omitted when the score could not be parsed. */
4553
4736
  export type ScoreFormat = "two_side" | "multi_set" | "esports_series";
4737
+ /** Settings for market_settled; every set field must match. Optional: subscribing without it stores {"sports_market_types": ["moneyline"]}, every market Polymarket labels moneyline, and sending it without the event is refused (400). That label is each head-to-head game's winner market, but in golf and other field events Polymarket labels every player market moneyline (winner, make the cut, round leader), so one tournament can send hundreds of states. Narrow it with leagues, which no market outside the list matches, including one whose league is null (a golf event slug that starts with a year, such as 2026-world-wide-technology-championship), or with condition_ids. A PATCH without it keeps the stored settings while the event stays subscribed; removing the event clears them. Stored as the API normalized it: trimmed and deduplicated, leagues, market types and condition IDs lowercased, and sports_market_types filled in when omitted. */
4738
+ export type SettlementSubscriptionFilters = {
4739
+ /** Event slug league prefixes such as nba or epl, matched case-insensitively; any one matches. A polyv2 copy's league is read after its polyv2 prefix. PGA Tour golf, whose event slugs start with the year, is pga. */
4740
+ leagues?: string[];
4741
+ /** Polymarket sportsMarketType values such as moneyline, spreads, totals or a prop type, matched case-insensitively; any one matches, and * matches every type. Omitted, it is ["moneyline"], or ["*"] when condition_ids names the markets. */
4742
+ sports_market_types?: string[];
4743
+ /** Polymarket event (game) slugs; any one matches. */
4744
+ event_slugs?: string[];
4745
+ /** Market condition IDs, raw or mkt_-prefixed; any one matches. */
4746
+ condition_ids?: string[];
4747
+ };
4554
4748
  /** `sharp_money_flow_detected` data (Pro and Max): ranked-trader net flow on a market crossed the threshold. The deprecated spelling `smart_money_flow_detected` delivers the same object until its sunset on 2027-02-01 (#29352). */
4555
4749
  export type SharpMoneyFlowDetectedData = {
4556
4750
  /** Polymarket condition id of the market. */
@@ -4783,7 +4977,7 @@ export type SuspiciousTradeFlaggedData = {
4783
4977
  /** Fill price of the flagged trade. */
4784
4978
  price: number;
4785
4979
  };
4786
- /** Optional current-game tennis facts from API-Tennis, aligned with live_score.scores display order. These facts have their own revision and expiry; Polymarket remains the source of sets, match status, period, and the outer live-score revision. New observations require corroborated identity, current set/games, and live state. Where Polymarket publishes no score (tennis doubles, whose live_score reads one 0-0 set throughout), the group binds on both pairs' names, the tour, the date and API-Tennis's live flag, and carries set_games, the provider's set score for the match. Cached responses and replayed frames may still carry expired facts, so clients must enforce expires_at. */
4980
+ /** Optional current-game tennis facts from API-Tennis, aligned with live_score.scores display order. These facts have their own revision and expiry; Polymarket remains the source of sets, match status, period, and the outer live-score revision, except on ITF singles, which Polymarket does not score: there API-Tennis supplies the whole live_score, bound on both players' names, the tournament and the date. New observations require corroborated identity, current set/games, and live state. Where Polymarket publishes no score (tennis doubles, whose live_score reads one 0-0 set throughout), the group binds on both pairs' names, the tour, the date and API-Tennis's live flag, and carries set_games, the provider's set score for the match. Cached responses and replayed frames may still carry expired facts, so clients must enforce expires_at. */
4787
4981
  export type TennisPoints = {
4788
4982
  source: "api_tennis";
4789
4983
  /** API-Tennis match ID. This is not a Polymarket market or event ID. */
@@ -4942,7 +5136,7 @@ export type TraderBreakdowns = {
4942
5136
  entry_price_analysis: TraderEntryPriceAnalysis;
4943
5137
  };
4944
5138
  export type TraderCategoryRecord = {
4945
- /** Canonical category bucket, for example Soccer, Esports, Tennis. Esports is one bucket, and the Esports record carries its per-game records in games. */
5139
+ /** Canonical category bucket, for example Soccer, Esports, Tennis. Esports is one bucket, and the Esports record carries its per-game records in games. Every record carries its per-scope records (esports titles, soccer leagues, other sports' leagues) in scopes. */
4946
5140
  category: string;
4947
5141
  /** Markets in this category the wallet closed with a profit. */
4948
5142
  wins: number;
@@ -4954,6 +5148,8 @@ export type TraderCategoryRecord = {
4954
5148
  status: "measured" | "not_enough_data";
4955
5149
  /** The wallet's record per esports title, busiest first. Present only on the Esports record, and only when the wallet has a settled market in at least one title; absent on every other category and on an Esports record whose markets are all in series that are not games (skin-price indices, streamer props) or carry no series. Absent means no per-game record, the same rule as an absent category. Each entry's decided is a subset of the Esports record's, read in the same statement from the same daily rebuild. */
4956
5150
  games?: TraderEsportsGameRecord[];
5151
+ /** The wallet's record per scope of this category, busiest first: each esports title on the Esports record, each soccer league on the Soccer record (UEFA Champions League, LaLiga, Premier League, ...), and each registered league of another sport on its record (NBA, NFL, ATP, ...). The same records Pick of the Day and the holder chips name in category_win_rate_game. Present only when the wallet has a settled market in at least one scope; absent means no per-scope record, the same rule as an absent category. On the Esports record it lists the same titles as games, with the same counts. Each entry's decided is a subset of its record's, read in the same statement from the same daily rebuild. */
5152
+ scopes?: TraderCategoryScopeRecord[];
4957
5153
  };
4958
5154
  export type TraderCategoryRecords = {
4959
5155
  /** Prefixed trader id (trd_<wallet>). */
@@ -4964,11 +5160,72 @@ export type TraderCategoryRecords = {
4964
5160
  basis: "settled_markets_all_sizes";
4965
5161
  /** Decided markets a category needs before win_rate is served. Published so a caller can apply its own sample rule to the raw counts. */
4966
5162
  min_decided_for_win_rate: number;
4967
- /** When the served records were last rebuilt (RFC3339, Z): the newest stamp among every row served, game rows included, which the daily rebuild writes in one transaction. Null when the wallet has no record at all. */
5163
+ /** When the served records were last rebuilt (RFC3339, Z): the newest stamp among every row served, game and scope rows included, which the daily rebuild writes in one transaction. Null when the wallet has no record at all. */
4968
5164
  computed_at: string | null;
4969
- /** One entry per canonical category with at least one decided market, ordered by decided descending then category. A category with no decided market is omitted. The Esports entry carries its per-game records in games. */
5165
+ /** One entry per canonical category with at least one decided market, ordered by decided descending then category. A category with no decided market is omitted. The Esports entry carries its per-game records in games, and every entry its per-scope records in scopes. */
4970
5166
  records: TraderCategoryRecord[];
4971
5167
  };
5168
+ export type TraderCategoryScopeRecord = {
5169
+ /** The stable key the scope's record is stored under: an esports series slug (league-of-legends, counter-strike), a soccer league's season-stripped series stem (ucl, la-liga, premier-league), or another sport's league stem (nba, nfl, atp). display_name is the label. */
5170
+ scope_key: string;
5171
+ /** The scope's name as Pick of the Day and every holder chip print it in category_win_rate_game: LoL, CS2, UEFA Champions League, LaLiga, NBA. Match a chip to this row by string equality. */
5172
+ display_name: string;
5173
+ /** Markets in this scope the wallet closed with a profit. */
5174
+ wins: number;
5175
+ /** Markets in this scope it closed with a profit or a loss. A subset of the parent record's decided: the two are read from the same daily rebuild. */
5176
+ decided: number;
5177
+ /** wins / decided in [0,1], truncated to four decimals. Null when status is not_enough_data. */
5178
+ win_rate: number | null;
5179
+ /** The same rule as the parent record: measured when decided cleared min_decided_for_win_rate, not_enough_data when the counts are real but the sample is under the floor. A chip on a market in this scope shows this row's rate when it is measured and the parent record's otherwise. */
5180
+ status: "measured" | "not_enough_data";
5181
+ };
5182
+ /** Closing line value over one wallet's large trades in a window (#32517). */
5183
+ export type TraderClv = {
5184
+ /** Wallet address, lowercase. */
5185
+ address: string;
5186
+ /** The CLV definition, clv@v1, each trade's clv.basis_version. */
5187
+ basis_version: string;
5188
+ /** The category filter as sent, or null. */
5189
+ category: string | null;
5190
+ /** The window's trades that carry no CLV, by clv.status. */
5191
+ excluded: {
5192
+ in_play: number;
5193
+ pending: number;
5194
+ unavailable: number;
5195
+ };
5196
+ /** Window start, inclusive. */
5197
+ from: string;
5198
+ /** trd_-prefixed trader id. */
5199
+ id: string;
5200
+ /** Large trades in the window, every status. */
5201
+ large_trades: number;
5202
+ /** Figures over the trades whose clv.status is measured. */
5203
+ measured: {
5204
+ /** Normal 95% interval on market_mean_clv_cents from the markets' sample deviation, as low and high. null below two markets. */
5205
+ market_ci95_cents: {
5206
+ high: number;
5207
+ low: number;
5208
+ } | null;
5209
+ /** Mean over markets of each market's mean clv_cents. null with no measured trade. */
5210
+ market_mean_clv_cents: number | null;
5211
+ /** Distinct markets among them. */
5212
+ markets: number;
5213
+ /** Plain mean of clv_cents. null with no measured trade. */
5214
+ mean_clv_cents: number | null;
5215
+ /** Share of measured trades with clv_cents > 0, 0 to 1. null with no measured trade. */
5216
+ share_beat_close: number | null;
5217
+ /** Their summed size in USDC. */
5218
+ size_usd: number;
5219
+ /** Mean of clv_cents weighted by each trade's size_usd. null with no measured trade. */
5220
+ stake_weighted_clv_cents: number | null;
5221
+ /** Large trades with clv.status measured. */
5222
+ trades: number;
5223
+ };
5224
+ /** Size floor in USDC, as /large-trades/history reads it. */
5225
+ min_size: number;
5226
+ /** Window end, exclusive. */
5227
+ to: string;
5228
+ };
4972
5229
  export type TraderContext = {
4973
5230
  trader: Trader;
4974
5231
  /** Aggregate position and P&L coverage for the trader, over its synced markets. markets_open, unrealized_mtm and cost_basis_locked cover the open positions on sports and esports markets, each market judged when the summary is read (#32119). markets_synced, markets_resolved and the resolved win figures count every stored market: since 2026-10-27 (#29366) those are mostly sports and esports markets, but a market that moved out of sports and esports, or one stored before its category was known, stays in them, and sync_coverage counts every category on both sides. markets_total, total_realized_pnl and synced_realized_pnl still cover every Polymarket market of the wallet. Omitted entirely (key absent, never null) when the trader is not in the local database or native net economics is unavailable. Realized fields remain numbers when present, including a genuine zero. */
@@ -5607,6 +5864,8 @@ export type UpdateWebhookRequest = {
5607
5864
  url?: string;
5608
5865
  event_types?: WebhookEventType[];
5609
5866
  trade_filters?: LargeTradeSubscriptionFilters;
5867
+ price_move_filters?: PriceMoveSubscriptionFilters;
5868
+ settlement_filters?: SettlementSubscriptionFilters;
5610
5869
  enabled?: boolean;
5611
5870
  };
5612
5871
  export type Usage = {
@@ -5668,7 +5927,7 @@ export type WalletGradeChangedData = {
5668
5927
  direction: "upgrade" | "downgrade";
5669
5928
  /** Cohort skill index that drove the grade, 0 to 1. */
5670
5929
  skill_index: number;
5671
- /** Final 0 to 100 score banded into the new grade. */
5930
+ /** The new grade's sort key, not a rating out of 100: the cohort percentile times 100, held inside the new grade's band. */
5672
5931
  final_score: number;
5673
5932
  /** The ranking date of the re-grade. */
5674
5933
  date: string;
@@ -5703,6 +5962,10 @@ export type WebhookEndpoint = {
5703
5962
  url: string;
5704
5963
  event_types: WebhookEventType[];
5705
5964
  trade_filters: LargeTradeSubscriptionFilters;
5965
+ /** The market_price_moved settings; null unless that event is subscribed. */
5966
+ price_move_filters: PriceMoveSubscriptionFilters | null;
5967
+ /** The market_settled settings as stored, defaults filled in; null unless that event is subscribed. */
5968
+ settlement_filters: SettlementSubscriptionFilters | null;
5706
5969
  status: WebhookStatus;
5707
5970
  verified_at: string | null;
5708
5971
  verification_token_expires_at: string;
@@ -5725,7 +5988,7 @@ export type WebhookEventDescriptor = {
5725
5988
  /** active: the event has a firing producer callsite. dormant: advertised and subscribable, but does not yet enqueue any delivery. */
5726
5989
  status: "active" | "dormant";
5727
5990
  };
5728
- export type WebhookEventType = "large_trade_inserted_v2" | "large_trades_inserted" | "whale_trades_inserted" | "live_sports_updated" | "trader_synced" | "whale_trader_synced" | "large_positions_updated" | "wallet_grade_changed" | "suspicious_trade_flagged" | "insider_radar_flag_raised" | "sharp_money_flow_detected" | "smart_money_flow_detected" | "export_job_ready" | "export_job_failed" | "export_job_expired" | "export_job_cancelled";
5991
+ export type WebhookEventType = "large_trade_inserted_v2" | "large_trades_inserted" | "whale_trades_inserted" | "live_sports_updated" | "trader_synced" | "whale_trader_synced" | "large_positions_updated" | "wallet_grade_changed" | "suspicious_trade_flagged" | "insider_radar_flag_raised" | "sharp_money_flow_detected" | "smart_money_flow_detected" | "export_job_ready" | "export_job_failed" | "export_job_expired" | "export_job_cancelled" | "market_price_moved" | "market_settled";
5729
5992
  export type WebhookRetryPolicy = {
5730
5993
  max_attempts: 8;
5731
5994
  terminal_status: "dead_letter";
@@ -5898,6 +6161,27 @@ export type WhaleDatasetTrade = {
5898
6161
  /** Stored source trade identity. */
5899
6162
  trade_event_id: string;
5900
6163
  source_trade_ingested_at: string | null;
6164
+ /** Closing line value: the clv object of the same trade on /api/v1/large-trades, judged at the generation's selected_at from close states read inside the same snapshot. A pending row can be measured in a later generation. The close is stored once (GET /api/v1/market/{condition_id}/close), so a measured clv_cents changes only if the market's kickoff or YES token changes afterwards, which makes it unavailable (anchor_stale, close_token_mismatch). */
6165
+ clv: {
6166
+ /** The CLV definition, clv@v1. */
6167
+ basis_version: string;
6168
+ /** The anchor pre_kickoff was judged against: the stored close's anchor, else the market's kickoff. */
6169
+ close_anchor_at: string | null;
6170
+ /** The traded outcome's closing price, 0 to 1, whenever a usable close is stored and the outcome is known, in play included. */
6171
+ close_price: number | null;
6172
+ /** Cents per share, positive when the trade beat the close: buy is (close_price - price) * 100, sell is (price - close_price) * 100. Gross of fees. Computed from the exact stored price this row carries, so a recomputation from price and close_price agrees to the stored digits. Set exactly when status is measured. */
6173
+ clv_cents: number | null;
6174
+ /** Whether the trade filled before close_anchor_at. null when the market has no anchor. */
6175
+ pre_kickoff: boolean | null;
6176
+ /** measured: clv_cents is set. in_play: traded at or after the close anchor (kickoff), no CLV is defined. pending: traded before kickoff and the market's close is not stored yet. unavailable: see unavailable_reason. */
6177
+ status: "measured" | "in_play" | "pending" | "unavailable";
6178
+ /** Set exactly when status is unavailable. The market's reasons (see MarketClose.unavailable_reason), plus anchor_stale (the kickoff moved after the close was captured) and outcome_unknown (the traded outcome is not known for this trade). */
6179
+ unavailable_reason: "no_observation_in_lookback" | "provider_empty_window" | "provider_invalid_contract" | "capture_window_closed" | "no_game_start_time" | "not_one_sided_resolution" | "not_captured" | "close_token_mismatch" | "anchor_stale" | "outcome_unknown" | null;
6180
+ /** clv_cents - taker_fee_cents: the CLV after the fee the fill paid, cents per share. Set exactly when both are set. */
6181
+ clv_after_fees_cents: number | null;
6182
+ /** The fee the fill paid as taker, cents per share, from the exchange's on-chain record of the fill (the OrderFilled event in its Polygon receipt); the trader is its taker. Polymarket charges only takers, so a buy's fee adds to its cost and a sell's comes out of its proceeds, and either way it lowers the CLV by this amount. Includes any builder fee an app added; excludes maker and taker rebates, which Polymarket pays later and no fill records. Set whatever status is; null until the record is decoded (about a minute after the trade) and for trades before 2026-08-16. */
6183
+ taker_fee_cents: number | null;
6184
+ };
5901
6185
  };
5902
6186
  /**
5903
6187
  * The `data` payload of each webhook event type, from the document's
@@ -5913,6 +6197,8 @@ export interface WebhookEventData {
5913
6197
  large_trade_inserted_v2: LargeTradeInsertedV2Data;
5914
6198
  large_trades_inserted: LargeTradesInsertedData;
5915
6199
  live_sports_updated: LiveSportsUpdatedData;
6200
+ market_price_moved: MarketPriceMovedData;
6201
+ market_settled: MarketSettledData;
5916
6202
  sharp_money_flow_detected: SharpMoneyFlowDetectedData;
5917
6203
  smart_money_flow_detected: SharpMoneyFlowDetectedData;
5918
6204
  suspicious_trade_flagged: SuspiciousTradeFlaggedData;
@@ -5928,6 +6214,7 @@ export interface WebhookEventData {
5928
6214
  */
5929
6215
  export interface OperationData {
5930
6216
  activateWebhookSecret: WebhookEndpoint;
6217
+ batchGetMarketClose: BatchMarketCloseItem[];
5931
6218
  batchGetMarketFlow: BatchMarketFlowItem[];
5932
6219
  batchGetMarketIntel: BatchMarketFlowItem[];
5933
6220
  batchGetTraders: BatchTraderItem[];
@@ -6098,6 +6385,7 @@ export interface OperationData {
6098
6385
  getInsiderRadarFlag: SuspiciousTrade;
6099
6386
  getLargeTrade: LargeTradeDetail;
6100
6387
  getMarketCandles: MarketCandles;
6388
+ getMarketClose: MarketClose;
6101
6389
  getMarketContextMarkdown: string;
6102
6390
  getMarketFlow: MarketFlow;
6103
6391
  getMarketHolders: MarketHolder[];
@@ -6174,6 +6462,7 @@ export interface OperationData {
6174
6462
  getSuspiciousTrade: SuspiciousTrade;
6175
6463
  getTrader: Trader;
6176
6464
  getTraderCategoryRecords: TraderCategoryRecords;
6465
+ getTraderClv: TraderClv;
6177
6466
  getTraderContext: TraderContext;
6178
6467
  getTraderContextMarkdown: string;
6179
6468
  getTraderExportSnapshot: TraderExportSnapshot;
@@ -6344,7 +6633,12 @@ export interface OperationData {
6344
6633
  price_basis: "midpoint" | "last_trade" | null;
6345
6634
  price_observed_at: string | null;
6346
6635
  status: "observed" | "no_orderbook" | "unavailable";
6347
- book_unavailable_reason: "cache_miss" | "stream_capacity" | "no_orderbook" | "missing_provider_token_id" | null;
6636
+ book_unavailable_reason: "cache_miss" | "stream_capacity" | "no_orderbook" | "missing_provider_token_id" | "not_streamed" | "cache_unavailable" | null;
6637
+ book_source: "clob_stream" | "clob_rest" | null;
6638
+ book_depth_within_2c: {
6639
+ ask_usd: number;
6640
+ bid_usd: number;
6641
+ } | null;
6348
6642
  };
6349
6643
  })[];
6350
6644
  platform?: string;
@@ -6379,6 +6673,7 @@ export interface OperationData {
6379
6673
  status: "observed" | "not_posed" | "unavailable";
6380
6674
  was_disputed: boolean | null;
6381
6675
  winning_outcome_index: number | null;
6676
+ oracle_updated_at: string | null;
6382
6677
  };
6383
6678
  trading_terms?: {
6384
6679
  fee_schedule: {
@@ -6413,7 +6708,48 @@ export interface OperationData {
6413
6708
  listLargeTrades: LargeTrade[];
6414
6709
  listLeaderboard: LeaderboardEntry[];
6415
6710
  listLeaderboardLeagues: LeaderboardLeagues;
6711
+ listMarketTrades: MarketTrade[];
6416
6712
  listPositions: Position[];
6713
+ listProps: ({
6714
+ competitors: string[];
6715
+ condition_id: string;
6716
+ event_slug: string;
6717
+ id: string;
6718
+ league: string;
6719
+ line: number | null;
6720
+ outcomes: ({
6721
+ index: number;
6722
+ label?: string;
6723
+ token_id?: string;
6724
+ quote?: {
6725
+ best_ask: number | null;
6726
+ best_bid: number | null;
6727
+ book_observed_at: string | null;
6728
+ book_unavailable_reason: "cache_miss" | "stream_capacity" | "not_streamed" | "no_orderbook" | "missing_provider_token_id" | "cache_unavailable" | null;
6729
+ price: number | null;
6730
+ price_basis: "midpoint" | "last_trade" | null;
6731
+ price_observed_at: string | null;
6732
+ status: "observed" | "no_orderbook" | "unavailable";
6733
+ book_source: "clob_stream" | "clob_rest" | null;
6734
+ book_depth_within_2c: {
6735
+ ask_usd: number;
6736
+ bid_usd: number;
6737
+ } | null;
6738
+ };
6739
+ })[];
6740
+ player: {
6741
+ name: string;
6742
+ } | null;
6743
+ starts_at: string | null;
6744
+ stat: string;
6745
+ status: string;
6746
+ title: string | null;
6747
+ game_event_slug: string;
6748
+ group_item_title: string | null;
6749
+ player_unavailable_reason: "missing_provider_title" | null;
6750
+ resolved_at: string | null;
6751
+ })[];
6752
+ listSettledMarkets: MarketSettledData[];
6417
6753
  listSharpMoneyFlows: SmartMoneyFlowMarket[];
6418
6754
  listSmartMoneyFlows: SmartMoneyFlowMarket[];
6419
6755
  listSuspiciousTrades: SuspiciousTrade[];
@@ -6539,6 +6875,7 @@ export interface OperationData {
6539
6875
  /** Each operation's documented query parameters. */
6540
6876
  export interface OperationQuery {
6541
6877
  activateWebhookSecret: Record<string, never>;
6878
+ batchGetMarketClose: Record<string, never>;
6542
6879
  batchGetMarketFlow: Record<string, never>;
6543
6880
  batchGetMarketIntel: Record<string, never>;
6544
6881
  batchGetTraders: Record<string, never>;
@@ -6593,7 +6930,7 @@ export interface OperationQuery {
6593
6930
  category?: string;
6594
6931
  /** Required for view=observations; wider_holder, in_play or emerging_pile. Rejected for board and signals. wider_holder covers pregame markets that view=signals does not list at its widest selection (horizon_hours=48, min_grade=B, no selector), so until kickoff a market is read in one view or the other. A market view=signals lists leaves wider_holder as primary_slate_candidate, and is a wider_holder candidate again in the first refresh after view=signals stops listing it; signals_as_of names the view=signals snapshot each refresh read. Each refresh evaluates at most 8 markets per sport and cohort, wider_holder by soonest kickoff (most graded holders first among equal kickoffs) and in_play by most graded holders, so a market among a sport's 8 soonest stays evaluated until its game starts. wider_holder also evaluates up to 8 more markets per sport that kick off within 24 hours, most graded holders first, so the most-held markets appear up to a day before kickoff. Each of these keeps its place in later refreshes until its game starts while its holder page still shows a card or could not be read, so a more-held market waits for a free place instead of displacing it. Each row's admitted_by names its place, most_held or soonest_kickoff. The rest count in coverage.capacity_limited_markets. Emerging pile is a wider-holder projection with sharp_pct in [0.75,0.85), complete holder scans and future kickoff, not an independent population or arrival history. */
6595
6932
  cohort?: "wider_holder" | "in_play" | "emerging_pile";
6596
- /** Opt-in admission rule for view=observations with cohort=wider_holder; rejected for every other view and cohort. most_held_48h returns the most-held selection instead of the default one: per sport, up to 8 wider_holder markets kicking off within 48 hours, most graded holders first, then most volume, then soonest kickoff, at most 4 per event. It is recomputed every refresh and keeps no place, so a more-held market displaces a less-held one; markets view=signals lists stay excluded. Every row carries admitted_by most_held_48h, including a market the default selection also evaluates, and the response echoes admission. funnel, coverage, degraded and degradation_reasons describe this selection: a wider_holder candidate it did not take counts as capacity_limited. Its markets that no default place covers are read after every default market, at most once per 10 minutes, so a row can rest on a holder page up to 15 minutes old (holder_snapshot_at). most_held_48h_by_type requires market_types and runs the same rule within each named type: per sport and market_context.market_type, up to 8 markets (4 per event), most graded holders first, then volume, then soonest kickoff, so a type whose markets hold fewer wallets than team-win markets still gets its own places. Its rows carry admitted_by most_held_48h_by_type and it has no departures. Its markets no other selection read are read after every default and most_held_48h market, at most once per 10 minutes. A market type not asked for in the last 30 minutes answers 503 read_model_warming with Retry-After 45 s while the next refresh computes it. Omit for the default selection. Cursors and ETags bind it. */
6933
+ /** Opt-in admission rule for view=observations with cohort=wider_holder; rejected for every other view and cohort. most_held_48h returns the most-held selection instead of the default one: per sport, up to 8 wider_holder markets kicking off within 48 hours, most indexed_graded_holders first, then most volume, then soonest kickoff, at most 4 per event. indexed_graded_holders, on every row, counts the S, A and B wallets in the 0xinsider index holding either outcome; graded_holders counts the piled side of the provider's holder page and can be larger or smaller, so check the selection against indexed_graded_holders. rank orders the admitted rows by directional_rank_score, as in the default selection, not by either count. It is recomputed every refresh and keeps no place, so a more-held market displaces a less-held one; markets view=signals lists stay excluded. Every row carries admitted_by most_held_48h, including a market the default selection also evaluates, and the response echoes admission. funnel, coverage, degraded and degradation_reasons describe this selection: a wider_holder candidate it did not take counts as capacity_limited, and one it skips counts as provider_excluded. It skips every market of a game the provider marks postponed, cancelled, suspended or final, its exact-score, half-time and other side events included, and a market of the game's main event at a Yes price of 0.02 or lower, or 0.98 or higher. Its markets that no default place covers are read at most once per 10 minutes, one with no holder page to serve right after every default market with none, so a row can rest on a holder page up to 15 minutes old, or up to 30 minutes for a market more than an hour before kickoff that has not traded since that page (holder_snapshot_at). most_held_48h_by_type requires market_types and runs the same rule within each named type: per sport and market_context.market_type, up to 8 markets (4 per event), most indexed_graded_holders first, then volume, then soonest kickoff, so a type whose markets hold fewer wallets than team-win markets still gets its own places. Its rows carry admitted_by most_held_48h_by_type and it has no departures. Its markets no other selection read take turns with the most_held_48h ones in that same order, at most once per 10 minutes. A market type not asked for in the last 30 minutes answers 503 read_model_warming with Retry-After 45 s while the next refresh computes it. Omit for the default selection. Cursors and ETags bind it. */
6597
6934
  admission?: "most_held_48h" | "most_held_48h_by_type";
6598
6935
  /** Board and signals: S, A or B, default B. Requires a piled-side holder at the selected grade floor or better, without removing other holders. Rejected for observations. */
6599
6936
  min_grade?: "S" | "A" | "B";
@@ -6657,6 +6994,7 @@ export interface OperationQuery {
6657
6994
  /** Inclusive upper bound as a URL-decoded unix timestamp in seconds; points after this timestamp are omitted. If from is also present, from must be less than or equal to to. */
6658
6995
  to?: number;
6659
6996
  };
6997
+ getMarketClose: Record<string, never>;
6660
6998
  getMarketContextMarkdown: Record<string, never>;
6661
6999
  getMarketFlow: {
6662
7000
  /** Lookback window for whale flow aggregation. */
@@ -6715,10 +7053,10 @@ export interface OperationQuery {
6715
7053
  getPickOfTheDayStats: {
6716
7054
  /** full (default) is every section. summary returns view, sections and every section except the five that grow with the record: series, days, categories, months and voids. In summary and sections bodies hit_rate carries no series; series is its own top-level section. Ignored when sections is sent. Any other value returns 400 bad_request with error.param=view. */
6717
7055
  view?: "full" | "summary";
6718
- /** Exactly the sections to return, in the body's order whatever the request order. Repeatable and comma-separated: hit_rate, series, market_expectations, outcome_stats, days, categories, sports, tiers, selections, months, price_bands, market_types, total_sides, streaks, records, voids. The body names them in sections and carries view=sections. An unrecognized name returns 400 bad_request with error.param=sections rather than being ignored. */
6719
- sections?: ("hit_rate" | "series" | "market_expectations" | "outcome_stats" | "days" | "categories" | "sports" | "tiers" | "selections" | "months" | "price_bands" | "market_types" | "total_sides" | "streaks" | "records" | "voids")[];
7056
+ /** Exactly the sections to return, in the body's order whatever the request order. Repeatable and comma-separated: hit_rate, series, market_expectations, outcome_stats, days, categories, sports, tiers, months, price_bands, market_types, total_sides, streaks, records, voids. The body names them in sections and carries view=sections. An unrecognized name returns 400 bad_request with error.param=sections rather than being ignored. */
7057
+ sections?: ("hit_rate" | "series" | "market_expectations" | "outcome_stats" | "days" | "categories" | "sports" | "tiers" | "months" | "price_bands" | "market_types" | "total_sides" | "streaks" | "records" | "voids")[];
6720
7058
  /** Backward-compatible bracket alias for sections, for clients that emit array keys. Repeatable and comma-separated, with the same names. */
6721
- "sections[]"?: ("hit_rate" | "series" | "market_expectations" | "outcome_stats" | "days" | "categories" | "sports" | "tiers" | "selections" | "months" | "price_bands" | "market_types" | "total_sides" | "streaks" | "records" | "voids")[];
7059
+ "sections[]"?: ("hit_rate" | "series" | "market_expectations" | "outcome_stats" | "days" | "categories" | "sports" | "tiers" | "months" | "price_bands" | "market_types" | "total_sides" | "streaks" | "records" | "voids")[];
6722
7060
  };
6723
7061
  getPlatforms: Record<string, never>;
6724
7062
  getPositionTimeline: {
@@ -6774,6 +7112,12 @@ export interface OperationQuery {
6774
7112
  wallet?: string;
6775
7113
  /** Filter LargeTradeInsertedV2 frames to trades at or above this USD notional. Positive decimal with at most six places; other event types are excluded when set. */
6776
7114
  min_size?: string;
7115
+ /** Filter MarketPriceMoved frames to these event slug league prefixes (comma-separated, case-insensitive, e.g. nba,epl). Other event types are excluded when set. */
7116
+ league?: string;
7117
+ /** Filter MarketPriceMoved frames to the one level step per market and window that crosses this threshold, in whole cents (2 to 50): previous_level_cents < min_move_cents <= level_cents, the market_price_moved webhook rule. Other event types are excluded when set. */
7118
+ min_move_cents?: number;
7119
+ /** Filter MarketPriceMoved frames to moves measured over this window. Other event types are excluded when set. */
7120
+ window_seconds?: 60 | 120 | 300 | 900;
6777
7121
  };
6778
7122
  getSuspiciousTrade: Record<string, never>;
6779
7123
  getTrader: {
@@ -6785,7 +7129,17 @@ export interface OperationQuery {
6785
7129
  max_age_s?: number;
6786
7130
  };
6787
7131
  getTraderCategoryRecords: {
6788
- /** Filter to one canonical category, matched through the same rollup every other category surface uses: soccer, EPL and champions league all reach Soccer, every esports label folds into Esports, and football is AMERICAN football and reaches Football. A filter that reaches Esports returns the Esports record with all of its games; a game is not a filter of its own, so ask for esports and read games. A sports or esports category the wallet has no record in answers 200 with an empty records array, never 404. Sports and esports only (#27311): a category outside them, or a value that reaches no category, returns 400 bad_request with param category and names the accepted buckets. The word sports, in any casing, matches every sport but Esports, the provider's catch-all Sports category (cycling, lacrosse) included: use esports for Esports alone, or omit category for both (#32657). */
7132
+ /** Filter to one canonical category, matched through the same rollup every other category surface uses: soccer, EPL and champions league all reach Soccer, every esports label folds into Esports, and football is AMERICAN football and reaches Football. A filter that reaches Esports returns the Esports record with all of its games and scopes, and one that reaches Soccer returns the Soccer record with every league in scopes; a game or a league is not a filter of its own, so ask for its category and read games or scopes. A sports or esports category the wallet has no record in answers 200 with an empty records array, never 404. Sports and esports only (#27311): a category outside them, or a value that reaches no category, returns 400 bad_request with param category and names the accepted buckets. The word sports, in any casing, matches every sport but Esports, the provider's catch-all Sports category (cycling, lacrosse) included: use esports for Esports alone, or omit category for both (#32657). */
7133
+ category?: string;
7134
+ };
7135
+ getTraderClv: {
7136
+ /** Inclusive RFC3339 lower bound on the trade time. Defaults to 90 days before to. */
7137
+ from?: string;
7138
+ /** Exclusive RFC3339 upper bound on the trade time. Defaults to now; must be after from, and at most 366 days after it. */
7139
+ to?: string;
7140
+ /** Minimum trade size in USD. The capture floor was 3,000 USD before 2026-07-06 and 10,000 USD from then (1,000 USD in earnings markets), so 10000 gives one size rule across the whole archive. From 2026-09-23 a fill must also be at least 0.1% of its market's recorded traded volume (Polymarket's own share count), where a positive volume is recorded for the market; a market without one keeps the fill, and rows written before that date were not re-filtered. */
7141
+ min_size?: number;
7142
+ /** 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. Sports and esports only (#27430): a category outside them returns 400 bad_request with param category and names the accepted buckets. The word sports, in any casing, matches every sport but Esports, the provider's catch-all Sports category (cycling, lacrosse) included: use esports for Esports alone, or omit category for both (#32657). */
6789
7143
  category?: string;
6790
7144
  };
6791
7145
  getTraderContext: Record<string, never>;
@@ -6862,11 +7216,11 @@ export interface OperationQuery {
6862
7216
  "expand[]"?: ("sharp_money" | "quotes" | "trading_terms")[];
6863
7217
  };
6864
7218
  listGames: {
6865
- /** Canonical sport bucket, case-insensitive, with - and _ read as a space: table-tennis and Table Tennis are the same bucket. Omit for every covered sport. A bucket this deployment does not serve returns an empty page. */
7219
+ /** Canonical sport bucket, case-insensitive, with - and _ read as a space: table-tennis and Table Tennis are the same bucket. Omit for every covered sport. A bucket this deployment does not serve returns an empty page, not an error, and the response names sport in X-Query-Unmatched; coverage.sports lists the served buckets. */
6866
7220
  sport?: string;
6867
7221
  /** League tag, case-insensitive, as this list's coverage.leagues spells it (GET /api/v1/coverage lists no leagues): nfl, epl, cs2, euroleague, cbb, cwbb. EuroLeague games use sport=Basketball and league=euroleague; NCAA men's and women's college basketball games use sport=Basketball with league=cbb and league=cwbb. Omit for every league inside the selected sports. */
6868
7222
  league?: string;
6869
- /** Keep only games in this state. ended, cancelled and postponed also list finished games that have left the live board, read from their stored records, for kickoffs within starts_after..starts_before (default: the 7 days before now). Without status, or with any other state, the list is the live and upcoming board. A value outside the enum returns an empty page. */
7223
+ /** Keep only games in this state. ended, cancelled and postponed also list finished games that have left the live board, read from their stored records, for kickoffs within starts_after..starts_before (default: the 7 days before now). Without status, or with any other state, the list is the live and upcoming board. A value outside the enum answers 400 invalid_query with error.param=status, and its message lists the accepted values: upcoming games are scheduled. */
6870
7224
  status?: "scheduled" | "live" | "paused" | "ended" | "postponed" | "cancelled" | "suspended" | "delayed" | "unknown";
6871
7225
  /** RFC 3339 instant. Keep only games whose kickoff is at or after it. Games with no published kickoff are excluded whenever either bound is set. With a finished status, the stored games' look-back starts here; omitted, it starts 7 days before starts_before, and nothing caps an earlier value. */
6872
7226
  starts_after?: string;
@@ -6880,7 +7234,7 @@ export interface OperationQuery {
6880
7234
  cursor?: string;
6881
7235
  /** Backward-compatible alias for expand. Repeatable: sharp_money, settlement. */
6882
7236
  "expand[]"?: ("sharp_money" | "settlement")[];
6883
- /** sharp_money adds each game's sharp_money, the GameSharpMoney object GET /api/v1/games/{event_slug}/sharp-money returns, read from the sport board's cached aggregate: one board read per sport on the page, never a per-game compute. A game the board did not evaluate carries status not_computed (read the per-game route for it); a sport whose aggregate could not be read carries status unavailable while the rest of the page is served. Pro and Max only; adds 3 to the request cost. settlement adds settlement to each winner market, the GameMarketSettlement block GET /api/v1/games/{event_slug}/markets serves, from the same per-game store. It never waits for Polymarket: a game not read lately carries status unavailable and its read starts, so a read a moment later may answer. Every plan; adds 2 to the request cost. Repeatable; the two combine. */
7237
+ /** sharp_money adds each game's sharp_money, the GameSharpMoney object GET /api/v1/games/{event_slug}/sharp-money returns, read from the sport board's cached aggregate: one board read per sport on the page, never a per-game compute. A game the board did not evaluate carries status not_computed (read the per-game route for it); a sport whose aggregate could not be read carries status unavailable while the rest of the page is served. Pro and Max only; adds 3 to the request cost. settlement adds settlement to each winner market, the GameMarketSettlement block GET /api/v1/games/{event_slug}/markets serves, from the same per-game store. It never waits for Polymarket: a settled market carries its recorded settlement even on a game not read lately, and any other market of such a game carries status unavailable while its read starts, so a read a moment later may answer. Every plan; adds 2 to the request cost. Repeatable; the two combine. */
6884
7238
  expand?: ("sharp_money" | "settlement")[];
6885
7239
  };
6886
7240
  listGameTrades: {
@@ -6934,7 +7288,7 @@ export interface OperationQuery {
6934
7288
  limit?: number;
6935
7289
  /** Pagination cursor from previous response's next_cursor. Prefix: wth_. URL-encode when replaying as a query parameter. */
6936
7290
  cursor?: string;
6937
- /** Minimum trade size in USD. The capture floor was 3,000 USD before 2026-07-06 and 10,000 USD from then (1,000 USD in earnings markets), so 10000 gives one size rule across the whole archive. From 2026-09-23 a fill must also be at least 0.1% of its market's recorded traded volume (Polymarket's own share count); rows written before that date were not re-filtered. */
7291
+ /** Minimum trade size in USD. The capture floor was 3,000 USD before 2026-07-06 and 10,000 USD from then (1,000 USD in earnings markets), so 10000 gives one size rule across the whole archive. From 2026-09-23 a fill must also be at least 0.1% of its market's recorded traded volume (Polymarket's own share count), where a positive volume is recorded for the market; a market without one keeps the fill, and rows written before that date were not re-filtered. */
6938
7292
  min_size?: number;
6939
7293
  /** Exact raw provider condition_id. Unknown markets return an empty list. */
6940
7294
  condition_id?: string;
@@ -6990,7 +7344,7 @@ export interface OperationQuery {
6990
7344
  listLeaderboard: {
6991
7345
  /** Maximum number of ranked traders to return. Out-of-range values are clamped to 1..100. */
6992
7346
  limit?: number;
6993
- /** Opaque lbv1_ pagination cursor from a prior response. It binds the finite score/address boundary to the committed leaderboard generation and the effective category/strategy filters, and on a sorted page to its sort, dir and activity. A cursor from another sort or dir is a 400 bad_request on cursor; one from another activity, category, strategy or generation is cursor_expired. Legacy, malformed, non-finite, and unsupported-version cursors are rejected. */
7347
+ /** Opaque lbv1_ pagination cursor from a prior response. It binds the finite score/address boundary to the effective category/strategy filters, and on a sorted page to its sort, dir and activity, and it names the leaderboard generation it was read at. A cursor from another sort or dir is a 400 bad_request on cursor; one from another activity, category or strategy is cursor_expired. A cursor from an earlier generation continues after its boundary in the current ranking (since 2026-11-07, #33377); meta.continued_from_generation is set when the ranking moved under it. Legacy, malformed, non-finite, and unsupported-version cursors are rejected. */
6994
7348
  cursor?: string;
6995
7349
  /** Filter by category: a sport or esports bucket, matched case-insensitively. League values fold into their sport (NBA and NCAAB into Basketball, NFL into Football). Sports and esports only (#27306): a category outside them returns 400 bad_request with param category and names the accepted buckets. The word sports, in any casing, matches every sport but Esports, the provider's catch-all Sports category (cycling, lacrosse) included: use esports for Esports alone, or omit category for both (#32657). */
6996
7350
  category?: string;
@@ -7004,6 +7358,16 @@ export interface OperationQuery {
7004
7358
  activity?: "all" | "active" | "inactive";
7005
7359
  };
7006
7360
  listLeaderboardLeagues: Record<string, never>;
7361
+ listMarketTrades: {
7362
+ /** Inclusive RFC 3339 lower bound on traded_at. Omitted or earlier than coverage.recorded_from: the walk runs to the start of the record (coverage.recorded_from). With cursor, it must match the cursor's. */
7363
+ from?: string;
7364
+ /** Exclusive RFC 3339 upper bound on traded_at. A first page ends at the earlier of to and coverage.complete_through. With cursor, it must match the cursor's. */
7365
+ to?: string;
7366
+ /** Page size. Out-of-range values are clamped to 1..500. */
7367
+ limit?: number;
7368
+ /** Opaque mtr_v1_ cursor from next_cursor. It continues the walk before the last fill of the previous page and keeps the market, from and to it was issued for: another market, or a from or to that differs from the cursor's, answers 400 with error.reason cursor_expired. A cursor this endpoint did not issue returns 400 with error.param=cursor. */
7369
+ cursor?: string;
7370
+ };
7007
7371
  listPositions: {
7008
7372
  /** Maximum number of current positions to return. Out-of-range values are clamped to 1..100. */
7009
7373
  limit?: number;
@@ -7026,6 +7390,46 @@ export interface OperationQuery {
7026
7390
  /** Filter by the binary outcome side. `yes` maps to outcome_index=0, `no` to outcome_index=1. */
7027
7391
  side?: "yes" | "no";
7028
7392
  };
7393
+ listProps: {
7394
+ /** League tag as GET /api/v1/games coverage.leagues spells it, for example nfl or nba. Matched case-insensitively. */
7395
+ league: string;
7396
+ /** RFC 3339 kickoff bound. A game with no published kickoff is excluded whenever either bound is set. */
7397
+ starts_after?: string;
7398
+ /** RFC 3339 kickoff bound, inclusive. */
7399
+ starts_before?: string;
7400
+ /** Part of player.name, ignoring case and accents: jokic matches Nikola Jokić. A row with no player does not match. */
7401
+ player?: string;
7402
+ /** Provider sportsMarketType values to keep, case-insensitive, for example passing_yards or points. Repeat the parameter or send a comma-separated list. An unknown type returns an empty page. */
7403
+ stat?: string[];
7404
+ /** Bracket alias for stat, as expand[] is for expand. Repeatable; same values. */
7405
+ "stat[]"?: string[];
7406
+ /** active (default), closed, or all. closed means the provider closed the market or it resolved. */
7407
+ status?: "active" | "closed" | "all";
7408
+ /** Keep only props with an outcome whose cached best ask less best bid is at most this many cents: above 0, at most 100, in steps of 0.01. The books are the ones expand=quotes serves, read from the cache with no request-path CLOB call. A prop whose book is not cached yet is left out of data and counted on coverage.rows_without_book; the board reads its league's books behind the response, so a read a few seconds later can judge it. A cursor never revisits a prop a page passed over, whether its book was wider or not cached yet, so when coverage.rows_without_book is above 0, read from the first page again after a few seconds to judge those props; the board reads books for active props only, so a closed prop, or one whose outcome has no provider token id yet, stays unjudged. When the book cache cannot be read for the first prop a page must judge, the read answers 503 with error.reason read_model_warming and Retry-After, not an empty page that repeats its cursor. */
7409
+ max_spread_c?: number;
7410
+ /** Keep only props with an outcome whose cached book holds at least this many USD on each side within 2 cents of its midpoint: bids at or above the midpoint minus 0.02 and asks at or below the midpoint plus 0.02, each level's price times size, from the whole book. A whole number from 1 to 10000000, the measure the market_price_moved webhook filter of the same name uses; expand=quotes serves the two sums as book_depth_within_2c. With max_spread_c, one outcome must meet both. The books are read from the cache with no request-path CLOB call. A prop whose book or depth is not cached yet is left out of data and counted on coverage.rows_without_book; the board reads its league's books behind the response, so a read a few seconds later can judge it. A cursor never revisits a prop a page passed over, so when coverage.rows_without_book is above 0, read from the first page again after a few seconds to judge those props; the board reads books for active props only, so a closed prop, or one whose outcome has no provider token id yet, stays unjudged. When the book cache cannot be read for the first prop a page must judge, the read answers 503 with error.reason read_model_warming and Retry-After, not an empty page that repeats its cursor. */
7411
+ min_book_usd_within_2c?: number;
7412
+ /** Page size. Out-of-range values are clamped to 1..200. */
7413
+ limit?: number;
7414
+ /** Opaque prp_v1_ cursor from next_cursor, sent with the same filters. A cursor this endpoint did not issue returns 400 with error.param=cursor. */
7415
+ cursor?: string;
7416
+ /** quotes adds each outcome's cached quote, as on GET /api/v1/games/{event_slug}/markets; it adds 1 to the cost, on every plan. Repeatable: quotes. */
7417
+ expand?: "quotes"[];
7418
+ /** Backward-compatible alias for expand. Repeatable: quotes. */
7419
+ "expand[]"?: "quotes"[];
7420
+ };
7421
+ listSettledMarkets: {
7422
+ /** RFC 3339 time, required without cursor. Rows whose settlement.observed_at is at or after it. With cursor, the cursor's position replaces it. */
7423
+ since?: string;
7424
+ /** Comma-separated provider market types to keep, case-insensitive: moneyline, spreads, totals, a prop type; at most 64. Omitted: moneyline, or with cursor the cursor's filter. * keeps every type, including markets with no stored type. */
7425
+ sports_market_type?: string;
7426
+ /** Comma-separated leagues to keep, as the rows' league reports them (nba, epl, or pga for PGA Tour golf); at most 32, each starting with a letter and holding no hyphen. Omitted: every league, or with cursor the cursor's filter. */
7427
+ league?: string;
7428
+ /** Page size. Out-of-range values are clamped to 1..100. */
7429
+ limit?: number;
7430
+ /** Opaque stl_v1_ cursor from next_cursor. It replaces since and keeps the filters it was issued for: a sports_market_type or league sent with it must match them, or the read answers 400 with error.reason cursor_expired. A cursor this endpoint did not issue returns 400 with error.param=cursor. */
7431
+ cursor?: string;
7432
+ };
7029
7433
  listSharpMoneyFlows: {
7030
7434
  /** Lookback window for grade-filtered whale flow aggregation. */
7031
7435
  timeframe?: "1h" | "4h" | "24h" | "7d";
@@ -7207,6 +7611,7 @@ export interface OperationPath {
7207
7611
  /** Webhook endpoint id owned by the authenticated API key user. */
7208
7612
  id: number;
7209
7613
  };
7614
+ batchGetMarketClose: Record<string, never>;
7210
7615
  batchGetMarketFlow: Record<string, never>;
7211
7616
  batchGetMarketIntel: Record<string, never>;
7212
7617
  batchGetTraders: Record<string, never>;
@@ -7269,6 +7674,10 @@ export interface OperationPath {
7269
7674
  /** 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. */
7270
7675
  condition_id: string;
7271
7676
  };
7677
+ getMarketClose: {
7678
+ /** 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. */
7679
+ condition_id: string;
7680
+ };
7272
7681
  getMarketContextMarkdown: {
7273
7682
  /** 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. */
7274
7683
  condition_id: string;
@@ -7334,6 +7743,10 @@ export interface OperationPath {
7334
7743
  /** Wallet address (0x...), username, or trd_-prefixed trader id. */
7335
7744
  address: string;
7336
7745
  };
7746
+ getTraderClv: {
7747
+ /** Wallet address (0x...), username, or trd_-prefixed trader id. */
7748
+ address: string;
7749
+ };
7337
7750
  getTraderContext: {
7338
7751
  /** Ethereum wallet address (0x...), known trader username, or trd_-prefixed trader ID emitted by this API. */
7339
7752
  address: string;
@@ -7405,7 +7818,13 @@ export interface OperationPath {
7405
7818
  listLargeTrades: Record<string, never>;
7406
7819
  listLeaderboard: Record<string, never>;
7407
7820
  listLeaderboardLeagues: Record<string, never>;
7821
+ listMarketTrades: {
7822
+ /** 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. */
7823
+ condition_id: string;
7824
+ };
7408
7825
  listPositions: Record<string, never>;
7826
+ listProps: Record<string, never>;
7827
+ listSettledMarkets: Record<string, never>;
7409
7828
  listSharpMoneyFlows: Record<string, never>;
7410
7829
  listSmartMoneyFlows: Record<string, never>;
7411
7830
  listSuspiciousTrades: Record<string, never>;
@@ -7466,6 +7885,10 @@ export interface OperationPath {
7466
7885
  /** Each operation's JSON request body; `never` when it takes none. */
7467
7886
  export interface OperationBody {
7468
7887
  activateWebhookSecret: never;
7888
+ batchGetMarketClose: {
7889
+ /** Market condition IDs (raw or mkt_-prefixed) to resolve in input order. */
7890
+ condition_ids: string[];
7891
+ };
7469
7892
  batchGetMarketFlow: {
7470
7893
  /** Market condition IDs to resolve in input order. */
7471
7894
  condition_ids: string[];
@@ -7516,6 +7939,7 @@ export interface OperationBody {
7516
7939
  getInsiderRadarFlag: never;
7517
7940
  getLargeTrade: never;
7518
7941
  getMarketCandles: never;
7942
+ getMarketClose: never;
7519
7943
  getMarketContextMarkdown: never;
7520
7944
  getMarketFlow: never;
7521
7945
  getMarketHolders: never;
@@ -7539,6 +7963,7 @@ export interface OperationBody {
7539
7963
  getSuspiciousTrade: never;
7540
7964
  getTrader: never;
7541
7965
  getTraderCategoryRecords: never;
7966
+ getTraderClv: never;
7542
7967
  getTraderContext: never;
7543
7968
  getTraderContextMarkdown: never;
7544
7969
  getTraderExportSnapshot: never;
@@ -7564,7 +7989,10 @@ export interface OperationBody {
7564
7989
  listLargeTrades: never;
7565
7990
  listLeaderboard: never;
7566
7991
  listLeaderboardLeagues: never;
7992
+ listMarketTrades: never;
7567
7993
  listPositions: never;
7994
+ listProps: never;
7995
+ listSettledMarkets: never;
7568
7996
  listSharpMoneyFlows: never;
7569
7997
  listSmartMoneyFlows: never;
7570
7998
  listSuspiciousTrades: never;
@@ -7606,6 +8034,11 @@ export interface OperationResponse {
7606
8034
  data: OperationData["activateWebhookSecret"];
7607
8035
  meta: ResponseMeta;
7608
8036
  };
8037
+ batchGetMarketClose: {
8038
+ object: "market_close_batch";
8039
+ data: OperationData["batchGetMarketClose"];
8040
+ meta: BatchResponseMeta;
8041
+ };
7609
8042
  batchGetMarketFlow: {
7610
8043
  object: "market_flow_batch";
7611
8044
  data: OperationData["batchGetMarketFlow"];
@@ -7735,6 +8168,11 @@ export interface OperationResponse {
7735
8168
  data: OperationData["getMarketCandles"];
7736
8169
  meta: ResponseMeta;
7737
8170
  };
8171
+ getMarketClose: {
8172
+ object: "market_close";
8173
+ data: OperationData["getMarketClose"];
8174
+ meta: ResponseMeta;
8175
+ };
7738
8176
  getMarketContextMarkdown: string;
7739
8177
  getMarketFlow: {
7740
8178
  object: "market_flow";
@@ -7858,6 +8296,11 @@ export interface OperationResponse {
7858
8296
  data: OperationData["getTraderCategoryRecords"];
7859
8297
  meta: ResponseMeta;
7860
8298
  };
8299
+ getTraderClv: {
8300
+ object: "trader_clv";
8301
+ data: OperationData["getTraderClv"];
8302
+ meta: ResponseMeta;
8303
+ };
7861
8304
  getTraderContext: {
7862
8305
  object: "trader_context";
7863
8306
  data: OperationData["getTraderContext"];
@@ -8014,6 +8457,29 @@ export interface OperationResponse {
8014
8457
  data: OperationData["listLeaderboardLeagues"];
8015
8458
  meta: ResponseMeta;
8016
8459
  };
8460
+ listMarketTrades: {
8461
+ object: "list";
8462
+ /** Newest first by traded_at, then transaction_hash, then log_index. */
8463
+ data: OperationData["listMarketTrades"];
8464
+ /** True when older fills in the window remain: send next_cursor for them. */
8465
+ has_more: boolean;
8466
+ /** Opaque mtr_v1_ cursor for the next page; null when has_more is false. */
8467
+ next_cursor: string | null;
8468
+ /** The market's raw condition_id, lowercase. */
8469
+ condition_id: string;
8470
+ /** What the record holds. A window outside it reads empty because it is outside the record, not because nothing traded. */
8471
+ coverage: {
8472
+ /** A fill smaller than this, in USD, is not stored: 100. */
8473
+ min_size_usd: number;
8474
+ /** Where the record starts: the later of when recording began and 00:00 UTC on the day retention_days before today. No fill before this instant is served. */
8475
+ recorded_from: string;
8476
+ /** Every fill at or before this instant is in the record, and a first page serves none after it. It trails now by a few minutes. */
8477
+ complete_through: string;
8478
+ /** A stored fill is served at least this many days, then deleted. */
8479
+ retention_days: number;
8480
+ };
8481
+ meta: ResponseMeta;
8482
+ };
8017
8483
  listPositions: {
8018
8484
  object: "list";
8019
8485
  data: OperationData["listPositions"];
@@ -8031,6 +8497,27 @@ export interface OperationResponse {
8031
8497
  };
8032
8498
  meta: ResponseMeta;
8033
8499
  };
8500
+ listProps: {
8501
+ as_of: string;
8502
+ data: OperationData["listProps"];
8503
+ has_more: boolean;
8504
+ league: string;
8505
+ meta: ResponseMeta;
8506
+ next_cursor?: string;
8507
+ object: string;
8508
+ coverage: {
8509
+ sources_unavailable: string[];
8510
+ rows_without_book: number | null;
8511
+ };
8512
+ };
8513
+ listSettledMarkets: {
8514
+ complete_through: string;
8515
+ data: OperationData["listSettledMarkets"];
8516
+ has_more: boolean;
8517
+ meta: ResponseMeta;
8518
+ next_cursor: string;
8519
+ object: string;
8520
+ };
8034
8521
  listSharpMoneyFlows: {
8035
8522
  object: "list";
8036
8523
  data: OperationData["listSharpMoneyFlows"];