Skip to main content

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.

Fetch a live buy-or-sell price quote for any outcome of a prediction market. The endpoint calls the AMM’s own on-chain view functions — quoteBuyExactAssetsIn and quoteSellExactTokensIn on the Market contract — and returns the full protocol response, so integrators have access to the same numbers the UI uses. No authentication is required.

Endpoint

GET https://app.kash.bot/api/markets/{id}/quote

Path Parameters

id
string
required
The market’s unique identifier (UUID). Use GET /api/markets to discover market IDs.

Query Parameters

outcomeIndex
number
required
Which outcome to price. Zero-indexed. For binary markets: 0 = YES, 1 = NO. Must be between 0 and numOutcomes - 1.
action
string
required
buy quotes how many outcome tokens you receive for a given USDC input.sell quotes how much USDC you receive for a given outcome-token input (already net of the AMM’s sell fee).
amount
string
required
Input size as a positive integer in atomic units, passed as a string to preserve precision. Units depend on action:
  • buyUSDC atomic-6. 1_000_000 = 1 USDC.
  • selltoken WAD-18. 1_000_000_000_000_000_000 = 1.0 tokens.

Units

All bigint values in the response are serialised as decimal strings so that callers can parse them losslessly with BigInt(...).
Field familyUnitExampleNotes
USDC (amountIn, usdcOut)atomic-6"1000000" = 1 USDC6 decimals, matches USDC on Base.
Tokens, prices, capital shares (tokensOut, tokensIn, grossRelease, reserveAfter, c, pAfter[], qAfter[])WAD-18"1000000000000000000" = 1.0Protocol-internal 18-decimal fixed point.
The response always includes a units object reflecting the above so you never have to hardcode the convention on the caller side.
"units": { "usdc": "atomic-6", "token": "wad-18" }

Response — Buy

quote
object
market
object
Summary of the market the quote was computed for: id, contractAddress (the on-chain Market contract), chainId (8453 = Base mainnet), outcomes (labels and DB-side probabilities), and status.
units
object
{ "usdc": "atomic-6", "token": "wad-18" } — spelling out the units so you don’t have to hardcode them.

Response — Sell

The sell response has the same shape as the buy response, with the following differences:
quote.action
string
Always "sell" for this variant.
quote.tokensIn
string
Outcome tokens you would burn, WAD-18 (echoed from amount).
quote.usdcOut
string
USDC you would receive, atomic-6. This is already net of the AMM’s sell fee (sellFeeBps) — it is what the user actually gets.
quote.grossRelease
string
The pre-fee reserve release in WAD-18. The difference between grossRelease (converted to atomic USDC) and usdcOut is the fee the protocol retains. Exposed for integrators who want to display the fee transparently.
All other fields (reserveAfter, c, pAfter, qAfter, effectivePrice, impliedProbability) behave identically to the buy response.

Rate Limit

100 requests per minute per IP address. Quotes are cached for 10 seconds on the server side; repeated requests for the same (id, outcomeIndex, action, amount) within that window are essentially free.

Example Requests

curl "https://app.kash.bot/api/markets/abc123/quote?outcomeIndex=0&action=buy&amount=1000000"

Example Responses

200 - Buy quote
{
  "quote": {
    "outcomeIndex": 0,
    "action": "buy",
    "amountIn": "1000000",
    "tokensOut": "1923076923076923076",
    "reserveAfter": "11000000000000000000",
    "c": "1000000000000000000",
    "pAfter": ["600000000000000000", "400000000000000000"],
    "qAfter": ["600000000000000000", "400000000000000000"],
    "effectivePrice": 5.2e-13,
    "impliedProbability": 0.6
  },
  "market": {
    "id": "abc123",
    "contractAddress": "0xc7785fca5b1e7fd2ebd3cc1b20e0e73bca3f1fed",
    "chainId": 8453,
    "outcomes": [
      { "outcomeIndex": 0, "label": "YES", "probability": 0.5 },
      { "outcomeIndex": 1, "label": "NO", "probability": 0.5 }
    ],
    "status": "ACTIVE"
  },
  "units": { "usdc": "atomic-6", "token": "wad-18" }
}
200 - Sell quote
{
  "quote": {
    "outcomeIndex": 0,
    "action": "sell",
    "tokensIn": "500000000000000000",
    "usdcOut": "237500",
    "grossRelease": "250000000000000000",
    "reserveAfter": "9750000000000000000",
    "c": "990000000000000000",
    "pAfter": ["498000000000000000", "502000000000000000"],
    "qAfter": ["498000000000000000", "502000000000000000"],
    "effectivePrice": 4.75e-13,
    "impliedProbability": 0.498
  },
  "market": { "id": "abc123", "contractAddress": "0x...", "chainId": 8453, "outcomes": [], "status": "ACTIVE" },
  "units": { "usdc": "atomic-6", "token": "wad-18" }
}
400 - Validation error
{
  "error": "ValidationError",
  "message": "Amount must be greater than zero"
}
404 - Market not found
{
  "error": "NotFoundError",
  "message": "Market not found"
}

