Skip to main content

Overview

The TurbineClient class is the main interface for interacting with the Turbine CLOB API. It provides three access levels:
  • Level 0 (Public): No authentication, read-only market data
  • Level 1 (Signing): Private key for order signing
  • Level 2 (Full): Private key + API credentials for all endpoints
All operations are API-routed through api.turbinefi.com - no direct RPC or blockchain node access required.

Constructor

from turbine_client import TurbineClient

client = TurbineClient(
    host="https://api.turbinefi.com",
    chain_id=137,
    private_key="0x...",  # Optional: for order signing
    api_key_id="your_key_id",  # Optional: for authenticated endpoints
    api_private_key="your_ed25519_key",  # Optional: for bearer token auth
    timeout=30.0
)
host
str
required
The API host URL (e.g., https://api.turbinefi.com)
chain_id
int
required
The blockchain chain ID:
  • 137 - Polygon mainnet (recommended)
  • 43114 - Avalanche mainnet
  • 84532 - Base Sepolia testnet (currently non-operational)
private_key
str
default:"None"
Optional wallet private key (hex string with 0x prefix) for order signing. Required for Level 1+ access.
api_key_id
str
default:"None"
Optional API key ID for bearer token authentication. Required for Level 2 access.
api_private_key
str
default:"None"
Optional Ed25519 private key for bearer token signing. Required for Level 2 access.
timeout
float
default:"30.0"
HTTP request timeout in seconds.

Properties

host

client.host  # Returns: str
Get the configured API host URL.

chain_id

client.chain_id  # Returns: int
Get the configured chain ID.

address

client.address  # Returns: Optional[str]
Get the wallet address if a signer is configured, otherwise None.

can_sign

client.can_sign  # Returns: bool
Check if the client can sign orders (has a private key configured).

has_auth

client.has_auth  # Returns: bool
Check if the client has bearer token authentication configured.

Context Manager

The client can be used as a context manager to ensure proper cleanup:
with TurbineClient(host, chain_id, private_key) as client:
    markets = client.get_markets()
    # Client automatically closed on exit

Public Endpoints

These methods require no authentication (Level 0 access).

get_health

client.get_health()
Check API health status.
status
str
Health status (e.g., “ok”)
Example:
health = client.get_health()
print(health)  # {"status": "ok", "timestamp": 1234567890}

get_markets

client.get_markets(chain_id=None)
Get all markets.
chain_id
int
default:"None"
Optional chain ID to filter markets
markets
List[Market]
List of Market objects with fields:
  • market_id (str): Unique market identifier
  • question (str): Market question
  • settlement_address (str): Settlement contract address
  • start_time (int): Market start timestamp
  • end_time (int): Market end timestamp
  • resolved (bool): Whether the market is resolved
Example:
markets = client.get_markets(chain_id=137)
for market in markets:
    print(f"{market.market_id}: {market.question}")

get_market

client.get_market(market_id)
Get statistics for a specific market.
market_id
str
required
The market ID (hex string)
MarketStats
MarketStats
Market statistics including volume, liquidity, and price data
Example:
stats = client.get_market("0x1234...")
print(f"Volume: ${stats.volume / 1e6:.2f}")
print(f"Yes price: {stats.yes_price / 1e6:.2%}")

get_orderbook

client.get_orderbook(market_id, outcome=None)
Get the orderbook snapshot for a market.
market_id
str
required
The market ID
outcome
Outcome
default:"None"
Optional outcome filter (Outcome.YES or Outcome.NO)
OrderBookSnapshot
OrderBookSnapshot
Orderbook with bids and asks:
  • market_id (str): Market identifier
  • bids (List[PriceLevel]): Buy orders
  • asks (List[PriceLevel]): Sell orders
  • last_update (int): Last update timestamp
Example:
book = client.get_orderbook(market_id)
if book.bids:
    best_bid = book.bids[0]
    print(f"Best bid: {best_bid.price / 1e6:.2%} for {best_bid.size / 1e6:.2f} shares")

get_trades

client.get_trades(market_id, limit=100)
Get recent trades for a market.
market_id
str
required
The market ID
limit
int
default:"100"
Maximum number of trades to return
trades
List[Trade]
List of Trade objects
Example:
trades = client.get_trades(market_id, limit=50)
for trade in trades:
    print(f"Price: {trade.price / 1e6:.2%}, Size: {trade.size / 1e6:.2f}")

get_stats

client.get_stats(market_id)
Get statistics for a market (alias for get_market).

get_platform_stats

client.get_platform_stats()
Get platform-wide statistics.
PlatformStats
PlatformStats
Platform statistics including total volume, markets, and users
Example:
stats = client.get_platform_stats()
print(f"Total volume: ${stats.total_volume / 1e6:.2f}")
print(f"Active markets: {stats.active_markets}")

get_holders

client.get_holders(market_id, limit=100)
Get top position holders for a market.
market_id
str
required
The market ID
limit
int
default:"100"
Maximum number of holders to return
holders
List[Holder]
List of top holders with addresses and position sizes

get_quick_market

client.get_quick_market(asset)
Get the active quick market for an asset.
asset
str
required
The asset symbol (e.g., "BTC", "ETH")
QuickMarket
QuickMarket
Active quick market with:
  • market_id (str): Market identifier
  • asset (str): Asset symbol
  • start_price (int): Strike price (6 decimals)
  • start_time (int): Market start timestamp
  • end_time (int): Market end timestamp
  • settlement_address (str): Settlement contract
Example:
market = client.get_quick_market("BTC")
strike_price = market.start_price / 1e6
print(f"BTC market strike: ${strike_price:,.2f}")

get_quick_market_history

client.get_quick_market_history(asset, limit=100)
Get historical quick markets for an asset.
asset
str
required
The asset symbol
limit
int
default:"100"
Maximum number of markets to return
markets
List[QuickMarket]
List of historical quick markets

get_quick_market_price

client.get_quick_market_price(asset)
Get the current price for an asset.
asset
str
required
The asset symbol (e.g., "BTC", "ETH")
AssetPrice
AssetPrice
Current asset price with timestamp
Example:
price = client.get_quick_market_price("BTC")
print(f"BTC: ${price.price / 1e6:,.2f}")

get_quick_market_price_history

client.get_quick_market_price_history(asset, limit=100)
Get price history for an asset.
asset
str
required
The asset symbol
limit
int
default:"100"
Maximum number of prices to return
prices
List[AssetPrice]
List of historical prices

get_resolution

client.get_resolution(market_id)
Get resolution status for a market.
market_id
str
required
The market ID
Resolution
Resolution
Resolution status:
  • resolved (bool): Whether the market is resolved
  • winning_outcome (int): Winning outcome (0=YES, 1=NO)
  • resolution_time (int): Resolution timestamp
Example:
resolution = client.get_resolution(market_id)
if resolution.resolved:
    outcome = "YES" if resolution.winning_outcome == 0 else "NO"
    print(f"Market resolved: {outcome} won")

get_failed_trades

client.get_failed_trades()
Get all failed trades.
failed_trades
List[FailedTrade]
List of failed trade records

get_pending_trades

client.get_pending_trades()
Get all pending trades.
pending_trades
List[PendingTrade]
List of pending trade records

get_failed_claims

client.get_failed_claims()
Get all failed claims.
failed_claims
List[FailedClaim]
List of failed claim records

get_pending_claims

client.get_pending_claims()
Get all pending claims.
pending_claims
List[PendingClaim]
List of pending claim records

get_settlement_status

client.get_settlement_status(tx_hash)
Get settlement status for a transaction.
tx_hash
str
required
The transaction hash
SettlementStatus
SettlementStatus
Settlement status with confirmation details

Order Management

These methods require a private key (Level 1 access).

create_order

client.create_order(order_args, settlement_address=None)
Create and sign an order.
order_args
OrderArgs
required
Order arguments:
  • market_id (str): Market identifier
  • side (Side): Side.BUY or Side.SELL
  • outcome (Outcome): Outcome.YES or Outcome.NO
  • price (int): Price scaled by 1e6 (0-1,000,000)
  • size (int): Size with 6 decimals
  • expiration (int): Unix timestamp
settlement_address
str
default:"None"
Optional settlement contract address. If not provided, fetched from market.
SignedOrder
SignedOrder
A signed order ready for submission
Example:
from turbine_client import OrderArgs, Side, Outcome
import time

order_args = OrderArgs(
    market_id="0x1234...",
    side=Side.BUY,
    outcome=Outcome.YES,
    price=600_000,  # 60%
    size=1_000_000,  # 1 share
    expiration=int(time.time()) + 3600
)
signed_order = client.create_order(order_args)

create_limit_buy

client.create_limit_buy(
    market_id,
    outcome,
    price,
    size,
    expiration=None,
    settlement_address=None
)
Create a limit buy order.
market_id
str
required
The market ID
outcome
Outcome
required
Outcome.YES or Outcome.NO
price
int
required
Price scaled by 1e6 (1 to 999,999)
size
int
required
Size with 6 decimals
expiration
int
default:"None"
Optional expiration timestamp. Defaults to 1 hour from now.
settlement_address
str
default:"None"
Optional settlement contract address
SignedOrder
SignedOrder
A signed buy order
Example:
from turbine_client import Outcome

# Buy 10 YES shares at 55%
order = client.create_limit_buy(
    market_id="0x1234...",
    outcome=Outcome.YES,
    price=550_000,
    size=10_000_000
)

create_limit_sell

client.create_limit_sell(
    market_id,
    outcome,
    price,
    size,
    expiration=None,
    settlement_address=None
)
Create a limit sell order.
market_id
str
required
The market ID
outcome
Outcome
required
Outcome.YES or Outcome.NO
price
int
required
Price scaled by 1e6 (1 to 999,999)
size
int
required
Size with 6 decimals
expiration
int
default:"None"
Optional expiration timestamp
settlement_address
str
default:"None"
Optional settlement contract address
SignedOrder
SignedOrder
A signed sell order
Example:
from turbine_client import Outcome

# Sell 5 NO shares at 40%
order = client.create_limit_sell(
    market_id="0x1234...",
    outcome=Outcome.NO,
    price=400_000,
    size=5_000_000
)

Authenticated Endpoints

These methods require both a private key and API credentials (Level 2 access).

post_order

client.post_order(signed_order)
Submit a signed order to the orderbook.
signed_order
SignedOrder
required
The signed order from create_order, create_limit_buy, or create_limit_sell
response
Dict[str, Any]
Order submission response:
  • order_hash (str): Unique order identifier
  • status (str): Order status
Example:
order = client.create_limit_buy(market_id, Outcome.YES, 500_000, 1_000_000)
response = client.post_order(order)
print(f"Order hash: {response['order_hash']}")

get_orders

client.get_orders(trader=None, market_id=None, status=None)
Get orders with optional filters.
trader
str
default:"None"
Optional trader address to filter
market_id
str
default:"None"
Optional market ID to filter
status
str
default:"None"
Optional status filter: "open", "filled", or "cancelled"
orders
List[Order]
List of Order objects
Example:
open_orders = client.get_orders(status="open")
for order in open_orders:
    print(f"{order.order_hash}: {order.side} {order.size / 1e6:.2f} @ {order.price / 1e6:.2%}")

get_order

client.get_order(order_hash)
Get a specific order by hash.
order_hash
str
required
The order hash
Order
Order
Order details

cancel_order

client.cancel_order(order_hash, market_id=None, side=None)
Cancel an order.
order_hash
str
required
The order hash to cancel
market_id
str
default:"None"
Optional market ID for validation
side
Side
default:"None"
Optional side for validation
response
Dict[str, Any]
Cancellation response
Example:
response = client.cancel_order("0xabcd...")
print(f"Cancelled: {response['success']}")

cancel_market_orders

client.cancel_market_orders(market_id)
Cancel all orders for a market.
market_id
str
required
The market ID
response
Dict[str, Any]
Cancellation response with count of cancelled orders
Example:
response = client.cancel_market_orders(market_id)
print(f"Cancelled {response['count']} orders")

get_positions

client.get_positions(market_id, user_address=None)
Get positions for a market.
market_id
str
required
The market ID
user_address
str
default:"None"
Optional user address to filter
positions
List[Position]
List of Position objects with:
  • yes_shares (int): YES token balance
  • no_shares (int): NO token balance
  • total_cost (int): Total cost basis
  • total_revenue (int): Total revenue from sales

get_user_positions

client.get_user_positions(address, chain_id=None)
Get all positions for a user.
address
str
required
The user’s address
chain_id
int
default:"None"
Optional chain ID to filter
positions
List[Position]
List of all positions for the user
Example:
positions = client.get_user_positions(client.address)
for pos in positions:
    print(f"Market {pos.market_id}: {pos.yes_shares / 1e6:.2f} YES, {pos.no_shares / 1e6:.2f} NO")

get_user_orders

client.get_user_orders(address, status=None)
Get all orders for a user.
address
str
required
The user’s address
status
str
default:"None"
Optional status filter
orders
List[Order]
List of orders

get_user_activity

client.get_user_activity(address)
Get trading activity summary for a user.
address
str
required
The user’s address
UserActivity
UserActivity
User activity summary with trade counts and volumes

get_user_stats

client.get_user_stats()
Get statistics for the authenticated user.
UserStats
UserStats
User statistics including:
  • total_cost (int): Total amount spent
  • total_invested (int): Net amount invested
  • position_value (int): Current position value
  • pnl (int): Profit and loss
Example:
stats = client.get_user_stats()
print(f"PnL: ${stats.pnl / 1e6:.2f}")
print(f"Position value: ${stats.position_value / 1e6:.2f}")

get_claimable_positions

client.get_claimable_positions(address=None, verify=True)
Get resolved markets where the user has winning tokens to claim.
address
str
default:"None"
User address. Defaults to the signer’s address.
verify
bool
default:"True"
If True, verify each position on-chain and backfill already-claimed ones. Slower but handles pre-fix data.
result
Dict[str, Any]
Dictionary with:
  • claimable (List[ClaimablePosition]): Claimable positions
  • count (int): Number of claimable positions
  • totalPayout (str): Total payout amount
Example:
result = client.get_claimable_positions()
print(f"Found {result['count']} claimable positions worth ${result['totalPayout']}")
for pos in result['claimable']:
    print(f"  {pos.market_id}: {pos.outcome} - ${pos.payout / 1e6:.2f}")

Relayer Endpoints (Gasless Operations)

These methods use Turbine’s gasless relayer for zero-gas transactions.

approve_usdc_for_settlement

client.approve_usdc_for_settlement(settlement_address=None)
Approve a settlement contract to transfer USDC using gasless permit. This is a one-time operation per settlement contract.
settlement_address
str
default:"None"
The settlement contract to approve. If not provided, uses the default for the chain.
response
Dict[str, Any]
The relayer response with tx_hash on success
Example:
response = client.approve_usdc_for_settlement()
print(f"Approval tx: {response['tx_hash']}")

approve_ctf_for_settlement

client.approve_ctf_for_settlement(settlement_address=None)
Approve a settlement contract to transfer CTF tokens using gasless permit.
settlement_address
str
default:"None"
The settlement contract to approve
response
Dict[str, Any]
The relayer response with tx_hash on success

approve_usdc

client.approve_usdc(amount, spender=None)
Approve USDC spending via gasless permit.
amount
int
required
The amount to approve (with 6 decimals for USDC)
spender
str
default:"None"
The spender address. Defaults to settlement contract.
response
Dict[str, Any]
The relayer response with tx_hash on success

claim_winnings

client.claim_winnings(market_contract_address)
Claim winnings from a resolved market using gasless permit.
market_contract_address
str
required
The market’s contract address
response
Dict[str, Any]
The relayer response with tx_hash on success
Example:
response = client.claim_winnings("0x1234...")
print(f"Claim tx: {response['tx_hash']}")

batch_claim_winnings

client.batch_claim_winnings(market_contract_addresses)
Claim winnings from multiple resolved markets in a single transaction.
market_contract_addresses
List[str]
required
List of market contract addresses to claim from
response
Dict[str, Any]
The relayer response with tx_hash on success
Example:
markets = ["0x1234...", "0x5678...", "0xabcd..."]
response = client.batch_claim_winnings(markets)
print(f"Batch claim tx: {response['tx_hash']}")

claim_all_winnings

client.claim_all_winnings()
Discover and claim all winnings using Multicall3 discovery + gasless relayer.
response
Dict[str, Any]
The relayer response with tx_hash on success
Example:
response = client.claim_all_winnings()
print(f"Claimed all winnings: {response['tx_hash']}")

Position Discovery

discover_positions

client.discover_positions(address=None)
Discover all claimable and mergeable positions via the Turbine API.
address
str
default:"None"
Wallet address to check. Defaults to the signer’s address.
DiscoveryResult
DiscoveryResult
Discovery result with:
  • claimable (List[ClaimablePosition]): Claimable positions
  • mergeable (List[MergeablePosition]): Mergeable positions
  • total_claimable_usdc (float): Total claimable value
  • total_mergeable_usdc (float): Total mergeable value
  • markets_scanned (int): Number of markets scanned
Example:
result = client.discover_positions()
print(f"Claimable: ${result.total_claimable_usdc:.2f}")
print(f"Mergeable: ${result.total_mergeable_usdc:.2f}")

get_mergeable_positions

client.get_mergeable_positions(address=None)
Get all mergeable positions (paired YES+NO tokens that can be merged to USDC).
address
str
default:"None"
Wallet address to check. Defaults to the signer’s address.
mergeable
List[MergeablePosition]
List of MergeablePosition with merge amounts

Utility Methods

get_usdc_balance

client.get_usdc_balance(owner=None)
Get the USDC balance for an address via the Turbine API.
owner
str
default:"None"
The address to check. Defaults to signer address.
balance
int
The USDC balance (raw, 6 decimals)
Example:
balance = client.get_usdc_balance()
print(f"USDC balance: ${balance / 1e6:.2f}")

get_usdc_allowance

client.get_usdc_allowance(owner=None, spender=None)
Get the current USDC allowance for a spender via the Turbine API.
owner
str
default:"None"
The token owner. Defaults to signer address.
spender
str
default:"None"
The spender address. Defaults to settlement contract.
allowance
int
The current allowance (with 6 decimals)
Example:
allowance = client.get_usdc_allowance()
if allowance > 0:
    print(f"USDC approved: ${allowance / 1e6:.2f}")
else:
    print("USDC not approved - call approve_usdc_for_settlement()")

sign_usdc_permit

client.sign_usdc_permit(value, settlement_address=None, deadline=None)
Sign an EIP-2612 permit for USDC approval. This creates a signature for gasless approval.
value
int
required
The amount to approve (with 6 decimals for USDC)
settlement_address
str
default:"None"
The spender (settlement contract). Uses chain default if not provided.
deadline
int
default:"None"
Permit expiration timestamp. Defaults to 1 hour from now.
PermitSignature
PermitSignature
Permit signature that can be included with order submission

sync_permit_nonce

client.sync_permit_nonce(contract_address=None)
Sync the local permit nonce with the on-chain state via the API.
contract_address
str
default:"None"
The token contract. Defaults to USDC.
nonce
int
The current on-chain nonce

API Credentials

request_api_credentials (static)

TurbineClient.request_api_credentials(host, private_key, name=None)
Request API credentials by proving wallet ownership. This is a static method.
host
str
required
The API host URL (e.g., "https://api.turbinefi.com")
private_key
str
required
The wallet private key (for signing the auth message)
name
str
default:"None"
Optional friendly name for the API key
credentials
Dict[str, str]
Dictionary with:
  • api_key_id: The API key identifier
  • api_private_key: The Ed25519 private key (save this!)
  • message: Success message
Example:
creds = TurbineClient.request_api_credentials(
    host="https://api.turbinefi.com",
    private_key="0x...",
    name="My Trading Bot"
)
print(f"API Key ID: {creds['api_key_id']}")
print(f"API Private Key: {creds['api_private_key']}")

Error Handling

The client raises specific exceptions for different error conditions:
  • AuthenticationError: Missing credentials for the requested operation
  • TurbineApiError: API request failed
  • OrderValidationError: Invalid order parameters
  • SignatureError: Signature generation failed
Example:
from turbine_client.exceptions import AuthenticationError, TurbineApiError

try:
    order = client.create_limit_buy(market_id, Outcome.YES, 500_000, 1_000_000)
    response = client.post_order(order)
except AuthenticationError as e:
    print(f"Auth error: {e}")
except TurbineApiError as e:
    print(f"API error: {e}")

Resource Cleanup

Always close the client when done to release resources:
# Option 1: Context manager (recommended)
with TurbineClient(host, chain_id) as client:
    markets = client.get_markets()

# Option 2: Manual close
client = TurbineClient(host, chain_id)
try:
    markets = client.get_markets()
finally:
    client.close()

Build docs developers (and LLMs) love