{
  "openapi": "3.1.0",
  "info": {
    "title": "TensorCash wallet API (Esplora-compatible)",
    "version": "1.0.0",
    "description": "Esplora-compatible REST API for TensorCash light wallets: balances, UTXOs, history, mempool, fee estimates and broadcast of already-signed transactions. Esplora is the API Blockstream and mempool.space serve, so wallet code written against it works by changing the base URL. Amounts are integer satoshis (1 TSC = 100 000 000). Errors are plain text with an HTTP status. While the index lags the node, address and transaction routes answer 503 `Index syncing: n/m`.",
    "x-fastapi-version": "0.1.0",
    "x-tensorcash-source": {
      "product": "tensorcash-wallet-api (tensorcash-api)",
      "author": "bobponey",
      "license": "MIT",
      "repository": "https://git.tensorcash.org/bobponey/tensorcash-api",
      "tag": "v1.0.0",
      "commit": "772799e2c60aa30d3703bfca6286063e254bed66",
      "file": "tensorcash-wallet-api: FastAPI create_app().openapi(), also served at /esplora/api/openapi.json",
      "sha256": "34fc84216e9b2e137bc5254064a413836a8eeba133e2ecf277a079dc6bf8f2cf",
      "overlay": {
        "file": "scripts/api-docs/wallet-api.overlay.json",
        "sha256": "ecdb28bd5ab160905fb5c1f540da4fb9507caa92a2e9c82db3d433e0799d51f1"
      },
      "filtered_by": {
        "file": "scripts/api-docs/nginx-api-server.conf",
        "sha256": "2a7dc40dd1ae885832e00337a0f5736f7a01fad8e2f399c6c869b967424d6b9f"
      },
      "upstream_operations": 24,
      "published_operations": 24,
      "removed": []
    }
  },
  "paths": {
    "/health": {
      "get": {
        "summary": "Index and node tips",
        "description": "Index and node tips, heights with their hashes, so instances can be compared from one call. Two instances at the same height agree when their `indexed_hash` match. `synced` is false while the index lags the node by more than one block. When the node cannot serve the index the status is 503 and the body has an extra `error` field.",
        "operationId": "health_health_get",
        "responses": {
          "200": {
            "description": "Index state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "503": {
            "description": "The node cannot serve the index; `error` says why",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        },
        "tags": [
          "Health"
        ]
      }
    },
    "/esplora/api/blocks/tip/height": {
      "get": {
        "summary": "Tip height",
        "operationId": "tip_height_esplora_api_blocks_tip_height_get",
        "responses": {
          "200": {
            "description": "Height",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "Decimal block height."
                }
              }
            }
          },
          "503": {
            "description": "`Index empty`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Blocks"
        ],
        "description": "Height of the indexed chain tip."
      }
    },
    "/esplora/api/blocks/tip/hash": {
      "get": {
        "summary": "Tip hash",
        "operationId": "tip_hash_esplora_api_blocks_tip_hash_get",
        "responses": {
          "200": {
            "description": "Block hash",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "64 hex characters."
                }
              }
            }
          },
          "503": {
            "description": "`Index empty`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Blocks"
        ],
        "description": "Hash of the indexed chain tip."
      }
    },
    "/esplora/api/block-height/{height}": {
      "get": {
        "summary": "Block hash at a height",
        "operationId": "block_height_esplora_api_block_height__height__get",
        "parameters": [
          {
            "name": "height",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Height"
            },
            "description": "Block height."
          }
        ],
        "responses": {
          "200": {
            "description": "Block hash",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "64 hex characters."
                }
              }
            }
          },
          "404": {
            "description": "`Block not found`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "tags": [
          "Blocks"
        ],
        "description": "Hash of the indexed block at `height`. Wallets use it to detect reorganizations: a different hash at a remembered height means the blocks above the fork changed."
      }
    },
    "/esplora/api/tx/{txid}": {
      "get": {
        "summary": "Transaction",
        "operationId": "tx_esplora_api_tx__txid__get",
        "parameters": [
          {
            "name": "txid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Txid"
            },
            "description": "Transaction id, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid txid`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "`Transaction not found`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Transactions"
        ],
        "description": "The full transaction, confirmed or in the mempool: inputs with their `prevout`, outputs, size, weight, fee and status."
      }
    },
    "/esplora/api/tx/{txid}/status": {
      "get": {
        "summary": "Transaction status",
        "operationId": "tx_status_esplora_api_tx__txid__status_get",
        "parameters": [
          {
            "name": "txid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Txid"
            },
            "description": "Transaction id, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TxStatus"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid txid`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "`Transaction not found`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Transactions"
        ],
        "description": "Whether the transaction is confirmed, and in which block. A wallet polls it after broadcast. 404 means the transaction is neither in the chain nor in the mempool (replaced or evicted)."
      }
    },
    "/esplora/api/tx/{txid}/hex": {
      "get": {
        "summary": "Raw transaction hex",
        "operationId": "tx_hex_esplora_api_tx__txid__hex_get",
        "parameters": [
          {
            "name": "txid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Txid"
            },
            "description": "Transaction id, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Raw transaction",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "Hex-encoded transaction."
                }
              }
            }
          },
          "400": {
            "description": "`Invalid txid`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "`Transaction not found`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Transactions"
        ],
        "description": "The serialized transaction as hex text."
      }
    },
    "/esplora/api/tx/{txid}/outspends": {
      "get": {
        "summary": "Output spends",
        "operationId": "tx_outspends_esplora_api_tx__txid__outspends_get",
        "parameters": [
          {
            "name": "txid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Txid"
            },
            "description": "Transaction id, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "One entry per output",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Outspend"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid txid`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "`Transaction not found`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Transactions"
        ],
        "description": "For each output of the transaction, in order: whether it is spent, and by which input of which transaction."
      }
    },
    "/esplora/api/tx": {
      "post": {
        "summary": "Broadcast a signed transaction",
        "operationId": "post_tx_esplora_api_tx_post",
        "responses": {
          "200": {
            "description": "Accepted; the body is the txid",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "Transaction id."
                }
              }
            }
          },
          "400": {
            "description": "`Invalid transaction hex`, or `sendrawtransaction RPC error: {\"code\":…,\"message\":\"<reason>\"}`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Over the per-IP rate limit"
          },
          "502": {
            "description": "`node unavailable`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Transactions"
        ],
        "description": "Submits an already-signed transaction. No key reaches the server; it cannot alter the transaction without invalidating its signatures. The node first validates it (`testmempoolaccept`); an invalid transaction is rejected with the node's reason and never relayed. A valid one is sent to the local node and relayed to the other nodes. The node's default `maxfeerate` (0.1 TSC/kvB) rejects absurd fees. Limits: 10 requests per minute per IP (burst 20), body up to 256 KB, hex up to 200 000 characters.",
        "requestBody": {
          "required": true,
          "description": "The raw signed transaction as hex text.",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string",
                "description": "Hex-encoded signed transaction."
              }
            }
          }
        }
      }
    },
    "/esplora/api/wallet/addresses": {
      "post": {
        "summary": "Balances and UTXOs of many addresses",
        "description": "Not part of Esplora. One entry per requested address, in request order (duplicates included). An entry has either the data or an `error`, never neither, so a missing result is never mistaken for a zero balance. The data is exactly what `GET /address/{address}` and `GET /address/{address}/utxo` return; `tx_count` tells used-but-empty addresses apart, for gap-limit discovery. The whole request answers from one view: send `view` back on the next call of the same sync, to the same host, and every batch describes the same moment. Limits: 1 to 500 addresses, at most 20 000 UTXOs in the reply, body up to 128 KB, 2 requests per second per IP (burst 30).",
        "operationId": "wallet_addresses_esplora_api_wallet_addresses_post",
        "responses": {
          "200": {
            "description": "One entry per requested address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad body, more than 500 addresses, or more than 20 000 UTXOs in the reply",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "410": {
            "description": "`view expired`: restart the sync without `view`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "description": "Body over 128 KB",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Wallet batch"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletAddressesRequest"
              }
            }
          }
        }
      }
    },
    "/esplora/api/wallet/history": {
      "post": {
        "summary": "Merged history of many addresses",
        "description": "Not part of Esplora. One list, newest first (block height, then position in the block); a transaction touching several of the addresses appears once. Each entry is the Esplora transaction object. The first page (`cursor: null`) also returns the unconfirmed transactions of these addresses, up to 200; while `mempool_complete` is true it is the whole unconfirmed set, so a refresh replaces the wallet's unconfirmed list. Later pages, requested with `next_cursor` and the same address set, read the chain only up to `snapshot`, so new blocks never shift entries between pages. If a reorganization removed the snapshot block the cursor expires (409). Limits: 1 to 500 addresses, `limit` 1 to 100, a page also ends early past 2 MB of JSON, 2 requests per second per IP (burst 30).",
        "operationId": "wallet_history_esplora_api_wallet_history_post",
        "responses": {
          "200": {
            "description": "One page of merged history",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletHistoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad body, limit or cursor; a cursor made for another address set or view; more than 500 addresses",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "description": "`Cursor expired: the chain reorganized; start again without a cursor`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "410": {
            "description": "`view expired`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "description": "Body over 128 KB",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "description": "A node lookup failed",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Wallet batch"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletHistoryRequest"
              }
            }
          }
        }
      }
    },
    "/esplora/api/fee-estimates": {
      "get": {
        "summary": "Fee estimates",
        "operationId": "fee_estimates_esplora_api_fee_estimates_get",
        "responses": {
          "200": {
            "description": "Rates by target",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeeEstimates"
                }
              }
            }
          },
          "502": {
            "description": "`node unavailable`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Fees"
        ],
        "description": "Fee rate in sat/vB per confirmation target (1 to 25, 144, 504 and 1008 blocks), from the node's `estimatesmartfee`. Never below the node's `mempoolminfee`; a target without an estimate gets that floor. Cached for 60 seconds."
      }
    },
    "/esplora/api/address/{key}": {
      "get": {
        "summary": "Address balance",
        "operationId": "address_esplora_api_address__key__get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "TensorCash address (bech32 hrp `tc`, or base58)."
          }
        ],
        "responses": {
          "200": {
            "description": "Address summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressSummary"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid address`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Addresses"
        ],
        "description": "Funded and spent output counts and sums, confirmed and unconfirmed. Balance = `funded_txo_sum - spent_txo_sum`."
      }
    },
    "/esplora/api/address/{key}/utxo": {
      "get": {
        "summary": "Address UTXOs",
        "operationId": "address_utxo_esplora_api_address__key__utxo_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "TensorCash address."
          }
        ],
        "responses": {
          "200": {
            "description": "Unspent outputs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Utxo"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid address`, or `Too many unspent transaction outputs (>5000)`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Addresses"
        ],
        "description": "Unspent outputs, unconfirmed first. Outputs already spent in the mempool are left out. An address with more than 5000 unspent outputs gets 400."
      }
    },
    "/esplora/api/address/{key}/txs": {
      "get": {
        "summary": "Address transactions",
        "operationId": "address_txs_esplora_api_address__key__txs_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "TensorCash address."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid address`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Addresses"
        ],
        "description": "Up to 50 unconfirmed transactions, then the 25 newest confirmed ones."
      }
    },
    "/esplora/api/address/{key}/txs/chain": {
      "get": {
        "summary": "Confirmed address transactions",
        "operationId": "address_txs_chain_esplora_api_address__key__txs_chain_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "TensorCash address."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid address`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Addresses"
        ],
        "description": "The 25 newest confirmed transactions. Page with `/txs/chain/{last_seen}`."
      }
    },
    "/esplora/api/address/{key}/txs/chain/{last_seen}": {
      "get": {
        "summary": "Older confirmed address transactions",
        "operationId": "address_txs_chain_after_esplora_api_address__key__txs_chain__last_seen__get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "TensorCash address."
          },
          {
            "name": "last_seen",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Last Seen"
            },
            "description": "The last txid of the previous page."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid address` or `Invalid txid`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Addresses"
        ],
        "description": "The next 25 confirmed transactions, older than `last_seen`."
      }
    },
    "/esplora/api/address/{key}/txs/mempool": {
      "get": {
        "summary": "Unconfirmed address transactions",
        "operationId": "address_txs_mempool_esplora_api_address__key__txs_mempool_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "TensorCash address."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid address`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Addresses"
        ],
        "description": "Up to 50 unconfirmed transactions."
      }
    },
    "/esplora/api/scripthash/{key}": {
      "get": {
        "summary": "Script hash balance",
        "operationId": "scripthash_esplora_api_scripthash__key__get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "Electrum script hash: sha256 of the scriptPubKey, byte-reversed, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Script hash summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScripthashSummary"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid scripthash`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Script hashes"
        ],
        "description": "As `GET /address/{address}`, keyed by Electrum script hash."
      }
    },
    "/esplora/api/scripthash/{key}/utxo": {
      "get": {
        "summary": "Script hash UTXOs",
        "operationId": "scripthash_utxo_esplora_api_scripthash__key__utxo_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "Electrum script hash, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Unspent outputs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Utxo"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid scripthash`, or `Too many unspent transaction outputs (>5000)`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Script hashes"
        ],
        "description": "As `GET /address/{address}/utxo`, keyed by Electrum script hash."
      }
    },
    "/esplora/api/scripthash/{key}/txs": {
      "get": {
        "summary": "Script hash transactions",
        "operationId": "scripthash_txs_esplora_api_scripthash__key__txs_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "Electrum script hash, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid scripthash`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Script hashes"
        ],
        "description": "Up to 50 unconfirmed transactions, then the 25 newest confirmed ones."
      }
    },
    "/esplora/api/scripthash/{key}/txs/chain": {
      "get": {
        "summary": "Confirmed script hash transactions",
        "operationId": "scripthash_txs_chain_esplora_api_scripthash__key__txs_chain_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "Electrum script hash, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid scripthash`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Script hashes"
        ],
        "description": "The 25 newest confirmed transactions."
      }
    },
    "/esplora/api/scripthash/{key}/txs/chain/{last_seen}": {
      "get": {
        "summary": "Older confirmed script hash transactions",
        "operationId": "scripthash_txs_chain_after_esplora_api_scripthash__key__txs_chain__last_seen__get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "Electrum script hash, 64 hex characters."
          },
          {
            "name": "last_seen",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Last Seen"
            },
            "description": "The last txid of the previous page."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid scripthash` or `Invalid txid`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Script hashes"
        ],
        "description": "The next 25 confirmed transactions, older than `last_seen`."
      }
    },
    "/esplora/api/scripthash/{key}/txs/mempool": {
      "get": {
        "summary": "Unconfirmed script hash transactions",
        "operationId": "scripthash_txs_mempool_esplora_api_scripthash__key__txs_mempool_get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            },
            "description": "Electrum script hash, 64 hex characters."
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid scripthash`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "503": {
            "description": "`Index syncing: n/m`",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Script hashes"
        ],
        "description": "Up to 50 unconfirmed transactions."
      }
    }
  },
  "components": {
    "schemas": {
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "Health": {
        "type": "object",
        "required": [
          "network",
          "indexed_height",
          "indexed_hash",
          "node_height",
          "node_hash",
          "synced",
          "mempool_txs"
        ],
        "properties": {
          "network": {
            "type": "string",
            "enum": [
              "mainnet",
              "testnet",
              "regtest"
            ],
            "description": "Network this instance serves."
          },
          "indexed_height": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Height of the index tip the API answers from."
          },
          "indexed_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Hash of the index tip."
          },
          "node_height": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Node's best height at the indexer's last pass."
          },
          "node_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node's best block hash at the indexer's last pass."
          },
          "synced": {
            "type": "boolean",
            "description": "False while the index lags the node by more than one block."
          },
          "mempool_txs": {
            "type": "integer",
            "description": "Transactions in the indexed mempool copy."
          },
          "error": {
            "type": "string",
            "description": "Present with status 503: why the node cannot serve the index."
          }
        }
      },
      "TxStatus": {
        "type": "object",
        "required": [
          "confirmed"
        ],
        "properties": {
          "confirmed": {
            "type": "boolean",
            "description": "False while the transaction is in the mempool."
          },
          "block_height": {
            "type": "integer",
            "description": "Confirmed only."
          },
          "block_hash": {
            "type": "string",
            "description": "Confirmed only."
          },
          "block_time": {
            "type": "integer",
            "description": "Block timestamp, Unix seconds. Confirmed only."
          }
        }
      },
      "TxOut": {
        "type": "object",
        "required": [
          "scriptpubkey",
          "scriptpubkey_asm",
          "scriptpubkey_type",
          "value"
        ],
        "properties": {
          "scriptpubkey": {
            "type": "string",
            "description": "Output script, hex."
          },
          "scriptpubkey_asm": {
            "type": "string",
            "description": "Output script in bcore's asm format (not Esplora's `OP_PUSHBYTES_n` form)."
          },
          "scriptpubkey_type": {
            "type": "string",
            "enum": [
              "p2pkh",
              "p2sh",
              "v0_p2wpkh",
              "v0_p2wsh",
              "v1_p2tr",
              "op_return",
              "p2pk",
              "multisig",
              "anchor",
              "unknown"
            ]
          },
          "scriptpubkey_address": {
            "type": "string",
            "description": "Present when the script has an address."
          },
          "value": {
            "type": "integer",
            "description": "Amount in satoshis."
          }
        }
      },
      "TxIn": {
        "type": "object",
        "required": [
          "txid",
          "vout",
          "prevout",
          "scriptsig",
          "scriptsig_asm",
          "is_coinbase",
          "sequence"
        ],
        "properties": {
          "txid": {
            "type": "string",
            "description": "Spent transaction; 64 zeros for a coinbase input."
          },
          "vout": {
            "type": "integer",
            "description": "Spent output index; 4294967295 for a coinbase input."
          },
          "prevout": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TxOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The output this input spends; null for a coinbase input."
          },
          "scriptsig": {
            "type": "string",
            "description": "Input script, hex (the coinbase data for a coinbase input)."
          },
          "scriptsig_asm": {
            "type": "string"
          },
          "is_coinbase": {
            "type": "boolean"
          },
          "witness": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Witness stack, hex items. Present when not empty."
          },
          "sequence": {
            "type": "integer"
          }
        }
      },
      "Transaction": {
        "type": "object",
        "required": [
          "txid",
          "version",
          "locktime",
          "vin",
          "vout",
          "size",
          "weight",
          "fee",
          "status"
        ],
        "properties": {
          "txid": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "locktime": {
            "type": "integer"
          },
          "vin": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TxIn"
            }
          },
          "vout": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TxOut"
            }
          },
          "size": {
            "type": "integer",
            "description": "Bytes."
          },
          "weight": {
            "type": "integer",
            "description": "Weight units."
          },
          "fee": {
            "type": "integer",
            "description": "Satoshis."
          },
          "status": {
            "$ref": "#/components/schemas/TxStatus"
          }
        }
      },
      "Outspend": {
        "type": "object",
        "required": [
          "spent"
        ],
        "properties": {
          "spent": {
            "type": "boolean"
          },
          "txid": {
            "type": "string",
            "description": "Spending transaction. Spent only."
          },
          "vin": {
            "type": "integer",
            "description": "Input index in the spending transaction. Spent only."
          },
          "status": {
            "$ref": "#/components/schemas/TxStatus"
          }
        }
      },
      "ChainStats": {
        "type": "object",
        "required": [
          "funded_txo_count",
          "funded_txo_sum",
          "spent_txo_count",
          "spent_txo_sum",
          "tx_count"
        ],
        "properties": {
          "funded_txo_count": {
            "type": "integer",
            "description": "Outputs received."
          },
          "funded_txo_sum": {
            "type": "integer",
            "description": "Satoshis received."
          },
          "spent_txo_count": {
            "type": "integer",
            "description": "Outputs spent."
          },
          "spent_txo_sum": {
            "type": "integer",
            "description": "Satoshis spent."
          },
          "tx_count": {
            "type": "integer",
            "description": "Transactions touching the address."
          }
        }
      },
      "AddressSummary": {
        "type": "object",
        "required": [
          "address",
          "chain_stats",
          "mempool_stats"
        ],
        "properties": {
          "address": {
            "type": "string"
          },
          "chain_stats": {
            "$ref": "#/components/schemas/ChainStats"
          },
          "mempool_stats": {
            "$ref": "#/components/schemas/ChainStats"
          }
        }
      },
      "ScripthashSummary": {
        "type": "object",
        "required": [
          "scripthash",
          "chain_stats",
          "mempool_stats"
        ],
        "properties": {
          "scripthash": {
            "type": "string"
          },
          "chain_stats": {
            "$ref": "#/components/schemas/ChainStats"
          },
          "mempool_stats": {
            "$ref": "#/components/schemas/ChainStats"
          }
        }
      },
      "Utxo": {
        "type": "object",
        "required": [
          "txid",
          "vout",
          "status",
          "value"
        ],
        "properties": {
          "txid": {
            "type": "string"
          },
          "vout": {
            "type": "integer"
          },
          "status": {
            "$ref": "#/components/schemas/TxStatus"
          },
          "value": {
            "type": "integer",
            "description": "Satoshis."
          }
        }
      },
      "FeeEstimates": {
        "type": "object",
        "description": "Keys are confirmation targets in blocks (`\"1\"` to `\"25\"`, `\"144\"`, `\"504\"`, `\"1008\"`); values are sat/vB, rounded to 3 decimals.",
        "additionalProperties": {
          "type": "number"
        }
      },
      "Tip": {
        "type": "object",
        "required": [
          "height",
          "hash"
        ],
        "properties": {
          "height": {
            "type": "integer"
          },
          "hash": {
            "type": "string"
          }
        }
      },
      "WalletAddressesRequest": {
        "type": "object",
        "required": [
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 500,
            "description": "1 to 500 addresses."
          },
          "view": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional: the `view` of an earlier response from the same host, to answer from that state."
          }
        }
      },
      "WalletAddressEntry": {
        "type": "object",
        "required": [
          "address",
          "chain_stats",
          "mempool_stats",
          "utxo"
        ],
        "properties": {
          "address": {
            "type": "string"
          },
          "chain_stats": {
            "$ref": "#/components/schemas/ChainStats"
          },
          "mempool_stats": {
            "$ref": "#/components/schemas/ChainStats"
          },
          "utxo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Utxo"
            }
          }
        }
      },
      "AddressError": {
        "type": "object",
        "required": [
          "address",
          "error"
        ],
        "properties": {
          "address": {
            "type": "string"
          },
          "error": {
            "type": "string",
            "description": "`Invalid address`, or `Too many unspent transaction outputs (>5000)`."
          }
        }
      },
      "WalletAddressesResponse": {
        "type": "object",
        "required": [
          "tip",
          "view",
          "addresses"
        ],
        "properties": {
          "tip": {
            "$ref": "#/components/schemas/Tip"
          },
          "view": {
            "type": "string",
            "description": "Opaque id of the state this answer comes from. Send it back to pin later calls to it."
          },
          "addresses": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/WalletAddressEntry"
                },
                {
                  "$ref": "#/components/schemas/AddressError"
                }
              ]
            },
            "description": "One entry per requested address, in request order."
          }
        }
      },
      "WalletHistoryRequest": {
        "type": "object",
        "required": [
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 500,
            "description": "1 to 500 addresses."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 25,
            "description": "Confirmed transactions per page."
          },
          "cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "null for the first page, else the previous `next_cursor`."
          },
          "view": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional: the `view` of an earlier response from the same host."
          }
        }
      },
      "WalletHistoryResponse": {
        "type": "object",
        "required": [
          "tip",
          "view",
          "snapshot",
          "errors",
          "txs",
          "next_cursor"
        ],
        "properties": {
          "tip": {
            "$ref": "#/components/schemas/Tip"
          },
          "view": {
            "type": "string"
          },
          "snapshot": {
            "$ref": "#/components/schemas/Tip"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AddressError"
            },
            "description": "One entry per invalid address; the rest of the request is still served."
          },
          "mempool": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            },
            "description": "First page only: unconfirmed transactions, newest first, up to 200."
          },
          "mempool_complete": {
            "type": "boolean",
            "description": "First page only: false when `mempool` was cut."
          },
          "txs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            },
            "description": "Confirmed, newest first."
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "null when there is no older history."
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Blocks",
      "description": "Chain tip and block hashes, as plain text."
    },
    {
      "name": "Transactions",
      "description": "Esplora transaction objects, status, raw hex, spends, and broadcast of a signed transaction."
    },
    {
      "name": "Addresses",
      "description": "Per-address balances, UTXOs and history. Each GET answers from the server's current view."
    },
    {
      "name": "Script hashes",
      "description": "The same six routes as Addresses, keyed by Electrum script hash: sha256 of the scriptPubKey, byte-reversed, hex."
    },
    {
      "name": "Wallet batch",
      "description": "Not part of Esplora: many addresses per request, for HD wallets that track thousands of addresses. Responses carry a `view` that pins one chain tip and mempool copy across the calls of a sync."
    },
    {
      "name": "Fees",
      "description": "Fee-rate estimates."
    },
    {
      "name": "Health",
      "description": "Index and node tips, outside the /esplora/api prefix."
    }
  ],
  "servers": [
    {
      "url": "https://api.tensorcash.org",
      "description": "TensorCash mainnet chain API"
    }
  ]
}
