{
  "openapi": "3.1.1",
  "info": {
    "title": "Predxy.Api | v1",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.predxy.com",
      "description": "The address this API answers on."
    }
  ],
  "paths": {
    "/v1/venues": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Venue health and staleness",
        "description": "Per-venue status. A venue more than 120 seconds behind is reported as stale rather than having its prices served silently.",
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Browse markets",
        "description": "Filter by venue, status and free text. `venue` and `status` accept comma-separated values (case-insensitive): OR within each list, AND between lists. Omit a filter for all values, or use `none` to match no markets. `sort` accepts recent (default), question, venue, volume, liquidity, resolves and status; `dir` is asc or desc, and each key has its own when none is given — money and recency largest first, names and dates from the start. Cursor-free paging by skip and take; every response carries the total so a caller knows what it is not seeing.",
        "parameters": [
          {
            "name": "venue",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "recent"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets/{id}": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "One market, with its sibling legs",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets/{id}/detail": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Venue detail for one market",
        "description": "Holders, comments, order book and open interest, as that venue publishes them. Read from our index rather than from the venue, so `fetchedAt` may be older than `asOf` — look at it. A market nobody has opened yet returns empty and is queued by the asking. Fields a venue does not expose are null rather than zero — null means it does not say, zero would mean it says none.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read",
              "predxy.api.detail"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets/engagement": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Engagement counts for many markets at once",
        "description": "Holder, comment and trade counts for up to 100 markets in one call, so a list does not make one request per row. Markets not yet indexed are omitted rather than returned as zero, and asking for one schedules it.",
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets/{id}/comments": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "The venue's own discussion for one market",
        "description": "Every comment the venue published, newest first, paged. Comments belong to the venue's event rather than to a single market, so every leg of the same event shows the same thread — it is discussion of the question, not evidence about one outcome. Use `total` rather than the detail endpoint's `commentCount` when labelling a comment section: the venue counts comments its own API does not return, so `commentCount` is reliably the larger of the two.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets/{id}/history": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Recorded price history for one market",
        "description": "A series per outcome leg, bucketed. `window` and `interval` accept plain durations such as 24h, 7d, 30d, 1h, 15m. An interval that would return more than a thousand points per leg is widened until it does not, and the response says which one was used. `window=all` reaches back to the first price recorded for the market. History begins when recording began, not when the market opened. Recorded moves are supplemented by bounded hourly observations, even when unchanged. `gaps` identifies failed or missed hourly checks. Last known prices carried to window boundaries or the last price observation are marked `carried`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "7d"
            }
          },
          {
            "name": "interval",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "1h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read",
              "predxy.api.history"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/markets/stats": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Catalogue totals, overall and per venue",
        "parameters": [
          {
            "name": "tzOffsetMinutes",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/index": {
      "get": {
        "tags": [
          "Index"
        ],
        "summary": "The index of questions, in a chosen order",
        "description": "One entry per question, with every venue carrying it already combined. `sort` accepts weight (default), movers, trending, new, resolvingSoon, hyped, and disagreement: the widest spread between venues that price the question, five points or more. `category` filters to one shelf, `country` to an ISO-3166 alpha-2 code — a question naming several countries answers to each of them. `status` accepts open (default: at least one market still trading), closed (nothing left to trade, resolution pending), settled (every venue has resolved it) and any. A null `change` means there is not yet enough history to say, which is not the same as no movement. The ordered listings leave out what is decided or about to be: a question settling within 48 hours, or priced at or beyond 99/1, is not listed, movers need $5K of 24-hour volume and resolvingSoon $1K, and the first ten by weight hold at most three of one category. Movers fold the outcomes of one event into one row. Nothing is placed by hand.",
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "weight"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "open"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 100
            }
          },
          {
            "name": "top",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/index/search": {
      "get": {
        "tags": [
          "Index"
        ],
        "summary": "Free text over the index",
        "description": "Questions whose wording, or any venue's wording of them, contains `q` (two characters or more, case-insensitive). Live questions come first, then settled ones, each by weight. `country` narrows to questions about one ISO-3166 alpha-2 code, as the listing's filter does. Paged by `skip` and `take` (at most 50); `total` is how many questions match.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/index/countries": {
      "get": {
        "tags": [
          "Index"
        ],
        "summary": "Open questions per country",
        "description": "Every country an open question names, with how many name it and the heaviest of them, over the whole index. Only questions with a market still trading count, as in the listings; a question naming several countries counts once for each.",
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/index/{slug}/history": {
      "get": {
        "tags": [
          "Index"
        ],
        "summary": "The question's own history",
        "description": "The index line and each venue's line, from the prices Predxy recorded, bucketed. `window` and `interval` accept plain durations such as 24h, 7d, 30d, 1h, 15m; an interval that would return more than a thousand points is widened until it does not, and the response says which was used. The index line is the mean across venues in each bucket, on the side the row shows. History begins when recording began, not when the question did.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "7d"
            }
          },
          {
            "name": "interval",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "1h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read",
              "predxy.api.history"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/index/{slug}": {
      "get": {
        "tags": [
          "Index"
        ],
        "summary": "One question by slug",
        "description": "The entry exactly as the index lists it, alone, with the ids of the markets that make it up — each readable at /v1/markets/{id} for the venue's own wording and resolution rules. 404 when no question has the slug.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/changes": {
      "get": {
        "tags": [
          "Changes"
        ],
        "summary": "Questions in the order they changed",
        "description": "Every question that changed after `cursor`, oldest change first, each as the index lists it now. Leave `cursor` out to start from the beginning: that lists every question once, which is how a copy is built. Then keep the `cursor` each response returns and ask with it; while `hasMore` is true, ask again at once, and once it is false, again after a minute or so, when the index next refreshes. A question that changed several times since the cursor appears once, as it is now. `kind` is created (new since the cursor), updated or removed; a removed question has no entry and its slug stops answering. Changes counted are the wording, filing, price at a hundredth of a point, venues, dates, total volume and whether it trades or has settled — not the 24-hour change or volume, which move with the clock. `take` is at most 200. Removals are kept for 90 days: a cursor older than one forgotten is refused with 410, and the copy has to be built again from the beginning.",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeFeedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "410": {
            "description": "Gone",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/calendar": {
      "get": {
        "tags": [
          "Calendar"
        ],
        "summary": "Questions settling in a window, soonest first",
        "description": "`window` accepts today, tomorrow, thisWeek, nextWeek, past or custom, and defaults to today. Anything but custom is resolved against `tzOffsetMinutes` — the reader's offset from UTC, so a day boundary is the reader's midnight rather than ours. \n\nSending `from` and/or `to` implies custom, so bounds work without also setting `window`; either may be omitted for an open-ended period. Combining them with a named window is refused rather than guessed at. The `window` in the response is the one actually used. \n\nThe response repeats the resolved `from` and `to` so a client can label the period it is showing, and carries `total` for paging. Rows are ordered by settlement time; a page can therefore split a day, which is why grouping by date belongs in the client rather than here. \n\n`includeSettled=true` also includes closed and settled questions; the default continues to show open questions only. Scheduled dates are not proof of settlement. No importance score is returned. `volume24h`, `volumeTotal`, `venueCount` and `pricedVenueCount` are the raw signals a client can rank on — publishing a single opaque number would be a ranking we had not published the arithmetic for (invariant 14).",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tzOffsetMinutes",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 50
            }
          },
          {
            "name": "includeSettled",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/venues/ranking": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Venue leaderboard",
        "description": "Ranks tracked venues on a weighted composite. Every response carries the full methodology and a per-metric breakdown, so the score can be recomputed by hand.",
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/sentiment/fear-greed": {
      "get": {
        "tags": [
          "Sentiment"
        ],
        "summary": "Predxy Fear & Greed: latest snapshot, coverage and methodology",
        "description": "An experimental activity/uncertainty proxy over all open indexed questions. A nullable score is intentional during baseline warm-up or insufficient coverage. status=stale preserves the last snapshot and its original timestamp. No calculation or venue calls occur on this read.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FearGreedCurrentResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/v1/sentiment/fear-greed/history": {
      "get": {
        "tags": [
          "Sentiment"
        ],
        "summary": "Recorded UTC daily closing values, including warm-up gaps; 1–90 days",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FearGreedHistoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "predxy.api.read"
            ]
          },
          {
            "Bearer": [ ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ChangeFeedResponse": {
        "required": [
          "asOf",
          "cursor",
          "hasMore",
          "changes"
        ],
        "type": "object",
        "properties": {
          "asOf": {
            "type": "string",
            "format": "date-time"
          },
          "cursor": {
            "type": "string"
          },
          "hasMore": {
            "type": "boolean"
          },
          "changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuestionChangeResponse"
            }
          }
        }
      },
      "FearGreedCategory": {
        "required": [
          "category",
          "questions",
          "events",
          "score",
          "coverage",
          "components"
        ],
        "type": "object",
        "properties": {
          "category": {
            "type": "string"
          },
          "questions": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "events": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "coverage": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FearGreedComponent"
            }
          }
        }
      },
      "FearGreedComponent": {
        "required": [
          "key",
          "weight",
          "rawValue",
          "reportingQuestions",
          "questionCoverage",
          "baselineDays",
          "percentile",
          "score",
          "effectiveWeight",
          "contribution"
        ],
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "weight": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "rawValue": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "reportingQuestions": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "questionCoverage": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "baselineDays": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "percentile": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "effectiveWeight": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "contribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "readiness": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "FearGreedCurrentResponse": {
        "required": [
          "methodology",
          "status",
          "servedAt",
          "snapshot"
        ],
        "type": "object",
        "properties": {
          "methodology": {
            "$ref": "#/components/schemas/FearGreedMethodology"
          },
          "status": {
            "type": "string"
          },
          "servedAt": {
            "type": "string",
            "format": "date-time"
          },
          "snapshot": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FearGreedSnapshot"
              }
            ]
          }
        }
      },
      "FearGreedHistoryPoint": {
        "required": [
          "asOf",
          "score",
          "classification",
          "status",
          "coverage",
          "provisional"
        ],
        "type": "object",
        "properties": {
          "asOf": {
            "type": "string",
            "format": "date-time"
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "classification": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "type": "string"
          },
          "coverage": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "provisional": {
            "type": "boolean"
          }
        }
      },
      "FearGreedHistoryResponse": {
        "required": [
          "methodology",
          "from",
          "to",
          "points"
        ],
        "type": "object",
        "properties": {
          "methodology": {
            "$ref": "#/components/schemas/FearGreedMethodology"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FearGreedHistoryPoint"
            }
          }
        }
      },
      "FearGreedMethodology": {
        "required": [
          "version",
          "experimental",
          "interpretation",
          "universe",
          "aggregation",
          "normalisation",
          "limitations",
          "baselineDays",
          "minimumBaselineDays",
          "minimumQuestions",
          "minimumCoverage",
          "snapshotMinutes",
          "staleAfterMinutes",
          "metrics"
        ],
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "experimental": {
            "type": "boolean"
          },
          "interpretation": {
            "type": "string"
          },
          "universe": {
            "type": "string"
          },
          "aggregation": {
            "type": "string"
          },
          "normalisation": {
            "type": "string"
          },
          "limitations": {
            "type": "string"
          },
          "baselineDays": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "minimumBaselineDays": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "minimumQuestions": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "minimumCoverage": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "snapshotMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "staleAfterMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "metrics": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FearGreedMetric"
            }
          }
        }
      },
      "FearGreedMetric": {
        "required": [
          "key",
          "weight",
          "higherIsGreed",
          "formula"
        ],
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "weight": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "higherIsGreed": {
            "type": "boolean"
          },
          "formula": {
            "type": "string"
          },
          "comparableOnly": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "FearGreedSnapshot": {
        "required": [
          "version",
          "asOf",
          "computedAt",
          "status",
          "score",
          "classification",
          "provisional",
          "coverage",
          "indexedQuestions",
          "openQuestions",
          "categories"
        ],
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "asOf": {
            "type": "string",
            "format": "date-time"
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string"
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "classification": {
            "type": [
              "null",
              "string"
            ]
          },
          "provisional": {
            "type": "boolean"
          },
          "coverage": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "indexedQuestions": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "openQuestions": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FearGreedCategory"
            }
          },
          "baselineDaysCollected": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "inputCoverage": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "IndexEntryResponse": {
        "required": [
          "rank",
          "clusterId",
          "slug",
          "question",
          "eventTitle",
          "outcomeTitle",
          "foldedOutcomes",
          "hypeCount",
          "category",
          "categories",
          "countries",
          "outcome",
          "price",
          "basis",
          "change",
          "priceBefore",
          "volume24h",
          "volumeTotal",
          "marketCount",
          "venueCount",
          "pricedVenueCount",
          "priceLow",
          "priceHigh",
          "spread",
          "venues",
          "resolvesAt",
          "resolvesAtIsDate",
          "firstSeenAt",
          "sparkline",
          "settled"
        ],
        "type": "object",
        "properties": {
          "rank": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "clusterId": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "question": {
            "type": "string"
          },
          "eventTitle": {
            "type": [
              "null",
              "string"
            ]
          },
          "outcomeTitle": {
            "type": [
              "null",
              "string"
            ]
          },
          "foldedOutcomes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "hypeCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "category": {
            "type": "string"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "outcome": {
            "type": "string"
          },
          "price": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "basis": {
            "type": "string"
          },
          "change": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "priceBefore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "volume24h": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "volumeTotal": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "marketCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "venueCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pricedVenueCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "priceLow": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "priceHigh": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "spread": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "venues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "resolvesAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "resolvesAtIsDate": {
            "type": "boolean"
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "sparkline": {
            "type": "array",
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "settled": {
            "type": "boolean"
          },
          "holderCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "holderReportingMarkets": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "default": 0
          },
          "holderTotalMarkets": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "default": 0
          }
        }
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "QuestionChangeResponse": {
        "required": [
          "seq",
          "kind",
          "clusterId",
          "slug",
          "question"
        ],
        "type": "object",
        "properties": {
          "seq": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "kind": {
            "type": "string"
          },
          "clusterId": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "question": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/IndexEntryResponse"
              }
            ]
          }
        }
      }
    },
    "securitySchemes": {
      "OAuth2": {
        "type": "oauth2",
        "description": "Machine-to-machine. Send your client id and secret to the token endpoint and the reference page will carry the token on every request.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://id.predxy.com/connect/token",
            "scopes": {
              "predxy.api.read": "Read market data",
              "predxy.api.detail": "Read a venue's own detail for a market",
              "predxy.api.history": "Read recorded price history"
            }
          }
        }
      },
      "Bearer": {
        "type": "http",
        "description": "Paste an access token with the operation's required permissions. Partner tokens come from a client credentials POST to https://id.predxy.com/connect/token. Internal operations require the appropriate first-party or user token; signing into documentation does not authorize API calls.",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "tags": [
    {
      "name": "Public"
    },
    {
      "name": "Markets"
    },
    {
      "name": "Index"
    },
    {
      "name": "Changes"
    },
    {
      "name": "Calendar"
    },
    {
      "name": "Sentiment"
    }
  ]
}