{
  "openapi": "3.1.0",
  "info": {
    "title": "WartNode Explorer API",
    "version": "1.3.0",
    "description": "Free, read-only REST API for Warthog mainnet and DeFi testnet. No account or API key required. Supports GET, HEAD, and credential-free OPTIONS preflight. Initial public limits are 5 requests/second per IP with burst 20, shared by both networks, and 50 requests/second globally with burst 100. On 429 honor Retry-After (5 seconds) and back off. Responses are not HTTP cached; internal observations may be deduplicated for 10 seconds (60 seconds for portfolio observations). Inspect meta.coverage and meta.stale, and nested observation metadata. Block/action timestamps use Unix seconds; observedAt uses ISO 8601. Monetary quantities and u64 IDs are exact decimal strings. Normalized fields remain compatible within v1; raw node payloads can vary. Testnet may reset. Known data endpoints on disabled networks return 503 NETWORK_DISABLED, except overview and status, which return a 200 disabled-state response.",
    "contact": {
      "name": "WartNode",
      "url": "https://wartnode.com"
    }
  },
  "servers": [
    {
      "url": "/api/v1/mainnet",
      "description": "Mainnet"
    },
    {
      "url": "/api/v1/testnet",
      "description": "DeFi testnet"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Network",
      "description": "Chain overview and observations."
    },
    {
      "name": "Blocks",
      "description": "Indexed blocks and block lookups."
    },
    {
      "name": "Transactions",
      "description": "Confirmed and pending actions."
    },
    {
      "name": "Addresses",
      "description": "Observed address state and balance."
    },
    {
      "name": "Search",
      "description": "Find chain identifiers."
    },
    {
      "name": "DeFi",
      "description": "Testnet-only assets and markets."
    }
  ],
  "externalDocs": {
    "description": "Developer guide and interactive reference",
    "url": "https://wartnode.com/developers/api"
  },
  "paths": {
    "/overview": {
      "get": {
        "operationId": "getOverview",
        "tags": ["Network"],
        "summary": "Network overview",
        "description": "Chain head, recent blocks and actions, observed hashrate samples, and indexed 24-hour activity. A disabled network returns 200 with meta.enabled=false and source=configuration. Missing index/node data may appear as null or empty arrays with indexError/nodeError.",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OverviewResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/blocks": {
      "get": {
        "operationId": "listBlocks",
        "tags": ["Blocks"],
        "summary": "List indexed blocks",
        "description": "Newest blocks first. Historical results can be incomplete during backfill. Transactions may be omitted from block summaries; use block detail and the transactions block filter.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlocksResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/blocks/{heightOrHash}": {
      "get": {
        "operationId": "getBlock",
        "tags": ["Blocks"],
        "summary": "Get a block",
        "description": "Indexed blocks include at most 100 normalized transactions; transactionCount reports the full count. Use /transactions?block=HEIGHT for pagination. A node fallback can provide a block before it is indexed.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Block"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlockResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/transactions": {
      "get": {
        "operationId": "listTransactions",
        "tags": ["Transactions"],
        "summary": "List indexed transactions",
        "description": "Newest actions first, including rewards. For address history, supply address and paginate using nextCursor. Filters apply to the active network epoch. Optional from/to filters use Unix seconds with inclusive start and exclusive end.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "type",
            "in": "query",
            "description": "Action type.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "reward",
                "wartTransfer",
                "tokenTransfer",
                "assetCreation",
                "liquidityDeposit",
                "liquidityWithdrawal",
                "limitSwap",
                "cancelation",
                "match"
              ]
            }
          },
          {
            "name": "address",
            "in": "query",
            "description": "Sender/recipient or linked address history. Checksummed addresses are recommended; internal 40-character addresses are normalized.",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-fA-F0-9]{40}([a-fA-F0-9]{8})?$"
            }
          },
          {
            "name": "asset",
            "in": "query",
            "description": "Asset hash.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Hash"
            }
          },
          {
            "name": "block",
            "in": "query",
            "description": "Block height, not a block hash.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 4294967295
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Inclusive start in Unix seconds.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 999999999999
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Exclusive end in Unix seconds. Must be greater than from.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 999999999999
            }
          },
          {
            "name": "hash",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Hash"
            },
            "description": "Filter by reported transaction hash; returns all indexed occurrences with keyset pagination."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/transactions/{hash}": {
      "get": {
        "operationId": "getTransaction",
        "tags": ["Transactions"],
        "summary": "Get a transaction",
        "description": "Get one canonical occurrence. Repeated reported hashes return 409 AMBIGUOUS_TRANSACTION with bounded occurrence choices in error.details. Supply block and position to select one. Qualified lookups never fall back to a hash-only node response. Hash-only node observations may be incomplete while historical backfill is running. Before indexing, a qualified lookup reads the full node block and selects its exact position; missing occurrences in already indexed blocks return INDEX_INCONSISTENT.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Hash"
          },
          {
            "name": "block",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Canonical block height or hash. Required together with position."
          },
          {
            "name": "position",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647
            },
            "description": "Zero-based canonical position. Required together with block."
          },
          {
            "name": "epoch",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Optional active epoch guard; a different epoch returns CHAIN_RESET."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "description": "Ambiguous reported hash or chain epoch changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/addresses/{address}": {
      "get": {
        "operationId": "getAddress",
        "tags": ["Addresses"],
        "summary": "Get current address state",
        "description": "Observed WART balance, plus testnet open orders and optional token balance. These are current observations, not historical balances. Inspect each observation's stale/source fields; balance failures can appear within a successful response. For history use /transactions?address=ADDRESS. The asset parameter is ignored on mainnet.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Address"
          },
          {
            "name": "asset",
            "in": "query",
            "description": "Optional testnet asset hash for token balance.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Hash"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/mempool": {
      "get": {
        "operationId": "getMempool",
        "tags": ["Transactions"],
        "summary": "Observe pending actions",
        "description": "Actions currently observed by the node. Pending records have null height/timestamp. A snapshot may be returned with meta.stale=true.",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MempoolResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/metrics": {
      "get": {
        "operationId": "getMetrics",
        "tags": ["Network"],
        "summary": "Indexed activity and observed hashrate",
        "description": "Activity buckets are hourly for 24h and daily for 7d/30d. Hashrate samples use 120/3600/21600-second buckets respectively. Hashrate history starts when observations were collected; backfill only fills chain activity. First and last buckets can be partial. Timestamp buckets are Unix seconds encoded as strings.",
        "security": [],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "description": "Observation period.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["24h", "7d", "30d"],
              "default": "24h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/search": {
      "get": {
        "operationId": "search",
        "tags": ["Search"],
        "summary": "Search chain identifiers",
        "description": "Search height/hash, transaction hash, checksummed address, or testnet token name prefix. Multiple matches can be returned, e.g. token creation and transaction. An empty result may indicate incomplete indexing.",
        "security": [],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Identifier or token name prefix.",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "example": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/assets": {
      "get": {
        "operationId": "listAssets",
        "tags": ["DeFi"],
        "summary": "List testnet assets",
        "description": "**Testnet only.** Returns 404 FEATURE_UNAVAILABLE on enabled mainnet. Asset names are not unique; use hashes for identity. Directory completeness follows backfill. Without an index the node fallback returns truncated=true and nextCursor=null.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "q",
            "in": "query",
            "description": "Asset name or hash prefix.",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 64
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/assets/{assetHash}": {
      "get": {
        "operationId": "getAsset",
        "tags": ["DeFi"],
        "summary": "Get a testnet asset",
        "description": "**Testnet only.** Returns 404 FEATURE_UNAVAILABLE on enabled mainnet. Normalized asset metadata and original node data.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Asset"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/markets/{assetHash}": {
      "get": {
        "operationId": "getMarket",
        "tags": ["DeFi"],
        "summary": "Observe a testnet market",
        "description": "**Testnet only.** Returns 404 FEATURE_UNAVAILABLE on enabled mainnet. Current pool reserves and order book from the node. The market payload follows the node version; meta describes its source and freshness.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Asset"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/markets/{assetHash}/trades": {
      "get": {
        "operationId": "listTrades",
        "tags": ["DeFi"],
        "summary": "List indexed batch trades",
        "description": "**Testnet only.** Returns 404 FEATURE_UNAVAILABLE on enabled mainnet. Newest batch matches first. baseRaw and quoteRaw preserve exact quantities. Prices are decimal strings.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Asset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/markets/{assetHash}/candles": {
      "get": {
        "operationId": "getCandles",
        "tags": ["DeFi"],
        "summary": "Get indexed market candles",
        "description": "**Testnet only.** Returns 404 FEATURE_UNAVAILABLE on enabled mainnet. Up to 200 recent intervals, oldest first. Quiet intervals are omitted. Prices and raw volumes are strings. Timestamp buckets are Unix seconds encoded as strings. data.window.from/to report the requested lookback bounds in Unix seconds. An empty items list can mean no trades within that window; inspect coverage for incomplete indexing.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Asset"
          },
          {
            "name": "interval",
            "in": "query",
            "description": "Candle width.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["5m", "1h", "1d"],
              "default": "1h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CandlesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/status": {
      "get": {
        "operationId": "getStatus",
        "tags": ["Network"],
        "summary": "Lightweight network status",
        "description": "Chain head, observation freshness, and index coverage without historical blocks, actions, totals, or chart samples. Use for frequent status polling. Disabled networks return 200 with meta.enabled=false and source=configuration. Missing index/node data returns a degraded 200 response with head=null or indexError/nodeError. Wrong-chain validation still returns 503.",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful read. Inspect meta for freshness and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/addresses/{address}/portfolio": {
      "get": {
        "operationId": "getAddressPortfolio",
        "tags": ["Addresses"],
        "summary": "Get address portfolio and discover tokens",
        "description": "WART and testnet open orders plus up to 20 indexed candidate asset hashes. Candidates also include current order markets. Follow nextCursor until null; discovery cursors are bound to network, address, and epoch. Index errors leave live observations available. This is known holdings discovery, not proof that every holding has been found. Portfolio observations are deduplicated for 60 seconds. No local labels or watchlists are stored by this API.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Address"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque discovery cursor; unrelated list cursors are not accepted.",
            "schema": {
              "type": "string",
              "maxLength": 1024
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect per-component observations and index coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortfolioResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/addresses/{address}/portfolio/{asset}": {
      "get": {
        "operationId": "getAddressPortfolioHolding",
        "tags": ["Addresses"],
        "summary": "Get token and LP share balances",
        "description": "Testnet only. Separately observed asset metadata, token balance, and LP balance. Each component has its own time, stale flag, source, and nullable error. Failures never imply zero. Amounts are exact strings. Available is total minus locked minus mempool when every field is known. Portfolio observations are deduplicated for 60 seconds.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Address"
          },
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "description": "Asset creation hash.",
            "schema": {
              "$ref": "#/components/schemas/Hash"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect per-component observations and index coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortfolioHoldingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/addresses/{address}/activity-export": {
      "get": {
        "operationId": "exportAddressActivity",
        "tags": ["Addresses"],
        "summary": "Read a bounded address activity export",
        "description": "One record per confirmed transaction with combined address roles and address-specific match fills. Reads one repeatable-read database snapshot, including cutoff block and coverage; checks the chain before returning. New blocks and concurrent backfill are excluded from that snapshot. No pagination. At most 10,000 transactions; EXPORT_TOO_LARGE (413) or EXPORT_TIMEOUT (503, 10-second SQL timeout) requires a narrower date range. CHAIN_CHANGED (409) requires retry. Missing historical indexing or unresolved order references can omit transactions; inspect coverage. Returns JSON; the website serializes CSV locally to include private browser labels.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Address"
          },
          {
            "name": "type",
            "in": "query",
            "description": "Action type.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "reward",
                "wartTransfer",
                "tokenTransfer",
                "assetCreation",
                "liquidityDeposit",
                "liquidityWithdrawal",
                "limitSwap",
                "cancelation",
                "match"
              ]
            }
          },
          {
            "name": "asset",
            "in": "query",
            "description": "Asset hash.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Hash"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Inclusive start in Unix seconds.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 999999999999
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Exclusive end in Unix seconds. Must be greater than from.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 999999999999
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read. Inspect per-component observations and index coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityExportResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Invalid"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/ChainReset"
          },
          "413": {
            "description": "EXPORT_TOO_LARGE: choose a narrower range; no partial export is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Busy"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Hash": {
        "type": "string",
        "pattern": "^[a-fA-F0-9]{64}$",
        "description": "64-character hexadecimal hash."
      },
      "Address": {
        "type": "string",
        "pattern": "^[a-fA-F0-9]{48}$",
        "description": "Checksummed address: 20 bytes plus the first four bytes of its SHA256 checksum. Transaction filters also normalize internal 40-character addresses."
      },
      "Amount": {
        "type": "object",
        "properties": {
          "raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "decimals": {
            "type": "integer",
            "minimum": 0
          },
          "formatted": {
            "type": "string"
          }
        },
        "required": ["raw", "decimals", "formatted"]
      },
      "Coverage": {
        "type": "object",
        "properties": {
          "tip": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "indexedTip": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "backfillNext": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "complete": {
            "type": "boolean"
          },
          "indexerAlive": {
            "type": "boolean"
          }
        },
        "required": [
          "tip",
          "indexedTip",
          "backfillNext",
          "complete",
          "indexerAlive"
        ]
      },
      "Meta": {
        "type": "object",
        "properties": {
          "network": {
            "enum": ["mainnet", "testnet"]
          },
          "epoch": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "coverage": {
            "$ref": "#/components/schemas/Coverage"
          },
          "observedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "stale": {
            "type": "boolean"
          },
          "source": {
            "enum": ["index", "node", "snapshot", "configuration"]
          }
        },
        "required": [
          "network",
          "epoch",
          "enabled",
          "coverage",
          "observedAt",
          "stale",
          "source"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "description": "For AMBIGUOUS_TRANSACTION: up to 100 occurrence choices (height, position, href) and a truncated flag. Use /transactions?hash=... for all occurrences.",
                "additionalProperties": true
              }
            },
            "required": ["code", "message"]
          }
        },
        "required": ["error"]
      },
      "Head": {
        "type": "object",
        "properties": {
          "height": {
            "type": "integer"
          },
          "hash": {
            "$ref": "#/components/schemas/Hash"
          },
          "difficulty": {
            "type": "string"
          },
          "hashrate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "synced": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ]
          },
          "work": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "height",
          "hash",
          "difficulty",
          "hashrate",
          "synced",
          "work"
        ]
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "hash": {
            "$ref": "#/components/schemas/Hash",
            "description": "Reported node hash. Not unique: use network, epoch, block and position to identify a canonical occurrence."
          },
          "type": {
            "enum": [
              "reward",
              "wartTransfer",
              "tokenTransfer",
              "assetCreation",
              "liquidityDeposit",
              "liquidityWithdrawal",
              "limitSwap",
              "cancelation",
              "match",
              "unknown"
            ]
          },
          "height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "timestamp": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "position": {
            "type": "integer"
          },
          "historyId": {
            "anyOf": [
              {
                "type": "string",
                "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                "pattern": "^[0-9]+$"
              },
              {
                "type": "null"
              }
            ]
          },
          "sender": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "recipient": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "assetHash": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Hash"
              },
              {
                "type": "null"
              }
            ]
          },
          "amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          },
          "fee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          },
          "data": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          },
          "processed": {
            "anyOf": [
              {
                "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          },
          "raw": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "hash",
          "type",
          "height",
          "timestamp",
          "position",
          "historyId",
          "sender",
          "recipient",
          "assetHash",
          "amount",
          "fee",
          "data",
          "processed",
          "raw"
        ]
      },
      "Block": {
        "type": "object",
        "properties": {
          "height": {
            "type": "integer"
          },
          "hash": {
            "$ref": "#/components/schemas/Hash"
          },
          "previousHash": {
            "$ref": "#/components/schemas/Hash"
          },
          "timestamp": {
            "type": "integer",
            "description": "Unix seconds."
          },
          "difficulty": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "header": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          },
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            }
          },
          "raw": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          },
          "transactionCount": {
            "type": "integer"
          },
          "minerAddresses": {
            "type": "array",
            "description": "Unique reward payout addresses recorded in this block. Empty when no recipient is reported. These are payout destinations, not mining hardware or operator identities. Added in API 1.3.0.",
            "items": {
              "$ref": "#/components/schemas/Address"
            },
            "uniqueItems": true
          }
        },
        "required": [
          "height",
          "hash",
          "previousHash",
          "timestamp",
          "difficulty",
          "header",
          "raw",
          "transactionCount"
        ]
      },
      "Asset": {
        "type": "object",
        "properties": {
          "hash": {
            "$ref": "#/components/schemas/Hash"
          },
          "id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                "pattern": "^[0-9]+$"
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "decimals": {
            "type": "integer"
          },
          "supply": {
            "$ref": "#/components/schemas/Amount"
          },
          "height": {
            "type": "integer"
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "raw": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "hash",
          "id",
          "name",
          "decimals",
          "supply",
          "height",
          "owner",
          "raw"
        ]
      },
      "Trade": {
        "type": "object",
        "properties": {
          "hash": {
            "$ref": "#/components/schemas/Hash"
          },
          "assetHash": {
            "$ref": "#/components/schemas/Hash"
          },
          "height": {
            "type": "integer"
          },
          "timestamp": {
            "type": "integer"
          },
          "baseRaw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "quoteRaw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "decimals": {
            "type": "integer"
          },
          "price": {
            "type": "string"
          },
          "references": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "historyId": {
                  "type": "string",
                  "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                  "pattern": "^[0-9]+$"
                },
                "side": {
                  "enum": ["buy", "sell"]
                },
                "baseRaw": {
                  "type": "string",
                  "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                  "pattern": "^[0-9]+$"
                },
                "quoteRaw": {
                  "type": "string",
                  "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                  "pattern": "^[0-9]+$"
                }
              },
              "required": ["historyId", "side", "baseRaw", "quoteRaw"]
            }
          },
          "position": {
            "type": "integer",
            "minimum": 0,
            "description": "Canonical transaction position within the block."
          }
        },
        "required": [
          "hash",
          "assetHash",
          "height",
          "timestamp",
          "baseRaw",
          "quoteRaw",
          "decimals",
          "price",
          "references",
          "position"
        ]
      },
      "Reference": {
        "type": "object",
        "properties": {
          "history_id": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "side": {
            "enum": ["buy", "sell"]
          },
          "base_raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "quote_raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "order_hash": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Hash"
              },
              {
                "type": "null"
              }
            ]
          },
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "order_height": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Block height of the linked order occurrence."
          },
          "order_position": {
            "type": ["integer", "null"],
            "minimum": 0,
            "description": "Position of the linked order occurrence."
          }
        },
        "required": [
          "history_id",
          "side",
          "base_raw",
          "quote_raw",
          "order_hash",
          "address"
        ]
      },
      "Fill": {
        "type": "object",
        "properties": {
          "match_hash": {
            "$ref": "#/components/schemas/Hash"
          },
          "side": {
            "enum": ["buy", "sell"]
          },
          "base_raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "quote_raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "height": {
            "type": "integer"
          },
          "timestamp": {
            "type": "integer"
          },
          "position": {
            "type": "integer",
            "minimum": 0,
            "description": "Position of the match occurrence in its block."
          }
        },
        "required": [
          "match_hash",
          "side",
          "base_raw",
          "quote_raw",
          "height",
          "timestamp"
        ]
      },
      "Observation": {
        "type": "object",
        "properties": {
          "data": {
            "description": "Unmodified node data. Balance, order, and market structures follow the configured node version."
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "stale": {
            "type": "boolean"
          },
          "source": {
            "enum": ["node", "snapshot"]
          }
        },
        "required": ["data", "observedAt", "stale", "source"]
      },
      "BalanceObservation": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/Observation"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "null"
              },
              "observedAt": {
                "type": "null"
              },
              "stale": {
                "const": true
              },
              "error": {
                "type": "string"
              }
            },
            "required": ["data", "observedAt", "stale", "error"]
          }
        ]
      },
      "Sample": {
        "type": "object",
        "properties": {
          "timestamp": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "string",
                "pattern": "^[0-9]+$"
              }
            ],
            "description": "Unix timestamp in seconds."
          },
          "hashrate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "difficulty": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": ["timestamp", "hashrate", "difficulty"]
      },
      "Activity": {
        "type": "object",
        "properties": {
          "timestamp": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "string",
                "pattern": "^[0-9]+$"
              }
            ],
            "description": "Unix timestamp in seconds."
          },
          "blocks": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "transactions": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "fees": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          }
        },
        "required": ["timestamp", "blocks", "transactions", "fees"]
      },
      "Candle": {
        "type": "object",
        "properties": {
          "timestamp": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "string",
                "pattern": "^[0-9]+$"
              }
            ],
            "description": "Unix timestamp in seconds."
          },
          "open": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number."
          },
          "high": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number."
          },
          "low": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number."
          },
          "close": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number."
          },
          "base_raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "quote_raw": {
            "type": "string",
            "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
            "pattern": "^[0-9]+$"
          },
          "decimals": {
            "type": "integer"
          }
        },
        "required": [
          "timestamp",
          "open",
          "high",
          "low",
          "close",
          "base_raw",
          "quote_raw",
          "decimals"
        ]
      },
      "OverviewResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "head": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Head"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "blocks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Block"
                }
              },
              "transactions": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Transaction"
                }
              },
              "samples": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Sample"
                }
              },
              "activity": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "blocks": {
                        "type": "string",
                        "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                        "pattern": "^[0-9]+$"
                      },
                      "transactions": {
                        "type": "string",
                        "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                        "pattern": "^[0-9]+$"
                      },
                      "fees": {
                        "type": "string",
                        "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                        "pattern": "^[0-9]+$"
                      }
                    },
                    "required": ["blocks", "transactions", "fees"]
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "indexError": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "nodeError": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "head",
              "blocks",
              "transactions",
              "samples",
              "activity",
              "indexError"
            ]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "BlocksResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Block"
                }
              },
              "nextCursor": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": ["items", "nextCursor"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "BlockResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Block"
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "TransactionsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Transaction"
                }
              },
              "nextCursor": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": ["items", "nextCursor"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "TransactionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Transaction"
              },
              {
                "type": "object",
                "properties": {
                  "references": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Reference"
                    }
                  },
                  "fills": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Fill"
                    }
                  },
                  "current": {
                    "anyOf": [
                      {
                        "$ref": "#/components/schemas/Observation"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": ["references", "fills", "current"]
              }
            ]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "AddressResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "balance": {
                "$ref": "#/components/schemas/BalanceObservation"
              },
              "orders": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Observation"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "tokenBalance": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Observation"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "tokenBalanceError": {
                "description": "Null when no lookup was requested or an observation is available. A requested lookup failure without a usable snapshot preserves known error codes and messages here; other address data remains available.",
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "code": {
                        "type": "string"
                      },
                      "message": {
                        "type": "string"
                      }
                    },
                    "required": ["code", "message"]
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": ["address", "balance", "orders", "tokenBalance"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "MempoolResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            },
            "required": ["items"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "MetricsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "activity": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Activity"
                }
              },
              "samples": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Sample"
                }
              },
              "range": {
                "enum": ["24h", "7d", "30d"]
              },
              "intervals": {
                "type": "object",
                "properties": {
                  "activitySeconds": {
                    "type": "integer"
                  },
                  "hashrateSeconds": {
                    "type": "integer"
                  }
                },
                "required": ["activitySeconds", "hashrateSeconds"]
              }
            },
            "required": ["activity", "samples", "range", "intervals"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "query": {
                "type": "string"
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "enum": ["Block", "Transaction", "Address", "Token"]
                    },
                    "label": {
                      "type": "string"
                    },
                    "href": {
                      "type": "string"
                    }
                  },
                  "required": ["kind", "label", "href"]
                }
              }
            },
            "required": ["query", "items"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "AssetsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Asset"
                }
              },
              "nextCursor": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "truncated": {
                "type": "boolean"
              }
            },
            "required": ["items", "nextCursor"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "AssetResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Asset"
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "MarketResponse": {
        "type": "object",
        "properties": {
          "data": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "TradesResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Trade"
                }
              },
              "nextCursor": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": ["items", "nextCursor"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "CandlesResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Candle"
                }
              },
              "interval": {
                "enum": ["5m", "1h", "1d"]
              },
              "window": {
                "description": "Requested lookback window in Unix seconds; quiet intervals are omitted from items.",
                "type": "object",
                "properties": {
                  "from": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "to": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "required": ["from", "to"]
              }
            },
            "required": ["items", "interval"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "head": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Head"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "nodeError": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "indexError": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": ["head", "nodeError", "indexError"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "LookupError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": ["code", "message"]
      },
      "PortfolioBalances": {
        "type": "object",
        "properties": {
          "total": {
            "$ref": "#/components/schemas/Amount"
          },
          "locked": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          },
          "pending": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          },
          "available": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": ["total", "locked", "pending", "available"]
      },
      "PortfolioBalanceObservation": {
        "type": "object",
        "properties": {
          "data": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PortfolioBalances"
              },
              {
                "type": "null"
              }
            ]
          },
          "observedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "stale": {
            "type": "boolean"
          },
          "source": {
            "enum": ["node", "snapshot", null]
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LookupError"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": ["data", "observedAt", "stale", "source", "error"]
      },
      "PortfolioOrdersObservation": {
        "type": "object",
        "properties": {
          "data": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "observedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "stale": {
            "type": "boolean"
          },
          "source": {
            "enum": ["node", "snapshot", null]
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LookupError"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": ["data", "observedAt", "stale", "source", "error"]
      },
      "PortfolioAssetObservation": {
        "type": "object",
        "properties": {
          "data": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "hash": {
                    "$ref": "#/components/schemas/Hash"
                  },
                  "name": {
                    "type": "string"
                  },
                  "decimals": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 255
                  }
                },
                "required": ["hash", "name", "decimals"]
              },
              {
                "type": "null"
              }
            ]
          },
          "observedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "stale": {
            "type": "boolean"
          },
          "source": {
            "enum": ["node", "snapshot", null]
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LookupError"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": ["data", "observedAt", "stale", "source", "error"]
      },
      "PortfolioResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "wart": {
                "$ref": "#/components/schemas/PortfolioBalanceObservation"
              },
              "orders": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/PortfolioOrdersObservation"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "candidates": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "hash": {
                      "$ref": "#/components/schemas/Hash"
                    }
                  },
                  "required": ["hash"]
                }
              },
              "nextCursor": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "discoveryError": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/LookupError"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "address",
              "wart",
              "orders",
              "candidates",
              "nextCursor",
              "discoveryError"
            ]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "PortfolioHoldingResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "hash": {
                "$ref": "#/components/schemas/Hash"
              },
              "asset": {
                "$ref": "#/components/schemas/PortfolioAssetObservation"
              },
              "tokens": {
                "$ref": "#/components/schemas/PortfolioBalanceObservation"
              },
              "liquidity": {
                "$ref": "#/components/schemas/PortfolioBalanceObservation"
              }
            },
            "required": ["address", "hash", "asset", "tokens", "liquidity"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      },
      "ExportedTransaction": {
        "type": "object",
        "properties": {
          "hash": {
            "$ref": "#/components/schemas/Hash"
          },
          "type": {
            "enum": [
              "reward",
              "wartTransfer",
              "tokenTransfer",
              "assetCreation",
              "liquidityDeposit",
              "liquidityWithdrawal",
              "limitSwap",
              "cancelation",
              "match",
              "unknown"
            ]
          },
          "height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "timestamp": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "position": {
            "type": "integer"
          },
          "historyId": {
            "anyOf": [
              {
                "type": "string",
                "description": "Exact decimal string. Do not convert raw quantities or u64 identifiers to a JavaScript number.",
                "pattern": "^[0-9]+$"
              },
              {
                "type": "null"
              }
            ]
          },
          "sender": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "recipient": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "assetHash": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Hash"
              },
              {
                "type": "null"
              }
            ]
          },
          "amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          },
          "fee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amount"
              },
              {
                "type": "null"
              }
            ]
          },
          "data": {
            "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
            "type": "object",
            "additionalProperties": true
          },
          "processed": {
            "anyOf": [
              {
                "description": "Original node JSON. Fields and types are upstream-dependent and may change.",
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "hash",
          "type",
          "height",
          "timestamp",
          "position",
          "historyId",
          "sender",
          "recipient",
          "assetHash",
          "amount",
          "fee",
          "data",
          "processed"
        ]
      },
      "ActivityExportResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "generatedAt": {
                "type": "string",
                "format": "date-time"
              },
              "cutoff": {
                "type": "object",
                "properties": {
                  "height": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "hash": {
                    "$ref": "#/components/schemas/Hash"
                  }
                },
                "required": ["height", "hash"]
              },
              "filters": {
                "type": "object",
                "properties": {
                  "type": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "asset": {
                    "anyOf": [
                      {
                        "$ref": "#/components/schemas/Hash"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "from": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 0
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "to": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 0
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": ["type", "asset", "from", "to"]
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/ExportedTransaction"
                    },
                    "roles": {
                      "type": "array",
                      "items": {
                        "enum": ["sender", "recipient", "fill"]
                      }
                    },
                    "fills": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "side": {
                            "enum": ["buy", "sell"]
                          },
                          "baseRaw": {
                            "type": "string",
                            "pattern": "^[0-9]+$"
                          },
                          "quoteRaw": {
                            "type": "string",
                            "pattern": "^[0-9]+$"
                          },
                          "orderHash": {
                            "anyOf": [
                              {
                                "$ref": "#/components/schemas/Hash"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": ["side", "baseRaw", "quoteRaw", "orderHash"]
                      }
                    }
                  },
                  "required": ["transaction", "roles", "fills"]
                },
                "maxItems": 10000
              }
            },
            "required": ["address", "generatedAt", "cutoff", "filters", "items"]
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        },
        "required": ["data", "meta"]
      }
    },
    "parameters": {
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "Opaque nextCursor from the previous response. Bound to the active network epoch. Discard it after CHAIN_RESET.",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 512
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Page size. Values outside 1–100 return INVALID_LIMIT.",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        }
      },
      "Block": {
        "name": "heightOrHash",
        "in": "path",
        "description": "Block height (1–4294967295) or hexadecimal block hash.",
        "required": true,
        "schema": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,9}$"
            },
            {
              "$ref": "#/components/schemas/Hash"
            }
          ],
          "example": "1"
        }
      },
      "Hash": {
        "name": "hash",
        "in": "path",
        "description": "Transaction hash.",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Hash"
        }
      },
      "Address": {
        "name": "address",
        "in": "path",
        "description": "Checksummed 48-character Warthog address.",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Address"
        }
      },
      "Asset": {
        "name": "assetHash",
        "in": "path",
        "description": "Unique asset creation hash. Testnet only.",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Hash"
        }
      }
    },
    "responses": {
      "Invalid": {
        "description": "Invalid identifier, address checksum, cursor, query, filter, page limit, range, or interval.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "No matching record or endpoint. DeFi-only operations on enabled mainnet return FEATURE_UNAVAILABLE.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "Only GET, HEAD, and OPTIONS are supported.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "headers": {
          "Allow": {
            "schema": {
              "type": "string"
            },
            "example": "GET, HEAD, OPTIONS"
          }
        }
      },
      "ChainReset": {
        "description": "The cursor belongs to a previous epoch. Restart pagination without a cursor.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "CHAIN_RESET",
                "message": "The chain changed. Start again from the first page."
              }
            }
          }
        }
      },
      "Busy": {
        "description": "Request limit exceeded (RATE_LIMITED) or node queue busy (NODE_BUSY). Wait at least Retry-After seconds, then use increasing backoff.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "RATE_LIMITED",
                "message": "Request limit exceeded. Try again shortly."
              }
            }
          }
        },
        "headers": {
          "Retry-After": {
            "description": "Minimum seconds before retrying.",
            "schema": {
              "type": "integer"
            },
            "example": 5
          }
        }
      },
      "Unavailable": {
        "description": "Network disabled, index unavailable, node unreachable, wrong testnet chain, or service unavailable. Overview can instead return a degraded 200 response.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadGateway": {
        "description": "The upstream node returned an invalid or oversized response.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
