{
  "openapi": "3.1.0",
  "info": {
    "title": "PMWallets API",
    "version": "1.0.0",
    "summary": "Polymarket wallet leaderboard, address unlocks, live fill subscriptions and trade-history exports.",
    "description": "PMWallets tracks every Polymarket fill on Polygon, groups wallets that belong together into **entities**, and ranks them by forward-only PnL over published windows (`30d`, `7d`; each recomputed about once a day). It sells three things: the **address** behind an entity, a **live stream of its fills** (billed per hour), and **per-wallet daily trade-history files**.\n\n**Handles vs addresses.** An entity whose address you have not bought is named by a 12-character **handle** in `entityId` (Crockford base32, e.g. `7KQ2MF9X4B1C`) with a masked address in `label` (`0x4b96…984e`). After you unlock it (`POST /v1/account/reveals`), follow it, or unlock it from a plan, `entityId` and `label` are the full 0x address. Send handles back to every endpoint that takes an entity; a raw address is only accepted from a caller who already holds it. A masked label is never accepted.\n\n**Money.** Prices are integer US cents. Charges come from the prepaid account balance (top-ups happen on https://pmwallets.com). Every charging call takes a ceiling (`maxPriceCents` / `maxCents`) and answers 409 instead of charging more. 402 means not enough balance; nothing was charged.\n\n**Quotas.** A signed-in board read spends rows from a 20,000-row daily allowance (UTC day). Opening an entity page as a subscriber, unlocking, subscribing and exporting each spend one unit of a daily *distinct-entity* budget (50 by default, raised by plans); touching the same entity again that day is free. Over-limit answers are 403. Heavy reads are rate limited per account and per IP (429).\n\n**Auth.** Send an API key `pmw_<prefix>_<secret>` in `x-api-key` (`Authorization: Bearer <key>` also works). Create keys at https://pmwallets.com/keys. A key can spend the balance but cannot manage keys, add/remove webhooks or change a card plan (session-only, not in this document). Without a key: the 20-row board sample, periods, plans, rate card, markets, latency and readiness.\n\n**Live fills are not in this document.** They arrive over the WebSocket `wss://api.pmwallets.com/v1/ws` (send the key in `x-api-key`; one API connection per account, `?clientId=<8-64 chars>&takeover=1` replaces another) or as signed webhooks (see `webhooks.fill`; the endpoint is registered on the website). An agent without a long-running process can poll `GET /v1/account/fills` with the `next` cursor instead: same fills, same `eventId`, scoped to active subscriptions, retained 60 days.\n\n**Units.** In fills, `usdc`, `shares` and `fee` are integer strings in 1e-6 units (`\"1824000000\"` = $1,824); `price` is a decimal string; `ts` is UTC `YYYY-MM-DD HH:MM:SS`. Board and entity figures (`realizedPnl`, `grossBuyUsdc`, …) are dollars as numbers.",
    "contact": {
      "name": "PMWallets",
      "url": "https://pmwallets.com",
      "email": "support@pmwallets.com"
    }
  },
  "servers": [
    {
      "url": "https://api.pmwallets.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Board",
      "description": "Leaderboard, entity pages and market aggregates."
    },
    {
      "name": "Unlocks",
      "description": "Buying the address behind a handle."
    },
    {
      "name": "Push",
      "description": "Live fill subscriptions, webhook health and fill replay."
    },
    {
      "name": "Exports",
      "description": "Per-wallet daily trade-history files."
    },
    {
      "name": "Plans",
      "description": "Monthly plans (Base / Pro / Max)."
    },
    {
      "name": "Account",
      "description": "Identity, balance, statement and invites."
    },
    {
      "name": "Status",
      "description": "Service health and latency."
    }
  ],
  "paths": {
    "/v1/ready": {
      "get": {
        "operationId": "getReady",
        "tags": [
          "Status"
        ],
        "summary": "Service readiness",
        "security": [],
        "description": "200 when ingest, push, board, exports and smart-money files are all current; 503 with the failing components otherwise.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ready"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "Something is stale; `problems` says what.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ready"
                }
              }
            }
          }
        }
      }
    },
    "/v1/periods": {
      "get": {
        "operationId": "listPeriods",
        "tags": [
          "Board"
        ],
        "summary": "Published board windows",
        "security": [
          {},
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "The published windows (e.g. 30d, 7d) with their block range and run. Free.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Period"
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/leaderboard": {
      "get": {
        "operationId": "getLeaderboard",
        "tags": [
          "Board"
        ],
        "summary": "Ranked entities with filters",
        "security": [
          {},
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Entities ranked by PnL. Unbought entities appear as handles with their unlock price (revealCents). No key: 20-row sample. With a key: up to 200 rows a call; each call spends `limit` rows of a 20,000/day allowance (403 when used up). mine=1 lists your unlocked addresses, free. Never charges.",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Window id from GET /v1/periods (30d or 7d). Default 30d. Unknown → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Order column. Default realizedPnl; an unknown value falls back to realizedPnl.",
            "schema": {
              "type": "string",
              "enum": [
                "realizedPnl",
                "roiOnBuys",
                "eligible",
                "winsLosses",
                "nFills",
                "conditions",
                "grossBuyUsdc",
                "unrealizedPnl",
                "winLo",
                "fillsPerDay",
                "lastFill"
              ],
              "default": "realizedPnl"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "Sort direction. Anything other than asc means desc.",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows to return, 1-200 (anonymous capped to 20). Out of range → 400. With a key this many rows are taken from the daily allowance, whether or not that many come back.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Rows to skip, 0-100000 (anonymous forced to 0).",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "mine",
            "in": "query",
            "required": false,
            "description": "Set to 1 to list only the addresses you have unlocked (needs a key; 401 without). Spends no row allowance; minEligible defaults to 0.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          },
          {
            "name": "minEligible",
            "in": "query",
            "required": false,
            "description": "Floor on settled markets (wins + losses + breakevens). Default 5.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 5
            }
          },
          {
            "name": "minWinsLosses",
            "in": "query",
            "required": false,
            "description": "Floor on markets won or lost (breakevens excluded). Absent = no floor; the website uses 10.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000
            }
          },
          {
            "name": "minPnl",
            "in": "query",
            "required": false,
            "description": "Floor on realised PnL, dollars. May be negative.",
            "schema": {
              "type": "number",
              "minimum": -1000000000000,
              "maximum": 1000000000000
            }
          },
          {
            "name": "minRoi",
            "in": "query",
            "required": false,
            "description": "Floor on ROI on buys (0.2 = 20%).",
            "schema": {
              "type": "number",
              "minimum": -100,
              "maximum": 1000000
            }
          },
          {
            "name": "minWinLo",
            "in": "query",
            "required": false,
            "description": "Floor on the Wilson 95% lower bound of the win rate.",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            }
          },
          {
            "name": "maxWallets",
            "in": "query",
            "required": false,
            "description": "Ceiling on addresses of the entity that traded in the window (1 = single address).",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 100000
            }
          },
          {
            "name": "minFills",
            "in": "query",
            "required": false,
            "description": "Floor on fills in the window.",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 1000000000000
            }
          },
          {
            "name": "minVolume",
            "in": "query",
            "required": false,
            "description": "Floor on dollars spent buying in the window (grossBuyUsdc).",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 1000000000000000
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Last fill <24h (active), <7d (quiet), older (dormant).",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "quiet",
                "dormant"
              ]
            }
          },
          {
            "name": "style",
            "in": "query",
            "required": false,
            "description": "By share of traded value made as maker: >=0.8 maker, <=0.2 taker, else two-sided.",
            "schema": {
              "type": "string",
              "enum": [
                "maker",
                "taker",
                "two-sided"
              ]
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Entities that traded this category in the window.",
            "schema": {
              "type": "string",
              "enum": [
                "crypto-updown",
                "crypto",
                "esports",
                "sports",
                "politics",
                "economy",
                "geopolitics",
                "science-tech",
                "culture",
                "other",
                "unknown"
              ]
            }
          },
          {
            "name": "minCategoryShare",
            "in": "query",
            "required": false,
            "description": "With category only (400 otherwise): at least this share (0, 1] of traded value in that category.",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 1
            }
          },
          {
            "name": "bands",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "description": "Unlock price bands, any of them, comma-separated (0 = free … 5). Priced on the 30d window whatever `period` is.",
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "enum": [
                  0,
                  1,
                  2,
                  3,
                  4,
                  5
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Leaderboard"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "description": "mine=1 without a valid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Daily row allowance used up; resets 00:00 UTC.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "statusCode": 403,
                  "message": "daily row limit reached (20000); it resets at 00:00 UTC",
                  "error": "Forbidden"
                }
              }
            }
          },
          "404": {
            "description": "No published stats yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/entities/{id}": {
      "get": {
        "operationId": "getEntity",
        "tags": [
          "Board"
        ],
        "summary": "One entity in full",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Figures, badges, PnL curve, wallets and recent fills. Subscribers (active push or plan) open any entity, spending 1 daily distinct-entity unit; others only the free sample or entities they paid to unlock. A raw address you do not hold: 403 not_unlocked with handle and price. Never charges.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "A 12-character entity handle (Crockford base32, e.g. 7KQ2MF9X4B1C) or a full 0x address (40 hex).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Window id (30d or 7d). Default 30d.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entity"
                }
              }
            }
          },
          "400": {
            "description": "Not a handle or 0x address, unknown handle, or unknown period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`error: not_unlocked` (address you do not hold; body has entityId = handle, label, revealCents), the daily distinct-entity limit, or outside the free sample (needs a subscription or a paid unlock).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "statusCode": 403,
                  "error": "not_unlocked",
                  "message": "open this wallet by its handle; an address opens only for the reader who bought or follows it",
                  "entityId": "7KQ2MF9X4B1C",
                  "label": "0x4b96…984e",
                  "revealCents": 100
                }
              }
            }
          },
          "404": {
            "description": "No published stats for this entity in the window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/v1/markets": {
      "get": {
        "operationId": "listMarkets",
        "tags": [
          "Board"
        ],
        "summary": "Per-market trader aggregates",
        "security": [
          {},
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "The busiest markets of the 30d window (up to 1,000, at least 20 traders each) with counts and sums over traders, never any one trader. Same answer for everyone; may serve the previous run while a new one loads.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "periodId": {
                      "type": "string"
                    },
                    "b0": {
                      "type": "integer"
                    },
                    "b1": {
                      "type": "integer"
                    },
                    "completedAt": {
                      "type": "string"
                    },
                    "markets": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MarketStat"
                      }
                    },
                    "minTraders": {
                      "type": "integer"
                    },
                    "strongRule": {
                      "type": "object",
                      "properties": {
                        "minDecided": {
                          "type": "integer"
                        },
                        "minWinLo": {
                          "type": "number"
                        },
                        "minGroup": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No published stats yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/v1/latency": {
      "get": {
        "operationId": "getLatency",
        "tags": [
          "Status"
        ],
        "summary": "Chain head, ingest and push latency",
        "security": [],
        "description": "Current chain head, ingest timing, push latency (detect→push seconds, p50/p95) and board freshness over the last `hours`.",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "Window in hours, 1-720. Default 24. Out of range → 400.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 720,
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "hours": {
                      "type": "integer"
                    },
                    "head": {
                      "type": "object",
                      "properties": {
                        "block": {
                          "type": "integer"
                        },
                        "ts": {
                          "type": "string"
                        }
                      }
                    },
                    "ingest": {
                      "type": "object",
                      "additionalProperties": true,
                      "properties": {
                        "n": {
                          "type": "integer"
                        },
                        "blocksTotal": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "storedP50": {
                          "type": "number"
                        },
                        "storedP95": {
                          "type": "number"
                        },
                        "reorgs": {
                          "type": "integer"
                        }
                      }
                    },
                    "push": {
                      "type": "object",
                      "properties": {
                        "n": {
                          "type": "integer"
                        },
                        "detectToPushSecP50": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "detectToPushSecP95": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "failed": {
                          "type": "integer"
                        }
                      }
                    },
                    "stats": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "periodId": {
                          "type": "string"
                        },
                        "b1": {
                          "type": "integer"
                        },
                        "completedAt": {
                          "type": "string"
                        },
                        "ageSec": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/latency/shape": {
      "get": {
        "operationId": "getLatencyShape",
        "tags": [
          "Status"
        ],
        "summary": "Push latency series and histogram",
        "security": [],
        "description": "Push latency over time and its histogram, for deliveries actually handed off.",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "One of 1, 24, 168, 720; anything else means 24.",
            "schema": {
              "type": "integer",
              "enum": [
                1,
                24,
                168,
                720
              ],
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bucketSec": {
                      "type": "integer"
                    },
                    "statuses": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "series": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "t": {
                            "type": "string"
                          },
                          "n": {
                            "type": "integer"
                          },
                          "p50": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "p95": {
                            "type": [
                              "number",
                              "null"
                            ]
                          }
                        }
                      }
                    },
                    "histogram": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "bucket": {
                            "type": "string",
                            "enum": [
                              "<1s",
                              "1-2s",
                              "2-3s",
                              "3-5s",
                              "5-10s",
                              ">10s"
                            ]
                          },
                          "n": {
                            "type": "integer"
                          },
                          "share": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/latency/incidents": {
      "get": {
        "operationId": "listLatencyIncidents",
        "tags": [
          "Status"
        ],
        "summary": "Slow-push incidents, last 30 days",
        "security": [],
        "description": "Stretches in the last 30 days where the push median exceeded the threshold.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "days": {
                      "type": "integer"
                    },
                    "thresholdSec": {
                      "type": "number"
                    },
                    "incidents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string"
                          },
                          "to": {
                            "type": "string"
                          },
                          "p50": {
                            "type": "number"
                          },
                          "p95": {
                            "type": "number"
                          },
                          "worst": {
                            "type": "number"
                          },
                          "pushes": {
                            "type": "integer"
                          },
                          "failed": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/plans": {
      "get": {
        "operationId": "listPlans",
        "tags": [
          "Plans"
        ],
        "summary": "Monthly plan tiers",
        "security": [],
        "description": "Base / Pro / Max with price and allowances, and whether each is on sale.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currency": {
                      "type": "string",
                      "const": "usd"
                    },
                    "interval": {
                      "type": "string",
                      "const": "month"
                    },
                    "tiers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PlanTier"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/exports/rate-card": {
      "get": {
        "operationId": "getExportRateCard",
        "tags": [
          "Exports"
        ],
        "summary": "Export price list",
        "security": [],
        "description": "Per-day marginal price tiers, limits and the CSV columns of the daily files.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currency": {
                      "type": "string"
                    },
                    "cnyPerUsd": {
                      "type": "number"
                    },
                    "minDays": {
                      "type": "integer"
                    },
                    "maxDays": {
                      "type": "integer"
                    },
                    "maxEntities": {
                      "type": "integer"
                    },
                    "rateCard": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RateTier"
                      }
                    },
                    "quantityDiscount": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    },
                    "bulkDiscount": {
                      "type": "number"
                    },
                    "columns": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "format": {
                      "type": "string",
                      "const": "csv.zst"
                    },
                    "files": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/auth/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Account"
        ],
        "summary": "Who the key belongs to",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "The account behind the key. Use it to check a key works.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "name": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "avatarUrl": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "inviteLive": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/plan": {
      "get": {
        "operationId": "getPlan",
        "tags": [
          "Plans"
        ],
        "summary": "Your plan, balance and allowances",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Current plan (card or balance-paid), period, queued period, balance, and what is used of unlock / push / export allowances.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanStatus"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/plan/quote": {
      "post": {
        "operationId": "quotePlanChange",
        "tags": [
          "Plans"
        ],
        "summary": "Price a plan tier change",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "What moving to `tier` would do today (kind: upgrade with `cents` charged now, downgrade, same, keep, or a refusal kind such as not_active). Charges nothing. Card-plan changes themselves are session-only (website); a balance-paid plan is extended or moved down with POST /v1/account/plan/balance.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tier": {
                    "type": "string",
                    "enum": [
                      "base",
                      "pro",
                      "max"
                    ]
                  }
                },
                "required": [
                  "tier"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Quote (HTTP 201, nothing charged).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "upgrade",
                        "downgrade",
                        "same",
                        "keep",
                        "balance_downgrade",
                        "not_active",
                        "not_on_sale",
                        "downgrade_pending",
                        "payment_pending",
                        "trialing"
                      ]
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "cents": {
                      "type": "integer",
                      "description": "Charged today for an upgrade."
                    },
                    "periodEnd": {
                      "type": "string"
                    },
                    "caps": {
                      "type": "object",
                      "properties": {
                        "monthly": {
                          "type": "integer"
                        },
                        "exports": {
                          "type": "integer"
                        }
                      }
                    },
                    "period": {
                      "type": "integer",
                      "description": "Balance plans: the period number the quote is for."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/plan/balance": {
      "post": {
        "operationId": "buyPlanFromBalance",
        "tags": [
          "Plans"
        ],
        "summary": "Buy 30 days of a plan from the balance",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "CHARGES THE BALANCE the tier price for 30 days that never renew (starts now, or queues behind the running period). maxCents caps the charge (409 price_changed). requestId is required: a retry with it returns the same period, never a second charge. Refused while a card plan is active.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tier",
                  "maxCents",
                  "requestId"
                ],
                "properties": {
                  "tier": {
                    "type": "string",
                    "enum": [
                      "base",
                      "pro",
                      "max"
                    ],
                    "description": "Base 499, Pro 1499, Max 3999 cents per 30 days."
                  },
                  "maxCents": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Most you agree to be charged, in cents."
                  },
                  "requestId": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{8,64}$",
                    "description": "Your idempotency key for this purchase; reuse it on retry, use a new one for a new purchase."
                  }
                }
              },
              "example": {
                "tier": "base",
                "maxCents": 499,
                "requestId": "buy-2026-10-14-001"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Bought (HTTP 201); the body also carries the updated plan status.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "properties": {
                        "outcome": {
                          "type": "string",
                          "enum": [
                            "started",
                            "queued",
                            "replayed"
                          ]
                        },
                        "startsAt": {
                          "type": "string"
                        },
                        "endsAt": {
                          "type": "string"
                        },
                        "cents": {
                          "type": "integer"
                        }
                      }
                    },
                    {
                      "$ref": "#/components/schemas/PlanStatus"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`code: insufficient_balance`; nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "statusCode": 402,
                  "code": "insufficient_balance",
                  "message": "the period costs 499 cents, more than your balance; top up first",
                  "cents": 499
                }
              }
            }
          },
          "409": {
            "description": "`code` one of: price_changed (with `cents`), card_active, fix_payment, checkout_open, already_queued, request_conflict. Nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`code: stripe_unavailable` or temporarily unavailable; nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/account/billing": {
      "get": {
        "operationId": "getBilling",
        "tags": [
          "Account"
        ],
        "summary": "Balance and recent statement",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Balance in cents, the hourly push price, top-up limits, the first 25 statement lines (`ledgerNext` pages on via GET /v1/account/ledger) and any open crypto top-up order.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "balanceCents": {
                      "type": "integer"
                    },
                    "priceCentsPerHour": {
                      "type": "integer"
                    },
                    "minTopupCents": {
                      "type": "integer"
                    },
                    "maxTopupCents": {
                      "type": "integer"
                    },
                    "rails": {
                      "type": "object",
                      "properties": {
                        "stripe": {
                          "type": "boolean"
                        },
                        "crypto": {
                          "type": "boolean"
                        }
                      }
                    },
                    "ledger": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LedgerEntry"
                      }
                    },
                    "ledgerNext": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "openCryptoOrder": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/ledger": {
      "get": {
        "operationId": "listLedger",
        "tags": [
          "Account"
        ],
        "summary": "Balance statement, paged",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Credits and charges, newest first.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-100, default 25.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "`next` from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LedgerPage"
                }
              }
            }
          },
          "400": {
            "description": "Bad cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/reveals": {
      "post": {
        "operationId": "unlockEntity",
        "tags": [
          "Unlocks"
        ],
        "summary": "Buy an entity's address",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "CHARGES THE BALANCE the entity's band price (0 = free) and returns its address. Send the handle and maxPriceCents, the price shown (higher now: 409 price_changed, nothing charged). Paid unlocks are permanent. viaPlan uses the plan allowance instead. Spends 1 daily distinct-entity unit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entityId",
                  "maxPriceCents"
                ],
                "properties": {
                  "entityId": {
                    "type": "string",
                    "description": "The 12-character handle from the board. A raw address is refused (400) unless you already own it."
                  },
                  "maxPriceCents": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Ceiling in cents: the price you were shown. 0 is a real cap (free band)."
                  },
                  "viaPlan": {
                    "type": "boolean",
                    "description": "Unlock from the active plan allowance instead of buying."
                  }
                }
              },
              "example": {
                "entityId": "7KQ2MF9X4B1C",
                "maxPriceCents": 100
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Unlocked, or already owned (alreadyOwned: true, nothing charged). HTTP 201. A free unlock lasts only while the wallet stays in the free band.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnlockResult"
                }
              }
            }
          },
          "400": {
            "description": "Missing/invalid maxPriceCents, unknown handle, or a raw address you do not own.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`error: insufficient_balance` with priceCents and balanceCents; nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "statusCode": 402,
                  "error": "insufficient_balance",
                  "message": "not enough balance to unlock this address; top up and retry",
                  "priceCents": 100,
                  "balanceCents": 20
                }
              }
            }
          },
          "403": {
            "description": "Daily distinct-entity limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Entity is not in any published window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`error: price_changed` (priceCents, agreedCents) or `error: plan_exhausted` (limit, priceCents). Nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "statusCode": 409,
                  "error": "price_changed",
                  "message": "this wallet moved to another price band since the page loaded; confirm the new price",
                  "priceCents": 150,
                  "agreedCents": 100
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      },
      "get": {
        "operationId": "listUnlocks",
        "tags": [
          "Unlocks"
        ],
        "summary": "Addresses you have unlocked",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Your unlock receipts, newest payment first (up to 500). A lapsed free unlock shows its handle, `entitled: false` and the price to take it back.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Unlock"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/subscriptions": {
      "get": {
        "operationId": "listSubscriptions",
        "tags": [
          "Push"
        ],
        "summary": "Your push subscriptions",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Active and paused subscriptions, newest first, each with its entity's top categories and last fill. Canceled ones are not listed.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Subscription"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "createSubscription",
        "tags": [
          "Push"
        ],
        "summary": "Follow an entity (live fills)",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Pushes the entity's fills to your WebSocket/webhook. Unlock its address first (402 address_not_unlocked). CHARGES 1 cent now for the first hour, then hourly until canceled (free within plan push slots). Spends 1 daily distinct-entity unit. Starts ~96 s (65 blocks) behind the head.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entityId"
                ],
                "properties": {
                  "entityId": {
                    "type": "string",
                    "description": "A 12-character entity handle (Crockford base32, e.g. 7KQ2MF9X4B1C) or a full 0x address (40 hex)."
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "ws",
                        "webhook"
                      ]
                    },
                    "default": [
                      "ws"
                    ],
                    "description": "Where to deliver. Default [\"ws\"]."
                  },
                  "acceptInactive": {
                    "type": "boolean",
                    "description": "Subscribe even if the entity has had no fill for 7 days (otherwise 409)."
                  }
                }
              },
              "example": {
                "entityId": "0x9d84ce0306f8551e02efef1680475fc0f1dc1344",
                "channels": [
                  "ws",
                  "webhook"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Subscribed, first hour paid (HTTP 201). Hours with no feed are not charged; pauses when the balance runs out. At most 200 active.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            }
          },
          "400": {
            "description": "Bad entityId/channels, or 200 active subscriptions already.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`error: address_not_unlocked` (unlock it first), or not enough balance for the first hour (priceCentsPerHour, balanceCents). Nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "statusCode": 402,
                  "message": "insufficient balance for the first hour",
                  "priceCentsPerHour": 1,
                  "balanceCents": 0
                }
              }
            }
          },
          "403": {
            "description": "Daily distinct-entity limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Entity is not in any published window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Dormant entity (resend with acceptInactive: true), already subscribed, a concurrent create, or the only channel is a missing/switched-off webhook. Nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Fill feed or chain head unavailable; nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/account/subscriptions/{id}": {
      "delete": {
        "operationId": "cancelSubscription",
        "tags": [
          "Push"
        ],
        "summary": "Cancel a subscription",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Stops delivery and hourly charging now. The hour already paid is not refunded. Final: subscribe again for a new one.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Subscription id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The subscription, status canceled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/account/subscriptions/{id}/resume": {
      "post": {
        "operationId": "resumeSubscription",
        "tags": [
          "Push"
        ],
        "summary": "Resume a paused subscription",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "CHARGES THE BALANCE one hour at the subscription's own price and restarts delivery 65 blocks behind the head; the paused span is not backfilled. Idempotent under lock (a retry does not charge twice).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Subscription id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Active again (HTTP 201).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            }
          },
          "400": {
            "description": "200 active subscriptions already.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Not enough balance for the hour, or `error: address_not_unlocked` (the address came from a plan that ended).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Canceled (subscribe again instead) or the only channel is a missing/switched-off webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/v1/account/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "Push"
        ],
        "summary": "Your webhook endpoint and its health",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "The active webhook endpoint (at most one) with delivery health. With an API key the URL is reduced to its origin. Adding or removing endpoints is session-only (website).",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Webhook"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/webhooks/{id}/reactivate": {
      "post": {
        "operationId": "reactivateWebhook",
        "tags": [
          "Push"
        ],
        "summary": "Turn a switched-off webhook back on",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Re-enables an endpoint switched off for failing, then resumes the subscriptions that were paused for it; each resumed one CHARGES ITS FIRST HOUR again. Safe to retry (no double charge). Fills missed while off are not re-sent.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook endpoint id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "reactivated": {
                      "type": "boolean",
                      "description": "false = it was already on."
                    },
                    "resumed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "notResumed": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/v1/account/deliveries": {
      "get": {
        "operationId": "listDeliveries",
        "tags": [
          "Push"
        ],
        "summary": "Your push deliveries, paged",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Each fill pushed to you per channel, newest first, with status and timing.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-200, default 30.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 30
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "`next` from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Delivery"
                      }
                    },
                    "next": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/delivery-stats": {
      "get": {
        "operationId": "getDeliveryStats",
        "tags": [
          "Push"
        ],
        "summary": "Your push latency and failures",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Your own pushes over the window: count, failures, entities, detect→push p50/p95 seconds.",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "1-720 (clamped), default 24.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 720,
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "hours": {
                      "type": "integer"
                    },
                    "pushed": {
                      "type": "integer"
                    },
                    "failed": {
                      "type": "integer"
                    },
                    "entities": {
                      "type": "integer"
                    },
                    "detectToPushSecP50": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "detectToPushSecP95": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/fills": {
      "get": {
        "operationId": "listFills",
        "tags": [
          "Push"
        ],
        "summary": "Fills of followed entities after a cursor",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Polling alternative to the WebSocket: fills of your active subscriptions after the cursor, oldest first. Start without a cursor, pass `next` back until null, store the last one. Free. Kept 60 days (truncated = part of the range is gone).",
        "parameters": [
          {
            "name": "sinceBlock",
            "in": "query",
            "required": false,
            "description": "Cursor block (exclusive with sinceLogIndex). Default 0.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 4294967295,
              "default": 0
            }
          },
          {
            "name": "sinceLogIndex",
            "in": "query",
            "required": false,
            "description": "Cursor log index. Default 0.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 4294967295,
              "default": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-2000, default 500. Out of range → 400.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2000,
              "default": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Fill"
                      }
                    },
                    "next": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "sinceBlock": {
                          "type": "integer"
                        },
                        "sinceLogIndex": {
                          "type": "integer"
                        }
                      },
                      "description": "Pass back as query params; null = caught up."
                    },
                    "subscriptions": {
                      "type": "integer",
                      "description": "Active subscriptions in scope (0 = nothing to replay)."
                    },
                    "retainedFrom": {
                      "type": "integer",
                      "description": "Oldest block still kept (absent when subscriptions is 0)."
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "Part of the asked range is older than retention."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/exports/window": {
      "get": {
        "operationId": "getExportWindow",
        "tags": [
          "Exports"
        ],
        "summary": "Sellable export days and quick ranges",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "The span of published daily files you can buy, with the 30/60/90/all-day ranges priced for one entity.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "window": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "from": {
                          "type": "string"
                        },
                        "to": {
                          "type": "string"
                        }
                      }
                    },
                    "presets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "enum": [
                              "30",
                              "60",
                              "90",
                              "all"
                            ]
                          },
                          "from": {
                            "type": "string"
                          },
                          "to": {
                            "type": "string"
                          },
                          "days": {
                            "type": "integer"
                          },
                          "sellable": {
                            "type": "boolean"
                          },
                          "priceCents": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "minDays": {
                      "type": "integer"
                    },
                    "maxDays": {
                      "type": "integer"
                    },
                    "archive": {
                      "type": "object",
                      "properties": {
                        "days": {
                          "type": "integer"
                        },
                        "from": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "to": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "missing": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/exports/quote": {
      "post": {
        "operationId": "quoteExport",
        "tags": [
          "Exports"
        ],
        "summary": "Price an export",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Price of (entities × days); dates are clamped into the sellable window. Charges nothing, spends no budget. Name all entities the same way (all handles or all addresses).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportRequest"
              },
              "example": {
                "entityIds": [
                  "7KQ2MF9X4B1C"
                ],
                "from": "2026-08-01",
                "to": "2026-09-29"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Quote (HTTP 201, nothing charged).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportQuote"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/exports": {
      "get": {
        "operationId": "listExports",
        "tags": [
          "Exports"
        ],
        "summary": "Your export orders",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Your last 50 export orders, newest first.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExportOrder"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "createExport",
        "tags": [
          "Exports"
        ],
        "summary": "Buy an export",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "CHARGES THE BALANCE the order price; grants the entities' daily wallet files over [from, to] (30+ days, max 25 entities). maxPriceCents caps it (required for 2+). Same order within 24 h returns the existing one, no charge. 1 distinct-entity unit per entity. viaPlan: from the plan, free.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/ExportRequest"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "maxPriceCents": {
                        "type": "integer",
                        "minimum": 0,
                        "description": "Ceiling in cents (quote orderPriceCents). Required for 2+ entities."
                      },
                      "viaPlan": {
                        "type": "boolean",
                        "description": "Use the plan export allowance (whole window, no charge)."
                      }
                    }
                  }
                ]
              },
              "example": {
                "entityIds": [
                  "7KQ2MF9X4B1C"
                ],
                "from": "2026-08-01",
                "to": "2026-09-29",
                "maxPriceCents": 390
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Paid (or granted) and ready (HTTP 201).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "priceCents": {
                      "type": "integer"
                    },
                    "days": {
                      "type": "integer"
                    },
                    "rows": {
                      "type": "integer"
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "const": "ready"
                    },
                    "viaPlan": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad body, mixed handle/address naming, or `error: not_sellable` (below 30 days / no data).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`error: insufficient_balance` (priceCents, balanceCents) or `error: no_plan` for viaPlan. Nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`error: entity_budget`: daily distinct-entity limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`error: price_changed` with the new `quote`, or `error: plan_exhausted` (cap, used, needed). Nothing charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/v1/account/exports/{id}": {
      "get": {
        "operationId": "getExport",
        "tags": [
          "Exports"
        ],
        "summary": "One export order",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Export order id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportOrder"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/account/exports/{id}/files": {
      "get": {
        "operationId": "listExportFiles",
        "tags": [
          "Exports"
        ],
        "summary": "Files an export grants",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "One file per wallet per UTC day with fills (zstd-compressed CSV). Fetch each `path` to download.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Export order id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "files": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ExportFile"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/account/data/{wallet}/{day}": {
      "get": {
        "operationId": "downloadExportFile",
        "tags": [
          "Exports"
        ],
        "summary": "Download one purchased daily file",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "302 redirect to a signed link (valid 5 minutes) for `<wallet>-<day>.csv.zst`. 404 both when not purchased and when the wallet had no fills that day.",
        "parameters": [
          {
            "name": "wallet",
            "in": "path",
            "required": true,
            "description": "0x wallet address (from the files list).",
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            }
          },
          {
            "name": "day",
            "in": "path",
            "required": true,
            "description": "UTC day YYYY-MM-DD.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the file.",
            "headers": {
              "Location": {
                "description": "Short-lived download URL.",
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/account/invite": {
      "get": {
        "operationId": "getInvite",
        "tags": [
          "Account"
        ],
        "summary": "Your invite code and earnings",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Your code, campaign terms, the code you were invited with, commission earned and invitee count.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "bonusCents": {
                      "type": "integer"
                    },
                    "commissionPct": {
                      "type": "number"
                    },
                    "endsAt": {
                      "type": "string"
                    },
                    "live": {
                      "type": "boolean"
                    },
                    "bound": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "bonusCents": {
                          "type": "integer"
                        },
                        "at": {
                          "type": "string"
                        }
                      }
                    },
                    "earnedCents": {
                      "type": "integer"
                    },
                    "invitedCount": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/invite/invitees": {
      "get": {
        "operationId": "listInvitees",
        "tags": [
          "Account"
        ],
        "summary": "People you invited, paged",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-50, default 10.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "`next` from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "email": {
                            "type": "string",
                            "description": "Masked."
                          },
                          "at": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/invite/bind": {
      "post": {
        "operationId": "bindInviteCode",
        "tags": [
          "Account"
        ],
        "summary": "Redeem an invite code",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Binds an invite code to your account, once ever; while the campaign is live CREDITS a non-refundable bonus to your balance.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Bound (HTTP 201).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "bonusCents": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`error` one of: closed, unknown_code, own_code, already_bound, would_cycle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "webhooks": {
    "fill": {
      "post": {
        "operationId": "fillWebhook",
        "tags": [
          "Push"
        ],
        "summary": "A fill of an entity you follow (sent to your endpoint)",
        "description": "We POST each fill of a subscription with the webhook channel to your registered endpoint. Verify `x-pmw-signature` = hex HMAC-SHA256(endpoint secret, raw body) before parsing. Answer 2xx only after storing it; anything else (or no answer within 5 s) is retried, 3 attempts in total. At-least-once: deduplicate on `data.eventId`.",
        "security": [],
        "parameters": [
          {
            "name": "x-pmw-signature",
            "in": "header",
            "required": true,
            "description": "Hex HMAC-SHA256 of the raw body with your endpoint secret.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "data"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "fill"
                  },
                  "data": {
                    "$ref": "#/components/schemas/PushedFill"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Stored; no retry."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key `pmw_<12 hex>_<64 hex>` from https://pmwallets.com/keys. `Authorization: Bearer <key>` is accepted too."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Error body. `message` is always present; machine-readable refusals add `error` (unlock, export, subscription paths) or `code` (plan paths) plus the figures the caller needs.",
        "properties": {
          "statusCode": {
            "type": "integer"
          },
          "message": {
            "description": "Human-readable reason (English).",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "error": {
            "type": "string",
            "description": "Machine code, e.g. insufficient_balance, price_changed, not_unlocked, address_not_unlocked, entity_budget, not_sellable, plan_exhausted, no_plan."
          },
          "code": {
            "type": "string",
            "description": "Machine code on plan endpoints, e.g. insufficient_balance, price_changed, card_active, already_queued, request_conflict."
          }
        },
        "required": [
          "message"
        ],
        "additionalProperties": true
      },
      "Fill": {
        "type": "object",
        "description": "One fill of an entity you subscribe to, as GET /v1/account/fills returns it (and the stream carries it).",
        "properties": {
          "eventId": {
            "type": "string",
            "description": "`chain:block:blockHash:txHash:logIndex`; stable across retries and replays. Deduplicate on it."
          },
          "chain": {
            "type": "integer",
            "description": "137 (Polygon)."
          },
          "entityId": {
            "type": "string",
            "description": "The subscribed entity (0x address)."
          },
          "wallet": {
            "type": "string",
            "description": "The address inside the entity that traded (0x)."
          },
          "ts": {
            "type": "string",
            "description": "Block time, UTC, `YYYY-MM-DD HH:MM:SS`."
          },
          "block": {
            "type": "integer"
          },
          "blockHash": {
            "type": "string"
          },
          "txHash": {
            "type": "string"
          },
          "logIndex": {
            "type": "integer"
          },
          "exchange": {
            "type": "string",
            "description": "Which exchange contract matched it, e.g. pm_ctf_v2."
          },
          "side": {
            "type": "string",
            "enum": [
              "BUY",
              "SELL"
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "maker",
              "taker"
            ]
          },
          "tokenId": {
            "type": "string",
            "description": "Polymarket outcome token id (uint256 as a decimal string)."
          },
          "price": {
            "type": "string",
            "description": "Decimal string, e.g. \"0.570000\"."
          },
          "shares": {
            "type": "string",
            "description": "Integer string, 1e-6 share units (\"3200000000\" = 3,200 shares)."
          },
          "usdc": {
            "type": "string",
            "description": "Integer string, 1e-6 USDC units (\"1824000000\" = $1,824)."
          },
          "fee": {
            "type": "string",
            "description": "Integer string, 1e-6 USDC units."
          }
        },
        "required": [
          "eventId",
          "chain",
          "entityId",
          "wallet",
          "ts",
          "block",
          "blockHash",
          "txHash",
          "logIndex",
          "exchange",
          "side",
          "role",
          "tokenId",
          "price",
          "shares",
          "usdc",
          "fee"
        ]
      },
      "PushedFill": {
        "description": "A fill as pushed (WebSocket frame `data`, webhook body `data`): the Fill fields plus our timestamps and, when known, the market.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Fill"
          },
          {
            "type": "object",
            "properties": {
              "tDetect": {
                "type": "string",
                "format": "date-time",
                "description": "When we saw the fill."
              },
              "tPush": {
                "type": "string",
                "format": "date-time",
                "description": "When we sent it."
              },
              "marketTitle": {
                "type": "string",
                "description": "Market question; absent when not yet known."
              },
              "conditionId": {
                "type": "string",
                "description": "Market condition id; absent when not yet known."
              }
            },
            "required": [
              "tDetect",
              "tPush"
            ]
          }
        ]
      },
      "EntityFill": {
        "type": "object",
        "description": "A recent fill on the entity page. For readers who do not subscribe to the entity, `wallet`, `txHash` and `blockHash` are masked and the list is delayed 15 minutes.",
        "properties": {
          "block": {
            "type": "integer"
          },
          "logIndex": {
            "type": "integer"
          },
          "blockHash": {
            "type": "string"
          },
          "ts": {
            "type": "string"
          },
          "txHash": {
            "type": "string"
          },
          "wallet": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "side": {
            "type": "string"
          },
          "tokenId": {
            "type": "string"
          },
          "price": {
            "type": "string"
          },
          "shares": {
            "type": "string",
            "description": "1e-6 units."
          },
          "usdc": {
            "type": "string",
            "description": "1e-6 units."
          },
          "fee": {
            "type": "string",
            "description": "1e-6 units."
          },
          "exchange": {
            "type": "string"
          },
          "conditionId": {
            "type": "string"
          },
          "marketTitle": {
            "type": "string"
          },
          "marketSlug": {
            "type": "string"
          },
          "eventSlug": {
            "type": "string"
          }
        }
      },
      "Period": {
        "type": "object",
        "properties": {
          "periodId": {
            "type": "string",
            "description": "Window id, e.g. 30d or 7d."
          },
          "runId": {
            "type": "string",
            "description": "The published run the window is read from."
          },
          "b0": {
            "type": "integer",
            "description": "First block of the window."
          },
          "b1": {
            "type": "integer",
            "description": "Last block of the window."
          },
          "completedAt": {
            "type": "string",
            "description": "When the run was published (UTC)."
          },
          "coverageStart": {
            "type": "integer",
            "description": "First ledger block the run could see; positions opened earlier have no cost basis."
          }
        }
      },
      "Activity": {
        "type": "object",
        "properties": {
          "nFills": {
            "type": "integer"
          },
          "firstFillTs": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFillTs": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFillBlock": {
            "type": "integer"
          },
          "activeDays": {
            "type": "integer"
          },
          "fills24h": {
            "type": "integer"
          },
          "fills7d": {
            "type": "integer"
          },
          "windowEndTs": {
            "type": [
              "string",
              "null"
            ]
          },
          "makerFills": {
            "type": [
              "number",
              "null"
            ]
          },
          "makerUsdc": {
            "type": [
              "number",
              "null"
            ]
          },
          "usdc": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "PlanUsage": {
        "type": "object",
        "description": "The caller's plan and what is left of its unlock allowance (present when signed in).",
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "active",
              "grace",
              "none"
            ]
          },
          "tier": {
            "type": [
              "string",
              "null"
            ]
          },
          "graceUntil": {
            "type": [
              "string",
              "null"
            ]
          },
          "daily": {
            "type": "integer"
          },
          "dailyUsed": {
            "type": "integer"
          },
          "monthly": {
            "type": "integer"
          },
          "monthlyUsed": {
            "type": "integer"
          },
          "pushSlots": {
            "type": "integer"
          },
          "pushActive": {
            "type": "integer"
          }
        }
      },
      "LeaderboardRow": {
        "type": "object",
        "properties": {
          "entityId": {
            "type": "string",
            "description": "Handle until you hold the address, then the 0x address. Pass it back to other endpoints as-is."
          },
          "label": {
            "type": "string",
            "description": "Masked address (0x4b96…984e) until you hold it, then the full address."
          },
          "revealed": {
            "type": "boolean",
            "description": "You hold the address (paid unlock, a still-free free unlock, or an active plan unlock)."
          },
          "revealCents": {
            "type": "integer",
            "description": "What unlocking this address costs now (0 = free band). Absent when not for sale (prices not published for the window)."
          },
          "subscribed": {
            "type": "boolean",
            "description": "You have an active push subscription to it."
          },
          "subscriptionId": {
            "type": "string",
            "description": "Present when subscribed."
          },
          "viaPlan": {
            "type": "boolean",
            "description": "Held only through your plan; masked again when the plan ends."
          },
          "unlockedBy": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "paid",
              "free",
              "plan",
              null
            ],
            "description": "mine=1 only: how you hold it; null = lapsed (masked again)."
          },
          "pausedReason": {
            "type": "string",
            "description": "mine=1 only: your subscription to it is paused for this reason."
          },
          "wallets": {
            "type": "integer",
            "description": "Addresses of the entity that traded in the window."
          },
          "conditions": {
            "type": "integer",
            "description": "Markets traded in the window."
          },
          "eligible": {
            "type": "integer",
            "description": "Settled markets counted (wins + losses + breakevens)."
          },
          "wins": {
            "type": "integer"
          },
          "losses": {
            "type": "integer"
          },
          "breakevens": {
            "type": "integer"
          },
          "excludedConditions": {
            "type": "integer"
          },
          "realizedPnl": {
            "type": "number",
            "description": "Dollars."
          },
          "unrealizedPnl": {
            "type": "number",
            "description": "Dollars."
          },
          "totalPnl": {
            "type": "number",
            "description": "Dollars."
          },
          "grossBuyUsdc": {
            "type": "number",
            "description": "Dollars spent buying in the window."
          },
          "feeUsdc": {
            "type": "number"
          },
          "roiOnBuys": {
            "type": "number",
            "description": "realizedPnl / grossBuyUsdc (0.2 = 20%)."
          },
          "nFills": {
            "type": "integer"
          },
          "pnlExTop": {
            "type": "number",
            "description": "Realised PnL minus its single best settled market; decides the price band."
          },
          "pricePnlExTop": {
            "type": [
              "number",
              "null"
            ]
          },
          "wr": {
            "type": [
              "number",
              "null"
            ]
          },
          "lo": {
            "type": [
              "number",
              "null"
            ]
          },
          "hi": {
            "type": [
              "number",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "quiet",
              "dormant"
            ],
            "description": "Last fill <24h / <7d / older."
          },
          "statusAsOf": {
            "type": [
              "string",
              "null"
            ]
          },
          "style": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "maker",
              "taker",
              "two-sided",
              null
            ],
            "description": "By share of traded value made as maker (>=0.8 maker, <=0.2 taker)."
          },
          "makerShare": {
            "type": [
              "number",
              "null"
            ]
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "enum": [
                    "crypto-updown",
                    "crypto",
                    "esports",
                    "sports",
                    "politics",
                    "economy",
                    "geopolitics",
                    "science-tech",
                    "culture",
                    "other",
                    "unknown"
                  ]
                },
                "share": {
                  "type": "number"
                }
              }
            }
          },
          "activity": {
            "$ref": "#/components/schemas/Activity"
          },
          "dataSource": {
            "type": "string",
            "enum": [
              "live",
              "frozen"
            ]
          },
          "dataPeriodId": {
            "type": "string"
          },
          "dataAsOf": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Leaderboard": {
        "type": "object",
        "properties": {
          "periodId": {
            "type": "string"
          },
          "tier": {
            "type": "string",
            "enum": [
              "anon",
              "free",
              "subscriber"
            ],
            "description": "anon = no valid key; subscriber = an active push subscription or active plan."
          },
          "plan": {
            "$ref": "#/components/schemas/PlanUsage"
          },
          "sampled": {
            "type": "boolean",
            "description": "true for the anonymous 20-row sample."
          },
          "filters": {
            "type": "object",
            "additionalProperties": true,
            "description": "The filters actually applied."
          },
          "sort": {
            "type": "string",
            "enum": [
              "realizedPnl",
              "roiOnBuys",
              "eligible",
              "winsLosses",
              "nFills",
              "conditions",
              "grossBuyUsdc",
              "unrealizedPnl",
              "winLo",
              "fillsPerDay",
              "lastFill"
            ]
          },
          "dir": {
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ]
          },
          "sorts": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "historyFrom": {
            "type": [
              "string",
              "null"
            ],
            "description": "First UTC day of the ledger behind this window."
          },
          "refresh": {
            "type": "object",
            "properties": {
              "everyBlocks": {
                "type": "integer"
              },
              "maxIdleMin": {
                "type": "integer"
              },
              "blockSec": {
                "type": "number"
              }
            }
          },
          "pricing": {
            "type": "object",
            "properties": {
              "revealCents": {
                "type": "integer",
                "description": "Price of the cheapest paid band."
              },
              "subscriptionCentsPerHour": {
                "type": "integer"
              },
              "bands": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "band": {
                      "type": "integer"
                    },
                    "from": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "pnlExTop where the band starts; null = no floor."
                    },
                    "cents": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "limits": {
            "type": "object",
            "properties": {
              "maxRows": {
                "type": "integer"
              },
              "maxOffset": {
                "type": "integer"
              },
              "capped": {
                "type": "boolean",
                "description": "limit/offset were reduced to the tier maximum."
              },
              "dailyRows": {
                "type": "integer"
              },
              "usedToday": {
                "type": "integer"
              }
            }
          },
          "tracked": {
            "type": "integer",
            "description": "Entities in the window (independent of filters). With mine=1: how many addresses you have unlocked."
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaderboardRow"
            }
          },
          "outside": {
            "type": "array",
            "description": "mine=1, first page only: your unlocked addresses with no fill in this window.",
            "items": {
              "type": "object",
              "properties": {
                "entityId": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "revealed": {
                  "type": "boolean"
                },
                "subscribed": {
                  "type": "boolean"
                },
                "unlockedBy": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "pausedReason": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Entity": {
        "type": "object",
        "properties": {
          "periodId": {
            "type": "string"
          },
          "entityId": {
            "type": "string",
            "description": "Handle, or the address if you hold it."
          },
          "label": {
            "type": "string"
          },
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "subscriber"
            ]
          },
          "revealed": {
            "type": "boolean"
          },
          "revealCents": {
            "type": "integer",
            "description": "Unlock price now (0 = free band)."
          },
          "viaPlan": {
            "type": "boolean"
          },
          "plan": {
            "$ref": "#/components/schemas/PlanUsage"
          },
          "subscribed": {
            "type": "boolean"
          },
          "badges": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "two-sided-maker",
                "high-win-rate",
                "pnl-1k"
              ]
            }
          },
          "tagVersion": {
            "type": "integer"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string"
                },
                "share": {
                  "type": "number"
                }
              }
            }
          },
          "stats": {
            "description": "The window figures (same fields as a board row, plus wr/lo/hi).",
            "allOf": [
              {
                "$ref": "#/components/schemas/LeaderboardRow"
              }
            ]
          },
          "history": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "partialPct": {
                "type": "number"
              },
              "since": {
                "type": "string"
              }
            },
            "description": "Set when a notable share of markets were opened before the ledger begins."
          },
          "dataSource": {
            "type": "string",
            "enum": [
              "live",
              "frozen"
            ]
          },
          "dataPeriodId": {
            "type": "string"
          },
          "dataAsOf": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "quiet",
              "dormant"
            ]
          },
          "statusAsOf": {
            "type": [
              "string",
              "null"
            ]
          },
          "pnlCurve": {
            "type": "object",
            "description": "PnL from genesis to the end of each day.",
            "properties": {
              "locked": {
                "type": "boolean"
              },
              "since": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "through": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fromGenesis": {
                "type": "boolean"
              },
              "points": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string"
                    },
                    "pnl": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "wallets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "wallet": {
                  "type": "string",
                  "description": "Masked unless you subscribe to the entity."
                },
                "kind": {
                  "type": "string"
                },
                "method": {
                  "type": "string"
                }
              }
            }
          },
          "fills": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityFill"
            }
          },
          "tags": {
            "type": "object",
            "additionalProperties": true
          },
          "fillSample": {
            "type": "integer",
            "description": "Row cap applied to `fills` (100 subscribed, else 10)."
          },
          "fillsDelayedMs": {
            "type": "integer",
            "description": "0 when subscribed, else 900000 (15 min)."
          },
          "views": {
            "type": "object",
            "properties": {
              "usedToday": {
                "type": "integer"
              },
              "cap": {
                "type": "integer"
              }
            },
            "description": "Subscriber tier: the distinct-entity budget after this call."
          }
        }
      },
      "MarketStat": {
        "type": "object",
        "properties": {
          "conditionId": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "question": {
            "type": "string"
          },
          "eventSlug": {
            "type": "string"
          },
          "eventTitle": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "traders": {
            "type": "integer"
          },
          "boughtUsdc": {
            "type": "number"
          },
          "soldUsdc": {
            "type": "number"
          },
          "fills": {
            "type": "integer"
          },
          "resolved": {
            "type": "boolean"
          },
          "up": {
            "type": "integer",
            "description": "Traders whose result on this market was above a cent."
          },
          "down": {
            "type": "integer",
            "description": "Traders whose result was below minus a cent."
          },
          "strong": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "traders": {
                "type": "integer"
              },
              "up": {
                "type": "integer"
              },
              "down": {
                "type": "integer"
              }
            },
            "description": "Counts for traders with strong records; null under 5 members."
          }
        }
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "chain": {
            "type": "integer"
          },
          "entityId": {
            "type": "string",
            "description": "The 0x address once paid for and still held; a handle otherwise (never-charged or plan-locked rows)."
          },
          "label": {
            "type": "string"
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ws",
                "webhook"
              ]
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "canceled"
            ]
          },
          "pausedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "e.g. insufficient_balance, webhook_disabled, no_webhook, plan_ended, plan_limit, address_locked."
          },
          "fromBlock": {
            "type": "integer",
            "description": "Fills strictly after this block are delivered."
          },
          "syncedBlock": {
            "type": "integer"
          },
          "tier": {
            "type": "string"
          },
          "priceCents": {
            "type": "integer",
            "description": "Hourly price frozen on the subscription."
          },
          "billedThrough": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Prepaid up to here."
          },
          "planCovered": {
            "type": "boolean",
            "description": "The last billed hour was covered by a plan push slot (free)."
          },
          "activations": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "canceledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "followedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "categories": {
            "type": "array",
            "description": "List endpoint only.",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string"
                },
                "share": {
                  "type": "number"
                }
              }
            }
          },
          "lastFillTs": {
            "type": [
              "string",
              "null"
            ],
            "description": "List endpoint only."
          },
          "fills24h": {
            "type": [
              "integer",
              "null"
            ],
            "description": "List endpoint only."
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "description": "With an API key only the origin is returned (`https://host/…`)."
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastOkAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "failingSince": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "consecutiveFailures": {
            "type": "integer"
          },
          "disabledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Set when switched off after failing >=24h and >=20 times; reactivate to resume."
          },
          "disabledReason": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "subscriptionId": {
            "type": "string"
          },
          "chain": {
            "type": "integer"
          },
          "block": {
            "type": "integer"
          },
          "blockHash": {
            "type": "string"
          },
          "txHash": {
            "type": "string"
          },
          "logIndex": {
            "type": "integer"
          },
          "channel": {
            "type": "string",
            "enum": [
              "webhook",
              "ws"
            ]
          },
          "tBlock": {
            "type": "string",
            "format": "date-time"
          },
          "tDetect": {
            "type": "string",
            "format": "date-time"
          },
          "tPush": {
            "type": "string",
            "format": "date-time"
          },
          "tDelivered": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "attempted",
              "sent",
              "delivered",
              "skipped",
              "failed",
              "dead"
            ]
          },
          "attempts": {
            "type": "integer"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "LedgerEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "deltaCents": {
            "type": "integer",
            "description": "Positive = credit, negative = charge."
          },
          "reason": {
            "type": "string",
            "description": "e.g. topup_stripe, topup_crypto, charge_hour, entity_reveal, export, plan, invite_bonus, invite_commission, refund, adjustment."
          },
          "kind": {
            "type": "string",
            "enum": [
              "cash",
              "reward"
            ]
          },
          "ref": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "payment": {
            "type": "object",
            "description": "Crypto top-ups: coin, network and on-chain tx.",
            "properties": {
              "coin": {
                "type": "string"
              },
              "network": {
                "type": "string"
              },
              "tx": {
                "type": "string"
              }
            }
          }
        }
      },
      "LedgerPage": {
        "type": "object",
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LedgerEntry"
            }
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cursor for the next page; null at the end."
          }
        }
      },
      "Unlock": {
        "type": "object",
        "properties": {
          "entityId": {
            "type": "string",
            "description": "Address while entitled; handle when a free unlock has lapsed."
          },
          "label": {
            "type": "string"
          },
          "chain": {
            "type": "integer"
          },
          "priceCents": {
            "type": "integer",
            "description": "What was paid (0 = free unlock)."
          },
          "entitled": {
            "type": "boolean",
            "description": "false = a free unlock whose wallet has since moved into a paid band."
          },
          "revealCents": {
            "type": "integer",
            "description": "Only when not entitled: the price to take it back."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "UnlockResult": {
        "type": "object",
        "properties": {
          "entityId": {
            "type": "string",
            "description": "The full 0x address."
          },
          "label": {
            "type": "string"
          },
          "priceCents": {
            "type": "integer",
            "description": "Charged now (0 when free, from the plan, or already owned)."
          },
          "alreadyOwned": {
            "type": "boolean",
            "description": "You already had it; nothing was charged."
          },
          "viaPlan": {
            "type": "boolean"
          }
        }
      },
      "ExportQuote": {
        "type": "object",
        "properties": {
          "window": {
            "type": "object",
            "properties": {
              "from": {
                "type": "string"
              },
              "to": {
                "type": "string"
              },
              "days": {
                "type": "integer"
              }
            },
            "description": "The sellable span."
          },
          "from": {
            "type": "string",
            "description": "Requested day, clamped into the window."
          },
          "to": {
            "type": "string"
          },
          "days": {
            "type": "integer"
          },
          "sellable": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "enum": [
              "below_minimum",
              "no_data"
            ]
          },
          "minDays": {
            "type": "integer"
          },
          "entities": {
            "type": "integer"
          },
          "priceCents": {
            "type": "integer",
            "description": "One entity."
          },
          "orderPriceCents": {
            "type": "integer",
            "description": "The whole order; send it back as maxPriceCents."
          },
          "perEntityCents": {
            "type": "integer"
          },
          "discount": {
            "type": "number"
          },
          "price": {
            "type": "object",
            "properties": {
              "cents": {
                "type": "integer"
              },
              "usd": {
                "type": "number"
              },
              "cny": {
                "type": "number"
              }
            }
          },
          "breakdown": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fromDay": {
                  "type": "integer"
                },
                "toDay": {
                  "type": "integer"
                },
                "days": {
                  "type": "integer"
                },
                "perDayCents": {
                  "type": "integer"
                },
                "cents": {
                  "type": "integer"
                }
              }
            }
          },
          "rateCard": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RateTier"
            }
          }
        }
      },
      "RateTier": {
        "type": "object",
        "properties": {
          "fromDay": {
            "type": "integer"
          },
          "toDay": {
            "type": [
              "integer",
              "null"
            ]
          },
          "perDayCents": {
            "type": "integer"
          }
        }
      },
      "ExportOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "entityIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The entities as 0x addresses."
          },
          "fromDay": {
            "type": "string"
          },
          "toDay": {
            "type": "string"
          },
          "days": {
            "type": "integer"
          },
          "rows": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Fill rows granted; null for orders that are not ready."
          },
          "priceCents": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "description": "ready for every current order (legacy orders may be refunded/failed)."
          },
          "fileBytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "readyAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "viaPlan": {
            "type": "boolean",
            "description": "List endpoint only."
          }
        }
      },
      "ExportFile": {
        "type": "object",
        "properties": {
          "wallet": {
            "type": "string"
          },
          "day": {
            "type": "string",
            "description": "YYYY-MM-DD (UTC)."
          },
          "rows": {
            "type": "integer"
          },
          "bytes": {
            "type": "integer"
          },
          "path": {
            "type": "string",
            "description": "GET it (with the key) for a 302 to the file: /v1/account/data/{wallet}/{day}."
          }
        }
      },
      "PlanTier": {
        "type": "object",
        "properties": {
          "tier": {
            "type": "string",
            "enum": [
              "base",
              "pro",
              "max"
            ]
          },
          "cents": {
            "type": "integer",
            "description": "Monthly price."
          },
          "daily": {
            "type": "integer",
            "description": "Paid-band address unlocks per UTC day."
          },
          "monthly": {
            "type": "integer",
            "description": "Paid-band address unlocks per period."
          },
          "push": {
            "type": "integer",
            "description": "Wallets followed without the hourly charge."
          },
          "exports": {
            "type": "integer",
            "description": "Distinct wallets exported (full range) per period."
          },
          "rank": {
            "type": "integer"
          },
          "onSale": {
            "type": "boolean"
          },
          "trialDays": {
            "type": "integer"
          }
        }
      },
      "PlanStatus": {
        "type": "object",
        "properties": {
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlanTier"
            }
          },
          "plan": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "state": {
                "type": "string",
                "enum": [
                  "active",
                  "grace"
                ]
              },
              "tier": {
                "type": "string"
              },
              "source": {
                "type": "string",
                "enum": [
                  "card",
                  "balance"
                ]
              },
              "periodStart": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "periodEnd": {
                "type": "string"
              },
              "endedAt": {
                "type": "string"
              },
              "graceUntil": {
                "type": "string"
              },
              "cancelAtPeriodEnd": {
                "type": "boolean"
              },
              "renewing": {
                "type": "boolean"
              },
              "nextTier": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "queued": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "tier": {
                    "type": "string"
                  },
                  "startsAt": {
                    "type": "string"
                  },
                  "endsAt": {
                    "type": "string"
                  }
                }
              },
              "failedPayment": {
                "type": "boolean"
              },
              "trialing": {
                "type": "boolean"
              }
            }
          },
          "balance": {
            "type": "object",
            "properties": {
              "cents": {
                "type": "integer"
              },
              "periodDays": {
                "type": "integer"
              }
            }
          },
          "baseTrial": {
            "type": "object",
            "properties": {
              "days": {
                "type": "integer"
              },
              "eligible": {
                "type": "boolean"
              },
              "refused": {
                "type": "boolean"
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "daily": {
                "type": "integer"
              },
              "dailyUsed": {
                "type": "integer"
              },
              "monthly": {
                "type": "integer"
              },
              "monthlyUsed": {
                "type": "integer"
              },
              "push": {
                "type": "object",
                "properties": {
                  "slots": {
                    "type": "integer"
                  },
                  "used": {
                    "type": "integer"
                  }
                }
              },
              "exports": {
                "type": "object",
                "properties": {
                  "cap": {
                    "type": "integer"
                  },
                  "used": {
                    "type": "integer"
                  }
                }
              },
              "lookups": {
                "type": "object",
                "properties": {
                  "cap": {
                    "type": "integer"
                  },
                  "usedToday": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "trial": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "Ready": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "problems": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "component": {
                  "type": "string",
                  "enum": [
                    "ingest",
                    "push",
                    "push_latency",
                    "stats",
                    "exports",
                    "smart"
                  ]
                },
                "reason": {
                  "type": "string"
                }
              }
            }
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ExportRequest": {
        "type": "object",
        "required": [
          "entityIds",
          "from",
          "to"
        ],
        "properties": {
          "entityIds": {
            "type": "array",
            "minItems": 1,
            "maxItems": 25,
            "items": {
              "type": "string"
            },
            "description": "Entity handles, or 0x addresses — all the same form."
          },
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "First UTC day, inclusive."
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Last UTC day, inclusive."
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid parameter or body; `message` names what was expected.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No valid API key (missing, malformed, unknown or revoked).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "statusCode": 401,
              "message": "Unauthorized"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limited. Per IP 240/min overall and 180/min on the board and entity routes; per account 120/min (anonymous 60/min per IP) on board, entity and market reads. A `retry-after` header may be set.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "statusCode": 429,
              "message": "rate limited"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not found (or not yours).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unavailable": {
        "description": "Temporarily unavailable; nothing was charged. Retry shortly.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