Worked Examples

Integrators rarely want the raw tuple — they want to answer real user questions. Here are the four most common ones, each mapped to one field.

”If I put in $100, how many YES tokens do I get?"

// $100 in USDC atomic-6 = 100 * 1_000_000
const res = await fetch(
  'https://app.kash.bot/api/markets/abc123/quote' +
    '?outcomeIndex=0&action=buy&amount=100000000'
);
const { quote } = await res.json();

const tokens = Number(BigInt(quote.tokensOut)) / 1e18;
console.log(`You receive ${tokens.toFixed(4)} YES tokens`);
// → "You receive 177.6534 YES tokens"

"What’s the average price I’d pay per token?"

// amountIn is in USDC atomic-6, tokensOut in WAD-18
// To get $ / token: (amountIn / 1e6) / (tokensOut / 1e18)
const usdcIn = Number(BigInt(quote.amountIn)) / 1e6;
const tokens = Number(BigInt(quote.tokensOut)) / 1e18;
const pricePerToken = usdcIn / tokens;
console.log(`Average price: $${pricePerToken.toFixed(4)} / token`);
// → "Average price: $0.5629 / token"

"What’s the market probability after my trade?”

// impliedProbability is already a 0..1 decimal — just multiply by 100
console.log(
  `After your $100 buy, YES is priced at ${(quote.impliedProbability * 100).toFixed(1)}%`
);
// → "After your $100 buy, YES is priced at 56.3%"
For all outcomes at once, read pAfter[]:
// pAfter values are WAD-18; divide by 1e18 to get probabilities
quote.pAfter.forEach((p, i) => {
  const prob = Number(BigInt(p)) / 1e18;
  console.log(`  Outcome ${i}: ${(prob * 100).toFixed(1)}%`);
});

“How much USDC do I get if I sell 1 YES token?”

// 1 token in WAD-18 = 1_000000000000000000
const res = await fetch(
  'https://app.kash.bot/api/markets/abc123/quote' +
    '?outcomeIndex=0&action=sell&amount=1000000000000000000'
);
const { quote } = await res.json();

const usdc = Number(BigInt(quote.usdcOut)) / 1e6;      // post-fee
const gross = Number(BigInt(quote.grossRelease)) / 1e18; // pre-fee in USDC
const fee = gross - usdc;

console.log(`You receive $${usdc.toFixed(2)} (fee: $${fee.toFixed(4)})`);
// → "You receive $0.28 (fee: $0.0035)"

Advanced: “How much would it cost to move the market to 70%?”

There’s no single-call answer — walk amount up and watch pAfter[outcomeIndex] move. Quotes are cached 10s server-side, so a client-side binary search is cheap:
async function costToReach(marketId, outcomeIndex, targetProb) {
  let lo = 1_000_000n;            // $1
  let hi = 1_000_000_000_000n;    // $1M
  for (let i = 0; i < 20; i++) {
    const mid = (lo + hi) / 2n;
    const r = await fetch(
      `https://app.kash.bot/api/markets/${marketId}/quote` +
        `?outcomeIndex=${outcomeIndex}&action=buy&amount=${mid}`
    );
    const { quote } = await r.json();
    if (quote.impliedProbability < targetProb) lo = mid;
    else hi = mid;
  }
  return Number(lo) / 1e6; // USDC
}

Notes & Gotchas

  • Quotes are view calls — nothing on-chain changes. You can poll at will within the rate limit.
  • usdcOut on sells is post-fee. If you need to display the fee, compute grossRelease / 1e18 * 1e6 - Number(usdcOut) (or do it in bigint math).
  • Buy fee is zero on the current AMM; tokensOut reflects the full reserve increase.
  • pAfter and qAfter always sum to 1e18. The last element may absorb up to 1 wei of rounding dust.
  • effectivePrice is a JS-number convenience field and can lose precision on tiny trades. For any authoritative display or accounting, derive values from the string bigint fields with BigInt(...).
  • Finding market IDs. Use GET /api/markets for pagination/filtering or GET /api/markets/:id for a single market. Both are public and CORS-enabled.