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

# JavaScript Examples

> A small client for the Kash Public Embed API in plain JavaScript

Plain JavaScript that runs in any modern browser or in Node.js 18 and later. No API key or dependencies are needed.

## A minimal client

```javascript kash-embed-client.js theme={null}
const KASH_API = 'https://app.kash.bot/api';

export class KashApiError extends Error {
  constructor(status, body) {
    super(body?.message ?? `HTTP ${status}`);
    this.status = status;
    this.code = body?.code;
    this.details = body?.details;
    this.retryAfter = body?.details?.retryAfter;
  }
}

async function get(path, params = {}) {
  const query = new URLSearchParams(
    Object.entries(params).filter(([, v]) => v !== undefined && v !== null)
  );
  const qs = query.toString();
  const url = `${KASH_API}${path}${qs ? `?${qs}` : ''}`;
  const res = await fetch(url);
  const body = await res.json().catch(() => null);
  if (!res.ok) throw new KashApiError(res.status, body);
  return body;
}

export const kash = {
  markets: (params) => get('/markets', params),
  market: (id, params) => get(`/markets/${id}`, params),
  marketsState: (ids) => get('/markets/state', { ids: ids.join(',') }),
  quote: (id, outcomeIndex, action, amountAtomic) =>
    get(`/markets/${id}/quote`, { outcomeIndex, action, amount: String(amountAtomic) }),
  twitterLink: (id, outcomeIndex, amount, locale) =>
    get(`/markets/${id}/twitter-link`, { outcomeIndex, amount, locale }),
  threads: (params) => get('/threads', params),
  threadMarkets: (id, params) => get(`/threads/${id}/markets`, params),
};

/** Implied probabilities as shown on Kash: one percentage per outcome. */
export function formatPrices(market) {
  return market.outcomes.map((o) => ({
    label: o.label,
    percent: Math.round(o.impliedChance * 100),
  }));
}

/** Atomic USDC (6 decimals) to a display string. */
export function formatUsdc(atomic) {
  return (Number(atomic) / 1_000_000).toLocaleString(undefined, {
    style: 'currency',
    currency: 'USD',
    maximumFractionDigits: 0,
  });
}
```

## List live markets

```javascript theme={null}
import { kash, formatPrices, formatUsdc } from './kash-embed-client.js';

const { markets, pagination } = await kash.markets({
  status: 'active',
  tradableOnly: true,
  sortBy: 'total_volume',
  limit: 10,
});

for (const m of markets) {
  const prices = formatPrices(m).map((o) => `${o.label} ${o.percent}%`).join(' · ');
  console.log(`${m.title} — ${prices} — ${formatUsdc(m.totalVolume)} volume`);
}
console.log(`${pagination.total} live markets`);
```

## Search

```javascript theme={null}
const { markets } = await kash.markets({ search: 'champions league', status: 'all', limit: 20 });
```

## Keep prices live

Load the cards once, then poll the state endpoint. It refreshes about every second, so polling every 5 to 10 seconds is plenty.

```javascript theme={null}
import { kash } from './kash-embed-client.js';

function watchPrices(marketIds, onUpdate, intervalMs = 5000) {
  let stopped = false;
  async function tick() {
    try {
      const { markets } = await kash.marketsState(marketIds); // up to 200 ids
      for (const state of markets) onUpdate(state.id, state);
    } catch (err) {
      if (err.status === 429 && err.retryAfter) {
        await new Promise((r) => setTimeout(r, err.retryAfter * 1000));
      }
    }
    if (!stopped) setTimeout(tick, intervalMs);
  }
  tick();
  return () => { stopped = true; };
}

const stop = watchPrices(['93f1445c-912c-47b4-8065-d1ff5a6b8dfc'], (id, state) => {
  console.log(id, state.outcomes.map((o) => o.impliedChance));
});
```

## Price a trade

```javascript theme={null}
const usdc = 25;
const { quote } = await kash.quote(
  '93f1445c-912c-47b4-8065-d1ff5a6b8dfc',
  0,
  'buy',
  usdc * 1_000_000 // atomic USDC
);
console.log(`$${usdc} buys ${quote.estimate?.tokensReceived?.toFixed(2)} tokens`);
console.log(`Pays about $${quote.estimate?.payoutAtCurrentPriceUsdc?.toFixed(2)} if it wins at today's prices`);
```

## “Predict on X” buttons

```javascript theme={null}
import { kash, KashApiError } from './kash-embed-client.js';

async function predictOnX(marketId, outcomeIndex, amount) {
  try {
    const { twitterUrl } = await kash.twitterLink(marketId, outcomeIndex, amount);
    window.open(twitterUrl, '_blank', 'noopener');
  } catch (err) {
    if (err instanceof KashApiError && err.status === 400) {
      alert(err.message); // e.g. "This market is no longer accepting predictions"
    } else {
      throw err;
    }
  }
}

document.querySelectorAll('[data-kash-market]').forEach((button) => {
  button.addEventListener('click', () =>
    predictOnX(button.dataset.kashMarket, Number(button.dataset.outcome), 10)
  );
});
```

```html theme={null}
<button data-kash-market="93f1445c-912c-47b4-8065-d1ff5a6b8dfc" data-outcome="0">Yes · $10</button>
<button data-kash-market="93f1445c-912c-47b4-8065-d1ff5a6b8dfc" data-outcome="1">No · $10</button>
```

## Paginate through everything

```javascript theme={null}
async function* allMarkets(params) {
  let offset = 0;
  while (true) {
    const page = await kash.markets({ ...params, limit: 500, offset });
    yield* page.markets;
    if (!page.pagination.hasMore) return;
    offset += page.markets.length;
  }
}

for await (const m of allMarkets({ status: 'resolved' })) {
  // offset is capped at 10,000. To go further back, narrow by resolvedAfter / resolvedBefore
}
```

## Listen to iframe events

```javascript theme={null}
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://app.kash.bot') return;
  const { type, data } = event.data ?? {};
  if (type === 'kash-open-twitter') window.open(data.url, '_blank', 'noopener');
  if (type === 'kash-iframe-ready') console.log('ready', data);
});
```

## Next steps

> [card] [React examples](https://docs.kash.bot/developer-docs/public-embed-api/examples/react.md)
>
> Components and hooks

> [card] [API overview](https://docs.kash.bot/developer-docs/public-embed-api/overview.md)
>
> Endpoints, limits and errors


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.