{"openapi":"3.1.0","info":{"title":"Ostium Builder Service API","description":"Transaction builder service for Ostium perpetual futures trading platform.\n\nThis service accepts trading requests and returns unsigned transactions\nthat can be signed and submitted to the Ostium smart contracts.\n\n## Authentication\nThe trader's address must be provided via the `X-Trader-Address` header.\nFor delegated (gasless) mode, include `X-API-Key`.\n\n## Request Tracking\nAll requests are assigned a unique `X-Request-ID` header for tracing.\n\n## Rate Limiting\n- **Limit**: 100 requests per minute per IP\n- Response headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`\n","version":"1.0.0","contact":{"name":"Ostium","url":"https://ostium.com"}},"servers":[{"url":"https://builder.ostiscan.xyz","description":"Production server"}],"tags":[{"name":"Trading","description":"Trading operations"},{"name":"Health","description":"Service health checks"},{"name":"Agent","description":"Agent wallet management"},{"name":"Market","description":"Live market data streaming"},{"name":"Balance","description":"Balance lookups"},{"name":"OpenAPI","description":"OpenAPI specification endpoints"}],"paths":{"/v1/health":{"get":{"tags":["Health"],"summary":"Global health check","operationId":"getHealth","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceHealthResponse"}}}}}}},"/v1/exchange/health":{"get":{"tags":["Health"],"summary":"Exchange endpoint health check","operationId":"getExchangeHealth","responses":{"200":{"description":"Exchange endpoint is healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeHealthResponse"}}}}}}},"/openapi":{"get":{"tags":["OpenAPI"],"summary":"OpenAPI spec (JSON)","operationId":"getOpenApi","responses":{"200":{"description":"OpenAPI specification in JSON","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/openapi.json":{"get":{"tags":["OpenAPI"],"summary":"OpenAPI spec (JSON)","operationId":"getOpenApiJson","responses":{"200":{"description":"OpenAPI specification in JSON","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/openapi.yaml":{"get":{"tags":["OpenAPI"],"summary":"OpenAPI spec (YAML)","operationId":"getOpenApiYaml","responses":{"200":{"description":"OpenAPI specification in YAML","content":{"text/yaml":{"schema":{"type":"string"}}}}}}},"/v1/exchange/open":{"post":{"tags":["Trading"],"summary":"Open new positions","description":"Builds unsigned transactions to open new trading positions.\n\n**Open Types:**\n- `market`: Execute immediately at current market price (uses slippage tolerance)\n- `limit`: Execute when price reaches specified level\n- `stop`: Trigger market order when price crosses threshold\n\n**Features:**\n- One open action per request\n- Supports take-profit (TP) and stop-loss (SL) levels\n- Leverage up to 100x\n- Optional builder fees for integrators\n","operationId":"open","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKey"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenRequest"},"example":{"open":{"a":0,"b":true,"t":"market","p":"42500.00","s":"100","l":"10","tp":"45000.00","sl":"40000.00"},"bd":{"b":"0x742d35Cc6634C0532925a3b844Bc9e7595f5bE21","f":0.1},"sp":0.25}}}},"responses":{"200":{"$ref":"#/components/responses/TransactionResponse"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/exchange/ws":{"get":{"tags":["Trading"],"summary":"Trade actions over WebSocket","description":"WebSocket endpoint for low-latency trade actions.\nClients send JSON envelopes with action, headers, and payload.\n","operationId":"exchangeWebSocket","responses":{"101":{"description":"Switching Protocols (WebSocket upgrade)"},"426":{"description":"WebSocket upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/exchange/close":{"post":{"tags":["Trading"],"summary":"Close positions","description":"Builds unsigned transactions to close existing open positions.\n\n**Features:**\n- Partial closes supported (1-100% via `r` field)\n- Uses market execution with slippage tolerance\n- Requires current market price for slippage calculation\n- Returns multiple transactions for direct submission when multiple closes provided\n","operationId":"close","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKey"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloseRequest"},"example":{"closes":[{"a":0,"t":0,"p":"43000.00","r":100}],"sp":0.25}}}},"responses":{"200":{"$ref":"#/components/responses/TransactionResponse"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/exchange/cancel":{"post":{"tags":["Trading"],"summary":"Cancel orders","description":"Builds unsigned transactions to cancel pending or stuck orders.\n\n**Cancel Types:**\n- `limit`: Cancel a pending limit order (requires `a` + `i`)\n- `close`: Cancel a close market order stuck in timeout (requires `o`)\n- `open`: Cancel an open market order stuck in timeout (requires `o`)\n\nUse timeout cancels when oracle price updates fail to execute your market orders.\nReturns multiple transactions for direct submission when multiple cancels provided.\n","operationId":"cancel","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKey"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRequest"},"examples":{"cancelLimit":{"summary":"Cancel a limit order","value":{"cancels":[{"t":"limit","a":0,"i":1}]}},"cancelOpenTimeout":{"summary":"Cancel stuck open market order","value":{"cancels":[{"t":"open","o":12345}]}},"cancelCloseTimeout":{"summary":"Cancel stuck close market order","value":{"cancels":[{"t":"close","o":12346}]}}}}}},"responses":{"200":{"$ref":"#/components/responses/TransactionResponse"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/exchange/modify":{"post":{"tags":["Trading"],"summary":"Modify orders or positions","description":"Builds unsigned transaction to modify limit orders or update TP/SL on open trades.\n\n**Two modes based on whether `p` is provided:**\n\n**With `p`** - Update Limit Order:\n- `a`: pair index, `i`: limit order index\n- Changes the limit order's trigger price\n- Can also update TP/SL levels on the limit order\n\n**Without `p`** - Update Open Trade TP/SL:\n- `a`: pair index, `i`: trade index\n- Updates take-profit OR stop-loss on an existing open position\n- Only one of `tp` or `sl` can be updated per call\n\n**Default Values:**\nSetting TP/SL to \"0\" resets to on-chain defaults (TP = openPrice + 900%, SL = liquidation price)\n","operationId":"modify","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKey"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyRequest"},"examples":{"updateLimitOrder":{"summary":"Update limit order (with price)","value":{"a":0,"i":1,"p":"41000.00","tp":"46000.00","sl":"38000.00"}},"updateTp":{"summary":"Update TP on open trade (no price)","value":{"a":0,"i":0,"tp":"46000.00"}},"updateSl":{"summary":"Update SL on open trade (no price)","value":{"a":0,"i":0,"sl":"38000.00"}}}}}},"responses":{"200":{"$ref":"#/components/responses/TransactionResponse"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/exchange/margin":{"post":{"tags":["Trading"],"summary":"Update position margin","description":"Builds unsigned transaction to adjust collateral on an open position.\n\n- `a`: pair index, `i`: trade index\n\n**Amount Behavior:**\n- **Positive**: Add collateral (reduces liquidation risk, lowers effective leverage)\n- **Negative**: Remove collateral (increases liquidation risk, raises effective leverage)\n","operationId":"updateMargin","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKey"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarginRequest"},"example":{"a":0,"i":0,"amount":"50.00"}}}},"responses":{"200":{"$ref":"#/components/responses/TransactionResponse"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/auth/create":{"post":{"tags":["Auth"],"summary":"Create API key and setup transactions","description":"Creates an API key and agent wallet, then returns unsigned\n`setDelegate` and optional USDC `approve` transactions.\n","operationId":"authCreate","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Auth create response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/auth/verify-auth":{"post":{"tags":["Auth"],"summary":"Verify delegation and approval","description":"Verifies the delegation relationship and USDC allowance\nfor the agent wallet. Requires `X-API-Key`.\n","operationId":"authVerify","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKeyRequired"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentVerifyResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/auth/cancel":{"post":{"tags":["Auth"],"summary":"Get cancel message","description":"Returns a message that the trader must sign to cancel\nan unverified agent wallet.\n","operationId":"authCancel","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Cancel message response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentActionMessageResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/auth/verify-cancel":{"post":{"tags":["Auth"],"summary":"Verify cancel signature","description":"Verifies a signed cancel message and deletes the unverified agent wallet.\n","operationId":"authVerifyCancel","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthVerifyMessageRequest"}}}},"responses":{"200":{"description":"Cancel verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentVerifyModeResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/auth/revoke":{"post":{"tags":["Auth"],"summary":"Get revoke transaction + message","description":"Returns an unsigned remove-delegate transaction and a message\nthat must be signed to finalize revoke verification.\n","operationId":"authRevoke","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Revoke transaction response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRevokeBundleResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/auth/verify-revoke":{"post":{"tags":["Auth"],"summary":"Verify revoke and delete agent wallet","description":"Verifies delegation removal and USDC allowance revocation,\nthen deletes the agent wallet record.\n","operationId":"authVerifyRevoke","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthVerifyMessageRequest"}}}},"responses":{"200":{"description":"Revoke verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentVerifyRevokeResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/agent":{"post":{"deprecated":true,"tags":["Agent"],"summary":"Create agent wallet","description":"Deprecated. Use `POST /v1/auth/create`.\nCreates an agent wallet and returns an unsigned `setDelegate` transaction.\nA USDC `approve` transaction is returned only when `usdcApprovalRequired` is true.\n","operationId":"createAgent","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Agent created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/agent/verify":{"post":{"deprecated":true,"tags":["Agent"],"summary":"Verify delegation and approval","description":"Deprecated. Use `POST /v1/auth/verify-auth`,\n`POST /v1/auth/verify-cancel`, or `POST /v1/auth/verify-revoke`.\nVerifies the delegation relationship and USDC allowance\nfor the agent wallet. Requires `X-API-Key`.\nIf a `mode` payload is provided, verifies cancel/reset signatures instead.\n","operationId":"verifyAgent","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKey"},{"$ref":"#/components/parameters/RequestId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentVerifyModeRequest"}}}},"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AgentVerifyResponse"},{"$ref":"#/components/schemas/AgentVerifyModeResponse"}]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/agent/revoke":{"post":{"deprecated":true,"tags":["Agent"],"summary":"Revoke agent wallet","description":"Deprecated. Use `POST /v1/auth/revoke` + `POST /v1/auth/verify-revoke`.\nRevokes server access to the agent wallet and returns\nan unsigned `removeDelegate` transaction.\n","operationId":"revokeAgent","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/ApiKeyRequired"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Agent revoked successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRevokeResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"429":{"$ref":"#/components/responses/RateLimitError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/agent/pending":{"get":{"deprecated":true,"tags":["Agent"],"summary":"Pending agent details","description":"Deprecated. Use `POST /v1/auth/cancel` for cancel messages.","operationId":"agentPending","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Pending agent response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPendingResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/agent/public":{"get":{"deprecated":true,"tags":["Agent"],"summary":"Agent wallet public address","description":"Deprecated. Legacy public lookup.","operationId":"agentPublic","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Agent public address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPublicResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/agent/remove":{"post":{"deprecated":true,"tags":["Agent"],"summary":"Remove delegation transaction","description":"Deprecated. Use `POST /v1/auth/revoke`.","operationId":"agentRemove","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Remove delegate transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRemoveResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/market/stream":{"get":{"tags":["Market"],"summary":"Live market WebSocket stream","description":"WebSocket endpoint that streams live market ticks as raw JSON.\nClients should connect via ws/wss.\n","operationId":"marketStream","responses":{"101":{"description":"Switching Protocols (WebSocket upgrade)"},"426":{"description":"WebSocket upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/balance/usdc":{"get":{"tags":["Balance"],"summary":"USDC balance","description":"Returns the trader's USDC balance.","operationId":"usdcBalance","parameters":[{"$ref":"#/components/parameters/TraderAddress"},{"$ref":"#/components/parameters/TraderAddressQuery"},{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"USDC balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"parameters":{"TraderAddress":{"name":"X-Trader-Address","in":"header","required":false,"description":"Ethereum address of the trader (0x prefixed). Provide either this header or the `address` query param.","schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f5bE21"}},"TraderAddressQuery":{"name":"address","in":"query","required":false,"description":"Trader address as query parameter (HTTP only). Provide either this or `X-Trader-Address` (header preferred).","schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f5bE21"}},"RequestId":{"name":"X-Request-ID","in":"header","required":false,"description":"Optional request ID for tracing (auto-generated if not provided)","schema":{"type":"string","format":"uuid"}},"ApiKey":{"name":"X-API-Key","in":"header","required":false,"description":"API key for delegated (sponsored) mode","schema":{"type":"string"}},"ApiKeyRequired":{"name":"X-API-Key","in":"header","required":true,"description":"API key required for auth verification and legacy agent endpoints","schema":{"type":"string"}}},"schemas":{"AgentCreateResponse":{"type":"object","required":["apiKey","smartAccountAddress","delegateApprovalTx","usdcApprovalRequired","chainId"],"properties":{"apiKey":{"type":"string"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"delegateApprovalTx":{"$ref":"#/components/schemas/UnsignedTransaction"},"usdcApprovalRequired":{"type":"boolean","description":"Whether the trader must submit a USDC approval for trading storage."},"usdcApprovalTx":{"$ref":"#/components/schemas/UnsignedTransaction","nullable":true},"chainId":{"type":"integer"}}},"AgentVerifyResponse":{"type":"object","required":["verified","smartAccountAddress","allowance"],"properties":{"verified":{"type":"boolean"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"allowance":{"type":"string","description":"USDC allowance in base units"}}},"AgentActionMessageResponse":{"type":"object","required":["message","nonce","expiresAt","smartAccountAddress"],"properties":{"message":{"type":"string","description":"Message the trader must sign."},"nonce":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"}}},"AgentRevokeResponse":{"type":"object","required":["removeDelegateTx"],"properties":{"removeDelegateTx":{"$ref":"#/components/schemas/UnsignedTransaction"}}},"AgentRevokeBundleResponse":{"type":"object","required":["removeDelegateTx","smartAccountAddress","message","nonce","expiresAt"],"properties":{"removeDelegateTx":{"$ref":"#/components/schemas/UnsignedTransaction"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"message":{"type":"string"},"nonce":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}},"AgentPublicResponse":{"type":"object","required":["agentWalletAddress","smartAccountAddress"],"properties":{"agentWalletAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"}}},"AgentRemoveResponse":{"type":"object","required":["removeDelegateTx","smartAccountAddress"],"properties":{"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"removeDelegateTx":{"$ref":"#/components/schemas/UnsignedTransaction"}}},"AgentResetResponse":{"type":"object","deprecated":true,"description":"Deprecated. Use AgentVerifyModeResponse.","required":["reset","smartAccountAddress","delegatedTo"],"properties":{"reset":{"type":"boolean"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"delegatedTo":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"}}},"AgentVerifyModeRequest":{"type":"object","required":["mode","nonce","expiresAt","signature"],"properties":{"mode":{"type":"string","enum":["cancel","reset"]},"nonce":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"signature":{"type":"string"}}},"AuthVerifyMessageRequest":{"type":"object","required":["message","signature"],"properties":{"message":{"type":"string"},"signature":{"type":"string"}}},"AgentVerifyModeResponse":{"type":"object","required":["success","mode","smartAccountAddress","delegatedTo"],"properties":{"success":{"type":"boolean"},"mode":{"type":"string","enum":["cancel","reset"]},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"delegatedTo":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"}}},"AgentVerifyRevokeResponse":{"type":"object","required":["success","smartAccountAddress","delegatedTo","allowance"],"properties":{"success":{"type":"boolean"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"delegatedTo":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"allowance":{"type":"string"}}},"AgentPendingResponse":{"type":"object","required":["hasPending"],"properties":{"hasPending":{"type":"boolean"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"agentWalletAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"createdAt":{"type":"string","format":"date-time"},"isVerified":{"type":"boolean"},"nonce":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}},"BalanceResponse":{"type":"object","required":["address","symbol","decimals","balance","balanceFormatted"],"properties":{"address":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"symbol":{"type":"string","example":"USDC"},"decimals":{"type":"integer","example":6},"balance":{"type":"string","description":"Raw balance in base units"},"balanceFormatted":{"type":"string","description":"Human-readable balance with 6 decimals"}}},"OpenRequest":{"type":"object","required":["open"],"properties":{"open":{"$ref":"#/components/schemas/Open"},"bd":{"$ref":"#/components/schemas/BuilderConfig"},"sp":{"type":"number","description":"Slippage percentage for market orders (0-100)","minimum":0,"maximum":100,"default":0.25}}},"Open":{"type":"object","required":["a","b","t","p","s","l"],"properties":{"a":{"type":"integer","minimum":0,"description":"Pair index"},"b":{"type":"boolean","description":"Direction (true = long, false = short)"},"t":{"type":"string","enum":["market","limit","stop"],"description":"Open type"},"p":{"type":"string","description":"Price (e.g., \"42500.00\")"},"s":{"type":"string","description":"Collateral in USD (minimum 5)"},"l":{"type":"string","description":"Leverage (e.g., \"10\" for 10x)"},"tp":{"type":"string","description":"Take profit price (\"0\" = default openPrice + 900%)"},"sl":{"type":"string","description":"Stop loss price (\"0\" = default liquidation price)"}}},"BuilderConfig":{"type":"object","description":"Builder fee configuration for integrators","required":["b","f"],"properties":{"b":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"Builder address (0x...)"},"f":{"type":"number","minimum":0,"maximum":0.5,"description":"Fee percentage (e.g., 0.1 = 0.1%, max 0.5%)"}}},"CloseRequest":{"type":"object","required":["closes"],"properties":{"closes":{"type":"array","description":"Positions to build close transactions for","minItems":1,"items":{"$ref":"#/components/schemas/CloseItem"}},"sp":{"type":"number","description":"Slippage percentage (0-100)","minimum":0,"maximum":100,"default":0.25}}},"CloseItem":{"type":"object","required":["a","t","p","r"],"properties":{"a":{"type":"integer","minimum":0,"description":"Pair index"},"t":{"type":"integer","minimum":0,"description":"Trade index"},"p":{"type":"string","description":"Current market price"},"r":{"type":"number","minimum":1,"maximum":100,"description":"Close percentage (1-100)"}}},"CancelRequest":{"type":"object","required":["cancels"],"properties":{"cancels":{"type":"array","description":"Orders to build cancel transactions for","minItems":1,"items":{"$ref":"#/components/schemas/CancelItem"}}}},"CancelItem":{"type":"object","required":["t"],"properties":{"t":{"type":"string","enum":["limit","close","open"],"description":"Cancel type: limit (requires a, i), close/open (requires o)"},"a":{"type":"integer","minimum":0,"description":"Pair index (for limit cancel)"},"i":{"type":"integer","minimum":0,"description":"Order index (for limit cancel)"},"o":{"type":"integer","minimum":0,"description":"Order ID (for close/open timeout cancel)"}}},"ModifyRequest":{"type":"object","description":"With `p`: updates limit order. Without `p`: updates open trade TP/SL (one of tp/sl per call).","required":["a","i"],"properties":{"a":{"type":"integer","minimum":0,"description":"Pair index"},"i":{"type":"integer","minimum":0,"description":"Limit order index (if p provided) or trade index (if updating TP/SL)"},"p":{"type":"string","description":"New limit order trigger price (omit to update open trade TP/SL)"},"tp":{"type":"string","description":"New take profit price (\"0\" = reset to default)"},"sl":{"type":"string","description":"New stop loss price (\"0\" = reset to default)"}}},"MarginRequest":{"type":"object","required":["a","i","amount"],"properties":{"a":{"type":"integer","minimum":0,"description":"Pair index"},"i":{"type":"integer","minimum":0,"description":"Trade index"},"amount":{"type":"string","description":"USD amount: positive = add, negative = remove"}}},"TransactionResponse":{"type":"object","required":["transactions"],"properties":{"transactions":{"type":"array","items":{"$ref":"#/components/schemas/UnsignedTransaction"}}}},"DelegatedTransactionResponse":{"type":"object","required":["txHash","smartAccountAddress"],"properties":{"txHash":{"type":"string","description":"Transaction hash from sponsored user operation"},"smartAccountAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"}}},"UnsignedTransaction":{"type":"object","required":["to","data","value"],"properties":{"to":{"type":"string","description":"Contract address"},"data":{"type":"string","description":"ABI-encoded calldata"},"value":{"type":"string","description":"ETH value (usually \"0\")"},"from":{"type":"string","description":"Trader address"}}},"ServiceHealthResponse":{"type":"object","required":["status","service","version","timestamp"],"properties":{"status":{"type":"string","enum":["healthy"]},"service":{"type":"string","example":"builder-service"},"version":{"type":"string","example":"v1"},"timestamp":{"type":"string","format":"date-time"}}},"ExchangeHealthResponse":{"type":"object","required":["status","endpoint","version","timestamp"],"properties":{"status":{"type":"string","enum":["healthy"]},"endpoint":{"type":"string","example":"exchange"},"version":{"type":"string","example":"v1"},"timestamp":{"type":"string","format":"date-time"}}},"ErrorResponse":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable error message"},"code":{"type":"integer","description":"HTTP status code"},"errorCode":{"type":"string","enum":["VALIDATION_ERROR","INVALID_REQUEST","INVALID_ACTION","INVALID_ADDRESS","NOT_FOUND","UNAUTHORIZED","RATE_LIMIT_EXCEEDED","INTERNAL_ERROR","SERVICE_UNAVAILABLE","UPGRADE_REQUIRED","UPGRADE_FAILED"],"description":"Machine-readable error code"},"details":{"type":"object","description":"Additional error context","additionalProperties":true}}}},"responses":{"TransactionResponse":{"description":"Transactions built successfully","headers":{"X-Request-ID":{"description":"Request tracking ID","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TransactionResponse"},{"$ref":"#/components/schemas/DelegatedTransactionResponse"}]}}}},"ValidationError":{"description":"Invalid request (validation error, invalid address, etc.)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Validation failed: Price must be a positive number string","code":400,"errorCode":"VALIDATION_ERROR"}}}},"UnauthorizedError":{"description":"Unauthorized (invalid or missing API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Unauthorized","code":401,"errorCode":"UNAUTHORIZED"}}}},"RateLimitError":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded","code":429,"errorCode":"RATE_LIMIT_EXCEEDED"}}}},"InternalError":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"securitySchemes":{"traderAddress":{"type":"apiKey","in":"header","name":"X-Trader-Address","description":"Ethereum address of the trader (0x prefixed)"}}}}