{"openapi":"3.1.0","info":{"title":"zexplorer","version":"1.0.0","description":"Public Zexplorer API. A typed BFF that fronts the Zinder gRPC plane and never exposes shielded counterparties from public chain data.\n\n**Envelope.** Every per-network read response is shaped `{ data, freshness, capabilities }`. `freshness` is the consumer-facing freshness signal: `tip_height`, `tip_hash`, `derive_lag_blocks`, `capability_version`, `fetched_at_millis`. `capabilities` is the live, sorted list of explorer capabilities the upstream advertises right now; consumers must gate every feature on this list, never on hard-coded versions. Operator-facing state (writer phase, canonical-store lag) is exposed only on `/{network}/network` under `data.operator`; public consumers may ignore it.\n\n**Capabilities.** Identifiers are `explorer.<domain>.<view>_v1`. The closed vocabulary lives in `packages/zcash/src/capabilities.ts` and is wire-typed on the envelope as `capabilities: enum[...]`. Adding a new identifier requires a human description in `apps/web/components/capability-grid.tsx`; the type system enforces coverage. Wallet-plane capabilities (`wallet.*`) are intentionally not surfaced here; they are internal to the BFF -> Zinder link.\n\n**Errors.** Every failure is `application/problem+json` (RFC 7807) with a stable `error_code` (closed enum). The closed registry lives in `packages/zcash/src/error-codes.ts`; the human-readable map is at `docs/reference/error-vocabulary.md`. Broadcast outcomes (`duplicate`, `rejected`, `invalid_encoding`, `unknown`) are NOT error codes: the broadcast route always returns 200 with a typed `outcome` field. Pagination cursor invalidation returns 410 `cursor_expired`.\n\n**Privacy invariants.** `paid_fee_zat` is always null when a transaction has any shielded input. Shielded counterparties are never returned. Raw transaction bytes are not part of any typed read; the explorer plane is fact-first per the upstream Zinder model."},"servers":[{"url":"/api/v1"}],"components":{"schemas":{"ProcessHealthzResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"]},"networks_served":{"type":"array","items":{"type":"string","enum":["mainnet","testnet","regtest"]}},"networks":{"type":"array","items":{"type":"object","properties":{"network":{"type":"string","enum":["mainnet","testnet","regtest"]},"zinder_reachable":{"type":"boolean"}},"required":["network","zinder_reachable"]}}},"required":["status","networks_served","networks"]}},"required":["data"]},"Problem":{"type":"object","properties":{"type":{"type":"string","format":"uri","description":"Stable problem-type URI keyed by `error_code`. Identifies the failure class for client-side switch logic."},"title":{"type":"string","description":"Human-readable summary derived from the error code. Stable per code."},"status":{"type":"integer","description":"HTTP status this response carries. Mirrors `status`."},"detail":{"type":"string","description":"Free-text explanation of this specific failure. Safe to log; never contains secrets."},"error_code":{"type":"string","enum":["zinder_unavailable","capability_unavailable","not_found","invalid_argument","rate_limited","broadcast_disabled","block_not_in_best_chain","chain_epoch_pin_unavailable","cursor_expired","internal"],"description":"Closed vocabulary; see `packages/zcash/src/error-codes.ts`. Clients branch on this value, never on `status` or `title`."},"retry_posture":{"type":"string","enum":["retryable","not_retryable","requires_operator"],"description":"Stable per `error_code`. `retryable` for transient upstream failures, `not_retryable` for client-fixable failures, `requires_operator` for failures that need an out-of-band intervention."},"upstream_reason":{"type":"string","nullable":true,"description":"Verbatim gRPC reason string from the upstream Zinder when the failure originated there. Null when the API synthesized the failure or the upstream provided no reason."}},"required":["type","title","status","detail","error_code","retry_posture","upstream_reason"]},"ChainFreshness":{"type":"object","properties":{"network":{"type":"string","enum":["mainnet","testnet","regtest"]},"tip_height":{"type":"integer","nullable":true,"minimum":0,"description":"Best-chain tip height the upstream has indexed. Null on the bootstrap call (ServerInfo) or when the upstream has not yet committed a block on this network."},"tip_hash":{"type":"string","nullable":true,"pattern":"^[0-9a-f]{64}$","description":"Hash of the tip block at the same height. Null when `tip_height` is null."},"tip_block_time_unix_seconds":{"type":"integer","nullable":true,"description":"Unix-seconds timestamp of the tip block header. Null on the bootstrap call, when the upstream has not yet committed a block on this network, or until the upstream `ChainEpoch` proto extension lands. Consumers compute relative-age display (e.g. \"12 seconds ago\") from this field."},"derive_lag_blocks":{"type":"integer","nullable":true,"description":"Blocks the derive projections (transparent index, recent transactions, mempool activity) trail the canonical store by. Zero means derive consumers are at the canonical tip; positive means typed reads may be missing the last N blocks of derived state. Null when the upstream did not report the value."},"capability_version":{"type":"string","description":"Capability identifier the response was served against (for example `explorer.transaction.detail_v1`). Stable per route; clients pin client-side handlers against this value."},"fetched_at_millis":{"type":"integer","description":"Wall-clock millis at which the BFF observed the upstream response. Useful for client-side staleness checks independent of the underlying upstream lag signals."}},"required":["network","tip_height","tip_hash","tip_block_time_unix_seconds","derive_lag_blocks","capability_version","fetched_at_millis"]},"NetworkHealthzResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded"],"description":"`healthy` when the upstream is reachable and answered server-info; `degraded` when reachable but the call failed."},"zinder":{"type":"object","properties":{"reachable":{"type":"boolean"},"service":{"type":"string","nullable":true,"description":"Service identity from the upstream server-info handshake. Null when the upstream is unreachable."},"service_version":{"type":"string","nullable":true,"description":"Semver-style upstream version. Null when the upstream is unreachable."}},"required":["reachable","service","service_version"]}},"required":["status","zinder"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"NetworkOperatorState":{"type":"object","nullable":true,"properties":{"ingest_phase":{"type":"string","nullable":true,"enum":["unspecified","awaiting_upstream","bulk_catchup","following_tip"],"description":"Closed enum: `unspecified | awaiting_upstream | bulk_catchup | following_tip`. Only `following_tip` proves the canonical store is at the upstream Zebra tip. Null when IngestControl is not wired for this network."},"canonical_lag_blocks":{"type":"integer","nullable":true,"description":"Blocks the canonical store trails the upstream Zebra tip by. Zero when the writer is at the tip. Null when IngestControl is not wired or the writer has not yet measured the gap (early bulk-catchup)."}},"required":["ingest_phase","canonical_lag_blocks"],"description":"Operator-facing state for this network: writer phase and canonical-store lag. Present when `ZINDER_INGEST_OPS_URL_<NETWORK>` is wired; null otherwise. Public consumers may ignore this field; the live-sync chip and indexer-health panel depend on it."},"NetworkData":{"type":"object","properties":{"service":{"type":"string","description":"Upstream service identifier reported by Zinder's ServerInfo.","example":"zinder-explorer"},"service_version":{"type":"string","description":"Upstream service version string.","example":"0.4.0"},"vendor":{"type":"string","description":"Upstream vendor name (typically `Zinder`).","example":"Zinder"},"operator":{"$ref":"#/components/schemas/NetworkOperatorState"}},"required":["service","service_version","vendor","operator"]},"NetworkResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/NetworkData"},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"ValuePoolSummaryResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"tip_height":{"type":"integer","minimum":0},"pools":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Pool identifier: one of `transparent`, `sprout`, `sapling`, `orchard`."},"monitored":{"type":"boolean","description":"Whether the upstream node tracks this pool. Some deployments disable sprout monitoring."},"chain_value_zat":{"type":"string","nullable":true,"description":"Cumulative zatoshis held in this pool at the chain tip. Null when the pool is not monitored or the upstream has not reported a value. Decimal-string zatoshis when populated."}},"required":["id","monitored","chain_value_zat"]}}},"required":["tip_height","pools"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"FeeSummaryResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"block_count":{"type":"integer","minimum":0,"description":"Number of blocks the aggregate was computed over."},"transaction_count":{"type":"integer","minimum":0,"description":"Total non-coinbase transactions seen across the aggregated blocks."},"total_zip317_conventional_fee_zat":{"type":"string","description":"Sum of ZIP-317 conventional-fee floors across every non-coinbase transaction in the aggregate. Decimal-string zatoshis. This is a derived floor, not miner-collected fee."},"min_zip317_conventional_fee_zat":{"type":"string","description":"Smallest ZIP-317 conventional-fee floor seen across the aggregate. Decimal-string zatoshis."},"max_zip317_conventional_fee_zat":{"type":"string","description":"Largest ZIP-317 conventional-fee floor seen across the aggregate. Decimal-string zatoshis."}},"required":["block_count","transaction_count","total_zip317_conventional_fee_zat","min_zip317_conventional_fee_zat","max_zip317_conventional_fee_zat"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"BlockListResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"blocks":{"type":"array","items":{"type":"object","properties":{"block_height":{"type":"integer","minimum":0},"block_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"block_time_unix_seconds":{"type":"integer","description":"Block timestamp as Unix seconds. The consensus-recorded time the block claims, not when the explorer observed it."},"transaction_count":{"type":"integer","minimum":0,"description":"Number of transactions in the block, including coinbase."},"previous_block_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"total_size_bytes":{"type":"integer","minimum":0,"description":"Wire-encoded byte size of the entire block."},"fees_collected_zat":{"type":"string","description":"Sum of ZIP-317 conventional-fee floors across every non-coinbase transaction in the block. Decimal-string zatoshis."},"coinbase_reward_zat":{"type":"string","description":"Total zatoshis paid to the miner by the coinbase transaction. Decimal-string zatoshis. Includes both the protocol subsidy and any included fees the coinbase chooses to claim."},"sapling_output_count":{"type":"integer","minimum":0,"description":"Total Sapling output components across every transaction in the block. Counts are public; amounts are not."},"orchard_action_count":{"type":"integer","minimum":0,"description":"Total Orchard action components across every transaction in the block. Counts are public; amounts are not."},"confirmations":{"type":"integer","minimum":0,"description":"Depth below the current best-chain tip. Zero on the tip block; grows by one each new block."},"is_canonical":{"type":"boolean","description":"True when the block currently lives on the best chain. False during an active reorg pass for blocks that have been orphaned."},"fee_transaction_count":{"type":"integer","nullable":true,"minimum":0,"description":"Number of non-coinbase transactions in the block. Null when the upstream has not yet populated this field."},"min_zip317_conventional_fee_zat":{"type":"string","nullable":true,"description":"Smallest ZIP-317 conventional-fee floor among the block's non-coinbase transactions. Decimal-string zatoshis. Null when the upstream has not yet populated this field or the block carries no non-coinbase transactions."},"max_zip317_conventional_fee_zat":{"type":"string","nullable":true,"description":"Largest ZIP-317 conventional-fee floor among the block's non-coinbase transactions. Decimal-string zatoshis. Null when the upstream has not yet populated this field or the block carries no non-coinbase transactions."}},"required":["block_height","block_hash","block_time_unix_seconds","transaction_count","previous_block_hash","total_size_bytes","fees_collected_zat","coinbase_reward_zat","sapling_output_count","orchard_action_count","confirmations","is_canonical","fee_transaction_count","min_zip317_conventional_fee_zat","max_zip317_conventional_fee_zat"]}}},"required":["blocks"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"BlockDetailResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"type":"object","properties":{"block_height":{"type":"integer","minimum":0},"block_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"block_time_unix_seconds":{"type":"integer","description":"Block timestamp as Unix seconds. The consensus-recorded time the block claims, not when the explorer observed it."},"transaction_count":{"type":"integer","minimum":0,"description":"Number of transactions in the block, including coinbase."},"previous_block_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"total_size_bytes":{"type":"integer","minimum":0,"description":"Wire-encoded byte size of the entire block."},"fees_collected_zat":{"type":"string","description":"Sum of ZIP-317 conventional-fee floors across every non-coinbase transaction in the block. Decimal-string zatoshis."},"coinbase_reward_zat":{"type":"string","description":"Total zatoshis paid to the miner by the coinbase transaction. Decimal-string zatoshis. Includes both the protocol subsidy and any included fees the coinbase chooses to claim."},"sapling_output_count":{"type":"integer","minimum":0,"description":"Total Sapling output components across every transaction in the block. Counts are public; amounts are not."},"orchard_action_count":{"type":"integer","minimum":0,"description":"Total Orchard action components across every transaction in the block. Counts are public; amounts are not."},"confirmations":{"type":"integer","minimum":0,"description":"Depth below the current best-chain tip. Zero on the tip block; grows by one each new block."},"is_canonical":{"type":"boolean","description":"True when the block currently lives on the best chain. False during an active reorg pass for blocks that have been orphaned."},"fee_transaction_count":{"type":"integer","nullable":true,"minimum":0,"description":"Number of non-coinbase transactions in the block. Null when the upstream has not yet populated this field."},"min_zip317_conventional_fee_zat":{"type":"string","nullable":true,"description":"Smallest ZIP-317 conventional-fee floor among the block's non-coinbase transactions. Decimal-string zatoshis. Null when the upstream has not yet populated this field or the block carries no non-coinbase transactions."},"max_zip317_conventional_fee_zat":{"type":"string","nullable":true,"description":"Largest ZIP-317 conventional-fee floor among the block's non-coinbase transactions. Decimal-string zatoshis. Null when the upstream has not yet populated this field or the block carries no non-coinbase transactions."}},"required":["block_height","block_hash","block_time_unix_seconds","transaction_count","previous_block_hash","total_size_bytes","fees_collected_zat","coinbase_reward_zat","sapling_output_count","orchard_action_count","confirmations","is_canonical","fee_transaction_count","min_zip317_conventional_fee_zat","max_zip317_conventional_fee_zat"]},"transaction_ids":{"type":"array","items":{"type":"string"}}},"required":["summary","transaction_ids"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"RecentTransactionsResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object","properties":{"transaction_id":{"type":"string","pattern":"^[0-9a-f]{64}$"},"block_height":{"type":"integer","minimum":0},"block_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"block_time_unix_seconds":{"type":"integer"},"is_coinbase":{"type":"boolean"},"privacy_shape":{"type":"string","enum":["transparent_only","shielding","deshielding","shielded_only","mixed","unclassified"]},"size_bytes":{"type":"integer","minimum":0},"zip317_conventional_fee_zat":{"type":"string","nullable":true,"description":"ZIP-317 conventional-fee floor. Null on coinbase transactions (no inputs to charge a fee on). Decimal-string zatoshis when populated."},"paid_fee_zat":{"type":"string","nullable":true,"description":"Null whenever the transaction has any shielded input (privacy invariant) or prevout resolution is incomplete. Decimal-string zatoshis when populated."},"logical_action_count":{"type":"integer","minimum":0,"description":"ZIP-317 logical action count: inputs plus outputs, used for fee-floor accounting."},"component_counts":{"type":"object","properties":{"transparent_input_count":{"type":"integer","minimum":0},"transparent_output_count":{"type":"integer","minimum":0},"sapling_spend_count":{"type":"integer","minimum":0},"sapling_output_count":{"type":"integer","minimum":0},"orchard_action_count":{"type":"integer","minimum":0},"sprout_joinsplit_count":{"type":"integer","minimum":0}},"required":["transparent_input_count","transparent_output_count","sapling_spend_count","sapling_output_count","orchard_action_count","sprout_joinsplit_count"]}},"required":["transaction_id","block_height","block_hash","block_time_unix_seconds","is_coinbase","privacy_shape","size_bytes","zip317_conventional_fee_zat","paid_fee_zat","logical_action_count","component_counts"]}}},"required":["transactions"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"TransactionDetailResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"transaction_id":{"type":"string","pattern":"^[0-9a-f]{64}$"},"status":{"type":"string","enum":["mined","pending","conflicting","invalidated","suppressed","not_found","unavailable"]},"privacy_shape":{"type":"string","enum":["transparent_only","shielding","deshielding","shielded_only","mixed","unclassified"]},"block_height":{"type":"integer","nullable":true,"minimum":0,"description":"Null while the transaction is in the mempool only; populated once mined."},"block_hash":{"type":"string","nullable":true,"pattern":"^[0-9a-f]{64}$","description":"Null while the transaction is in the mempool only."},"block_time_unix_seconds":{"type":"integer","nullable":true,"description":"Null while the transaction is in the mempool only."},"confirmations":{"type":"integer","nullable":true,"minimum":0,"description":"Null while the transaction is in the mempool only."},"first_seen_unix_millis":{"type":"integer","nullable":true,"description":"Mempool observation time. Null for transactions that arrived through a mined block and were never seen in mempool."},"size_bytes":{"type":"integer","nullable":true,"minimum":0,"description":"Wire-encoded transaction size. Null when size has not been computed (rare; usually mempool ingestion races)."},"expiry_height":{"type":"integer","nullable":true,"minimum":0,"description":"Zcash expiry height. Null when the transaction has no expiry (coinbase or `expiry_height == 0`)."},"is_coinbase":{"type":"boolean"},"zip317_conventional_fee_zat":{"type":"string","description":"ZIP-317 conventional-fee floor (a recommended minimum) computed from logical action counts. Decimal-string zatoshis. Always present."},"paid_fee_zat":{"type":"string","nullable":true,"description":"Null whenever the transaction has any shielded input (privacy invariant: revealing the paid fee would leak shielded value) or prevout resolution is incomplete. Decimal-string zatoshis when populated."},"prevout_resolution_status":{"type":"string","enum":["unspecified","resolved","partial","unavailable"],"description":"Closed enum: `unspecified | resolved | partial | unavailable`. Explains why per-input `value_zat` and `paid_fee_zat` are or are not populated."},"transparent_inputs":{"type":"array","items":{"type":"object","properties":{"input_index":{"type":"integer","minimum":0},"value_zat":{"type":"string","nullable":true,"description":"Null while the upstream prevout-resolution worker has not yet fetched the producing output. Decimal-string zatoshis when populated."}},"required":["input_index","value_zat"]}},"component_counts":{"type":"object","properties":{"transparent_input_count":{"type":"integer","minimum":0},"transparent_output_count":{"type":"integer","minimum":0},"sapling_spend_count":{"type":"integer","minimum":0},"sapling_output_count":{"type":"integer","minimum":0},"orchard_action_count":{"type":"integer","minimum":0},"sprout_joinsplit_count":{"type":"integer","minimum":0}},"required":["transparent_input_count","transparent_output_count","sapling_spend_count","sapling_output_count","orchard_action_count","sprout_joinsplit_count"]}},"required":["transaction_id","status","privacy_shape","block_height","block_hash","block_time_unix_seconds","confirmations","first_seen_unix_millis","size_bytes","expiry_height","is_coinbase","zip317_conventional_fee_zat","paid_fee_zat","prevout_resolution_status","transparent_inputs","component_counts"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"MempoolSummaryResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"transaction_count":{"type":"integer","minimum":0},"total_size_bytes":{"type":"integer","minimum":0},"oldest_entry_age_millis":{"type":"integer","minimum":0},"newest_entry_age_millis":{"type":"integer","minimum":0},"privacy_shape_distribution":{"type":"array","items":{"type":"object","properties":{"shape":{"type":"string","enum":["transparent_only","shielding","deshielding","shielded_only","mixed","unclassified"]},"count":{"type":"integer","minimum":0}},"required":["shape","count"]}}},"required":["transaction_count","total_size_bytes","oldest_entry_age_millis","newest_entry_age_millis","privacy_shape_distribution"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"MempoolActivityResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"transaction_id":{"type":"string","pattern":"^[0-9a-f]{64}$"},"first_seen_unix_millis":{"type":"integer","minimum":0,"description":"When the upstream first observed this transaction."},"size_bytes":{"type":"integer","minimum":0},"privacy_shape":{"type":"string","enum":["transparent_only","shielding","deshielding","shielded_only","mixed","unclassified"]},"zip317_conventional_fee_zat":{"type":"string","description":"ZIP-317 conventional-fee floor (a recommended minimum). Decimal-string zatoshis. Always present."},"paid_fee_zat":{"type":"string","nullable":true,"description":"Null whenever the transaction has any shielded input (privacy invariant) or prevout resolution is incomplete. Decimal-string zatoshis when populated."},"logical_action_count":{"type":"integer","minimum":0,"description":"ZIP-317 logical action count. Inputs (transparent inputs, sapling spends, orchard actions, sprout joinsplits) plus outputs, used for fee-floor accounting."}},"required":["transaction_id","first_seen_unix_millis","size_bytes","privacy_shape","zip317_conventional_fee_zat","paid_fee_zat","logical_action_count"]}}},"required":["entries"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"MempoolEventCountsResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"window_seconds":{"type":"integer","minimum":0,"exclusiveMinimum":true},"added_count":{"type":"integer","minimum":0},"mined_count":{"type":"integer","minimum":0},"invalidated_count":{"type":"integer","minimum":0},"suppressed_count":{"type":"integer","minimum":0}},"required":["window_seconds","added_count","mined_count","invalidated_count","suppressed_count"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"SearchResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"query":{"type":"string"},"results":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["block"]},"height":{"type":"number","description":"Best-chain block height (decimal). Always non-negative."},"hash":{"type":"string","description":"Lowercase block hash hex; matches the canonical form."}},"required":["kind","height","hash"],"description":"A block matched by height or 64-hex hash query."},{"type":"object","properties":{"kind":{"type":"string","enum":["transaction"]},"transaction_id":{"type":"string"},"in_mempool":{"type":"boolean","description":"True when the transaction is currently in the mempool snapshot the explorer can see."},"mined_block_height":{"type":"number","nullable":true,"description":"Null while the transaction is in mempool only. Decimal height once mined."}},"required":["kind","transaction_id","in_mempool","mined_block_height"],"description":"A transaction identified by lowercase 64-hex txid."},{"type":"object","properties":{"kind":{"type":"string","enum":["transparent_address"]},"canonical_form":{"type":"string"},"is_p2pkh":{"type":"boolean"}},"required":["kind","canonical_form","is_p2pkh"],"description":"Transparent address (`t1`/`t2`/`t3`/`tm` prefix). Public history is available at `/transparent-addresses/{address}`."},{"type":"object","properties":{"kind":{"type":"string","enum":["tex_address"]},"canonical_tex_form":{"type":"string"},"equivalent_p2pkh":{"type":"string"},"transparent_source_only":{"type":"boolean","description":"True when the TEX address only accepts transparent inputs (ZIP-320 constraint)."}},"required":["kind","canonical_tex_form","equivalent_p2pkh","transparent_source_only"],"description":"ZIP-320 TEX address (`tex1`/`textest1` prefix). Carries the equivalent P2PKH form for callers that need it."},{"type":"object","properties":{"kind":{"type":"string","enum":["unified_address"]},"canonical_form":{"type":"string"},"network":{"type":"string"},"receiver_count":{"type":"number"}},"required":["kind","canonical_form","network","receiver_count"],"description":"ZIP-316 unified address (`u1`/`utest1` prefix). The explorer cannot derive shielded history; this entry only confirms parseability."},{"type":"object","properties":{"kind":{"type":"string","enum":["private_by_design"]},"reason":{"type":"string","enum":["shielded_address","shielded_address_mainnet","shielded_address_testnet","shielded_receiver_in_unified","unified_address_no_transparent_receiver","viewing_key"],"description":"Closed enum from `packages/zcash/src/privacy-reasons.ts`. Names which privacy-protected form was detected (shielded address, viewing key, transparent receiver of a unified address, etc.)."},"human_reason":{"type":"string","description":"Pre-rendered English copy suitable for surfacing to humans. Never echoes the canonical form."}},"required":["kind","reason","human_reason"],"description":"The query parsed as a privacy-protected form (shielded address, viewing key, unified address transparent receiver). No history page is opened; the canonical form is intentionally not echoed back."},{"type":"object","properties":{"kind":{"type":"string","enum":["payment_disclosure"]},"hint":{"type":"string"}},"required":["kind","hint"],"description":"The query looks like a ZIP-311 payment-disclosure payload. Use `/payment-disclosures/verify` to validate."},{"type":"object","properties":{"kind":{"type":"string","enum":["unclassified"]},"hint":{"type":"string"}},"required":["kind","hint"],"description":"The explorer could not classify the query. `hint` carries a short copy explaining why."}]}}},"required":["query","results"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"TransparentAddressDetailResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"address":{"type":"string"},"confirmed_zat":{"type":"string"},"unconfirmed_delta_zat":{"type":"string"},"utxos":{"type":"array","items":{"type":"object","properties":{"outpoint_txid":{"type":"string","pattern":"^[0-9a-f]{64}$"},"outpoint_index":{"type":"integer","minimum":0},"value_zat":{"type":"string"},"block_height":{"type":"integer","minimum":0},"block_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"}},"required":["outpoint_txid","outpoint_index","value_zat","block_height","block_hash"]}}},"required":["address","confirmed_zat","unconfirmed_delta_zat","utxos"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"TransparentAddressActivityResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"address":{"type":"string"},"entries":{"type":"array","items":{"type":"object","properties":{"transaction_id":{"type":"string","pattern":"^[0-9a-f]{64}$"},"block_height":{"type":"integer","minimum":0},"block_time_unix_seconds":{"type":"integer"},"net_value_zat":{"type":"string","nullable":true,"description":"Net signed transparent value delta for this address (`outputs minus inputs`). Null when prevout resolution is incomplete (the upstream cannot price the inputs yet). Decimal-string zatoshis when populated."},"input_count":{"type":"integer","minimum":0},"output_count":{"type":"integer","minimum":0},"prevout_resolution_status":{"type":"string","enum":["unspecified","resolved","partial","unavailable"],"description":"Closed enum: `unspecified | resolved | partial | unavailable`. Explains why `net_value_zat` is or is not populated."}},"required":["transaction_id","block_height","block_time_unix_seconds","net_value_zat","input_count","output_count","prevout_resolution_status"]}}},"required":["address","entries"]},"freshness":{"$ref":"#/components/schemas/ChainFreshness"},"capabilities":{"type":"array","items":{"type":"string","enum":["explorer.server_info_v1","explorer.block.summary_v1","explorer.block.detail_v1","explorer.transaction.detail_v1","explorer.transaction.recent_v1","explorer.transaction.fees_v1","explorer.transparent_address.balance_v1","explorer.transparent_address.activity_v1","explorer.search_v1","explorer.mempool.summary_v1","explorer.mempool.activity_v1","explorer.mempool.event_counts_v1","explorer.fee.summary_v1","explorer.value_pool.summary_v1","explorer.payment_disclosure.verify_v1"]},"description":"Closed vocabulary; see `packages/zcash/src/capabilities.ts`. Sorted alphabetically. Gate every UI feature on this live array, never on hard-coded version strings."}},"required":["data","freshness","capabilities"]},"BroadcastResponse":{"type":"object","properties":{"data":{"oneOf":[{"type":"object","properties":{"outcome":{"type":"string","enum":["accepted"]},"transaction_id":{"type":"string","pattern":"^[0-9a-f]{64}$"}},"required":["outcome","transaction_id"],"description":"The upstream node accepted the broadcast and returned a transaction id."},{"type":"object","properties":{"outcome":{"type":"string","enum":["duplicate"]},"upstream_message":{"type":"string"}},"required":["outcome","upstream_message"],"description":"The upstream node already has this transaction (mempool or recently mined). Treated as success."},{"type":"object","properties":{"outcome":{"type":"string","enum":["invalid_encoding"]},"upstream_message":{"type":"string"}},"required":["outcome","upstream_message"],"description":"The hex bytes did not decode as a valid Zcash transaction. Resubmit with corrected encoding."},{"type":"object","properties":{"outcome":{"type":"string","enum":["rejected"]},"upstream_message":{"type":"string"}},"required":["outcome","upstream_message"],"description":"The upstream node refused the transaction. `upstream_message` carries the node's reason."},{"type":"object","properties":{"outcome":{"type":"string","enum":["unknown"]},"upstream_message":{"type":"string"}},"required":["outcome","upstream_message"],"description":"The upstream returned an outcome the explorer does not recognize. Inspect `upstream_message` for detail."}]}},"required":["data"]},"BroadcastRequest":{"type":"object","properties":{"raw_transaction_hex":{"type":"string","minLength":2,"maxLength":1500000,"pattern":"^[0-9a-fA-F]+$","description":"Redacted at the API boundary. Accepted as input; never returned in responses or written to structured logs (ADR 0016 + ADR 0005)."},"network":{"type":"string","enum":["mainnet","testnet","regtest"]}},"required":["raw_transaction_hex","network"]},"PaymentDisclosureVerifyResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"verdict":{"type":"string","enum":["valid","invalid_signature","transaction_not_found","malformed","unspecified"],"description":"Closed enum: `valid | invalid_signature | transaction_not_found | malformed | unspecified`. Only `valid` carries `public_facts`."},"public_facts":{"type":"object","nullable":true,"properties":{"transaction_id":{"type":"string","pattern":"^[0-9a-f]{64}$"},"payment_id_hex":{"type":"string","description":"ZIP-311 payment identifier as lowercase hex. Public component of the disclosure; safe to surface."},"disclosed_value_zat":{"type":"string","description":"Value disclosed by the proof (the recipient amount). Decimal-string zatoshis."}},"required":["transaction_id","payment_id_hex","disclosed_value_zat"],"description":"Populated only when `verdict` is `valid`. Null otherwise."}},"required":["verdict","public_facts"]}},"required":["data"]},"PaymentDisclosureVerifyRequest":{"type":"object","properties":{"payment_disclosure_hex":{"type":"string","minLength":2,"maxLength":100000,"pattern":"^[0-9a-fA-F]+$","description":"Redacted at the API boundary. Accepted as input; never returned in responses or written to structured logs (ADR 0016 + ADR 0005)."}},"required":["payment_disclosure_hex"]}},"parameters":{}},"paths":{"/healthz":{"get":{"summary":"Process-level liveness probe across every served network.","description":"Returns a single JSON object that names every network this API process serves and whether the upstream Zinder for each is reachable. The aggregate `status` is `healthy` when every network reports reachable; `degraded` when at least one is reachable; `unhealthy` when none are. Load balancers should probe this endpoint, not the per-network detail.","tags":["ops"],"responses":{"200":{"description":"Process health.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessHealthzResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/healthz":{"get":{"summary":"Per-network liveness probe with upstream capability set.","description":"Returns the status of one configured network plus the freshness envelope (capability set and tip lag). Use this for ops/monitoring; load balancers should probe `/healthz` instead.","tags":["ops"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"}],"responses":{"200":{"description":"Per-network health.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkHealthzResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/network":{"get":{"summary":"Service identity, capability set, and operator state.","description":"Calls ExplorerQuery.ServerInfo on the upstream Zinder for the network in the path and returns a normalized envelope. Capabilities echo Zinder's advertised set; clients gate features on this list, not on hard-coded version strings. `data.operator` carries writer-phase and canonical-lag signals for the live-sync chip and the indexer-health panel; both are null when IngestControl is not configured for the network.","tags":["network"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"}],"responses":{"200":{"description":"Server identity, capability set, and operator state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/value-pools":{"get":{"summary":"Chain value pool totals at the upstream tip.","description":"Cumulative per-pool zatoshi totals reported by the upstream node. Capability-gated on `explorer.value_pool.summary_v1`.","tags":["value-pools"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"}],"responses":{"200":{"description":"Value pool totals.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValuePoolSummaryResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/fees/summary":{"get":{"summary":"ZIP-317 conventional fee floors over recent blocks.","description":"Aggregates ZIP-317 conventional fees across the most recent blocks. Capability-gated on `explorer.fee.summary_v1`. Values are floors, not miner-collected fees.","tags":["fees"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":50},"required":false,"name":"lookback","in":"query"}],"responses":{"200":{"description":"Recent fee summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeeSummaryResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/blocks":{"get":{"summary":"Recent block summaries.","description":"Capability-gated on `explorer.block.summary_v1`. Returns 503 with `capability_unavailable` when the upstream block-summary derive consumer has not caught up.","tags":["blocks"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Recent blocks.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockListResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/blocks/{selector}":{"get":{"summary":"Block detail by height or hash.","description":"The `selector` is a decimal block height or a 64-character lowercase block hash. Capability-gated on `explorer.block.detail_v1`.","tags":["blocks"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"selector","in":"path"}],"responses":{"200":{"description":"Block detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockDetailResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/transactions/recent":{"get":{"summary":"Streaming projection of the most recently mined transactions.","description":"Reads the upstream `RecentTransactions` projection in one streaming round trip. Each entry carries privacy shape, component counts, size, ZIP-317 conventional fee floor, and the actual paid fee when prevout resolution is complete and the transaction has no shielded inputs. Capability-gated on `explorer.transaction.recent_v1`.","tags":["transactions"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":64,"default":8},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Recent transactions snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecentTransactionsResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/transactions/{transaction_id}":{"get":{"summary":"Public facts about a transaction.","description":"Returns the canonical transaction facts, location (mined or mempool), confirmations, component counts, privacy shape, and ZIP 317 conventional fee. Shielded counterparties are never returned. Raw transaction bytes are NOT part of any typed read; the explorer plane is fact-first per the upstream Zinder model.","tags":["transactions"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"string","pattern":"^[0-9a-f]{64}$"},"required":true,"name":"transaction_id","in":"path"}],"responses":{"200":{"description":"Transaction facts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionDetailResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/mempool":{"get":{"summary":"Mempool snapshot summary.","description":"Aggregate counters across the current mempool snapshot. Capability-gated on `explorer.mempool.summary_v1`. Use the WebSocket stream at `/api/v1/stream` for live updates.","tags":["mempool"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"}],"responses":{"200":{"description":"Snapshot summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MempoolSummaryResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/mempool/activity":{"get":{"summary":"Recent mempool entries.","description":"Newest-first mempool entries with privacy shape, ZIP-317 conventional fee floor, and paid fee when prevout resolution is complete and the transaction has no shielded inputs. Capability-gated on `explorer.mempool.activity_v1`. Mempool state is transient; consumers should expect churn.","tags":["mempool"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Mempool entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MempoolActivityResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/mempool/events":{"get":{"summary":"Rolling counts of mempool lifecycle events.","description":"Returns added / mined / invalidated / suppressed counts observed by the upstream derive consumer over the last `window_seconds` (default 300; clamped to [60, 3600] by the server). Capability-gated on `explorer.mempool.event_counts_v1`. The effective window after server clamping is echoed in the response. For per-event delivery in real time use the WebSocket stream at `/api/v1/stream`.","tags":["mempool"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"integer","minimum":60,"maximum":3600,"default":300},"required":false,"name":"window_seconds","in":"query"}],"responses":{"200":{"description":"Mempool event counts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MempoolEventCountsResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/search":{"get":{"summary":"Typed search across blocks, transactions, and address candidates.","description":"Returns one or more typed result candidates for the named network. Shielded addresses and viewing keys always return `private_by_design`; this endpoint never opens a shielded history page.","tags":["search"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":4096},"required":true,"name":"q","in":"query"}],"responses":{"200":{"description":"Result candidates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/transparent-addresses/{address}":{"get":{"summary":"Transparent address balance and UTXOs.","description":"Returns the confirmed balance, signed mempool delta, and unspent outputs for a transparent address. Capability-gated on `explorer.transparent_address.balance_v1`.","tags":["transparent-addresses"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"string"},"required":true,"name":"address","in":"path"}],"responses":{"200":{"description":"Address detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparentAddressDetailResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/transparent-addresses/{address}/activity":{"get":{"summary":"Confirmed transparent-address activity feed.","description":"Returns newest-first confirmed activity rows for a transparent address. Each row carries the signed net value (when prevouts resolve), per-row input and output counts, and a `prevout_resolution_status` chip that explains why `net_value_zat` is or is not set. Mempool activity is served separately via `/mempool/activity`. Capability-gated on `explorer.transparent_address.activity_v1`.","tags":["transparent-addresses"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"},{"schema":{"type":"string"},"required":true,"name":"address","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Activity entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparentAddressActivityResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/broadcast":{"post":{"summary":"Broadcast a raw transaction to the upstream node.","description":"Accepts a hex-encoded raw transaction and forwards it to the upstream node. Returns a typed outcome (`accepted`, `duplicate`, `invalid_encoding`, `rejected`, or `unknown`). The raw hex is never logged or stored.","tags":["broadcast"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastRequest"}}}},"responses":{"200":{"description":"Broadcast outcome.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/{network}/payment-disclosures/verify":{"post":{"summary":"Verify a ZIP-311 payment disclosure.","description":"Forwards the hex-encoded disclosure bytes to the upstream verifier for the named network. Capability-gated on `explorer.payment_disclosure.verify_v1`; returns `503 capability_unavailable` when the upstream Zinder does not advertise the verifier. Disclosure payloads are never logged or persisted at the API layer.","tags":["payment-disclosures"],"parameters":[{"schema":{"type":"string","enum":["mainnet","testnet","regtest"]},"required":true,"name":"network","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDisclosureVerifyRequest"}}}},"responses":{"200":{"description":"Verification verdict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDisclosureVerifyResponse"}}}},"400":{"description":"Request rejected by the upstream node.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Resource not found in the indexed state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Pagination cursor expired; restart from the head.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Request did not validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal failure reaching upstream.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Upstream Zinder unavailable or capability missing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}}}