Clients & SDKs
Choose a client for market data, trading, or Deposit Wallet actions
Use an SDK when you want typed models, authentication helpers, and order signing. Use the REST and WebSocket APIs directly when your runtime is unsupported or you need lower-level control.
Download configured bundles
Open Settings → SDKs to download a bundle configured for your operator's environment.
Choose a client
| Client | Languages | Best for |
|---|---|---|
| CLOB | TypeScript, Python, Rust | Market data, authentication, signing, orders, cancellations, and trades |
| Builder Relayer | TypeScript, Python, Rust | Deposit Wallet deployment and gasless onchain batches |
| REST API | Any | Raw JSON access and unsupported runtimes |
| WebSocket | Any | Order-book, order, trade, and live-data updates |
| Task | Use |
|---|---|
| Discover events and market metadata | Gamma API |
| Read books, prices, spreads, and tick sizes | CLOB client or REST |
| Create credentials and place orders | Authenticated CLOB client |
| Deploy a Deposit Wallet or batch approvals | Builder Relayer client |
| Track live market changes | Market WebSocket |
| Track private order and trade changes | User WebSocket |
CLOB quickstart
Public methods need only the CLOB URL. Trading also needs a signer, L2 credentials,
signature type 3, and the Deposit Wallet funder address.
import { ClobClient, OrderType, Side, SignatureType } from '@kuestcom/clob-client'
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { polygonAmoy } from 'viem/chains'
const host = process.env.CLOB_URL!
const chainId = 80002
const tokenID = process.env.CLOB_TOKEN_ID!
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const signer = createWalletClient({
account,
chain: polygonAmoy,
transport: http(process.env.RPC_URL),
})
const bootstrap = new ClobClient(host, chainId, signer)
const creds = await bootstrap.createOrDeriveApiKey()
const client = new ClobClient(
host,
chainId,
signer,
creds,
SignatureType.DEPOSIT_WALLET,
process.env.DEPOSIT_WALLET!,
)
const tickSize = await client.getTickSize(tokenID)
const negRisk = await client.getNegRisk(tokenID)
const result = await client.createAndPostOrder(
{ tokenID, price: 0.42, size: 5, side: Side.BUY },
{ tickSize, negRisk },
OrderType.GTC,
false,
true,
)
console.log(result)import os
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType, PartialCreateOrderOptions
from py_clob_client.order_builder.constants import BUY
client = ClobClient(
os.environ["CLOB_URL"],
chain_id=80002,
key=os.environ["PRIVATE_KEY"],
signature_type=3,
funder=os.environ["DEPOSIT_WALLET"],
)
client.set_api_creds(client.create_or_derive_api_creds())
token_id = os.environ["CLOB_TOKEN_ID"]
order = client.create_order(
OrderArgs(token_id=token_id, price=0.42, size=5, side=BUY),
options=PartialCreateOrderOptions(
tick_size=client.get_tick_size(token_id),
neg_risk=client.get_neg_risk(token_id),
),
)
print(client.post_order(order, OrderType.GTC))[dependencies]
kuest-client-sdk = { version = "2", features = ["clob"] }
rust_decimal = "1"
rust_decimal_macros = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }use std::str::FromStr as _;
use alloy::signers::{local::LocalSigner, Signer as _};
use kuest_client_sdk::clob::types::{OrderType, Side, SignatureType};
use kuest_client_sdk::clob::{Client, Config};
use kuest_client_sdk::types::{Address, U256};
use kuest_client_sdk::AMOY;
use rust_decimal::Decimal;
use rust_decimal_macros::dec;
#[tokio::main]
async fn main() -> kuest_client_sdk::Result<()> {
let signer = LocalSigner::from_str(&std::env::var("PRIVATE_KEY")?)?
.with_chain_id(Some(AMOY));
let funder = Address::from_str(&std::env::var("DEPOSIT_WALLET")?)?;
let token_id = U256::from_str(&std::env::var("CLOB_TOKEN_ID")?)?;
let clob_url = std::env::var("CLOB_URL")?;
let client = Client::new(&clob_url, Config::default())?
.authentication_builder(&signer)
.signature_type(SignatureType::DepositWallet)
.funder(funder)
.authenticate()
.await?;
let order = client.limit_order()
.token_id(token_id)
.side(Side::Buy)
.price(dec!(0.42))
.size(Decimal::new(5, 0))
.order_type(OrderType::GTC)
.build()
.await?;
let result = client.post_order(client.sign(&signer, order).await?).await?;
println!("{result:?}");
Ok(())
}Keep signing server-side
Never place private keys, CLOB API secrets, relayer credentials, or builder credentials in browser-exposed code. The frontend should call a protected service when privileged signing is required.
Builder Relayer workflow
Use the relayer for Deposit Wallet actions that should not require the end user to hold the network gas token.
Required configuration:
RELAYER_URL=<operator_relayer_url>
KUEST_BUILDER_API_KEY=...
KUEST_BUILDER_SECRET=...
KUEST_BUILDER_PASSPHRASE=...
PRIVATE_KEY=...A typical workflow is:
- Derive the expected Deposit Wallet address.
- Check whether its contract is deployed.
- Deploy it when necessary.
- Build the calls, such as collateral approval and
splitPosition. - Sign the Deposit Wallet batch with a short deadline.
- Submit through the relayer and wait for the transaction receipt.
The downloaded bundle includes environment-specific relayer examples and contract addresses. Use those values instead of copying addresses from another deployment.
Market-maker workflow
A market-making service usually:
- discovers active markets through Gamma;
- checks CLOB token IDs, tick size, negative-risk status, and trading state;
- prepares outcome-token inventory;
- reads the order book and calculates fair value;
- posts non-crossing, post-only bid and ask ladders;
- cancels or replaces stale quotes as price, inventory, or risk limits change.
Protect against stale or crossed quotes
Confirm the best buy is below the best sell, cap inventory and notional exposure, and cancel quotes when your data stream is stale or the strategy loses connectivity.
Authentication and updates
- CLOB trading uses Deposit Wallet orders with signature type
3. - The CLOB client derives L2 credentials from a wallet signature.
- Relayer clients use
KUEST_BUILDER_*credentials. - Server time should be synchronized before signing authenticated requests.
Refresh a downloaded bundle in place from its directory:
./.sdk/update --latest