openapi: 3.1.0
info:
  title: SQD Portal API - Solana Dataset Endpoints
  description: API endpoints for interacting with Solana datasets under the SQD Portal, specifically for the solana-mainnet dataset.
  version: 1.0.0
servers:
  - url: https://portal.sqd.dev/datasets/solana-mainnet
paths:
  /metadata:
    get:
      summary: Dataset Metadata
      operationId: getSolanaDatasetMetadata
      x-mint:
        href: "/en/api/solana/metadata"
        metadata:
          description: "Get Solana dataset metadata from the SQD Portal API."
      x-codeSamples:
        - lang: shell
          label: Get Solana Mainnet Metadata
          source: |
            curl --compressed 'https://portal.sqd.dev/datasets/solana-mainnet/metadata'
        - lang: python
          label: Get Solana Mainnet Metadata
          source: |
            import requests

            response = requests.get(
                "https://portal.sqd.dev/datasets/solana-mainnet/metadata"
            )
            data = response.json()
        - lang: javascript
          label: Get Solana Mainnet Metadata
          source: |
            const response = await fetch("https://portal.sqd.dev/datasets/solana-mainnet/metadata");
            const data = await response.json();
      description: "Retrieves metadata describing the dataset, including its name, aliases, start block, and real-time status."
      responses:
        "200":
          description: Dataset metadata response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DatasetMetadata"
              examples:
                solana-mainnet:
                  summary: Solana Mainnet metadata
                  value:
                    dataset: "solana-mainnet"
                    aliases: ["solana-beta"]
                    real_time: true
                    start_block: 0
        "404":
          description: Dataset not found (`error.code` is `unknown_dataset`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: unknown_dataset
                  message: "Unknown dataset: no-such-chain"
  /stream:
    post:
      summary: Stream Blocks
      operationId: streamSolanaBlocks
      x-mint:
        href: "/en/api/solana/stream"
        metadata:
          description: "Stream Solana blockchain data with the SQD Portal API."
      x-codeSamples:
        - lang: shell
          label: Track SPL Token Transfers
          source: |
            curl --compressed -X POST 'https://portal.sqd.dev/datasets/solana-mainnet/stream' \
              -H 'Content-Type: application/json' \
              -d '{
                "type": "solana",
                "fromBlock": 280000000,
                "toBlock": 280000100,
                "fields": {
                  "block": {
                    "number": true,
                    "timestamp": true
                  },
                  "tokenBalance": {
                    "account": true,
                    "preMint": true,
                    "postMint": true,
                    "preAmount": true,
                    "postAmount": true,
                    "preOwner": true,
                    "postOwner": true
                  }
                },
                "tokenBalances": [{
                  "preMint": ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"]
                }]
              }'
        - lang: shell
          label: Program Instructions
          source: |
            curl --compressed -X POST 'https://portal.sqd.dev/datasets/solana-mainnet/stream' \
              -H 'Content-Type: application/json' \
              -d '{
                "type": "solana",
                "fromBlock": 280000000,
                "toBlock": 280000100,
                "fields": {
                  "block": {
                    "number": true,
                    "timestamp": true
                  },
                  "instruction": {
                    "programId": true,
                    "accounts": true,
                    "data": true,
                    "transactionIndex": true
                  }
                },
                "instructions": [{
                  "programId": ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"]
                }]
              }'
        - lang: shell
          label: Transactions
          source: |
            curl --compressed -X POST 'https://portal.sqd.dev/datasets/solana-mainnet/stream' \
              -H 'Content-Type: application/json' \
              -d '{
                "type": "solana",
                "fromBlock": 280000000,
                "toBlock": 280000100,
                "fields": {
                  "block": {
                    "number": true,
                    "timestamp": true
                  },
                  "transaction": {
                    "signatures": true,
                    "feePayer": true,
                    "err": true
                  }
                },
                "transactions": [{}]
              }'
        - lang: python
          label: Track SPL Token Transfers
          source: |
            import requests

            response = requests.post(
                "https://portal.sqd.dev/datasets/solana-mainnet/stream",
                json={
                    "type": "solana",
                    "fromBlock": 280000000,
                    "toBlock": 280000100,
                    "fields": {
                        "block": {
                            "number": True,
                            "timestamp": True
                        },
                        "tokenBalance": {
                            "account": True,
                            "preMint": True,
                            "postMint": True,
                            "preAmount": True,
                            "postAmount": True,
                            "preOwner": True,
                            "postOwner": True
                        }
                    },
                    "tokenBalances": [{
                        "preMint": ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"]
                    }]
                }
            )
            data = response.json()
        - lang: javascript
          label: Track SPL Token Transfers
          source: |
            const response = await fetch("https://portal.sqd.dev/datasets/solana-mainnet/stream", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    type: "solana",
                    fromBlock: 280000000,
                    toBlock: 280000100,
                    fields: {
                        block: {
                            number: true,
                            timestamp: true
                        },
                        tokenBalance: {
                            account: true,
                            preMint: true,
                            postMint: true,
                            preAmount: true,
                            postAmount: true,
                            preOwner: true,
                            postOwner: true
                        }
                    },
                    tokenBalances: [{
                        preMint: ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"]
                    }]
                })
            });
            const data = await response.json();
      description: "Streams a list of blocks matching the provided data query, potentially including real-time data. Required request headers: `Content-Type: application/json`; optional request headers: `Accept-Encoding: gzip`, `Content-Encoding: gzip`."
      requestBody:
        description: "Data query to filter and retrieve blocks. Request body may be gzipped (Content-Encoding: gzip)."
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DataQuery"
            examples:
              token-transfers:
                summary: Track SPL Token Transfers
                value:
                  type: solana
                  fromBlock: 280000000
                  toBlock: 280000100
                  fields:
                    block:
                      number: true
                      timestamp: true
                    tokenBalance:
                      account: true
                      preMint: true
                      postMint: true
                      preAmount: true
                      postAmount: true
                      preOwner: true
                      postOwner: true
                  tokenBalances:
                    - preMint:
                        - "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
              program-instructions:
                summary: Program Instructions
                value:
                  type: solana
                  fromBlock: 280000000
                  toBlock: 280000100
                  fields:
                    block:
                      number: true
                      timestamp: true
                    instruction:
                      programId: true
                      accounts: true
                      data: true
                      transactionIndex: true
                  instructions:
                    - programId:
                        - "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"
              transactions:
                summary: Transactions
                value:
                  type: solana
                  fromBlock: 280000000
                  toBlock: 280000100
                  fields:
                    block:
                      number: true
                      timestamp: true
                    transaction:
                      signatures: true
                      feePayer: true
                      err: true
                  transactions:
                    - {}
      responses:
        "200":
          description: A stream of blocks in JSON lines format, optionally gzipped. Can only be empty if the data query has a bounded range and all blocks in the range have been skipped. May include X-Sqd-Finalized-Head-Number and X-Sqd-Finalized-Head-Hash headers, indicating the latest finalized block that's on the same chain as the returned blocks
          headers:
            X-Sqd-Finalized-Head-Number:
              schema:
                type: integer
                format: int64
              description: Slot number of the latest finalized block. Returned blocks can be above, at or below this slot number
              required: false
            X-Sqd-Finalized-Head-Hash:
              schema:
                type: string
              description: Hash of the latest finalized block. All returned blocks are guaranteed to belong to the same (not necessarily final) chain as this block
              required: false
          content:
            application/jsonl:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Block"
              examples:
                token-balance-response:
                  summary: Token balance response
                  value:
                    - header:
                        number: 280000042
                        timestamp: 1700000000
                      tokenBalances:
                        - transactionIndex: 3
                          account: "7kMFogLSGwpcPmxjYBYZq2F5uSJa3Fy6jhfW3GfdhGE8"
                          preMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
                          postMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
                          preAmount: 1000000
                          postAmount: 500000
                          preOwner: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
                          postOwner: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
        "204":
          description: No new blocks available in the requested range - the range is entirely above the current dataset head. Not an error and the response has no body; wait and retry to keep following the chain head. The portal may wait for up to 5s before returning this.
          headers:
            X-Sqd-Finalized-Head-Number:
              schema:
                type: integer
                format: int64
              description: Slot number of the latest finalized block. Returned blocks can be above, at or below this slot number
              required: false
            X-Sqd-Finalized-Head-Hash:
              schema:
                type: string
              description: Hash of the latest finalized block. All returned blocks are guaranteed to belong to the same (not necessarily final) chain as this block
              required: false
        "400":
          description: >
            Invalid request or query (`error.code` is `malformed_request`; `error.param` names the request field at fault when one is). Possible causes: (1) request headers or body encoding are incorrect; (2) the query is invalid - `error.message` includes an explanation; (3) fromBlock is below the dataset's start_block (see /metadata).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: malformed_request
                  message: "Bad request: fromBlock must be a non-negative integer"
                  param: fromBlock
        "404":
          description: Dataset not found (`error.code` is `unknown_dataset`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: unknown_dataset
                  message: "Unknown dataset: no-such-chain"
        "409":
          description: Parent block hash mismatch (`error.code` is `base_block_mismatch`) - the query's parentBlockHash does not match the canonical parent of the first requested block, typically after a chain reorganization. Walk the top-level previousBlocks list to find the most recent block you have already processed, roll back your data to it, then resume the stream from the next block, passing that block's hash as parentBlockHash. If nothing in the list matches your records, restart from an earlier fromBlock, again with parentBlockHash.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConflictResponse"
        "429":
          description: Rate limited (`error.type` is `rate_limit_error`). Retry after the interval in the Retry-After header; it is always present and counts seconds
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: rate_limit_error
                  code: overloaded
                  message: Service is overloaded, please try again later
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
        "500":
          description: Internal server error (`error.type` is `api_error`). Do not retry; report the error together with its request_id
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: api_error
                  code: internal_error
                  message: Internal server error
                  request_id: "0198c3f1-..."
        "502":
          description: A data source the Portal depends on is unavailable (`error.code` is `upstream_unavailable`) - retry later. A proxied upstream failure keeps the upstream's own 5xx status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: availability_error
                  code: upstream_unavailable
                  message: Upstream data source is unavailable, please try again later
                  request_id: "0198c3f1-..."
        "503":
          description: Service temporarily unavailable (`error.type` is `availability_error`, typically `no_workers` or `retries_exhausted`) - retry later. May carry Retry-After; honor it when present
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: availability_error
                  code: no_workers
                  message: No workers available for dataset
                  request_id: "0198c3f1-..."
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
        "529":
          description: Overloaded (`error.code` is `overloaded`) - the Portal or a data source is at capacity. Retry after the interval in the Retry-After header; it is always present and counts seconds
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: rate_limit_error
                  code: overloaded
                  message: Service is overloaded, please try again later
                  request_id: "0198c3f1-..."
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
  /finalized-stream:
    post:
      summary: Stream Finalized Blocks
      operationId: streamSolanaFinalizedBlocks
      x-mint:
        href: "/en/api/solana/finalized-stream"
        metadata:
          description: "Stream finalized Solana blockchain data with the SQD Portal API."
      x-codeSamples:
        - lang: shell
          label: Track SPL Token Transfers
          source: |
            curl --compressed -X POST 'https://portal.sqd.dev/datasets/solana-mainnet/finalized-stream' \
              -H 'Content-Type: application/json' \
              -d '{
                "type": "solana",
                "fromBlock": 280000000,
                "toBlock": 280000100,
                "fields": {
                  "block": {
                    "number": true,
                    "timestamp": true
                  },
                  "tokenBalance": {
                    "account": true,
                    "preMint": true,
                    "postMint": true,
                    "preAmount": true,
                    "postAmount": true,
                    "preOwner": true,
                    "postOwner": true
                  }
                },
                "tokenBalances": [{
                  "preMint": ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"]
                }]
              }'
        - lang: shell
          label: Program Instructions
          source: |
            curl --compressed -X POST 'https://portal.sqd.dev/datasets/solana-mainnet/finalized-stream' \
              -H 'Content-Type: application/json' \
              -d '{
                "type": "solana",
                "fromBlock": 280000000,
                "toBlock": 280000100,
                "fields": {
                  "block": {
                    "number": true,
                    "timestamp": true
                  },
                  "instruction": {
                    "programId": true,
                    "accounts": true,
                    "data": true,
                    "transactionIndex": true
                  }
                },
                "instructions": [{
                  "programId": ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"]
                }]
              }'
        - lang: shell
          label: Transactions
          source: |
            curl --compressed -X POST 'https://portal.sqd.dev/datasets/solana-mainnet/finalized-stream' \
              -H 'Content-Type: application/json' \
              -d '{
                "type": "solana",
                "fromBlock": 280000000,
                "toBlock": 280000100,
                "fields": {
                  "block": {
                    "number": true,
                    "timestamp": true
                  },
                  "transaction": {
                    "signatures": true,
                    "feePayer": true,
                    "err": true
                  }
                },
                "transactions": [{}]
              }'
        - lang: python
          label: Track SPL Token Transfers
          source: |
            import requests

            response = requests.post(
                "https://portal.sqd.dev/datasets/solana-mainnet/finalized-stream",
                json={
                    "type": "solana",
                    "fromBlock": 280000000,
                    "toBlock": 280000100,
                    "fields": {
                        "block": {
                            "number": True,
                            "timestamp": True
                        },
                        "tokenBalance": {
                            "account": True,
                            "preMint": True,
                            "postMint": True,
                            "preAmount": True,
                            "postAmount": True,
                            "preOwner": True,
                            "postOwner": True
                        }
                    },
                    "tokenBalances": [{
                        "preMint": ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"]
                    }]
                }
            )
            data = response.json()
        - lang: javascript
          label: Track SPL Token Transfers
          source: |
            const response = await fetch("https://portal.sqd.dev/datasets/solana-mainnet/finalized-stream", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    type: "solana",
                    fromBlock: 280000000,
                    toBlock: 280000100,
                    fields: {
                        block: {
                            number: true,
                            timestamp: true
                        },
                        tokenBalance: {
                            account: true,
                            preMint: true,
                            postMint: true,
                            preAmount: true,
                            postAmount: true,
                            preOwner: true,
                            postOwner: true
                        }
                    },
                    tokenBalances: [{
                        preMint: ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"]
                    }]
                })
            });
            const data = await response.json();
      description: "Streams only finalized blocks matching the provided data query (finalized data does not reorganize; a 409 here only means the provided parentBlockHash is stale). Query structure is identical to that of the /stream endpoint. Required request headers: `Content-Type: application/json`; optional request headers: `Accept-Encoding: gzip`, `Content-Encoding: gzip`."
      requestBody:
        description: "Data query to filter and retrieve finalized blocks. Request body may be gzipped (Content-Encoding: gzip)."
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DataQuery"
            examples:
              token-transfers:
                summary: Track SPL Token Transfers
                value:
                  type: solana
                  fromBlock: 280000000
                  toBlock: 280000100
                  fields:
                    block:
                      number: true
                      timestamp: true
                    tokenBalance:
                      account: true
                      preMint: true
                      postMint: true
                      preAmount: true
                      postAmount: true
                      preOwner: true
                      postOwner: true
                  tokenBalances:
                    - preMint:
                        - "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
              program-instructions:
                summary: Program Instructions
                value:
                  type: solana
                  fromBlock: 280000000
                  toBlock: 280000100
                  fields:
                    block:
                      number: true
                      timestamp: true
                    instruction:
                      programId: true
                      accounts: true
                      data: true
                      transactionIndex: true
                  instructions:
                    - programId:
                        - "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"
              transactions:
                summary: Transactions
                value:
                  type: solana
                  fromBlock: 280000000
                  toBlock: 280000100
                  fields:
                    block:
                      number: true
                      timestamp: true
                    transaction:
                      signatures: true
                      feePayer: true
                      err: true
                  transactions:
                    - {}
      responses:
        "200":
          description: A stream of blocks in JSON lines format, optionally gzipped. Can only be empty if the data query has a bounded range and all blocks in the range have been skipped.
          content:
            application/jsonl:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Block"
              examples:
                token-balance-response:
                  summary: Token balance response
                  value:
                    - header:
                        number: 280000042
                        timestamp: 1700000000
                      tokenBalances:
                        - transactionIndex: 3
                          account: "7kMFogLSGwpcPmxjYBYZq2F5uSJa3Fy6jhfW3GfdhGE8"
                          preMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
                          postMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
                          preAmount: 1000000
                          postAmount: 500000
                          preOwner: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
                          postOwner: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
        "204":
          description: No new blocks available in the requested range - the range is entirely above the current dataset head. Not an error and the response has no body; wait and retry to keep following the chain head. The portal may wait for up to 5s before returning this.
        "400":
          description: >
            Invalid request or query (`error.code` is `malformed_request`; `error.param` names the request field at fault when one is). Possible causes: (1) request headers or body encoding are incorrect; (2) the query is invalid - `error.message` includes an explanation; (3) fromBlock is below the dataset's start_block (see /metadata).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: malformed_request
                  message: "Bad request: fromBlock must be a non-negative integer"
                  param: fromBlock
        "404":
          description: Dataset not found (`error.code` is `unknown_dataset`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: unknown_dataset
                  message: "Unknown dataset: no-such-chain"
        "409":
          description: Parent block hash mismatch (`error.code` is `base_block_mismatch`). Finalized data does not reorganize, so the provided parentBlockHash is stale or was carried over from an unfinalized block. Recover as for /stream by walking the top-level previousBlocks list.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConflictResponse"
        "429":
          description: Rate limited (`error.type` is `rate_limit_error`). Retry after the interval in the Retry-After header; it is always present and counts seconds
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: rate_limit_error
                  code: overloaded
                  message: Service is overloaded, please try again later
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
        "500":
          description: Internal server error (`error.type` is `api_error`). Do not retry; report the error together with its request_id
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: api_error
                  code: internal_error
                  message: Internal server error
                  request_id: "0198c3f1-..."
        "502":
          description: A data source the Portal depends on is unavailable (`error.code` is `upstream_unavailable`) - retry later. A proxied upstream failure keeps the upstream's own 5xx status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: availability_error
                  code: upstream_unavailable
                  message: Upstream data source is unavailable, please try again later
                  request_id: "0198c3f1-..."
        "503":
          description: Service temporarily unavailable (`error.type` is `availability_error`, typically `no_workers` or `retries_exhausted`) - retry later. May carry Retry-After; honor it when present
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: availability_error
                  code: no_workers
                  message: No workers available for dataset
                  request_id: "0198c3f1-..."
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
        "529":
          description: Overloaded (`error.code` is `overloaded`) - the Portal or a data source is at capacity. Retry after the interval in the Retry-After header; it is always present and counts seconds
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: rate_limit_error
                  code: overloaded
                  message: Service is overloaded, please try again later
                  request_id: "0198c3f1-..."
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
  /head:
    get:
      summary: Latest Block
      operationId: getSolanaHead
      x-mint:
        href: "/en/api/solana/head"
        metadata:
          description: "Get the latest Solana block number and hash available from SQD Portal."
      x-codeSamples:
        - lang: shell
          label: Get Latest Solana Block
          source: |
            curl --compressed 'https://portal.sqd.dev/datasets/solana-mainnet/head'
        - lang: python
          label: Get Latest Solana Block
          source: |
            import requests

            response = requests.get(
                "https://portal.sqd.dev/datasets/solana-mainnet/head"
            )
            data = response.json()
        - lang: javascript
          label: Get Latest Solana Block
          source: |
            const response = await fetch("https://portal.sqd.dev/datasets/solana-mainnet/head");
            const data = await response.json();
      description: "Returns the slot number and hash of the highest block available in the dataset, or null if no blocks are available. Takes real-time data into account. Useful mostly for diagnostics, as clients using /stream can get this info from the X-Sqd-Finalized-Head-Number and X-Sqd-Finalized-Head-Hash response headers."
      responses:
        "200":
          description: Highest block information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BlockHead"
              examples:
                solana-head:
                  summary: Latest Solana block
                  value:
                    number: 450375284
                    hash: "GdqUPS2umM4C8HNHbXHcAQGtLnnY9MtBsiq7VpZf1ktX"
        "404":
          description: Dataset not found (`error.code` is `unknown_dataset`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: unknown_dataset
                  message: "Unknown dataset: no-such-chain"
  /finalized-head:
    get:
      summary: Latest Finalized Block
      operationId: getSolanaFinalizedHead
      x-mint:
        href: "/en/api/solana/finalized-head"
        metadata:
          description: "Get the latest finalized Solana block number and hash from SQD Portal."
      x-codeSamples:
        - lang: shell
          label: Get Latest Finalized Solana Block
          source: |
            curl --compressed 'https://portal.sqd.dev/datasets/solana-mainnet/finalized-head'
        - lang: python
          label: Get Latest Finalized Solana Block
          source: |
            import requests

            response = requests.get(
                "https://portal.sqd.dev/datasets/solana-mainnet/finalized-head"
            )
            data = response.json()
        - lang: javascript
          label: Get Latest Finalized Solana Block
          source: |
            const response = await fetch("https://portal.sqd.dev/datasets/solana-mainnet/finalized-head");
            const data = await response.json();
      description: "Returns the slot number and hash of the highest finalized block available in the dataset, or null if no blocks are available. Useful mostly for diagnostics, as clients using /stream can get this info from the X-Sqd-Finalized-Head-Number and X-Sqd-Finalized-Head-Hash response headers."
      responses:
        "200":
          description: Highest finalized block information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BlockHead"
              examples:
                solana-finalized:
                  summary: Latest finalized Solana block
                  value:
                    number: 450375255
                    hash: "5QcRbJMof3LXAur9vjRaNfSFjN4HhtMHhMQkyMngyQnx"
        "404":
          description: Dataset not found (`error.code` is `unknown_dataset`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: unknown_dataset
                  message: "Unknown dataset: no-such-chain"
  /timestamps/{timestamp}/block:
    get:
      summary: Block at Timestamp
      operationId: resolveSolanaTimestampToBlock
      x-mint:
        href: "/en/api/solana/timestamp-block"
        metadata:
          description: "Resolve a Unix timestamp to a Solana block with the SQD Portal API."
      x-codeSamples:
        - lang: shell
          label: Resolve timestamp to block
          source: |
            curl 'https://portal.sqd.dev/datasets/solana-mainnet/timestamps/1713053593/block'
        - lang: python
          label: Resolve timestamp to block
          source: |
            import requests

            response = requests.get(
                "https://portal.sqd.dev/datasets/solana-mainnet/timestamps/1713053593/block"
            )
            block_number = response.json()["block_number"]
        - lang: javascript
          label: Resolve timestamp to block
          source: |
            const response = await fetch("https://portal.sqd.dev/datasets/solana-mainnet/timestamps/1713053593/block");
            const { block_number } = await response.json();
      description: >
        Resolves a Unix timestamp (in seconds) to a block number. Returns the first block whose
        timestamp is greater than or equal to `timestamp`. Resolution prefers archival data and
        falls back to the real-time source when available; the `x-sqd-data-source` response header
        reports which source served the result (`network` or `real_time`).
      parameters:
        - name: timestamp
          in: path
          required: true
          schema:
            type: integer
            format: int64
            default: 1713053593
            example: 1713053593
          description: Unix timestamp in seconds.
      responses:
        "200":
          description: Block number resolved.
          headers:
            x-sqd-data-source:
              schema:
                type: string
                enum: [network, real_time]
              description: Source that served the result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BlockNumberResponse"
              examples:
                "solana-mainnet":
                  summary: First block at or after the timestamp
                  value:
                    block_number: 259984800
        "400":
          description: Unparseable `timestamp` path segment (`error.code` is `malformed_request`), or the real-time source refused the query the Portal generated on the client's behalf; read `error.message`
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: malformed_request
                  message: "Bad request: fromBlock must be a non-negative integer"
                  param: fromBlock
        "404":
          description: No block at or after the given timestamp yet (`error.code` is `not_found`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: invalid_request_error
                  code: not_found
                  message: No block at or after the given timestamp
        "429":
          description: Rate limited (`error.type` is `rate_limit_error`). Retry after the interval in the Retry-After header; it is always present and counts seconds
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: rate_limit_error
                  code: overloaded
                  message: Service is overloaded, please try again later
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
        "500":
          description: Internal server error (`error.type` is `api_error`). Do not retry; report the error together with its request_id
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: api_error
                  code: internal_error
                  message: Internal server error
                  request_id: "0198c3f1-..."
        "502":
          description: A data source the Portal depends on is unavailable (`error.code` is `upstream_unavailable`) - retry later. A proxied upstream failure keeps the upstream's own 5xx status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: availability_error
                  code: upstream_unavailable
                  message: Upstream data source is unavailable, please try again later
                  request_id: "0198c3f1-..."
        "503":
          description: Service temporarily unavailable (`error.type` is `availability_error`, typically `no_workers` or `retries_exhausted`) - retry later. May carry Retry-After; honor it when present
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: availability_error
                  code: no_workers
                  message: No workers available for dataset
                  request_id: "0198c3f1-..."
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
        "529":
          description: Overloaded (`error.code` is `overloaded`) - the Portal or a data source is at capacity. Retry after the interval in the Retry-After header; it is always present and counts seconds
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  type: rate_limit_error
                  code: overloaded
                  message: Service is overloaded, please try again later
                  request_id: "0198c3f1-..."
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying (at least 1)
components:
  schemas:
    BlockNumberResponse:
      type: object
      properties:
        block_number:
          type: integer
          format: int64
          description: Number of the first block whose timestamp is greater than or equal to the requested timestamp.
          example: 259984800
      required:
        - block_number
    DatasetMetadata:
      type: object
      properties:
        dataset:
          type: string
          description: The default name used to reference this dataset
          example: "solana-mainnet"
        aliases:
          type: array
          items:
            type: string
          description: Alternative names for the dataset
          example: ["solana-beta"]
        real_time:
          type: boolean
          description: Indicates if the dataset has real-time data
          example: true
        start_block:
          type: integer
          format: int64
          description: The slot number of the first known block
          example: 0
      required:
        - dataset
        - aliases
        - real_time
    DatasetState:
      type: object
      properties:
        worker_ranges:
          type: object
          description: Keys are workers' peer ids
          additionalProperties:
            type: object
            properties:
              ranges:
                type: array
                items:
                  type: object
                  properties:
                    begin:
                      type: integer
                      format: int64
                    end:
                      type: integer
                      format: int64
                  required:
                    - begin
                    - end
        highest_seen_block:
          type: integer
          format: uint64
        first_gap:
          type: integer
          format: uint64
      required:
        - worker_ranges
        - highest_seen_block
    DataQuery:
      type: object
      properties:
        type:
          type: string
          enum: ["solana"]
          default: "solana"
        fromBlock:
          type: integer
          format: int64
          description: The number of the first block to fetch. If unsure how far into the past this can go consult /metadata
          default: 317617480
        toBlock:
          type: integer
          format: int64
          description: "The slot number to fetch up to (inclusive). Optional; if omitted, streams until dataset height or timeout."
          default: 317617482
        parentBlockHash:
          type: string
          description: Expected hash of the parent of the first requested block
        includeAllBlocks:
          type: boolean
          description: If true, includes blocks with no matching data
        fields:
          type: object
          description: Field selector. See the HTTP 200 response description for details on fields that aren't self-explanatory
          properties:
            instruction:
              type: object
              description: Field selector for instructions
              properties:
                transactionIndex:
                  type: boolean
                  description: Index of the parent transaction within the slot
                instructionAddress:
                  type: boolean
                  description: Position of the instruction in the call tree
                programId:
                  type: boolean
                  description: Public key of the program that executed the instruction
                accounts:
                  type: boolean
                  description: List of account public keys used by the instruction
                data:
                  type: boolean
                  description: Base58-encoded instruction data
                d1:
                  type: boolean
                  description: One-byte instruction discriminator
                d2:
                  type: boolean
                  description: Two-byte instruction discriminator
                d4:
                  type: boolean
                  description: Four-byte instruction discriminator
                d8:
                  type: boolean
                  description: Eight-byte instruction discriminator (Anchor standard)
                error:
                  type: boolean
                  description: Error message if the instruction failed
                computeUnitsConsumed:
                  type: boolean
                  description: Number of compute units consumed by the instruction
                isCommitted:
                  type: boolean
                  description: Whether the transaction containing this instruction was committed
                hasDroppedLogMessages:
                  type: boolean
                  description: Whether log messages were truncated for this instruction
            transaction:
              type: object
              description: Field selector for transactions
              properties:
                transactionIndex:
                  type: boolean
                  description: Index of the transaction within the slot
                version:
                  type: boolean
                  description: Transaction version (legacy or 0)
                accountKeys:
                  type: boolean
                  description: List of account public keys used by the transaction
                addressTableLookups:
                  type: boolean
                  description: Address table lookups used by versioned transactions
                numReadonlySignedAccounts:
                  type: boolean
                  description: Number of readonly accounts that require signatures
                numReadonlyUnsignedAccounts:
                  type: boolean
                  description: Number of readonly accounts that do not require signatures
                numRequiredSignatures:
                  type: boolean
                  description: Total number of signatures required by the transaction
                recentBlockhash:
                  type: boolean
                  description: Recent blockhash used by the transaction
                signatures:
                  type: boolean
                  description: List of transaction signatures
                err:
                  type: boolean
                  description: Error object if the transaction failed, null otherwise
                fee:
                  type: boolean
                  description: Transaction fee in lamports
                computeUnitsConsumed:
                  type: boolean
                  description: Number of compute units consumed by the transaction
                loadedAddresses:
                  type: boolean
                  description: Addresses loaded from address lookup tables
                feePayer:
                  type: boolean
                  description: Public key of the account that paid the transaction fee
                hasDroppedLogMessages:
                  type: boolean
                  description: Whether log messages were truncated for this transaction
            log:
              type: object
              description: Field selector for log messages
              properties:
                transactionIndex:
                  type: boolean
                  description: Index of the parent transaction within the slot
                logIndex:
                  type: boolean
                  description: Index of the log message within the transaction
                instructionAddress:
                  type: boolean
                  description: Address of the instruction that produced the log
                programId:
                  type: boolean
                  description: Public key of the program that emitted the log
                kind:
                  type: boolean
                  description: Log kind (log, data, or other)
                message:
                  type: boolean
                  description: The log message content
            balance:
              type: object
              description: Field selector for SOL balance updates
              properties:
                transactionIndex:
                  type: boolean
                  description: Index of the parent transaction within the slot
                account:
                  type: boolean
                  description: Public key of the account whose SOL balance changed
                pre:
                  type: boolean
                  description: SOL balance in lamports before the transaction
                post:
                  type: boolean
                  description: SOL balance in lamports after the transaction
            tokenBalance:
              type: object
              description: Field selector for token balance updates
              properties:
                transactionIndex:
                  type: boolean
                  description: Index of the parent transaction within the slot
                account:
                  type: boolean
                  description: Public key of the token account
                preMint:
                  type: boolean
                  description: Token mint address before the transaction
                postMint:
                  type: boolean
                  description: Token mint address after the transaction
                preDecimals:
                  type: boolean
                  description: Token decimals before the transaction
                postDecimals:
                  type: boolean
                  description: Token decimals after the transaction
                preProgramId:
                  type: boolean
                  description: Token program ID before the transaction
                postProgramId:
                  type: boolean
                  description: Token program ID after the transaction
                preOwner:
                  type: boolean
                  description: Owner of the token account before the transaction
                postOwner:
                  type: boolean
                  description: Owner of the token account after the transaction
                preAmount:
                  type: boolean
                  description: Token amount before the transaction
                postAmount:
                  type: boolean
                  description: Token amount after the transaction
            reward:
              type: object
              description: Field selector for rewards
              properties:
                pubKey:
                  type: boolean
                  description: Public key of the account that received the reward
                lamports:
                  type: boolean
                  description: Reward amount in lamports
                postBalance:
                  type: boolean
                  description: Account balance in lamports after the reward was applied
                rewardType:
                  type: boolean
                  description: Type of reward (e.g. fee, rent, voting, staking)
                commission:
                  type: boolean
                  description: Vote account commission when the reward was credited
            block:
              type: object
              description: Field selector for block headers (the .header objects of JSON block records)
              properties:
                number:
                  type: boolean
                  description: Slot number of the block
                hash:
                  type: boolean
                  description: Block hash
                parentNumber:
                  type: boolean
                  description: Slot number of the parent block
                parentHash:
                  type: boolean
                  description: Hash of the parent block
                height:
                  type: boolean
                  description: Block height (may differ from slot number due to skipped slots)
                timestamp:
                  type: boolean
                  description: Unix timestamp of the block
          default:
            instruction:
              data: true
            block:
              number: true
        instructions:
          type: array
          default:
            - programId:
                - dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH
          description: Instruction data requests. Selects instructions found anywhere in the call tree, not just the top level ones. d1-d8 filter by the starting bytes of the data (in 0x-prefixed hex format); a0-a15 filter by account at the corresponding position in the accounts array; mentionsAccount filters by account mentions anywhere in the list
          items:
            type: object
            properties:
              programId:
                type: array
                items:
                  type: string
              d1:
                description: Accepted values for the first byte of the data in 0x-prefixed hex format
                type: array
                items:
                  type: string
              d2:
                description: Accepted values for the first two bytes of the data in 0x-prefixed hex format
                type: array
                items:
                  type: string
              d3:
                description: Accepted values for the first three bytes of the data in 0x-prefixed hex format
                type: array
                items:
                  type: string
              d4:
                description: Accepted values for the first four bytes of the data in 0x-prefixed hex format
                type: array
                items:
                  type: string
              d8:
                description: Accepted values for the first eight bytes of the data in 0x-prefixed hex format
                type: array
                items:
                  type: string
              mentionsAccount:
                description: Selects instructions that mention a given account anywhere in their account lists, including at the positions higher than these accessible by the a* filters listed below
                type: array
                items:
                  type: string
              a0:
                type: array
                items:
                  type: string
              a1:
                type: array
                items:
                  type: string
              a2:
                type: array
                items:
                  type: string
              a3:
                type: array
                items:
                  type: string
              a4:
                type: array
                items:
                  type: string
              a5:
                type: array
                items:
                  type: string
              a6:
                type: array
                items:
                  type: string
              a7:
                type: array
                items:
                  type: string
              a8:
                type: array
                items:
                  type: string
              a9:
                type: array
                items:
                  type: string
              a10:
                type: array
                items:
                  type: string
              a11:
                type: array
                items:
                  type: string
              a12:
                type: array
                items:
                  type: string
              a13:
                type: array
                items:
                  type: string
              a14:
                type: array
                items:
                  type: string
              a15:
                type: array
                items:
                  type: string
              isCommitted:
                type: boolean
              transaction:
                description: Fetch parent transactions for all matching instructions
                type: boolean
              transactionBalances:
                description: Fetch SOL balance updates caused by parent transactions of all matching instructions
                type: boolean
              transactionTokenBalances:
                description: Fetch token balance updates caused by parent transactions of all matching instructions
                type: boolean
              transactionInstructions:
                description: Fetch all "sibling" instructions / instructions executed by parent transactions of all matching instructions
                type: boolean
              innerInstructions:
                description: Fetch all instructions called by matching instructions (entire subtrees, not just the ones called directly)
                type: boolean
              logs:
                description: Fetch logs produced by matching instructions. Read https://docs.soldexer.dev/api-reference/data-notes/logs-truncation before attempting to use logs
                type: boolean
        transactions:
          type: array
          description: Transaction data requests
          items:
            type: object
            properties:
              feePayer:
                type: array
                items:
                  type: string
              mentionsAccount:
                type: array
                items:
                  type: string
              instructions:
                description: Fetch all instructions executed in the matching transactions
                type: boolean
              balances:
                description: Fetch all SOL balance updates due to the matching transactions
                type: boolean
              tokenBalances:
                description: Fetch all token balance updates due to the matching transactions
                type: boolean
              logs:
                description: Fetch all logs produced by the matching transactions. Read https://docs.soldexer.dev/api-reference/data-notes/logs-truncation before attempting to use logs
                type: boolean
        balances:
          type: array
          description: Requests for SOL balance updates
          items:
            type: object
            properties:
              account:
                type: array
                items:
                  type: string
              transaction:
                description: Fetch parent transactions for all matching balance updates
                type: boolean
              transactionInstructions:
                description: Fetch all instructions executed by parent transactions of all matching balance updates
                type: boolean
        tokenBalances:
          type: array
          description: Requests for token balance updates
          items:
            type: object
            properties:
              account:
                type: array
                items:
                  type: string
              preProgramId:
                type: array
                items:
                  type: string
              postProgramId:
                type: array
                items:
                  type: string
              preMint:
                type: array
                items:
                  type: string
              postMint:
                type: array
                items:
                  type: string
              preOwner:
                type: array
                items:
                  type: string
              postOwner:
                type: array
                items:
                  type: string
              transaction:
                description: Fetch parent transactions for all matching balance updates
                type: boolean
              transactionInstructions:
                description: Fetch all instructions executed by parent transactions of all matching balance updates
                type: boolean
        rewards:
          type: array
          description: Reward data requests
          items:
            type: object
            properties:
              pubkey:
                type: array
                items:
                  type: string
        logs:
          type: array
          description: >
            Logs data requests. Read https://docs.soldexer.dev/api-reference/data-notes/logs-truncation before attempting to use logs
          items:
            type: object
            properties:
              programId:
                type: array
                items:
                  type: string
              kind:
                type: array
                items:
                  type: string
                  enum: ["log", "data", "other"]
              instruction:
                description: Fetch parent instructions for all matching logs
                type: boolean
              transaction:
                description: Fetch parent transactions for all matching logs
                type: boolean
      required:
        - fromBlock
    Block:
      type: object
      properties:
        header:
          type: object
          properties:
            number:
              type: integer
              format: uint64
            hash:
              type: string
            parentNumber:
              type: integer
              format: uint64
            parentHash:
              type: string
            height:
              type: integer
              format: uint64
        instructions:
          type: array
          items:
            type: object
            properties:
              transactionIndex:
                type: integer
              instructionAddress:
                description: An array of tree indices addressing the instruction in the call tree. Top level instructions get addresses [0], [1], ...; addresses of length 2 indicate inner instructions directly called by one of the top ones; and so on.
                type: array
                items:
                  type: integer
              programId:
                type: string
              accounts:
                type: array
                items:
                  type: string
              data:
                type: string
              d1:
                description: One byte instruction discriminator
                type: string
              d2:
                description: Two bytes instruction discriminator
                type: string
              d4:
                description: Four bytes instruction discriminator
                type: string
              d8:
                description: Eight bytes instruction discriminator (Anchor standard)
                type: string
              error:
                type: string
              computeUnitsConsumed:
                type: integer
                format: uint64
              isCommitted:
                type: boolean
              hasDroppedLogMessages:
                type: boolean
        transactions:
          type: array
          items:
            type: object
            properties:
              transactionIndex:
                type: integer
              version:
                type: integer
              accountKeys:
                type: array
                items:
                  type: integer
              addressTableLookups:
                type: array
                items:
                  type: object
                  properties:
                    accountKey:
                      type: string
                    readonlyIndexes:
                      type: array
                      items:
                        type: integer
                    writableIndexes:
                      type: array
                      items:
                        type: integer
              numReadonlySignedAccounts:
                type: integer
              numReadonlyUnsignedAccounts:
                type: integer
              numRequiredSignatures:
                type: integer
              recentBlockhash:
                type: string
              signatures:
                description: List of transaction signatures. The first one of these is also known as a "transaction hash"
                type: array
                items:
                  type: string
              err:
                type: [object, "null"]
              fee:
                type: integer
              computeUnitsConsumed:
                type: integer
              loadedAddresses:
                type: object
                properties:
                  readonly:
                    type: array
                    items:
                      type: string
                  writable:
                    type: array
                    items:
                      type: string
              feePayer:
                type: string
              hasDroppedLogMessages:
                type: boolean
        balances:
          type: array
          description: >
            Records of SOL balance updates done per transaction and account. Combines pre- and post-balance records, making one record per account
          items:
            type: object
            properties:
              transactionIndex:
                type: integer
              account:
                type: string
              pre:
                type: integer
              post:
                type: integer
        tokenBalances:
          type: array
          description: >
            Records of token balance updates done per transaction and token account. Uses data from https://solana.com/docs/rpc/json-structures#token-balances but combines pre- and post-balance records, making one record per token account
          items:
            type: object
            properties:
              transactionIndex:
                type: integer
              account:
                description: The token account
                type: string
              preMint:
                description: The token mint account. Coincides with postMint when both are defined
                type: string
              postMint:
                description: The token mint account. Coincides with preMint when both are defined
                type: string
              preDecimals:
                type: integer
              postDecimals:
                type: integer
              preProgramId:
                type: string
              postProgramId:
                type: string
              preOwner:
                description: The owner of the token account at the start of the transaction
                type: string
              postOwner:
                description: The owner of the token account at the end of the transaction. When both pre- and postOwner are defined they can only be different if the transaction has changed the token account owner via the SetAuthority instruction
                type: string
              preAmount:
                type: integer
              postAmount:
                type: integer
        rewards:
          type: array
          items:
            type: object
            properties:
              pubKey:
                type: string
              lamports:
                type: integer
              postBalance:
                type: integer
              rewardType:
                type: string
              commission:
                type: integer
        logs:
          type: array
          description: >
            Read https://docs.soldexer.dev/api-reference/data-notes/logs-truncation before attempting to use logs
          items:
            type: object
            properties:
              transactionIndex:
                type: integer
              logIndex:
                type: integer
              instructionAddress:
                description: Address of the instruction that produced the log. See the instruction field description for details (HTTP 200 response description -> instructions -> instructionAddress)
                type: array
                items:
                  type: integer
              programId:
                type: string
              kind:
                type: string
                enum:
                  - log
                  - data
                  - other
              message:
                type: string
      required:
        - header
    BlockHead:
      type: [object, "null"]
      properties:
        number:
          type: integer
          format: int64
          description: Slot number of the highest available block
          example: 450375284
        hash:
          type: string
          example: "GdqUPS2umM4C8HNHbXHcAQGtLnnY9MtBsiq7VpZf1ktX"
    ErrorDetail:
      type: object
      description: Machine-readable error detail. Branch on `type`; match on `code` for one specific case.
      properties:
        type:
          type: string
          description: Coarse category to branch on. One of `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error`, `availability_error`, or `api_error`. The two credential types answer 403 and appear only on a Portal that requires an API key. Treat an unknown `code` according to its `type`.
          example: invalid_request_error
        code:
          type: string
          description: Specific cause, stable across releases. Match on this rather than on `message`.
          example: base_block_mismatch
        message:
          type: string
          description: Human-readable detail. Prose, not stable; do not parse or match on it.
        param:
          type: string
          description: The request parameter at fault, when the error is about one.
        request_id:
          type: string
          description: Echo of the `x-request-id` response header, included in the body on 5xx errors. Quote it when reporting a problem.
      required:
        - type
        - code
        - message
    ErrorResponse:
      type: object
      description: Error body shared by every failing response.
      properties:
        error:
          $ref: "#/components/schemas/ErrorDetail"
      required:
        - error
      example:
        error:
          type: invalid_request_error
          code: unknown_dataset
          message: "Unknown dataset: no-such-chain"
    ConflictResponse:
      type: object
      description: The 409 body carries the standard error envelope plus a top-level `previousBlocks` list - a slice of the current canonical chain at and below the conflict point, in ascending block-number order.
      properties:
        error:
          $ref: "#/components/schemas/ErrorDetail"
        previousBlocks:
          type: array
          description: "`{ number, hash }` pairs from the current canonical chain in ascending order; the last entry is the most recent block at or below the conflict point. Guaranteed to contain at least the parent of the requested fromBlock."
          items:
            type: object
            properties:
              number:
                type: integer
                format: int64
              hash:
                type: string
            required:
              - number
              - hash
      required:
        - error
        - previousBlocks
      example:
        error:
          type: invalid_request_error
          code: base_block_mismatch
          message: Base block mismatch
        previousBlocks:
          - number: 450375255
            hash: "5QcRbJMof3LXAur9vjRaNfSFjN4HhtMHhMQkyMngyQnx"
          - number: 450375284
            hash: "GdqUPS2umM4C8HNHbXHcAQGtLnnY9MtBsiq7VpZf1ktX"
