Quickstart
This guide walks you through trading Kalshi prediction market positions using Bebop API. An API key and basic understanding of EVM wallets and token approvals is required.
Discovering Available Markets
You can get the list of supported markets by querying Bebop API on Base:
curl -X GET "https://api.bebop.xyz/prediction/base/v1/events"Response
{
"events": [
{
"ticker": "KXLLM1-25DEC31",
"markets": [
{
"ticker": "KXLLM1-25DEC31-GOOG",
"yes_token_address": "0xbffd09A68059A40Aa738FA77698d2f62EA7F10cb",
"no_token_address": "0xB097564D3f9d59BD42a468833b7EB5b3815EF0FE"
},
{
"ticker": "KXLLM1-25DEC31-OAI",
"yes_token_address": "0xee5D2513a8629ee880FeACa24eEabd3B4409a5B7",
"no_token_address": "0x31aa33Cf8D2A45b3398A457703f59Adc4354aF98"
},
{
"ticker": "KXLLM1-25DEC31-XAI",
"yes_token_address": "0x241166f441e1b076F7Ae9F907A81524964F45b51",
"no_token_address": "0x7cBaE26090f42E71A39964645aE61392745C0B5f"
}
]
},
]
}For complete market details, rules and resolution criteria, please refer to the Kalshi API directly:
curl -X GET "https://api.elections.kalshi.com/trade-api/v2/markets/KXLLM1-25DEC31-GOOG"Response (abridged for brevity)
{
"market": {
"ticker": "KXLLM1-25DEC31-GOOG",
"title": "Best AI at year end?",
"custom_strike": {
"Organization": "Google"
},
"event_ticker": "KXLLM1-25DEC31",
"expected_expiration_time": "2025-12-31T15:00:00Z",
"last_price": 89,
"last_price_dollars": "0.8900",
"latest_expiration_time": "2026-01-31T15:00:00Z",
"liquidity": 25644820,
"liquidity_dollars": "256448.2000",
"market_type": "binary",
"rules_primary": "If Google has the top-ranked LLM on Dec 31, 2025, then the market resolves to Yes.",
"rules_secondary": "If two models are tied under Rank (UB), then all the strikes for this market will resolve to No. This event is not affected by the amendment that is effective in April 2025.",
"settlement_timer_seconds": 3600,
"strike_type": "custom",
"subtitle": "Gemini:: Google",
...
}
}Opening a Position
Each market is represented by two or more ERC-20 tokens on Base (i.e., one per outcome), for example:
Market: Best AI at the end of 2025 - Google Gemini? (event link)
Yes
0xbffd09A68059A40Aa738FA77698d2f62EA7F10cb
No
0xB097564D3f9d59BD42a468833b7EB5b3815EF0FE
Under the hood, buying a position involves swapping USDC ( 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 on Base) for the corresponding outcome token. The /quote endpoint abstracts all of this — just request what you need, and we return a ready-to-sign order.
Prediction market positions can only be traded in whole contract units. Fractional contracts are not supported.
Request a Quote
Important: You will need an API key to request a quote
To invest 10 USDC in YES contracts (i.e., betting GOOG will be best LLM):
curl -X GET "https://api.bebop.xyz/prediction/base/v1/quote" \
-G \
--data-urlencode "market=KXLLM1-25DEC31-GOOG" \
--data-urlencode "action=buy" \
--data-urlencode "side=yes" \
--data-urlencode "taker=<your wallet address>" \
--data-urlencode "tokens=10" \
--data-urlencode "quoteToken=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" \
--data-urlencode "apiKey=<your api key>"Quote Response
{
"quoteId": "9bac05c2-4974-4d04-9bd6-9723e678c2c8",
"requestId": "0cf5d553-8261-42d5-b4ef-74d4a9256a1b",
"action": "buy",
"side": "yes",
"taker": "<your wallet address>",
"marketToken": "0xbffd09A68059A40Aa738FA77698d2f62EA7F10cb",
"quoteToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"price": "0.9091",
"request": {
"type": "tokens",
"amount": "10"
},
"quote": {
"contracts": "11",
"contractsMin": "10.67"
},
"toSign": {
"permitted": [
{
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "10000000"
}
],
"spender": "0xC5a350853E4e36b73EB0C24aaA4b8816C9A3579a",
"nonce": "206923531211374501497099925755897889480",
"deadline": 1764944094,
"witness": {
"taker": "<your wallet address>",
"receiver": "<your wallet address>",
"expiry": 1764944094,
"exclusivityDeadline": 1764944094,
"nonce": "206923531211374501497099925755897889480",
"executor": "0x34CFAC845AfB89d62d0937931b1C9d54618e8303",
"partnerInfo": "0",
"sellTokens": [
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
],
"buyTokens": [
"0xbffd09A68059A40Aa738FA77698d2f62EA7F10cb"
],
"sellAmounts": [
"10000000"
],
"buyAmounts": [
"10670000000000000000"
],
"hooksHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"gbop": "😎"
}quoteId- Include this when submitting your signed order or monitoring the settlement processprice- Current price of the requested optionquote.contracts/quote.contractsMin- How many requested contracts you will get for the set sell amount of USDC, and expected number of contracts after 3% slippage (round down, 10.67 to 10.00)toSign- Key transaction information you are signing, with amounts and settlement instructionstoSign.witness.expiry- Unix timestamp; order invalid after this timetoSign.spender- Contract that needs token approval, Bebop's Balance Manager.
Token Approval
Bebop prediction market orders utilise permit2 for approvals.
Before submitting your order, you need to ensure that the Permit2 Contract has sufficient approvals for the token you are trading.
The message signed (toSign in the quote response) gives a permit to the Bebop Balance Manager which is a dedicated contract that uses your token approvals. It only grants the settlement contract access to your funds for the duration of each transaction - your approval is never exposed directly to the settlement logic.
Check Existing Allowance
Approve if Needed
Signing and Submitting the Order
Sign the Order
The toSign object from the quote response must be signed using EIP-712 typed data. Currently, only Permit2 approval is supported.
Submit the Order
curl -X POST "https://api.bebop.xyz/prediction/base/v1/order" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "9bac05c2-4974-4d04-9bd6-9723e678c2c8",
"signature": "0xYourSignature..."
}'Order Response
{
"status": "Pending",
"txHash": null
}Check Order Status
curl "https://api.bebop.xyz/prediction/base/v1/order-status?quoteId=9bac05c2-4974-4d04-9bd6-9723e678c2c8"Order Statuses:
Pending
Order submitted, awaiting execution
Success
Order executed successfully
Failed
Order execution failed
Important Notes
Whole Contracts Only
Prediction market positions can only be traded in whole contract units. Fractional contracts are not supported.
Since you specify the tokens parameter (i.e., how much USDC to spend), Bebop calculates the maximum whole contacts you can buy and returns the change, for example:
You spend: 10 USDC
Price per contract: 0.47 USDC
Maximum possible: 21.27 contracts → rounded down to 21 contracts
Actual cost: 21 × 0.47 = 9.87 USDC
Change returned: 10 - 9.87 = 0.13 USDC
Quote Expiry
Quotes have a limited validity window (check the expiry field in the quote response). If you don't submit before expiry, request a fresh quote.
To ensure the highest possible fill rate, we recommend to update quotes every 5-15 seconds.
Slippage
By default, slippage equals to 3%.
Gasless Execution
All orders are executed gaslessly.
Got it working?
Great! Check out JAM API Reference for more info.
Last updated
