Docs

webData2 - HyperCore Info Endpoint

Get the Hyperliquid `webData2` envelope for a user. This response can be sparse and is best treated as a lightweight, web-client-oriented payload rather than a guaranteed full dashboard snapshot.

Get the webData2 envelope for a user. In practice this payload is a sparse top-level object, so treat it as a lightweight web-client response rather than a guaranteed all-in-one dashboard snapshot.

Depending on the account and current product rollout, the live response can expose fields such as clearinghouseState, openOrders, assetCtxs, meta, and perpsAtOpenInterestCap without promising that every field is populated for every address.

Authenticate HyperCore Info requests by sending your Dwellir API key in the x-api-key header to https://api-hyperliquid-mainnet-info.n.dwellir.com/info.

When to Use This Endpoint

The webData2 endpoint is most useful when you want to:

  • Bootstrap Web UI State — Fetch a user-scoped response used by Hyperliquid web clients
  • Check for Available Web Payload Data — Read whatever envelope data the service currently exposes for an address
  • Reduce One-Off Probing Calls — Replace ad hoc exploratory requests with a single typed lookup

Common Use Cases

1. Load the Current Envelope

Load the current webData2 response for a user:

JavaScript
async function loadUserDashboard(userAddress) {
  const webData = await getWebData2(userAddress);

  console.log('webData2 loaded');
  return webData;
}

// Usage
const dashboardData = await loadUserDashboard('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');

2. Initialize a Web Client Cache

Bootstrap a web client with the available webData2 payload:

JavaScript
class WebInterface {
  constructor(userAddress) {
    this.userAddress = userAddress;
    this.data = null;
  }

  async initialize() {
    console.log('Initializing web interface...');
    this.data = await getWebData2(this.userAddress);
    console.log('Interface ready');
    return this.data;
  }

  getData() {
    return this.data;
  }

  async refresh() {
    console.log('Refreshing data...');
    this.data = await getWebData2(this.userAddress);
    return this.data;
  }
}

// Usage
const interface = new WebInterface('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
await interface.initialize();

3. Periodic Data Refresh

Refresh dashboard data at intervals:

JavaScript
class DashboardDataManager {
  constructor(userAddress, refreshIntervalMs = 30000) {
    this.userAddress = userAddress;
    this.refreshIntervalMs = refreshIntervalMs;
    this.currentData = null;
    this.onUpdate = null;
  }

  async start(updateCallback) {
    this.onUpdate = updateCallback;

    // Initial load
    await this.refresh();

    // Periodic refresh
    setInterval(() => this.refresh(), this.refreshIntervalMs);
  }

  async refresh() {
    try {
      this.currentData = await getWebData2(this.userAddress);

      if (this.onUpdate) {
        this.onUpdate(this.currentData);
      }

      return this.currentData;
    } catch (error) {
      console.error('Failed to refresh data:', error);
    }
  }

  getCurrentData() {
    return this.currentData;
  }
}

// Usage
const manager = new DashboardDataManager('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
manager.start((data) => {
  console.log('Dashboard data updated');
  // Update UI with new data
});

4. Check Whether Payload Data Exists

Check whether a user currently has any webData2 payload available:

JavaScript
async function buildTradingInterface(userAddress) {
  try {
    const webData = await getWebData2(userAddress);

    return {
      status: 'success',
      data: webData,
      hasData: Boolean(
        webData.clearinghouseState ||
          (Array.isArray(webData.openOrders) && webData.openOrders.length > 0) ||
          (Array.isArray(webData.assetCtxs) && webData.assetCtxs.length > 0)
      ),
      lastUpdated: new Date().toISOString()
    };
  } catch (error) {
    return {
      status: 'error',
      error: error.message,
      hasData: false
    };
  }
}

// Usage
const tradingInterface = await buildTradingInterface('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');

if (tradingInterface.status === 'success') {
  console.log('webData2 request succeeded');
} else {
  console.error('Failed to load interface:', tradingInterface.error);
}

5. Cache-Optimized Data Loading

Implement efficient caching for web data:

JavaScript
class CachedWebDataLoader {
  constructor(userAddress, cacheDurationMs = 60000) {
    this.userAddress = userAddress;
    this.cacheDurationMs = cacheDurationMs;
    this.cache = null;
    this.cacheTime = 0;
  }

  async load(forceRefresh = false) {
    const now = Date.now();
    const cacheAge = now - this.cacheTime;

    if (!forceRefresh && this.cache && cacheAge < this.cacheDurationMs) {
      console.log(`Using cached data (age: ${Math.round(cacheAge / 1000)}s)`);
      return this.cache;
    }

    console.log('Loading fresh data...');
    const data = await getWebData2(this.userAddress);

    this.cache = data;
    this.cacheTime = now;

    return data;
  }

  invalidateCache() {
    this.cache = null;
    this.cacheTime = 0;
  }
}

// Usage
const loader = new CachedWebDataLoader('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
const data = await loader.load(); // Fresh load
const cachedData = await loader.load(); // From cache

Best Practices

  1. Expect sparse payloads — Handle partially populated top-level objects without treating missing fields as errors
  2. Validate addresses — Ensure user addresses are valid before requests
  3. Cache conservatively — Refresh only as often as your UI actually needs
  4. Avoid assuming schema stability — Prefer defensive parsing over tightly coupled field access
  5. Combine with specific endpoints — Use dedicated info endpoints for positions, orders, or fees when you need guaranteed fields

Performance Tips

Efficient Dashboard Updates

JavaScript
class EfficientDashboard {
  constructor(userAddress) {
    this.userAddress = userAddress;
    this.lastData = null;
  }

  async update() {
    const newData = await getWebData2(this.userAddress);

    // Compare with previous data
    const hasChanged = JSON.stringify(newData) !== JSON.stringify(this.lastData);

    if (hasChanged) {
      console.log('Data changed - updating UI');
      this.lastData = newData;
      return { changed: true, data: newData };
    }

    console.log('No changes detected');
    return { changed: false, data: newData };
  }
}

Build resilient Hyperliquid integrations with Dwellir's HyperCore Info Endpoint. Get your API key →