BETA The Prediction Market API is currently in beta and subject to breaking changes as we continue to improve the product. If you have any feedback, please reach out in Discord .
This doc walks through creating a buy order to open a position in a prediction market. You’ll learn how to construct the order request, sign the returned transaction, and submit it to the Solana network.
Prerequisite
Before opening a position, ensure you have:
Create Buy Order
Use POST /orders to create a buy order for YES or NO contracts.
Parameter Type Required Description ownerPubkeystring Yes Your wallet’s public key marketIdstring Yes The market identifier isYesboolean Yes true for YES contracts, false for NOisBuyboolean Yes true for buy orderscontractsstring No Number of contracts to purchase depositAmountstring Yes Amount to deposit (in native token units of JupUSD or USDC) depositMintstring Yes Token mint for deposit (JupUSD or USDC)
Example: Create a buy order for 2 USD worth of contracts
const response = await fetch ( 'https://api.jup.ag/prediction/v1/orders' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'x-api-key' : 'your-api-key'
},
body: JSON . stringify ({
ownerPubkey: wallet . publicKey . toString (),
depositAmount: '2000000' ,
depositMint: 'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD' ,
marketId: marketId ,
isYes: true ,
isBuy: true ,
})
});
const orderResponse = await response . json ();
console . log ( orderResponse );
Understanding the Response
Field Description transactionBase64-encoded Solana transaction to sign and submit order.pubkeyThe order’s on-chain account address order.positionPubkeyThe position’s on-chain account address order.contractsThe number of contracts being purchased
Sign and Submit the Transaction
After receiving the order response, you need to:
Deserialize the base64 transaction
Sign it with your wallet
Submit to the Solana network
// Step 1: Create order
const orderResponse = await fetch ( 'https://api.jup.ag/prediction/v1/orders' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'x-api-key' : 'your-api-key'
},
body: JSON . stringify ({
ownerPubkey: wallet . publicKey . toString (),
depositAmount: '2000000' ,
depositMint: 'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD' ,
marketId: marketId , // Get from events and markets guide
isYes: true ,
isBuy: true ,
})
}). then ( r => r . json ());
// Step 2: Deserialize and sign transaction
const transaction = VersionedTransaction . deserialize (
Buffer . from ( orderResponse . transaction , 'base64' )
);
transaction . sign ([ wallet ]);
const transactionBinary = transaction . serialize ();
const blockhashInfo = await connection . getLatestBlockhashAndContext ({ commitment: "confirmed" });
// Step 3: Send the transaction and await status
const signature = await connection . sendRawTransaction ( transactionBinary , {
maxRetries: 0 ,
skipPreflight: true ,
preflightCommitment: "confirmed" ,
});
console . log ( `Transaction sent: https://solscan.io/tx/ ${ signature } ` );
try {
const confirmation = await connection . confirmTransaction ({
signature ,
blockhash: blockhashInfo . value . blockhash ,
lastValidBlockHeight: blockhashInfo . value . lastValidBlockHeight ,
}, "confirmed" );
if ( confirmation . value . err ) {
console . error ( `Transaction failed: ${ JSON . stringify ( confirmation . value . err ) } ` );
console . log ( `Examine the failed transaction: https://solscan.io/tx/ ${ signature } ` );
} else {
console . log ( `Transaction successful: https://solscan.io/tx/ ${ signature } ` );
}
} catch ( error ) {
console . error ( `Error confirming transaction: ${ error } ` );
console . log ( `Examine the transaction status: https://solscan.io/tx/ ${ signature } ` );
}
Checking Order Status
After submitting, the order enters the keeper network for matching and execution. Use GET /orders/status/{orderPubkey} to check the fill status.
Order Flow
Create Order : You sign a transaction that creates an order account on-chain - this transaction only opens an order account and does not guarantee that the order will be filled.
Keeper Fills : Jupiter’s keeper network matches your order with the underlying prediction market
Position Updated : Once filled, your position account reflects the new contracts
Order Closed : The order account is closed after completion
Polling immediately after submitting the transaction might return a pending status or a no order history found error. Wait for a few slots before polling again.
Status Description pendingOrder submitted, waiting to be filled filledOrder fully executed failedOrder could not be filled
const orderPubkey = orderResponse . order . pubkey ;
const statusResponse = await fetch (
`https://api.jup.ag/prediction/v1/orders/status/ ${ orderPubkey } ` ,
{
headers: {
'x-api-key' : 'your-api-key'
}
}
);
const status = await statusResponse . json ();
console . log ( status );
Fee Calculation
To understand how fees work, refer to the Fees page.
What’s Next
Once you have open positions, learn how to manage them - view your holdings, sell contracts, or cancel pending orders.