> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.umbraprivacy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tree Metadata

> Returns metadata for a specific Indexed Merkle Tree: leaf count, current root hash, and Stealth Pool Note record count.

The root hash changes every time a new leaf is inserted. Use this endpoint to check the current state of a tree before fetching notes or generating Merkle proofs.

<Note>
  `utxo_count` may differ from `num_leaves` if some leaves were inserted without Stealth Pool Note ciphertext data (e.g. padding leaves).
</Note>


## OpenAPI

````yaml GET /v1/trees/{tree_index}
openapi: 3.0.3
info:
  title: Umbra Indexer Read Service
  description: >
    Read-only REST API for querying Umbra mixer tree state, UTXO records,

    and Merkle inclusion proofs.


    ## Response Encoding


    **All endpoints** support `application/x-protobuf` encoding. The encoding

    strategy differs by endpoint category:


    - **Always Protobuf** (no content negotiation): stats, tree metadata, Merkle
    proofs,
      and all UTXO data endpoints. These endpoints always respond with
      `Content-Type: application/x-protobuf` regardless of the `Accept` header.
    - **Content negotiation** (health endpoints only): respond with JSON by
    default,
      or Protobuf when `Accept: application/x-protobuf` is set. Send
      `Accept: application/x-protobuf` for consistent protobuf-only clients.

    ## UTXO Response Layouts


    The three UTXO data endpoints (`GET /v1/utxos`, `GET
    /v1/utxos/{absolute_index}`,

    `GET /v1/trees/{tree_index}/utxos`) support two Protobuf response layouts

    controlled by the `X-Response-Layout` request header:


    - **Row-oriented** (default) -- `UtxoResponse` message: each UTXO is a
      self-contained `UtxoDataItem` sub-message. Easier to iterate record-by-record.
    - **Columnar** (`X-Response-Layout: columnar`) -- `UtxoColumnarResponse`
    message:
      each field across all UTXOs is packed into a parallel array inside a single
      `UtxoColumns` sub-message. Compresses significantly better over the wire and is
      preferred by vectorized consumers (e.g. data pipelines, analytics).

    ## Rate Limiting


    All endpoints are subject to rate limiting. Exceeded limits return `429 Too
    Many Requests`.


    ## Compression


    All responses are compressed. Send `Accept-Encoding: gzip, br`.


    ## Absolute Index


    The **absolute index** is a globally monotonic cursor across all Merkle
    trees:

    ```

    absolute_index = tree_index * MAX_LEAVES_PER_TREE + insertion_index

    ```

    where `MAX_LEAVES_PER_TREE = 1,048,576` (2^20).
  version: 0.1.0
  contact:
    name: Umbra Protocol
servers:
  - url: https://utxo-indexer.api.umbraprivacy.com
    description: Mainnet
  - url: https://utxo-indexer.api-devnet.umbraprivacy.com
    description: Devnet
security: []
tags:
  - name: health
    description: |
      Health and readiness probes for Kubernetes or load-balancer checks.
      Support both JSON and Protobuf via `Accept` header negotiation.
  - name: stats
    description: Aggregate statistics for the UTXO index. Always Protobuf.
  - name: trees
    description: Per-tree Merkle metadata and Merkle inclusion proofs. Always Protobuf.
  - name: utxos
    description: >
      UTXO data queries with absolute-index-based pagination. Always Protobuf.

      Supports row-oriented and columnar response layouts via
      `X-Response-Layout`.
paths:
  /v1/trees/{tree_index}:
    get:
      tags:
        - trees
      summary: Merkle tree metadata
      description: >
        Returns metadata for a specific Indexed Merkle Tree:

        - `num_leaves` -- current leaf count.

        - `root` -- current Poseidon root hash (raw bytes).

        - `utxo_count` -- UTXO records stored for this tree.


        **Always Protobuf** -- responds with `application/x-protobuf` regardless

        of the `Accept` header.


        **Tree capacity**: `MAX_LEAVES_PER_TREE = 1,048,576` (depth-20 tree).

        Once full, the write service starts a new tree at the next sequential
        index.
      operationId: getTreeInfo
      parameters:
        - name: tree_index
          in: path
          required: true
          description: Zero-based index of the Merkle tree to query.
          schema:
            type: integer
            format: int64
            minimum: 0
          example: 0
      responses:
        '200':
          description: Tree metadata retrieved successfully.
          content:
            application/x-protobuf:
              schema:
                $ref: '#/components/schemas/TreeInfoResponse'
        '400':
          description: Invalid `tree_index` parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No tree with the specified index exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Storage backend error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    TreeInfoResponse:
      type: object
      description: >
        Protobuf `TreeInfoResponse` message returned by `GET
        /v1/trees/{tree_index}`.


        The `root` field is a `bytes` field in the Protobuf encoding containing
        the

        raw 32-byte little-endian Poseidon root hash.


        **Tree capacity**: Each tree holds at most `MAX_LEAVES_PER_TREE =
        1,048,576`

        leaves (depth-20 Indexed Merkle Tree).
      required:
        - tree_index
        - num_leaves
        - root
        - utxo_count
      properties:
        tree_index:
          type: integer
          format: int64
          description: Zero-based index identifying the Merkle tree.
          example: 0
        num_leaves:
          type: integer
          format: int64
          description: Total number of leaf commitments currently inserted into the tree.
          example: 1024
        root:
          type: string
          format: byte
          description: >
            Raw 32-byte little-endian Poseidon root hash (Protobuf `bytes`
            field).

            In a JSON representation this would be base64-encoded.
          example: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
        utxo_count:
          type: integer
          format: int64
          description: Number of UTXO records stored for this tree in the UTXO store.
          example: 1024
    ErrorResponse:
      type: object
      description: Standard JSON error body returned on 4xx and 5xx responses.
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: |
            Short error category, e.g. `"Bad Request"`, `"Not Found"`,
            `"Too Many Requests"`, `"Internal Server Error"`.
          example: Not Found
        message:
          type: string
          description: Human-readable explanation of what went wrong.
          example: Tree 99 not found

````