{
  "openapi": "3.1.0",
  "info": {
    "title": "Project Blackcoin Public API",
    "version": "1.3.1",
    "summary": "Read-only public telemetry and explorer API. NOT a custody API.",
    "description": "Quorum-verified, read-only telemetry and explorer data for Blackcoin Protocol V4, served from v30.1.3 observers and re-validated against an exact schema before leaving the origin. Nothing is guessed. Quantum schema 3, supply, and release surfaces may serve an explicitly labeled last_verified public record for at most one hour after its original verified timestamp; these responses carry Warning: 110 and X-Data-Quality/Verified-At/Expires-At/Age-Seconds. Retained data is never represented as live. Mutable /api/explorer/* machine endpoints, readiness, search, record lookup, mempool, address, UTXO, negative, and unavailable responses remain strict and never use the Explorer dashboard's separate UI-only retention path. CORS is open on every listed endpoint; no authentication. Query keys are validated exactly — sending an unlisted, duplicated, or malformed parameter returns 400 invalid_request with field-level errors. Amounts are canonical integer-sats strings; heights are exact; hashes are lowercase hex.\n\nThe private Explorer producer and this public API are independently versioned. The origin translates only an internal unversioned or internal schema 1 envelope into public Explorer schema 3 after full validation; every other present internal schema version fails closed.\n\nThis API does not create addresses, hold keys, track deposits, sign, or broadcast. Exchanges and custodians must run the signed-source v30.1.3 daemon (blackcoind) and integrate via its JSON-RPC for custody; this API is a mirror of that daemon, not a substitute for it. Error model: available/not_found/unavailable envelopes (components/schemas); 429 with Retry-After on rate limiting. Amounts are exact integer-sats strings; heights are exact integers. Address-index coverage is disclosed at /api/explorer/status and on affected responses; totals under partial coverage are lower bounds. Standard Explorer GETs are limited to 240 requests/minute per client; Explorer SSE connection attempts are limited to 60/minute. Every /api/explorer response (200/400/404/429/503, after per-request accounting) carries X-RateLimit-Limit/Remaining/Reset, and 429 adds Retry-After. Malformed requests return 400 invalid_request with field-level errors; 404 not_found is reserved for well-formed identifiers that match no record inside disclosed coverage."
  },
  "servers": [
    {
      "url": "https://projectblackcoin.org"
    }
  ],
  "paths": {
    "/api/v3/quantum": {
      "get": {
        "summary": "Current quorum-verified Gold Rush snapshot (schema 3).",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters. Quality ladder live/delayed/last_verified by snapshot age; weak ETag on a content hash of the public fields; CORS open."
      }
    },
    "/api/v3/quantum/stream": {
      "get": {
        "summary": "SSE stream of accepted snapshots.",
        "responses": {
          "200": {
            "description": "Snapshot event stream. An unavailable event is emitted when no retained snapshot is currently valid.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "503": {
            "description": "Stream capacity exhausted or request already disconnected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "text/event-stream; each snapshot is an `event: snapshot` frame, id `<height>:<snapshot_id>:<quality>`, retry 5000ms. No parameters. The origin caps active streams, coalesces snapshot reads across clients, bounds each connection's pending bytes, and closes streams after 15 minutes so EventSource reconnects cleanly."
      }
    },
    "/api/v3/lifecycle": {
      "get": {
        "summary": "Quorum-attested schema-12 replay marker, commitment, protocol phase, and consensus schedule.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailableEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters."
      }
    },
    "/api/quantum": {
      "get": {
        "summary": "Legacy schema-2 snapshot envelope (unchanged for existing consumers).",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailableEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters."
      }
    },
    "/api/supply": {
      "get": {
        "summary": "Base-chain supply sample (JSON): sats and decimal BLK; phase-locked shadow credits excluded.",
        "responses": {
          "200": {
            "description": "Available live or explicitly last_verified supply envelope. Quality is repeated in Warning/X-Data-* response headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailableEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters. Sampled from gettxoutsetinfo muhash every ~10 min. Reconciled supply taxonomy: base_merkle_utxo_nominal_sats, base_circulating_effective_sats, shadow_issued/unspent_nominal_sats, shadow_outstanding_pool_sats, shadow_scheduled_remaining_sats, protocol_nominal_utxo_sats, protocol_circulating_effective_sats, gold_rush_schedule_cap_sats, absolute_max_supply_sats (null), and dual anchors (periodic base UTXO sample + live shadow ledger). A combined response is admitted only when both height and hash match and anchors.consistent is true; otherwise the endpoint serves a previously reconciled last_verified record within its exact one-hour boundary or returns 503. Reconciliation equations and the additive sample_age_seconds/sample_retained/sample_stale/sample_status/sample_anchor_status/sample_max_age_seconds producer-provenance set are validated before any response is served. Inner sample_* fields preserve the Explorer's collection/restart history; outer quality/verified_at/expires_at/age_seconds fields describe this site's delivery and retention state. A restart-retained or >10-minute producer sample, or a site disk fallback, is outer quality last_verified, never live. A schema-valid record may be retained only through the exact one-hour sampled_at boundary; after that the route returns 503. Every 200 is no-store and carries X-Data-Quality/Verified-At/Expires-At/Age-Seconds; last_verified also carries Warning: 110. circulating_sats/total_sats are DEPRECATED aliases for the base UTXO set, unchanged in meaning."
      }
    },
    "/api/supply/circulating": {
      "get": {
        "summary": "Plain-text circulating supply in decimal BLK (aggregator format).",
        "responses": {
          "200": {
            "description": "Decimal BLK amount as plain text (aggregator format). The numeric body remains unchanged; X-Data-* and Warning: 110 disclose last-verified quality.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "pattern": "^[0-9]+\\.[0-9]{8}$"
                }
              }
            }
          },
          "503": {
            "description": "Plain-text unavailable response when the sample cannot be served."
          }
        },
        "description": "text/plain body, no envelope. No parameters. This base-only compatibility alias remains available when the shadow anchor drifts, uses its own generation-scoped retained record, preserves the existing nominal base-UTXO meaning, and applies the exact one-hour verified-at boundary with quality headers."
      }
    },
    "/api/supply/total": {
      "get": {
        "summary": "Plain-text total supply in decimal BLK (aggregator format).",
        "responses": {
          "200": {
            "description": "Decimal BLK amount as plain text (aggregator format). The numeric body remains unchanged; X-Data-* and Warning: 110 disclose last-verified quality.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "pattern": "^[0-9]+\\.[0-9]{8}$"
                }
              }
            }
          },
          "503": {
            "description": "Plain-text unavailable response when the sample cannot be served."
          }
        },
        "description": "text/plain body, no envelope. No parameters. This base-only compatibility alias remains available when the shadow anchor drifts, uses its own generation-scoped retained record, preserves the existing nominal base-UTXO meaning, and applies the exact one-hour verified-at boundary with quality headers."
      }
    },
    "/api/releases": {
      "get": {
        "summary": "Validated signed-release catalog from the GitHub record.",
        "responses": {
          "200": {
            "description": "Validated live or explicitly last_verified release catalog. Quality is repeated in Warning/X-Data-* response headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailableEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters. ETag/304 supported. The sanitized catalog may remain available for at most one hour during GitHub interruption or restart. The catalog body adds quality, verified_at, and expires_at. Catalog, RSS, and Atom are no-store and carry X-Data-Quality/Verified-At/Expires-At/Age-Seconds; last_verified responses also carry Warning: 110. Exact release pages visibly label catalog quality and age. /download redirects are intentionally live-only: every request resolves the pinned GitHub asset ID to a fresh GitHub-signed HTTPS target, and returns 503 instead of redirecting when the catalog is retained or the asset identity cannot be revalidated. Production GitHub API calls use a dedicated file-mounted public-read-only credential and fail closed rather than falling back to the shared anonymous origin quota."
      }
    },
    "/api/health": {
      "get": {
        "summary": "Liveness probe.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "Returns {status:\"ok\", service:\"projectblackcoin-site\"}. No parameters."
      }
    },
    "/api/og": {
      "get": {
        "summary": "Dynamic Open Graph card (PNG, 1200x630).",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "t",
            "in": "query",
            "required": false,
            "description": "Card kind: home | block | tx | shadow | address",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Short identifier shown on the card (<=80 chars of [A-Za-z0-9:,#.- ])",
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Returns image/png, not JSON."
      }
    },
    "/api/explorer/status": {
      "get": {
        "summary": "Chain status, observer agreement, tip freshness, per-index sync state, and canonical base/shadow coverage.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters. A 200 response means the status record passed the public schema, not necessarily that the explorer is ready. Consumers must inspect tip_fresh, observer_quorum, every index, coverage integrity, and shadow_coverage. /api/ready applies all of those invariants."
      }
    },
    "/api/explorer/network": {
      "get": {
        "summary": "Live network telemetry: hashrate, difficulty, connections, mempool, chain size, aggregate peer-version mix (no peer addresses).",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters."
      }
    },
    "/api/explorer/recent-blocks": {
      "get": {
        "summary": "Newest blocks with base and shadow summaries.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Integer 1-50 (default 10)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Height (1-9 digits); pages backward from this height, exclusive",
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Query keys are validated exactly; only limit and/or before are accepted."
      }
    },
    "/api/explorer/block/{id}": {
      "get": {
        "summary": "Full block record: header, paginated transactions, anchored shadow events.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Block height (0 to 100000000) or 64-hex block hash",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tx_offset",
            "in": "query",
            "required": false,
            "description": "Integer 0 to 1000000000",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tx_limit",
            "in": "query",
            "required": false,
            "description": "Integer 1-100",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/tx/{txid}": {
      "get": {
        "summary": "Transaction with prevout-resolved inputs; spentness where provable, else null.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "txid",
            "in": "path",
            "required": true,
            "description": "64-hex transaction id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vin_offset",
            "in": "query",
            "required": false,
            "description": "0 to 1e9",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vin_limit",
            "in": "query",
            "required": false,
            "description": "1-100",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vout_offset",
            "in": "query",
            "required": false,
            "description": "0 to 1e9",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vout_limit",
            "in": "query",
            "required": false,
            "description": "1-100",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/address/{address}": {
      "get": {
        "summary": "Base activity within disclosed coverage plus the complete synthetic payout history, paginated independently.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58 or bech32 address, 14-128 chars of [A-Za-z0-9:]",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Base activity offset 0 to 1e9",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Base activity page 1-100",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "shadow_offset",
            "in": "query",
            "required": false,
            "description": "Shadow activity offset 0 to 1e9",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "shadow_limit",
            "in": "query",
            "required": false,
            "description": "Shadow activity page 1-100",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/shadow/tx/{synthetic_txid}": {
      "get": {
        "summary": "Synthetic payout record: lifecycle, maturity, demurrage, spend linkage.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "synthetic_txid",
            "in": "path",
            "required": true,
            "description": "64-hex synthetic transaction id",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/shadow/supply": {
      "get": {
        "summary": "Anchored shadow supply: pools, materialized and phase-locked totals, claim counts.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "No query parameters. The active_signaler_count field is reserved and currently always null; the reviewed active-signaler count is published in the live snapshot at /api/v3/quantum (data.next_block.active_signalers) — one authoritative disclosure, one source."
      }
    },
    "/api/explorer/events": {
      "get": {
        "summary": "Shadow events — recent scan, or filtered history from the payout index.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "Without parameters: the most recent shadow events (claims, distributions, signals) from a tip scan. With any filter: indexed payout events (pow_claim / pos_distribution only — signal events are not payout records and appear only in the unfiltered scan) served from the local index with a coverage disclosure. Height filters are bounded by disclosed coverage; absence outside coverage is not proof of absence.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "pow_claim",
                "pos_distribution"
              ]
            }
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:]{14,128}$"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Lowest height (inclusive)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Highest height (inclusive)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            }
          }
        ]
      }
    },
    "/api/explorer/analytics/leaderboard": {
      "get": {
        "summary": "Addresses ranked by materialized Gold Rush payouts, with PoW/PoS split and active range.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Integer 1-100 (default 50)",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/analytics/series": {
      "get": {
        "summary": "Bucketed per-block series (payout value, event counts, difficulty, size, fees) for charting; capped at 240 buckets.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Start height (1-9 digits)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "End height (1-9 digits)",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/analytics/network-series": {
      "get": {
        "summary": "Time series of PoW hashrate, network stake weight, and PoS/PoW difficulty sampled every ~5 min.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "Integer 1-336 (default 24)",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/search": {
      "get": {
        "summary": "Classify a query into its explorer path.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "Known-shape not-found envelope (explorer records only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Height, block hash, txid, or address (1-128 chars of [A-Za-z0-9:])",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/explorer/stream": {
      "get": {
        "summary": "Best-effort SSE notification of verified canonical-tip identity changes.",
        "responses": {
          "200": {
            "description": "Best-effort validated event stream. The legacy event:block frame retains its raw projected PublicBlock payload and integer-height ID. Each immediately following event:block-v3 frame carries the public Explorer schema-3 available envelope and a height:hash ID. The versioned envelope retains the sanitized internal generated_at timestamp. The connection opens only after one authenticated schema-valid block and a source-identity recheck.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Fail-closed unavailable envelope: {status:\"unavailable\"}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        },
        "description": "Best-effort tip notification, not a lossless event log or reorg replay service. Each observed forward block, rollback, or same-height canonical replacement emits two additive compatibility frames: legacy `event: block` with raw PublicBlock data and integer-height ID, followed by `event: block-v3` with a public schema-3 envelope and height:hash ID. Unchanged polls emit keepalive comments. Clients must refetch and reconcile canonical state by height and hash after every connect/reconnect and whenever they detect a gap; notifications can be coalesced or missed while disconnected. The origin translates only an internal unversioned or schema 1 envelope to public schema 3 and rejects any other present internal version. No parameters. The origin caps active streams, shares one bounded upstream poll across connected clients, closes streams after 15 minutes so clients reconnect, and emits `event: unavailable` with schema_version 3 before closing if validation or the explorer kill switch fails."
      }
    },
    "/explorer/address/{address}/feed.xml": {
      "get": {
        "summary": "Atom feed of an address's shadow payouts.",
        "responses": {
          "200": {
            "description": "Available envelope: {status:\"available\", ...}"
          },
          "400": {
            "description": "Malformed request (plain text)."
          },
          "404": {
            "description": "Address not found (plain text)."
          },
          "429": {
            "description": "Rate limited (plain text). Retry-After and X-RateLimit-* headers are included."
          },
          "503": {
            "description": "Explorer or shadow coverage unavailable (plain text)."
          }
        },
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Base58 or bech32 address, 14-128 chars of [A-Za-z0-9:]",
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Returns application/atom+xml, not JSON."
      }
    },
    "/api/chain-params": {
      "get": {
        "summary": "Machine-readable chain parameters, lifecycle heights, and integration guidance.",
        "description": "Static-shape JSON: asset identity (ticker, decimals), network params (ports, bech32 HRP, block timing, consensus), lifecycle heights (Gold Rush window, competing-claims activation, final lockout), endpoint listing, and custody-interface guidance. CORS open. Both bech32 (HRP 'blk') and legacy Base58 ('B...') address classes remain valid until the published final-lockout height. Not rate limited (static document).",
        "responses": {
          "200": {
            "description": "Raw chain-parameter document (schema blackcoin.chain-params/2) — not an envelope. Includes the versioned identity manifest: genesis hash/merkle root, message start, base58 prefixes, BIP44 type, quantum replay domain, source commit, shared-history statement, and null future branch anchors."
          }
        }
      }
    },
    "/releases/{tag}": {
      "get": {
        "summary": "Immutable HTML record for one exact release tag.",
        "description": "Server-rendered page describing exactly the named release: validated assets, checksums, signature status, and the exact upstream GitHub record. Unknown tags return 404. RSS/Atom items link here so an item for an older build never opens a newer one.",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,64}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Immutable release record (text/html)."
          },
          "404": {
            "description": "Unknown tag (HTML not-found page)."
          }
        }
      }
    },
    "/api/ready": {
      "get": {
        "summary": "Readiness: fails when a required dependency cannot serve its contract.",
        "description": "Distinct from /api/health (shallow liveness). Returns 200 {status:'ready'} only when the quantum snapshot store is valid, a fully validated reconciled supply sample is non-null, and the explorer proves a fresh health snapshot, full observer quorum and agreement, a fresh canonical tip, synchronized required indexes, canonical address anchoring, complete contiguous SQLite-backed base coverage, and gap-free payload-complete shadow coverage. A null supply read fails closed as 503 and is reported in components.reconciled_supply. A live, operational explorer that is catching up returns 503 {status:'not_ready'} while retaining live/operational/state detail and does not imply that a restart is recommended.",
        "responses": {
          "200": {
            "description": "All required components ready (per-component detail included)."
          },
          "503": {
            "description": "One or more components cannot serve; body discloses which and why."
          }
        }
      }
    },
    "/api/explorer/address/{address}/utxos": {
      "get": {
        "summary": "Address unspent outputs",
        "description": "Paginated unspent outputs of an address (txid, vout, value_sats, height, confirmations) with canonical-chain anchor, canonical local-snapshot anchor, and integrity-bearing index coverage. Totals are lower bounds whenever coverage is incomplete.",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Blackcoin address"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "0-based offset"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1..100"
          }
        ],
        "responses": {
          "200": {
            "description": "available/unavailable envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Explorer unavailable; no stale substitute is presented as current.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/explorer/mempool": {
      "get": {
        "summary": "Mempool contents",
        "description": "Current mempool: count, total bytes, and pending txids (capped at 1000 with a truncation flag).",
        "responses": {
          "200": {
            "description": "available/unavailable envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Explorer unavailable; no stale substitute is presented as current.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/explorer/tx/{txid}/hex": {
      "get": {
        "summary": "Raw transaction hex",
        "description": "The raw serialized hex of a transaction, for decoding or re-broadcast on your own node.",
        "parameters": [
          {
            "name": "txid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "64-hex transaction id"
          }
        ],
        "responses": {
          "200": {
            "description": "available/unavailable envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Explorer unavailable; no stale substitute is presented as current.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/explorer/block/{id}/hex": {
      "get": {
        "summary": "Raw block hex",
        "description": "The raw serialized hex of a block by height or 64-hex hash.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Block height or 64-hex hash"
          }
        ],
        "responses": {
          "200": {
            "description": "available/unavailable envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerAvailableEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ExplorerInvalidRequest"
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerNotFoundEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ExplorerRateLimited"
          },
          "503": {
            "description": "Explorer unavailable; no stale substitute is presented as current.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplorerUnavailableEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Sats": {
        "type": "string",
        "pattern": "^[0-9]+$",
        "description": "Exact integer satoshi amount as a decimal string (1 BLK = 100,000,000 sats). Never a float."
      },
      "Height": {
        "type": "integer",
        "minimum": 0,
        "description": "Exact block height."
      },
      "Hash": {
        "type": "string",
        "pattern": "^[0-9a-f]{64}$",
        "description": "Lowercase hex block/transaction hash."
      },
      "AvailableEnvelope": {
        "type": "object",
        "required": [
          "status",
          "generated_at",
          "data"
        ],
        "properties": {
          "status": {
            "const": "available"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "description": "Endpoint-specific payload; see the endpoint description."
          }
        },
        "description": "Generic non-Explorer success envelope. Refer to each endpoint for its schema version and exact payload."
      },
      "NotFoundEnvelope": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "const": "not_found"
          }
        },
        "description": "Generic non-Explorer not-found shape. Explorer records use ExplorerNotFoundEnvelope."
      },
      "UnavailableEnvelope": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "const": "unavailable"
          }
        },
        "description": "Generic non-Explorer fail-closed shape. Explorer responses use ExplorerUnavailableEnvelope."
      },
      "RateLimited": {
        "type": "object",
        "description": "Generic rate-limit response. Refer to the endpoint for its media type and exact body."
      },
      "Coverage": {
        "type": "object",
        "properties": {
          "from_height": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0,
                "description": "Exact block height."
              },
              {
                "type": "null"
              }
            ]
          },
          "through_height": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0,
                "description": "Exact block height."
              },
              {
                "type": "null"
              }
            ]
          },
          "complete": {
            "type": "boolean",
            "description": "false while the historical backfill toward genesis is in progress; totals derived from partial coverage are lower bounds, not complete totals."
          },
          "expected_through_height": {
            "type": "integer",
            "minimum": 0,
            "description": "Canonical height through which this coverage record is expected to be complete."
          },
          "block_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Durably indexed canonical block rows. Present on explorer status coverage."
          },
          "expected_block_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Expected contiguous block rows for the disclosed bounds. Present on explorer status coverage."
          },
          "contiguous": {
            "type": "boolean",
            "description": "Whether the indexed base-chain height interval is contiguous. Present on explorer status coverage."
          },
          "sqlite_integrity": {
            "type": "object",
            "properties": {
              "healthy": {
                "type": "boolean"
              }
            },
            "description": "Sanitized SQLite integrity result; private paths and recovery details are never exposed."
          }
        }
      },
      "ShadowCoverage": {
        "type": "object",
        "required": [
          "from_height",
          "through_height",
          "expected_through_height",
          "complete",
          "gap_count",
          "incomplete_payload_count"
        ],
        "properties": {
          "from_height": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "through_height": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "expected_through_height": {
            "type": "integer",
            "minimum": 0
          },
          "complete": {
            "type": "boolean"
          },
          "gap_count": {
            "type": "integer",
            "minimum": 0
          },
          "incomplete_payload_count": {
            "type": "integer",
            "minimum": 0
          }
        },
        "description": "Contiguous canonical Gold Rush shadow coverage. complete can be true only when the through and expected heights match and both gap counters are zero."
      },
      "InvalidRequestEnvelope": {
        "type": "object",
        "required": [
          "schema_version",
          "status",
          "errors"
        ],
        "properties": {
          "schema_version": {
            "const": 1
          },
          "status": {
            "const": "invalid_request"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "param",
                "reason"
              ],
              "properties": {
                "param": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "HTTP 400 v1 request-error envelope used by non-Explorer APIs. Explorer request errors use ExplorerInvalidRequestEnvelope (schema_version 3)."
      },
      "ExplorerAvailableEnvelope": {
        "type": "object",
        "required": [
          "schema_version",
          "status",
          "generated_at",
          "data"
        ],
        "properties": {
          "schema_version": {
            "const": 3
          },
          "status": {
            "const": "available"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "description": "Endpoint-specific payload; see the endpoint description."
          }
        },
        "description": "Success envelope. Amounts are Sats strings; heights are exact integers."
      },
      "ExplorerNotFoundEnvelope": {
        "type": "object",
        "required": [
          "schema_version",
          "status"
        ],
        "properties": {
          "schema_version": {
            "const": 3
          },
          "status": {
            "const": "not_found"
          }
        },
        "description": "The identifier is well-formed but no record exists inside disclosed coverage. Records outside coverage may exist on chain but are not yet indexed — check /api/explorer/status coverage before treating absence as proof."
      },
      "ExplorerUnavailableEnvelope": {
        "type": "object",
        "required": [
          "schema_version",
          "status"
        ],
        "properties": {
          "schema_version": {
            "const": 3
          },
          "status": {
            "const": "unavailable"
          }
        },
        "description": "Fail-closed envelope (HTTP 503): the source cannot prove a response right now. Never a guess or a stale substitute presented as current."
      },
      "ExplorerRateLimitedEnvelope": {
        "type": "object",
        "required": [
          "schema_version",
          "status"
        ],
        "properties": {
          "schema_version": {
            "const": 3
          },
          "status": {
            "const": "rate_limited"
          }
        },
        "description": "HTTP 429: per-client request limit exceeded. Honor Retry-After and back off. Limits are enforced at the origin; keep request rates neighborly."
      },
      "ExplorerInvalidRequestEnvelope": {
        "type": "object",
        "required": [
          "schema_version",
          "status",
          "errors"
        ],
        "properties": {
          "schema_version": {
            "const": 3
          },
          "status": {
            "const": "invalid_request"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "param",
                "reason"
              ],
              "properties": {
                "param": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "HTTP 400: the request shape is wrong (unknown/duplicated/malformed parameter or malformed identifier), with one entry per offending field. Distinct from 404 not_found, which means a well-formed identifier matched no record inside disclosed coverage."
      }
    },
    "responses": {
      "RateLimited": {
        "description": "Rate limited. Retry after the indicated delay.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait before retrying."
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Requests allowed per minute (currently 240 per client)."
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until the window resets."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RateLimited"
            }
          }
        }
      },
      "InvalidRequest": {
        "description": "Malformed request with field-level errors.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvalidRequestEnvelope"
            }
          }
        }
      },
      "ExplorerRateLimited": {
        "description": "Explorer rate limited. Honor Retry-After and retry after the indicated delay.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait before retrying."
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Current endpoint's requests-per-minute limit. Standard Explorer GETs use 240; Explorer SSE connection attempts use 60."
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until the window resets."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ExplorerRateLimitedEnvelope"
            }
          }
        }
      },
      "ExplorerInvalidRequest": {
        "description": "Malformed Explorer request with field-level errors.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ExplorerInvalidRequestEnvelope"
            }
          }
        }
      }
    }
  }
}
