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

# Reading Commitment Data

> Display live commitment data and statistics on your sale page.

This guide covers how to fetch and display commitment data for your sale, including total amounts committed, participant counts, and individual commitments.

The commitment data API is public and does not require authentication, so you can display this information to all visitors.

## Use cases

* Display the total amount committed to your sale
* Show the number of unique participants
* List recent commitments to create a live activity feed
* For auctions: show the current estimated clearing price

## Data freshness and limits

The commitment data API reads directly from the sale contract, but it is designed for displaying live sale activity rather than for reconciliation. Keep the following characteristics in mind:

* **Caching:** Responses are cached for about a minute, so newly confirmed commitments may take up to that long to appear.
* **Recent commitments only:** The `Commitments` array contains only the most recent 100 commitments. There is no pagination, so on larger sales this window will not include every commitment.
* **Clearing price:** The auction clearing price is computed off-chain by Sonar. The `ClearingPriceNumerator` and `ClearingPriceDenominator` fields are the source of truth for it; it is not derived on-chain.

<Info>
  For a complete or exact per-entity total (for example, on large sales, or when reconciling a specific entity's committed amount), read the committed amount directly from the sale contract rather than relying on the API's 100-record window. See [smart contract operations](../operations/smart-contract-operations) for how to query the contract directly.
</Info>

### Polling, not webhooks

There is no webhook or subscription for commitment updates. Polling the endpoint (or the `useCommitmentData` hook, which accepts a `pollingIntervalMs`) is the intended pattern for keeping displayed data fresh.

## Using the React hook

The simplest way to fetch commitment data is with the `useCommitmentData` hook from `@echoxyz/sonar-react`.

```tsx theme={null}
import { useCommitmentData } from "@echoxyz/sonar-react";

function CommitmentStats({ saleUUID }: { saleUUID: string }) {
  const { loading, commitmentData, error } = useCommitmentData({
    saleUUID,
    pollingIntervalMs: 10000, // Poll every 10 seconds for updates
  });

  if (loading && !commitmentData) {
    return <p>Loading...</p>;
  }

  if (error) {
    return <p>Error loading commitment data: {error.message}</p>;
  }

  if (!commitmentData) {
    return null;
  }

  return (
    <div>
      <p>Total Participants: {commitmentData.UniqueCommitmentCount}</p>
      <p>Total Committed: {commitmentData.TotalCommitmentAmount}</p>
    </div>
  );
}
```

The hook supports optional polling to keep the data fresh. If `pollingIntervalMs` is not provided, the data is fetched once when the component mounts.

[Reference docs](../reference/sonar-react#usecommitmentdata) for the `useCommitmentData` hook.

## Formatting amounts

The `TotalCommitmentAmount` and individual commitment amounts are returned as strings in the payment token's smallest unit (e.g. USDC has 6 decimals, so the smallest unit is 1/1,000,000 of a USDC).

Use `PaymentTokenDecimals` to format these values for display:

```tsx theme={null}
function formatAmount(amount: string, decimals: number): string {
  const value = BigInt(amount);
  const divisor = BigInt(10 ** decimals);
  const integerPart = value / divisor;
  return `$${integerPart.toLocaleString()}`;
}

// Usage
const formattedTotal = formatAmount(
  commitmentData.TotalCommitmentAmount,
  commitmentData.PaymentTokenDecimals
);
```

## Displaying recent commitments

The `Commitments` array contains individual commitments sorted by creation time (most recent first). Each commitment includes:

* `SaleSpecificEntityID`: The entity that made the commitment
* `CreatedAt`: When the commitment was made (ISO 8601 timestamp)
* `Amounts`: Array of amounts committed per wallet and payment token

```tsx theme={null}
import { useCommitmentData } from "@echoxyz/sonar-react";
import { Commitment, WalletTokenAmount } from "@echoxyz/sonar-core";

function calculateTotal(amounts: WalletTokenAmount[]): bigint {
  return amounts.reduce((sum, item) => sum + BigInt(item.Amount), BigInt(0));
}

function formatTimestamp(timestamp: string): string {
  return new Date(timestamp).toLocaleString(undefined, {
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function RecentCommitments({ saleUUID }: { saleUUID: string }) {
  const { commitmentData } = useCommitmentData({
    saleUUID,
    pollingIntervalMs: 10000,
  });

  if (!commitmentData) {
    return null;
  }

  // Show the 10 most recent commitments
  const recentCommitments = commitmentData.Commitments.slice(0, 10);

  if (recentCommitments.length === 0) {
    return <p>No commitments yet</p>;
  }

  // Note the commitments also include the price,
  // which you might also want to display for auction sales.
  return (
    <div>
      <h3>Recent Commitments</h3>
      <ul>
        {recentCommitments.map((commitment) => {
          const total = calculateTotal(commitment.Amounts);
          const formatted = formatAmount(
            total.toString(),
            commitmentData.PaymentTokenDecimals
          );
          return (
            <li key={commitment.CommitmentID}>
              {formatted} - {formatTimestamp(commitment.CreatedAt)}
            </li>
          );
        })}
      </ul>
    </div>
  );
}

function formatAmount(amount: string, decimals: number): string {
  const value = BigInt(amount);
  const divisor = BigInt(10 ** decimals);
  const integerPart = value / divisor;
  return `$${integerPart.toLocaleString()}`;
}
```

## Auction clearing price

For English auction sales, the response includes the current estimated clearing price:

* `ClearingPriceNumerator` and `ClearingPriceDenominator`: The clearing price as a fraction (in smallest units of the payment token per smallest unit of the offered token)
* `ClearingPriceMicroUSD`: The clearing price in micro-USD (1 USD = 1,000,000 micro-USD) per human-readable offered token

The clearing price is recalculated as new bids come in and represents the price that all winning bidders would pay if the auction ended at that moment.

The `ClearingPriceMicroUSD` field is convenient for display purposes, but may lose precision. For machine-readable use cases (e.g., passing to a contract or performing calculations), use the `ClearingPriceNumerator` and `ClearingPriceDenominator` fraction instead.

```tsx theme={null}
function AuctionClearingPrice({ saleUUID }: { saleUUID: string }) {
  const { commitmentData } = useCommitmentData({
    saleUUID,
    pollingIntervalMs: 5000, // More frequent polling during an auction
  });

  if (!commitmentData?.ClearingPriceMicroUSD) {
    return null;
  }

  // Convert micro-USD to dollars for display
  const priceInDollars = Number(commitmentData.ClearingPriceMicroUSD) / 1_000_000;

  return (
    <div>
      <p>Estimated Clearing Price: ${priceInDollars.toFixed(4)}</p>
    </div>
  );
}
```

## Using the core library directly

If you're not using React, you can call the API directly using `SonarClient`:

```typescript theme={null}
import { createClient } from "@echoxyz/sonar-core";

const client = createClient();

const commitmentData = await client.readCommitmentData({
  saleUUID: "YOUR_SALE_UUID",
});

console.log(`Total committed: ${commitmentData.TotalCommitmentAmount}`);
console.log(`Participants: ${commitmentData.UniqueCommitmentCount}`);
```

[Reference docs](../reference/sonar-core#readcommitmentdata) for the `readCommitmentData` function.

## API reference

For more details on the response format and available fields, see:

* [readCommitmentData](../reference/sonar-core#readcommitmentdata) - Core library function
* [useCommitmentData](../reference/sonar-react#usecommitmentdata) - React hook
* [ReadCommitmentData API](/api-reference/readcommitmentdata) - HTTP API reference
