Sign & Post Order
import { Wallet, solidityPackedKeccak256, getBytes, randomBytes, hexlify } from "ethers";
const order = {
marketHash:
"0x0eeace4a9bbf6235bc59695258a419ed3a05a2c8e3b6a58fb71a0d9e6b031c2b",
maker: "0x6F75bA6c90E3da79b7ACAfc0fb9cf3968aa4ee39",
totalBetSize: "10000000",
percentageOdds: "52500000000000000000",
baseToken: "0x6629Ce1Cf35Cc1329ebB4F63202F3f197b3F050B", // Mainnet — see References for testnet address
apiExpiry: 1631233201,
expiry: 2209006800,
executor: "0x52adf738AAD93c31f798a30b2C74D658e1E9a562", // Mainnet — use GET /metadata → executorAddress for testnet
isMakerBettingOutcomeOne: true,
salt: BigInt(hexlify(randomBytes(32))).toString(),
};
const orderHash = getBytes(
solidityPackedKeccak256(
[
"bytes32",
"address",
"uint256",
"uint256",
"uint256",
"uint256",
"address",
"address",
"bool",
],
[
order.marketHash,
order.baseToken,
order.totalBetSize,
order.percentageOdds,
order.expiry,
order.salt,
order.maker,
order.executor,
order.isMakerBettingOutcomeOne,
]
)
);
// Example with an ethers.js wallet using a private key
const wallet = new Wallet(process.env.SX_PRIVATE_KEY);
const signature = await wallet.signMessage(orderHash);
// Example with an injected web3 provider such as MetaMask
// const provider = new BrowserProvider(window.ethereum);
// const signer = await provider.getSigner();
// const signature = await signer.signMessage(orderHash);
const signedOrder = { ...order, signature };
const result = await fetch("https://api.sx.bet/orders/new", { // Mainnet — use https://api.toronto.sx.bet for testnet
method: "POST",
body: JSON.stringify({ orders: [signedOrder] }),
headers: { "Content-Type": "application/json" },
});{
"status": "success",
"data": {
"orders": [
"0x7a9d420551c4a635849013dd908f7894766e97aee25fe656d0c5ac857e166fac"
],
"statuses": {
"0x7a9d420551c4a635849013dd908f7894766e97aee25fe656d0c5ac857e166fac": "OK"
},
"inserted": 1
}
}Orders
Post a new order
Submit a new maker order to the SX Bet orderbook. Requires an EIP-712 signature.
POST
/
orders
/
new
Sign & Post Order
import { Wallet, solidityPackedKeccak256, getBytes, randomBytes, hexlify } from "ethers";
const order = {
marketHash:
"0x0eeace4a9bbf6235bc59695258a419ed3a05a2c8e3b6a58fb71a0d9e6b031c2b",
maker: "0x6F75bA6c90E3da79b7ACAfc0fb9cf3968aa4ee39",
totalBetSize: "10000000",
percentageOdds: "52500000000000000000",
baseToken: "0x6629Ce1Cf35Cc1329ebB4F63202F3f197b3F050B", // Mainnet — see References for testnet address
apiExpiry: 1631233201,
expiry: 2209006800,
executor: "0x52adf738AAD93c31f798a30b2C74D658e1E9a562", // Mainnet — use GET /metadata → executorAddress for testnet
isMakerBettingOutcomeOne: true,
salt: BigInt(hexlify(randomBytes(32))).toString(),
};
const orderHash = getBytes(
solidityPackedKeccak256(
[
"bytes32",
"address",
"uint256",
"uint256",
"uint256",
"uint256",
"address",
"address",
"bool",
],
[
order.marketHash,
order.baseToken,
order.totalBetSize,
order.percentageOdds,
order.expiry,
order.salt,
order.maker,
order.executor,
order.isMakerBettingOutcomeOne,
]
)
);
// Example with an ethers.js wallet using a private key
const wallet = new Wallet(process.env.SX_PRIVATE_KEY);
const signature = await wallet.signMessage(orderHash);
// Example with an injected web3 provider such as MetaMask
// const provider = new BrowserProvider(window.ethereum);
// const signer = await provider.getSigner();
// const signature = await signer.signMessage(orderHash);
const signedOrder = { ...order, signature };
const result = await fetch("https://api.sx.bet/orders/new", { // Mainnet — use https://api.toronto.sx.bet for testnet
method: "POST",
body: JSON.stringify({ orders: [signedOrder] }),
headers: { "Content-Type": "application/json" },
});{
"status": "success",
"data": {
"orders": [
"0x7a9d420551c4a635849013dd908f7894766e97aee25fe656d0c5ac857e166fac"
],
"statuses": {
"0x7a9d420551c4a635849013dd908f7894766e97aee25fe656d0c5ac857e166fac": "OK"
},
"inserted": 1
}
}Rate limit: All
POST /orders/* endpoints share a combined limit of 5,500 requests/min. See Rate Limits.totalBetSize - fillAmount) remains under your wallet balance. If your wallet balance dips under your total exposure, orders will be removed from the book until it reaches the minimum again.
Your assets must be on SX Mainnet to place orders.
If the API finds that your balance is consistently below your total exposure requiring orders to be cancelled, your account may be temporarily restricted.
Status messages
The following status messages exist for each order:| Message | Description |
|---|---|
OK | The order was created successfully |
INSUFFICIENT_BALANCE | The order could not be created due to insufficient maker token balance |
INVALID_MARKET | The order could not be created since the user specified non-unique marketHashes |
ORDERS_ALREADY_EXIST | The order already exists |
Note that
totalBetSize is from the perspective of the market maker. totalBetSize can be thought of as the maximum amount of tokens the maker (you) will be putting into the pot if the order was fully filled. This is the maximum amount you will risk.Last modified on April 15, 2026
⌘I
