# Kyan Documentation > Documentation for Kyan Append .md to any documentation page URL to get its markdown version. ## Guides - [About Kyan](https://docs.kyan.blue/docs/about-kyan.md) - [Portfolio Margin](https://docs.kyan.blue/docs/portfolio-margin.md) - [Account System](https://docs.kyan.blue/docs/account-system.md) - [Liquidations](https://docs.kyan.blue/docs/liquidations.md) - [Smart Contracts](https://docs.kyan.blue/docs/smart-contracts.md) - [Data Feeds and Pricing](https://docs.kyan.blue/docs/data-feeds-and-pricing.md) - [Getting Started with Kyan](https://docs.kyan.blue/docs/getting-started-with-kyan.md) - [API Key Guide](https://docs.kyan.blue/docs/api-key-guide.md) - [EIP-712 Signatures Guide](https://docs.kyan.blue/docs/eip-712-signatures-guide.md) - [Private](https://docs.kyan.blue/docs/websocket-api.md) - [Authentication](https://docs.kyan.blue/docs/ws-authentication.md) - [Commands](https://docs.kyan.blue/docs/ws-commands.md) - [Connection & Errors](https://docs.kyan.blue/docs/ws-connection.md) - [Session Recovery](https://docs.kyan.blue/docs/ws-session-recovery.md) - [Market Data](https://docs.kyan.blue/docs/ws-market-data.md) - [Index Price](https://docs.kyan.blue/docs/ws-index-price.md) - [Instruments](https://docs.kyan.blue/docs/ws-instruments.md) - [Funding](https://docs.kyan.blue/docs/ws-funding.md) - [Interest Rate](https://docs.kyan.blue/docs/ws-interest-rate.md) - [Implied Volatility (SVI)](https://docs.kyan.blue/docs/ws-iv.md) - [Orderbook](https://docs.kyan.blue/docs/ws-orderbook.md) - [Orderbook Perps](https://docs.kyan.blue/docs/ws-orderbook-perps.md) - [Orderbook Options](https://docs.kyan.blue/docs/ws-orderbook-options.md) - [Orderbook Maker](https://docs.kyan.blue/docs/ws-orderbook-maker.md) - [Orderbook Events](https://docs.kyan.blue/docs/ws-orderbook-events.md) - [Account](https://docs.kyan.blue/docs/ws-account.md) - [Account State](https://docs.kyan.blue/docs/ws-account-state.md) - [Position](https://docs.kyan.blue/docs/ws-position.md) - [Trade](https://docs.kyan.blue/docs/ws-trade.md) - [Transfer](https://docs.kyan.blue/docs/ws-transfer.md) - [Account Liquidation](https://docs.kyan.blue/docs/ws-account-liquidation.md) - [Bankruptcy](https://docs.kyan.blue/docs/ws-bankruptcy.md) - [MMP](https://docs.kyan.blue/docs/ws-mmp.md) - [Trading](https://docs.kyan.blue/docs/ws-trading.md) - [RFQ](https://docs.kyan.blue/docs/ws-rfq.md) - [MCP](https://docs.kyan.blue/docs/mcp.md) ## API Reference - [Create one-click trading session](https://docs.kyan.blue/reference/createsession.md): Create a session for one-click trading without requiring signatures for each order. Once a session is created, you can use the returned sessionHash in the `x-one-click` header for subsequent trading requests without providing signatures for each individual order. **Security**: The session is bound to the `user` address provided during creation. All subsequent one-click trading requests must use the same address as the `maker` (for limit orders, cancellations) or `taker` (for market/combo orders). Requests from a different address will be rejected with `ONE_CT_USER_MISMATCH`. ### EIP-712 Signature Example (TypeScript) ```typescript import { parseUnits } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; // Domain parameters for EIP-712 signature const EIP712Domain = { chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet) name: 'Premia', verifyingContract: '0x...' // ClearingHouseProxy address from deployment version: '1' }; // Type definition for one-click session const OneClickSignature = [ { name: 'deadline', type: 'uint256' }, { name: 'user', type: 'address' }, { name: 'bindToIp', type: 'bool' } ]; // Example session data const sessionData = { user: '0xYourWalletAddress', // Your Ethereum address bind_to_ip: true // Optional: bind session to IP address (defaults to true) }; // Calculate deadline (5 minutes from now) const deadline = Math.floor(Date.now() / 1000) + 300; // Setup wallet const account = privateKeyToAccount('0xYourPrivateKey'); // Sign the typed data const signature = await account.signTypedData({ domain: EIP712Domain, types: { OneClickSignature }, primaryType: 'OneClickSignature', message: { deadline, user: sessionData.user, bindToIp: sessionData.bind_to_ip } }); // Final request payload const requestPayload = { ...sessionData, signature, signature_deadline: deadline }; // Create session const response = await fetch(`${BASE_URL}/session`, { method: 'POST', headers: { 'x-apikey': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify(requestPayload) }); const { sessionHash } = await response.json(); // Use session for trading const orderResponse = await fetch(`${BASE_URL}/limit`, { method: 'POST', headers: { 'x-apikey': API_KEY, 'x-one-click': sessionHash, 'Content-Type': 'application/json' }, body: JSON.stringify(orders) // No signature required }); ``` - [End one-click trading session(s)](https://docs.kyan.blue/reference/endsession.md): End one or all one-click trading sessions for an API key. - **With `x-one-click` header**: Revokes only the specific session identified by the session hash - **Without `x-one-click` header**: Revokes all active sessions associated with the API key making the request This allows for granular session management or bulk session cleanup when needed. - [Get exchange information](https://docs.kyan.blue/reference/getexchangeinfo.md): Returns static exchange configuration and trading constraints. This endpoint provides essential information for integrating with the Kyan exchange. **No authentication required.** This is a public endpoint. **Information Provided:** - **Environments**: API base URLs and WebSocket URLs for different environments (alpha, sandbox, staging, production) - **Trading Pairs**: Available trading pairs and their status - **Instrument Specifications**: Naming formats, precision, and validation patterns for options and perpetuals - **Order Constraints**: Minimum order sizes, price increments, and maximum slippage limits - **RFQ Constraints**: Minimum sizes for Request-for-Quote orders - **Fees**: Trading, liquidation, and systemic fee structures - **Rate Limits**: REST API and WebSocket rate limiting configuration - **WebSocket Channels**: Available subscription channels and their parameters - **WebSocket Protocol**: Message ordering (seq_id), session recovery, and message replay - **Timeouts**: Session durations and reconnection strategies - **EIP-712 Domain**: Signature domain parameters This endpoint is served via KrakenD and returns pre-configured static data. Values are updated periodically and the `lastUpdated` field indicates when the configuration was last modified. - [Get active instruments](https://docs.kyan.blue/reference/getinstruments.md): Get all active instruments for a specific market with update timestamp. **Response includes:** - `updated_at`: Unix timestamp in milliseconds of when the instrument list was last updated - `instruments`: Array of active instrument names (both options and perpetuals) **Perpetual instruments are always active and available:** - BTC_USDC-PERPETUAL - ETH_USDC-PERPETUAL - ARB_USDC-PERPETUAL **Options instruments** are returned based on their expiration status and market availability. - [Get available expirations](https://docs.kyan.blue/reference/getexpirations.md): Get all available expiration dates for options - [Get current index price](https://docs.kyan.blue/reference/getindexprice.md): Get the current index price for a specific market. The index price is the external reference price used for mark-to-market calculations, margin requirements, and settlement. **Index Price Sources:** - **Chainlink Data Feeds**: Real-time price data from Chainlink's decentralized oracle network - **Supported Assets**: BTC, ETH, and ARB with dedicated price feeds for each market - **Real-time Updates**: Prices are streamed continuously via WebSocket connections **Use Cases:** - Portfolio valuation and mark-to-market calculations - Risk management and margin requirement calculations - Strategy analysis and option pricing models - Settlement price reference for options - [Get orderbook state](https://docs.kyan.blue/reference/getorderbook.md): Get the current state of the orderbook for a specific instrument - [Get options chain data](https://docs.kyan.blue/reference/getoptionschain.md): Retrieves a complete options chain for a given market, showing all available option contracts with their current orderbook state. Optionally filter by expiration date to view only specific maturity options. - [Get trade history by instrument](https://docs.kyan.blue/reference/gettradeshistory.md): Get historical trades for a specific instrument. - [Get maker's open orders](https://docs.kyan.blue/reference/getorders.md): Get all open orders for a specific maker address, optionally filtered by market. This includes orders currently being matched (inflight). Inflight orders appear with `filled_amount: 0` until the fill is confirmed on-chain. - [Cancel specific orders](https://docs.kyan.blue/reference/cancelorders.md): Cancel a list of orders by their IDs - [Cancel all maker's orders](https://docs.kyan.blue/reference/cancelallorders.md): Cancel all orders for a specific maker and market - [Place limit orders](https://docs.kyan.blue/reference/postlimitorders.md): Submit one or more limit orders to the orderbook. Can be used for both options and perpetual futures. **Authentication Options:** - **Signature**: Include `signature` and `signature_deadline` fields in each order (both required) - **One-click session**: Include `x-one-click` header with session hash (signature fields not required) **Important Constraints:** - All orders in a batch must be from the **same maker** (single maker per request) - All orders in a batch must be for the **same market** (BTC, ETH, or ARB - determined by trading pair) - When NOT using one-click sessions, both `signature` and `signature_deadline` are **required** fields - **Order size**: Both options and perpetual orders use `contracts` (base contracts) as the canonical size field. For perpetuals, the legacy `amount` field (USD notional) is still accepted for backward compatibility — supply exactly one of `contracts` or `amount` (prefer `contracts`). **The notional `amount` model is deprecated and will be removed in a future release**; migrate to `contracts` - The `taker` field must be the zero address (`0x0000000000000000000000000000000000000000`) indicating any taker can fill the order - There is a **per-pair open order cap** — submitting orders beyond the limit results in rejection with reason `max orders per market exceeded` - Submitting an **empty array** returns a `400` error - EIP-712 signature field order must match exactly as shown in the examples - **Price Increment**: Order `price` must be divisible by the minimum price increment for the base asset (see `GET /api/v1/exchange_info` → `orderConstraints.priceIncrements`). This applies to all orders including liquidation orders. - **Size Increment**: Order size in `contracts` (canonical for both options and perpetuals; or the legacy `amount` for perpetuals) must be at least the per-asset minimum and a whole multiple of the size increment (see `GET /api/v1/exchange_info` → `orderConstraints.options.sizeIncrements` or `orderConstraints.perpetuals.sizeIncrements`). Perpetual minimum order size equals the size increment, in base contracts: BTC `0.0001`, ETH `0.001`, ARB `1`. This applies to all orders including liquidation orders. ### EIP-712 Signature Example (TypeScript) ```typescript import { parseUnits, zeroAddress } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; // Domain parameters for EIP-712 signature const EIP712Domain = { chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet) name: 'Premia', verifyingContract: '0x...', // ClearingHouseProxy address from deployment version: '1' }; // Type definition for limit orders const UserLimitOrder = [ { name: 'deadline', type: 'uint256' }, { name: 'instrumentName', type: 'string' }, { name: 'size', type: 'uint256' }, { name: 'price', type: 'uint256' }, { name: 'taker', type: 'address' }, { name: 'maker', type: 'address' }, { name: 'direction', type: 'uint8' }, { name: 'isLiquidation', type: 'bool' }, { name: 'isPostOnly', type: 'bool' }, { name: 'mmp', type: 'bool' } ]; // Example order data (Options) const optionsOrder = { instrument_name: 'BTC_USDC-31OCT25-130000-C', type: 'good_til_cancelled', contracts: 1.5, direction: 'buy', price: 1000.5, post_only: true, mmp: false, liquidation: false, maker: '0xYourAddress', // Your Ethereum address taker: null // Set to a specific address or null for any taker }; // Example order data (Perpetuals) const perpsOrder = { instrument_name: 'BTC_USDC-PERPETUAL', type: 'good_til_cancelled', contracts: 0.2, direction: 'buy', price: 45000, post_only: false, mmp: false, liquidation: false, maker: '0xYourAddress', // Your Ethereum address taker: null // Set to a specific address or null for any taker }; // Calculate deadline (30 seconds from now) const deadline = Math.floor(Date.now() / 1000) + 30; // Setup wallet const account = privateKeyToAccount('0xYourPrivateKey'); // Choose which order to use (options or perps) const order = optionsOrder; // or perpsOrder for perpetuals // Sign the typed data const signature = await account.signTypedData({ domain: EIP712Domain, types: { UserLimitOrder }, primaryType: 'UserLimitOrder', message: { deadline, instrumentName: order.instrument_name, size: parseUnits((order.contracts ?? order.amount).toString(), 6), // Canonical `contracts`; legacy notional `amount` still accepted for perps price: parseUnits(order.price.toString(), 6), taker: order.taker ?? zeroAddress, maker: order.maker, direction: order.direction === 'buy' ? 0 : 1, isLiquidation: order.liquidation, isPostOnly: order.post_only, mmp: order.mmp } }); // Final request payload const requestPayload = { ...order, signature, signature_deadline: deadline }; ``` - [Edit limit orders](https://docs.kyan.blue/reference/patchlimitorders.md): Edit one or more existing limit orders on the orderbook. Can modify the size and/or price of options or perpetual futures orders. **Important: Editing creates a new order.** The original order is cancelled and a new order is created with a **new `order_id`** (derived from the new signature). The old `order_id` is discarded. Internally this emits a `CancelOrder` event for the old order followed by a `PostOrder` event for the new order. Clients tracking orders by ID must update their references to the new `order_id` returned in the response. **Authentication:** - **Signature**: Include `signature` and `signature_deadline` fields in each edit request (both required) - One-click sessions are NOT supported for editing orders **Important Constraints:** - All orders being edited must belong to the **same maker** - All orders being edited must be for the **same market** (BTC, ETH, or ARB) - MMP (Market Maker Protection) must **NOT be active** for the maker/market pair - Orders currently being filled (inflight) cannot be edited - **Post-only orders** cannot be edited to a price that would cross the market (rejected with `post only violation`) - **Non-post-only orders** edited to a crossing price will trigger **immediate matching** against resting orders (IOC-style fill). The edited order's `filled_amount` resets to 0 and the new size is used for matching. - **Wash trading**: Edited orders that would cross the maker's own resting orders are rejected with `wash trading violation` - **Self-crossing**: If multiple edits in the same batch would cross each other, they are rejected with `self crossing orders submitted` - Minimum size requirements still apply after editing - Each `order_id` must be unique in the batch (no duplicate order ids) - **Price Increment**: New `price` must be divisible by the minimum price increment for the base asset (see `GET /api/v1/exchange_info` → `orderConstraints.priceIncrements`) - **Size Increment**: New size in `contracts` (canonical for both options and perpetuals; or the legacy `amount` for perpetuals) must meet the per-asset minimum and be a whole multiple of the size increment (see `GET /api/v1/exchange_info` → `orderConstraints.options.sizeIncrements` or `orderConstraints.perpetuals.sizeIncrements`) ### EIP-712 Signature Example (TypeScript) ```typescript import { parseUnits } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; // Domain parameters for EIP-712 signature const EIP712Domain = { chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet) name: 'Premia', verifyingContract: '0x...', // ClearingHouseProxy address from deployment version: '1' }; // Type definition for editing limit orders const UserEditOrder = [ { name: 'deadline', type: 'uint256' }, { name: 'size', type: 'uint256' }, { name: 'price', type: 'uint256' }, { name: 'orderId', type: 'string' } ]; // Example edit request (Options) const optionsEdit = { order_id: 'abc123def456789012345678901234567', contracts: 2.5, // New size price: 1100.0 // New price }; // Example edit request (Perpetuals) const perpsEdit = { order_id: 'abc123def456789012345678901234567', contracts: 0.3, // New size in base contracts price: 46000 // New price }; // Calculate deadline (30 seconds from now) const deadline = Math.floor(Date.now() / 1000) + 30; // Setup wallet const account = privateKeyToAccount('0xYourPrivateKey'); // Choose which edit to use const edit = optionsEdit; // or perpsEdit for perpetuals // Sign the typed data const signature = await account.signTypedData({ domain: EIP712Domain, types: { UserEditOrder }, primaryType: 'UserEditOrder', message: { deadline, size: parseUnits((edit.contracts ?? edit.amount).toString(), 6), price: parseUnits(edit.price.toString(), 6), orderId: edit.order_id } }); // Final request payload const requestPayload = [{ ...edit, signature, signature_deadline: deadline }]; ``` - [Execute market orders](https://docs.kyan.blue/reference/postmarketorder.md): Execute a "marketable limit order" against the orderbook with built-in slippage protection. **Key Features:** - **Slippage Protection**: Requires `limit_price` to prevent execution at unfavorable prices - **Immediate Execution**: Fills immediately against available liquidity (IOC/FOK) - **Multi-Asset**: Supports both options and perpetual futures Unlike traditional market orders, Kyan's market orders won't execute beyond your `limit_price`, protecting you from excessive slippage during volatile conditions. **Important Constraints:** - **Price Increment**: The `limit_price` must be divisible by the minimum price increment for the base asset (see `GET /api/v1/exchange_info` → `orderConstraints.priceIncrements`) - **Size Increment**: Order size in `contracts` (canonical for both options and perpetuals; or the legacy `amount` for perpetuals) must be divisible by the size increment (see `GET /api/v1/exchange_info` → `orderConstraints.options.sizeIncrements` or `orderConstraints.perpetuals.sizeIncrements`) - **Order size**: Both options and perpetual orders use `contracts` (base contracts) as the canonical size field; for perpetuals the legacy `amount` field (USD notional) is still accepted for backward compatibility (supply exactly one of `contracts` or `amount`). **The notional `amount` model is deprecated and will be removed in a future release** — migrate to `contracts` - **Minimum Size**: Order size must meet the per-asset minimum. Perpetual minimum size equals the size increment, in base contracts: BTC `0.0001`, ETH `0.001`, ARB `1` - **Max Slippage**: Order will be rejected if `limit_price` exceeds the maximum allowed slippage from fair value **Authentication Options:** - Signature: Include `signature` and `signature_deadline` fields in the request - One-click session: Include `x-one-click` header with session hash (no signature needed) When using one-click sessions, the signature fields can be omitted from the request. - [Execute combo orders](https://docs.kyan.blue/reference/postcomboorder.md): Execute multiple orders as a combo. Supports options spreads or option+perp combos. Only fill_or_kill (FOK) order type is supported. **Important Constraints:** - **Price Increment (Perp Leg Only)**: If `limit_perp_price` is provided, it must be divisible by the minimum price increment for the base asset (see `GET /api/v1/exchange_info` → `orderConstraints.priceIncrements`). Option legs in combo orders are **not** subject to price increment validation since the net limit price is calculated across multiple legs. - **Size Increment**: Each leg's size is denominated in base `contracts` and must be divisible by the size increment (see `GET /api/v1/exchange_info` → `orderConstraints.options.sizeIncrements` or `orderConstraints.perpetuals.sizeIncrements`) - **Leg limits**: A combo may contain at most **6 option legs** and at most **1 perpetual leg** (maximum **7 legs** total). Exceeding these returns HTTP 400 with `must contain no more than 6 option legs` or `must contain no more than 1 perp leg` - **`limit_perp_price`**: Required (and must be positive) when the combo includes a perpetual leg, and must be omitted when it does not. Violations return HTTP 400 with `must include a positive limit_perp_price when a perp leg is present` or `must not include limit_perp_price when no perp leg is present` - **Minimum Size**: Each leg must meet the per-asset minimum size. Perpetual minimum size equals the size increment, in base contracts: BTC `0.0001`, ETH `0.001`, ARB `1` **Authentication Options:** - Signature: Include `signature` and `signature_deadline` fields in the request - One-click session: Include `x-one-click` header with session hash (no signature needed) When using one-click sessions, the signature fields can be omitted from the request. - [Send heartbeat ping (dead man's switch)](https://docs.kyan.blue/reference/postheartbeat.md): Send a heartbeat ping to keep your orders alive. If no heartbeat is received within the configured `timeout` period, all open orders for the maker are automatically cancelled. This acts as a **dead man's switch** for automated trading systems: if your bot crashes or loses connectivity, your orders are cancelled to prevent stale orders sitting on the book. **How it works:** 1. Call `POST /heartbeat` with your desired `timeout` (in seconds) 2. The server records the heartbeat configuration and last ping time 3. Continue calling periodically (before the timeout expires) 4. If a ping is missed beyond the timeout, all your open orders are cancelled **Authentication Options:** - **Signature**: Include `signature` and `signature_deadline` fields (uses EIP-712 `HeartbeatType`) - **One-click session**: Include `x-one-click` header with session hash (no signature needed) **Replay Protection:** When using signatures, the `signature_deadline` must be **strictly greater** than the last accepted deadline for this maker (deadline monotonicity). This prevents replay attacks without requiring per-call nonce storage. Deadlines are also bounded to at most 30 seconds in the future. - [Submit RFQ request](https://docs.kyan.blue/reference/submitrfqrequest.md): Submit a Request for Quote (RFQ) to solicit pricing for larger trades or custom orders. RFQs allow traders to request specific pricing without displaying their trading intentions to the entire market. This is particularly useful for size-sensitive orders or complex strategies. **Important: RFQ orders must be either a basket of options OR a single perpetual contract. You cannot mix options and perpetuals in the same RFQ request.** **Rate Limits:** - 10 requests per second per owner (regular tier) - 50 requests per second per owner (market maker tier, 5x) - 1-second fixed window, resets every second - Exceeding the limit returns HTTP 429 with "too many requests, try again later" **Minimum Size Requirements:** RFQ legs use the same per-asset minimum order sizes as regular limit and market orders. The minimum equals the size increment and is denominated in base contracts. **Options (base contracts):** - BTC options: Minimum 0.01 contracts per order - ETH options: Minimum 0.1 contracts per order - ARB options: Minimum 100 contracts per order **Perpetuals (base contracts):** - BTC perpetuals: Minimum 0.0001 contracts per order - ETH perpetuals: Minimum 0.001 contracts per order - ARB perpetuals: Minimum 1 contract per order Every leg must meet the minimum size for its instrument and be a whole multiple of it. Perpetual RFQ legs must specify size via `contracts`; the legacy notional `amount` field is not accepted on RFQ. Violating the minimum returns HTTP 400 (`MIN_SIZE_VIOLATION`). - [Get RFQ requests](https://docs.kyan.blue/reference/getrfqrequests.md): Retrieve all active Request for Quote (RFQ) requests for a specific address. This allows you to track the status of your outstanding RFQ requests and see which ones are still pending responses from liquidity providers. - [Submit RFQ response](https://docs.kyan.blue/reference/submitrfqresponse.md): Submit a response to a Request for Quote (RFQ) with your pricing. Makers use this endpoint to provide pricing for RFQ requests they've received. The response structure uses a nested array format where each order is represented as a pair of elements. **Response Structure:** The `fills` array structure mirrors the RFQ request structure with two categories: - **Basket of options response pairs only**: Up to 6 option response pairs - **Single perpetual response pair only**: Exactly 1 perpetual response pair Each response pair consists of: 1. **First element**: A copy of the original RFQ request parameters (instrument_name, contracts, direction) 2. **Second element**: The complete signed order with pricing and all execution details **Critical Requirements (MUST follow to avoid errors):** - **Order type MUST be `good_til_cancelled` (GTC)** - Using `good_til_date` (GTD) will cause validation errors - **`post_only` MUST be `true`** - Setting to `false` will cause validation errors for RFQ responses **Important Validation Rules:** - All orders from the original RFQ request must be included in the response - For each pair, the parameters in the first element must match those in the second element: - `instrument_name` must be identical - `direction` must be OPPOSITE (if request is "buy", response must be "sell" and vice versa) - `contracts` must be identical (perpetual RFQ legs use `contracts`, not the legacy `amount`) - The `taker` address must match across all locations (root level and in signed orders) - The `maker` address must be consistent across all signed orders - All signatures must be valid EIP-712 signatures and not expired **Key Fields in Signed Orders (second element of each pair):** - `price`: Your quoted price for this order - `type`: **MUST be "good_til_cancelled"** (GTD not supported for RFQ) - `post_only`: **MUST be true** (false will cause errors) - `signature`: Valid EIP-712 signature for the order - `signature_deadline`: Unix timestamp when the signature expires - `taker` and `maker`: Must match the root-level addresses **Note:** RFQ responses can be cancelled using the DELETE /orders endpoint with the order_id from this response. - [Get RFQ responses](https://docs.kyan.blue/reference/getrfqresponses.md): Get all active RFQ responses for a specific taker - [Fill RFQ](https://docs.kyan.blue/reference/fillrfq.md): Execute a trade based on an RFQ response - [Cancel RFQ request](https://docs.kyan.blue/reference/cancelrfqrequest.md): Cancel an open Request for Quote (RFQ) request that you previously submitted. Only the original taker can cancel their own request. Standard requests must include an EIP-712 `signature` over the `CancelRFQRequestType` type together with a `signature_deadline`. One-click trading sessions authenticate via the `x-one-click` header instead of a signature. - [Deposit USDC collateral into a margin account](https://docs.kyan.blue/reference/deposit.md): Deposit USDC funds into a specific margin account to use as collateral for trading. Each trading pair has its own isolated margin account, so you must specify which pair's account to fund. ### Prerequisites Before depositing, ensure: 1. **USDC Balance**: Your wallet has sufficient USDC tokens 2. **Token Approval**: You've approved the ClearingHouse contract to spend your USDC 3. **Smart Account**: Your smart account is deployed (happens automatically on first deposit) ### How Deposits Work 1. **You sign** an EIP-712 message authorizing the deposit 2. **System validates** your signature and checks your USDC balance 3. **Protocol executes** the on-chain transfer from your wallet 4. **Funds appear** in your margin account, ready for trading ### Security Features - **Signature Required**: Only you can authorize deposits from your wallet - **Deadline Protection**: Signatures expire after the specified deadline - **Amount Validation**: System verifies you have sufficient USDC balance - **Atomic Execution**: Deposits either complete fully or fail entirely ### Common Issues and Solutions - **"Insufficient allowance"**: Approve the ClearingHouse contract for USDC spending - **"Signature expired"**: Ensure deadline is at least 30 seconds in the future - **"Pair not found"**: Check that you're using valid base/quote token addresses - **"Invalid signature"**: Verify you're signing with the correct wallet and chain ID ### EIP-712 Signature Example (TypeScript) ```typescript import { parseUnits } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; // Domain parameters for EIP-712 signature const EIP712Domain = { chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet) name: 'Premia', verifyingContract: '0x...' // ClearingHouseProxy address from deployment version: '1' }; // Type definitions const Pair = [ { name: 'base', type: 'address' }, { name: 'quote', type: 'address' } ]; const UserDeposit = [ { name: 'deadline', type: 'uint256' }, { name: 'to', type: 'address' }, { name: 'from', type: 'address' }, { name: 'amount', type: 'uint256' }, { name: 'pair', type: 'Pair' } ]; // Example deposit data const deposit = { to: '0xYourSmartAccount', // Smart account address from: '0xYourWalletAddress', // EOA wallet address amount: 1000, // Amount to deposit pair: { base: '0xBaseTokenAddress', // e.g., WETH address quote: '0xQuoteTokenAddress' // e.g., USDC address } }; // Calculate deadline (30 seconds from now) const deadline = Math.floor(Date.now() / 1000) + 30; // Setup wallet const account = privateKeyToAccount('0xYourPrivateKey'); // Sign the typed data const signature = await account.signTypedData({ domain: EIP712Domain, types: { UserDeposit, Pair }, primaryType: 'UserDeposit', message: { deadline, to: deposit.to, from: deposit.from, amount: parseUnits(deposit.amount.toString(), 6), pair: deposit.pair } }); // Final request payload const requestPayload = { ...deposit, signature, signature_deadline: deadline }; ``` - [Withdraw USDC from a margin account to your wallet](https://docs.kyan.blue/reference/withdraw.md): Withdraw USDC funds from a specific margin account back to your wallet. The system performs comprehensive risk checks to ensure your account remains healthy after the withdrawal. ### Risk Checks and Requirements Before approving a withdrawal, the system verifies: 1. **Sufficient Equity**: Your remaining equity must exceed both: - **Initial Margin (IM)**: Required for opening new positions - **Maintenance Margin (MM)**: Minimum to avoid liquidation 2. **Account Status**: - Account must not be flagged for liquidation - No pending settlements that would affect equity 3. **Available Balance**: - Can only withdraw truly "free" collateral - System accounts for unrealized losses on open positions ### How Withdrawals Work 1. **You sign** an EIP-712 message requesting the withdrawal 2. **Risk engine checks** your account will remain solvent 3. **System approves** and executes the on-chain transfer 4. **USDC arrives** in your specified wallet address ### Important Considerations - **Isolated Margins**: Each trading pair has separate collateral - **Mark-to-Market**: Unrealized P&L affects available withdrawal amount - **Gas Costs**: On-chain withdrawal incurs network fees (paid by protocol) - **Processing Time**: Usually instant, but may take a few blocks ### Common Rejection Reasons - **"Insufficient equity - mm"**: Withdrawal would put account below maintenance margin - **"Insufficient equity - im"**: Withdrawal would put account below initial margin - **"Account in liquidation"**: Account is already flagged for liquidation - **"Margin account not found"**: No active account for the specified pair ### Best Practices 1. Check account state before withdrawing to see available balance 2. Leave buffer above minimum margins to avoid liquidation 3. Consider market volatility - your equity can change rapidly 4. Withdraw from accounts with no open positions first ### EIP-712 Signature Example (TypeScript) ```typescript import { parseUnits } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; // Domain parameters for EIP-712 signature const EIP712Domain = { chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet) name: 'Premia', verifyingContract: '0x...' // ClearingHouseProxy address from deployment version: '1' }; // Type definitions const Pair = [ { name: 'base', type: 'address' }, { name: 'quote', type: 'address' } ]; const UserWithdraw = [ { name: 'deadline', type: 'uint256' }, { name: 'to', type: 'address' }, { name: 'from', type: 'address' }, { name: 'amount', type: 'uint256' }, { name: 'pair', type: 'Pair' } ]; // Example withdrawal data const withdraw = { to: '0xYourWalletAddress', // Destination EOA wallet address from: '0xYourSmartAccount', // Smart account address amount: 500, // Amount to withdraw pair: { base: '0xBaseTokenAddress', // e.g., WETH address quote: '0xQuoteTokenAddress' // e.g., USDC address } }; // Calculate deadline (30 seconds from now) const deadline = Math.floor(Date.now() / 1000) + 30; // Setup wallet const account = privateKeyToAccount('0xYourPrivateKey'); // Sign the typed data const signature = await account.signTypedData({ domain: EIP712Domain, types: { UserWithdraw, Pair }, primaryType: 'UserWithdraw', message: { deadline, to: withdraw.to, from: withdraw.from, amount: parseUnits(withdraw.amount.toString(), 6), pair: withdraw.pair } }); // Final request payload const requestPayload = { ...withdraw, signature, signature_deadline: deadline }; ``` - [Transfer collateral between your margin accounts](https://docs.kyan.blue/reference/posttransfer.md): Transfer USDC collateral between your different margin accounts (e.g., from ETH_USDC to BTC_USDC account). This allows you to rebalance collateral without withdrawing to your wallet and re-depositing. **Requires signature:** Include `signature` and `signature_deadline` fields in the request. ### When to Use Transfers 1. **Rebalancing Collateral**: Move excess funds from one pair to another 2. **Risk Management**: Shift collateral to accounts needing more margin 3. **Efficient Capital Use**: Avoid on-chain transactions when moving between accounts 4. **Quick Position Changes**: Prepare collateral before opening positions in new pairs ### How Transfers Work - **Instant Execution**: No on-chain transaction required - **Atomic Operation**: Transfer completes fully or not at all - **Risk Validation**: Source account must maintain required margins after transfer - **Zero Fees**: Internal transfers don't incur blockchain gas costs ### Transfer Requirements The source account must maintain after the transfer: - Equity > Initial Margin (for new position capability) - Equity > Maintenance Margin (to avoid liquidation) - Account must not be in liquidation status ### Example Scenarios **Scenario 1: Free up capital** - You closed all ETH positions but have 10,000 USDC locked in ETH_USDC account - Transfer the full amount to BTC_USDC account for Bitcoin trading **Scenario 2: Emergency margin top-up** - Your BTC_USDC account is approaching liquidation - Quickly transfer funds from ETH_USDC to increase BTC margin **Scenario 3: Portfolio rebalancing** - Market conditions change, you want more ETH exposure - Transfer collateral from multiple accounts into ETH_USDC ### Best Practices 1. Always check source account state before transferring 2. Leave safety buffer in accounts with open positions 3. Consider pending orders that might require margin 4. Use transfers instead of withdraw/deposit for efficiency ### EIP-712 Signature Example (TypeScript) ```typescript import { parseUnits } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; // Domain parameters for EIP-712 signature const EIP712Domain = { chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet) name: 'Premia', verifyingContract: '0x...' // ClearingHouseProxy address from deployment version: '1' }; // Type definition for transfers const UserTransfer = [ { name: 'deadline', type: 'uint256' }, { name: 'account', type: 'address' }, { name: 'fromPair', type: 'Pair' }, { name: 'toPair', type: 'Pair' }, { name: 'amount', type: 'uint256' } ]; const Pair = [ { name: 'base', type: 'address' }, { name: 'quote', type: 'address' } ]; // Example transfer data const transfer = { account: '0xYourAddress', amount: '1000.0', // Amount in USDC from_pair: { base: '0x...', // ETH token address quote: '0x...' // USDC token address }, to_pair: { base: '0x...', // BTC token address quote: '0x...' // USDC token address } }; // Calculate deadline (30 seconds from now) const deadline = Math.floor(Date.now() / 1000) + 30; // Setup wallet const account = privateKeyToAccount('0xYourPrivateKey'); // Sign the typed data const signature = await account.signTypedData({ domain: EIP712Domain, types: { UserTransfer, Pair }, primaryType: 'UserTransfer', message: { deadline, account: transfer.account, fromPair: transfer.from_pair, toPair: transfer.to_pair, amount: parseUnits(transfer.amount, 6) } }); // Final request payload const requestPayload = { ...transfer, signature, signature_deadline: deadline }; ``` - [Get comprehensive account state across all margin accounts](https://docs.kyan.blue/reference/getaccountstate.md): Retrieve the complete financial state for all margin accounts associated with an Ethereum address. This endpoint is essential for monitoring account health, risk management, and trading decisions. **No signature required** - Only API key authentication is needed. ### What This Endpoint Returns For each margin account (one per trading pair), you'll receive: **Account Health Metrics:** - `equity`: Total account value (collateral + unrealized P&L) - `im`: Initial margin - minimum equity required to open new positions - `mm`: Maintenance margin - minimum equity required to avoid liquidation - `unrealised_pnl`: Profit/loss on open positions at current mark prices **Position Details:** - All open positions with sizes, entry prices, and fees - Current mark prices and Greeks for options - Instrument-specific P&L calculations **Risk Indicators:** - `matrix_risk`: Portfolio risk matrix component - `delta_risk`: Delta risk component - `roll_risk`: Roll risk component - `portfolio_greeks`: Portfolio-level Greeks (delta, gamma, vega, theta, rho) **Additional Fields:** - `timestamp`: Unix timestamp when state was calculated - `margin_account`: Unique margin account ID - `pair`: Trading pair for this margin account ### Use Cases 1. **Risk Monitoring**: Check if accounts are approaching liquidation 2. **Portfolio Management**: View all positions and their current values 3. **Trading Decisions**: Monitor risk metrics and margin requirements 4. **P&L Tracking**: Monitor realized and unrealized profits/losses ### Important Notes - Accounts are isolated by trading pair (e.g., separate ETH_USDC and BTC_USDC accounts) - All monetary values are in USDC with 6 decimal precision - Mark prices are updated in real-time from the orderbook - Greeks are calculated using the Black-Scholes model for options - [Get account history (Beta)](https://docs.kyan.blue/reference/getaccounthistoryv2.md): Retrieves the trading history and account events for a specified smart account address. This includes trades, transfers (deposits/withdrawals), settlements, and funding events with standardized event structures, advanced filtering, and cursor-based pagination for efficient retrieval. **This endpoint is currently in Beta** and has not been fully validated in production yet. **Features:** - **Cursor-based pagination**: Efficient retrieval of large datasets with `cursor` and `next_cursor` - **Advanced filtering**: Filter by event types, actions, markets, and transfer types - **Sorting**: Sort results by timestamp or realized P&L (ascending or descending) - **Standardized events**: Consistent event structure across all event types with typed `data` field **Available Event Types:** - `trade`: Trade execution events (buy/sell) - `transfer`: Deposit and withdrawal events - `settlement`: Option settlement events - `funding`: Funding rate payment events **Available Actions (for filtering):** - Trade actions: `buy`, `sell` - Transfer actions: `deposit`, `withdrawal` - Settlement actions: `settlement` - Funding actions: `funding` - [Get all margin accounts with positions for an address](https://docs.kyan.blue/reference/getpositions.md): Retrieve all margin accounts with their positions for a specific address. This endpoint returns complete margin account data including deposits, withdrawals, P&L tracking, and all open positions. **No signature required** - Only API key authentication is needed. ### Margin Account Information Returned For each margin account, you'll receive: - `id`: Unique margin account identifier - `pair_id`: Reference to the trading pair - `deposits`: Total deposits made to this account - `withdrawals`: Total withdrawals from this account - `realised_pnl`: Cumulative realized profit/loss - `accrued_funding`: Accumulated funding payments - `liquidation`: Whether the account has been liquidated - `smart_account_address`: Associated smart contract address - `positions`: Array of open positions with: - `id`: Position identifier - `instrument`: The specific option or perpetual contract - `instrument_type`: Type of instrument (option/perp) - `size`: Position size — USD notional (average price × contracts) for perpetuals, number of contracts for options (negative for short, positive for long) - `contracts`: Canonical position size in base contracts (for options equals `size`) - `average_price`: Volume-weighted average entry price - `entry_fees`: Total fees paid when opening the position ### Key Features - **Complete Account Data**: Full margin account information including financial metrics - **Consolidated View**: See all accounts and positions across different trading pairs - **Real-time Data**: Data reflects the latest trades, deposits, and settlements - **Comprehensive Tracking**: Deposits, withdrawals, P&L, and fees all tracked separately ### Example Use Cases 1. **Position Monitoring**: Quick overview of all open trades 2. **Risk Assessment**: Identify concentrated positions or exposures 3. **Trade Planning**: Check existing positions before placing new orders 4. **Fee Analysis**: Calculate total fees paid across all positions ### Understanding Position Sizes - **Positive size**: Long position (bought the instrument) - **Negative size**: Short position (sold the instrument) - **Options**: `size` represents the number of contracts (equal to `contracts`) - **Perpetuals**: `size` represents the USD notional (average price × `contracts`); `contracts` is the canonical base-contract size - [Calculate risk metrics for hypothetical portfolios](https://docs.kyan.blue/reference/calculateuserrisk.md): Calculate comprehensive risk metrics for one or more portfolios without requiring actual positions. This endpoint is ideal for "what-if" scenarios, risk analysis before trading, and portfolio planning. ### Risk Metrics Calculated For each portfolio, the system calculates: **Margin Requirements:** - `initial_margin`: Capital required to open these positions - `maintenance_margin`: Minimum capital to avoid liquidation **Risk Components:** - `matrix_risk`: Worst-case loss under various market scenarios - `delta_risk`: Additional margin for systemic market moves - `roll_risk`: Extra margin required near option expiration **Portfolio Greeks:** - `delta`: Rate of change with underlying price - `gamma`: Rate of change of delta - `vega`: Sensitivity to volatility changes - `theta`: Time decay per day - `rho`: Interest rate sensitivity ### Key Features - **No Account Required**: Analyze risk without having positions - **Multiple Portfolios**: Process multiple trading pairs in one request - **Hypothetical Analysis**: Test strategies before executing trades - **Individual Results**: Each portfolio succeeds/fails independently ### Use Cases 1. **Pre-Trade Analysis**: Check margin requirements before placing orders 2. **Strategy Testing**: Evaluate risk of complex option strategies 3. **Portfolio Planning**: Compare risk across different position combinations 4. **Education**: Learn how different positions affect portfolio risk ### Important Notes - This endpoint does NOT calculate equity or P&L - Risk calculations use current market prices (mark prices) only - Each portfolio in the array is processed independently - Failed portfolios return error details without affecting others - All monetary values are in USDC with 6 decimal precision - Designed for hypothetical analysis based on current market conditions - [Get account history](https://docs.kyan.blue/reference/getaccounthistory.md): Retrieves the trading history and account events for a specified smart account address. Returns a flat array of all events (trades, deposits, withdrawals, settlements, and funding payments) sorted by timestamp in ascending order. Each event has an `action` field indicating its type. For advanced filtering, cursor-based pagination, and sorting options, use the `GET /v2/account_history` endpoint instead. - [Export account history as CSV (Beta)](https://docs.kyan.blue/reference/exportaccounthistoryv2.md): Exports the trading history and account events for a specified smart account address as a CSV file, using the same filters as `GET /v2/account_history`. **This endpoint is currently in Beta** and has not been fully validated in production yet. The response is a downloadable CSV (`Content-Type: text/csv; charset=utf-8`) with a leading UTF-8 byte-order mark (BOM) for spreadsheet compatibility, and a `Content-Disposition: attachment` header. Each event is rendered as one wide row across all event types (trade, transfer, settlement, funding). **Pagination is not supported.** Unlike `GET /v2/account_history`, the export streams the full matching result set in a single response. Supplying any of `cursor`, `offset`, or `limit` (even with an empty value) returns HTTP 400. **Row cap:** the export returns up to a server-configured maximum number of rows (see the `X-Export-Max-Rows` response header). When the result set exceeds the cap, the response is truncated and `X-Export-Truncated` is set to `true`. **Response headers:** - `Content-Disposition`: `attachment` with a generated filename, e.g. `account-history-0x24a90351-20240101-all.csv` (address is truncated to a short lowercased prefix; an omitted start/end bound renders as `all`). - `X-Export-Row-Count`: number of data rows written. - `X-Export-Truncated`: `true` when the result set was clipped to the row cap, otherwise `false`. - `X-Export-Max-Rows`: the maximum number of rows the export will return. - [Get MMP configuration](https://docs.kyan.blue/reference/getmmpconfig.md): Retrieve the current Market Maker Protection (MMP) configuration for a smart account and trading pair. MMP is a risk management feature that helps market makers protect themselves from adverse market conditions by automatically freezing their trading activity when specified risk limits are exceeded. - [Set MMP configuration](https://docs.kyan.blue/reference/setmmpconfig.md): Configure or update Market Maker Protection (MMP) settings for a smart account and trading pair. ## How MMP Works MMP is a **per-order opt-in** risk management feature. When placing limit orders, each order includes a required `mmp` boolean field. Setting `mmp: true` on an order opts it into MMP protection for that specific order. Orders with `mmp: false` are completely unaffected by MMP at all times. **Lifecycle:** 1. **Configure** MMP with risk limits via this endpoint (per trading pair) 2. **Place orders** with `mmp: true` to opt them into MMP protection 3. **Only trades from `mmp: true` orders** count toward MMP threshold calculations 4. **When a threshold is breached**, only open orders with `mmp: true` are automatically cancelled 5. **Account is frozen** for `frozen_time` seconds — during which new orders with `mmp: true` are rejected (orders with `mmp: false` can still be placed) 6. **After freeze expires**, MMP counters reset and normal trading resumes 7. If `frozen_time` is 0, the freeze is **indefinite** — reset by re-submitting the MMP config with status "active" (this resets counters and clears the freeze) **Order Editing:** Orders with `mmp: true` can be edited normally while MMP is active and not frozen. If MMP is frozen, edits to `mmp: true` orders are rejected — the order retains its `mmp: true` status and would be rejected at the sequencer regardless. Orders with `mmp: false` can always be edited. **Deactivation:** When MMP is deactivated (status set to `inactive`), all open orders with `mmp: true` for the specified pair are automatically cancelled. The response includes the list of cancelled order IDs. This cancellation is best-effort — if it fails, the config is still deactivated but orders may remain open. ## Risk Limits - **Quantity Limit**: Total option contracts traded within the interval — cumulative absolute value, not net (Options only) - **Delta Limit**: Maximum absolute net delta exposure (Perpetuals and Options) - **Vega Limit**: Maximum absolute net vega exposure (Options only) ## Important Notes - At least one limit must be set when status is "active" - Setting status to "inactive" will delete the MMP configuration and cancel all open `mmp: true` orders for that pair - When MMP is triggered, only open orders with `mmp: true` are automatically cancelled — orders with `mmp: false` are not affected - Trading for `mmp: true` orders is frozen for the specified `frozen_time` duration ## EIP-712 Signature The request requires an EIP-712 signature with the following structure: ```typescript const MMPConfigType = [ { name: 'smartAccountAddress', type: 'address' }, { name: 'pairSymbol', type: 'string' }, { name: 'status', type: 'string' }, { name: 'interval', type: 'uint256' }, { name: 'frozenTime', type: 'uint256' }, { name: 'deadline', type: 'uint256' } ]; ``` **Note:** The risk limit fields (`quantity_limit`, `delta_limit`, `vega_limit`) are included in the request body but are **not** part of the signed EIP-712 message. Only the 6 fields above are signed. ## Recipes - [Simple Limit Order Life Cycle](https://docs.kyan.blue/recipes/simple-limit-order-life-cycle.md) ## Pages - [Order ID vs Trade ID](https://docs.kyan.blue/page/order-id-vs-trade-id.md) ## Changelog - [v1.19.0 - 2026-05-30](https://docs.kyan.blue/changelog/changelog-1-19-0.md) - [v1.18.0 - 2026-03-15](https://docs.kyan.blue/changelog/changelog-1-18-0.md) - [v1.17.1 - 2026-03-10](https://docs.kyan.blue/changelog/changelog-1-17-1.md) - [v1.17.0 - 2026-03-06](https://docs.kyan.blue/changelog/changelog-1-17-0.md) - [v1.9.0 - 2025-09-29](https://docs.kyan.blue/changelog/changelog-1-9-0.md) - [v1.8.1 - 2025-09-02](https://docs.kyan.blue/changelog/changelog-1-8-1.md) - [v1.8.0 - 2025-08-30](https://docs.kyan.blue/changelog/changelog-1-8-0.md) - [v1.7.0 - 2025-08-27](https://docs.kyan.blue/changelog/changelog-1-7-0.md) - [v1.6.1 - 2025-08-27](https://docs.kyan.blue/changelog/changelog-1-6-1.md) - [v1.6.0 - 2025-08-20](https://docs.kyan.blue/changelog/changelog-1-6-0.md)