{"openapi":"3.1.0","info":{"title":"avantis-tx-builder","version":"0.1.0","description":"GET-based HTTP service that builds Avantis trading transaction call data on Base (chainId 8453). The service ABI-encodes openTrade / closeTradeMarket / cancelOpenLimitOrder / updateMargin / updateTpAndSl / setDelegate / removeDelegate / approve calls into ready-to-sign `{ to, data, value }` payloads. Callers (wallets, bots, agents) are responsible for signing, gas, and broadcasting.\n\nThe service is read-only — no RPC, no signing, no on-chain side effects. Pre-trade safety checks (liquidity, min position size, leverage envelope) are run against the live `data.avantisfi.com/v2/trading` snapshot before encoding.","license":{"name":"Internal"}},"servers":[{"url":"https://tx-builder.avantisfi.com","description":"Production (Base mainnet)"},{"url":"http://localhost:8080","description":"Local development"}],"tags":[{"name":"meta","description":"Service metadata, pairs catalog, contract addresses"},{"name":"trade","description":"Open / close / cancel position calls"},{"name":"margin","description":"Deposit or withdraw collateral on an open trade"},{"name":"tpsl","description":"Update take-profit / stop-loss on an open trade"},{"name":"delegate","description":"Authorize / revoke a delegate trader"},{"name":"token","description":"USDC helpers (approve)"},{"name":"docs","description":"API documentation"}],"paths":{"/":{"get":{"tags":["meta"],"summary":"Service index","responses":{"200":{"description":"Service metadata and endpoint list","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Liveness check","responses":{"200":{"description":"Always returns ok / chainId 8453","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"},"example":{"ok":true,"data":{"status":"ok","chainId":8453}}}}}}}},"/addresses":{"get":{"tags":["meta"],"summary":"Avantis contract addresses on Base","responses":{"200":{"description":"Map of contract name to checksummed address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"},"example":{"ok":true,"data":{"chainId":8453,"Trading":"0x44914408af82bC9983bbb330e3578E1105e11d4e","TradingStorage":"0x8a311D7048c35985aa31C131B9A13e03a5f7422d","USDC":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}}}}}}},"/pairs":{"get":{"tags":["meta"],"summary":"List all trading pairs","description":"Pulled from the Avantis data API. Use the returned `index` for `pairIndex` query parameters.","responses":{"200":{"description":"Array of pairs","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PairSummary"}}}}]}}}}}}},"/pairs/{index}":{"get":{"tags":["meta"],"summary":"Single pair details","parameters":[{"name":"index","in":"path","required":true,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"Full pair record incl. leverages, OI, lazer feed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/trade/open":{"get":{"tags":["trade"],"summary":"Build an openTrade call","description":"Encodes `Trading.openTrade(t, type, slippageP)` (or `delegatedAction(trader, calldata)` when `delegate` is provided). Runs pre-trade validation by default — set `skipValidation=true` to opt out.","parameters":[{"$ref":"#/components/parameters/Trader"},{"$ref":"#/components/parameters/Delegate"},{"$ref":"#/components/parameters/PairIndex"},{"$ref":"#/components/parameters/Pair"},{"name":"side","in":"query","required":true,"schema":{"type":"string","enum":["long","short"]}},{"name":"orderType","in":"query","required":false,"schema":{"type":"string","enum":["market","limit","stop_limit","market_zero_fee"],"default":"market"}},{"name":"collateralUsdc","in":"query","required":true,"description":"Collateral in USDC (human decimal). Must be > 0.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$","example":"100"}},{"name":"leverage","in":"query","required":true,"description":"Leverage multiplier (e.g. `10` = 10x). Sanity-bounded `0 < x <= 1000` server-side; the pair's own envelope is enforced separately.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$","example":"10"}},{"name":"slippagePercent","in":"query","required":false,"description":"Allowed slippage in percent. Defaults to 1.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$","default":"1","example":"1"}},{"name":"openPrice","in":"query","required":false,"description":"Required for `limit` / `stop_limit`. Optional override for market orders — when omitted on a market order, the live Pyth (or Lazer when available) price is fetched.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"name":"takeProfit","in":"query","required":false,"description":"Take-profit price (human decimal). Omit or pass `0` for no TP — the contract treats `tp == 0` as 'not set' (avantis-contracts/docs/flows/market-open.md, 'Zero TP / Zero SL').","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"name":"stopLoss","in":"query","required":false,"description":"Stop-loss price (human decimal). Omit or pass `0` for no SL.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"$ref":"#/components/parameters/SkipValidation"}],"responses":{"200":{"description":"Encoded openTrade transaction call data","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CallData"}}}]},"example":{"ok":true,"data":{"to":"0x44914408af82bC9983bbb330e3578E1105e11d4e","from":"0x1111111111111111111111111111111111111111","data":"0x19cde9a1...","value":"0x0","chainId":8453,"description":"Open long BTC/USD 10x with 100 USDC (market)","meta":{"pair":"BTC/USD","pairIndex":1,"orderType":"market","isZfp":false,"validation":{"positionSizeUsdc":1000,"pairAvailableUsdc":33683421.1,"groupAvailableUsdc":31539778.34,"availableUsdc":31539778.34,"minLeverage":1,"maxLeverage":75,"minPositionUsdc":100,"isZfp":false,"marketOpen":true,"nextOpenSec":null,"nextCloseSec":null}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/trade/close":{"get":{"tags":["trade"],"summary":"Build a closeTradeMarket call","parameters":[{"$ref":"#/components/parameters/Trader"},{"$ref":"#/components/parameters/Delegate"},{"$ref":"#/components/parameters/PairIndexRequired"},{"$ref":"#/components/parameters/TradeIndex"},{"name":"collateralUsdc","in":"query","required":true,"description":"Collateral to close (USDC, human decimal). Pass the full collateral in trade to fully close.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}}],"responses":{"200":{"description":"Encoded closeTradeMarket call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/trade/cancel":{"get":{"tags":["trade"],"summary":"Build a cancelOpenLimitOrder call","parameters":[{"$ref":"#/components/parameters/Trader"},{"$ref":"#/components/parameters/Delegate"},{"$ref":"#/components/parameters/PairIndexRequired"},{"$ref":"#/components/parameters/TradeIndex"}],"responses":{"200":{"description":"Encoded cancelOpenLimitOrder call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/margin/update":{"get":{"tags":["margin"],"summary":"Build an updateMargin call (deposit / withdraw collateral)","description":"Encodes `Trading.updateMargin(pairIndex, index, type, amount, priceUpdateData[], priceSourcing)`. The required Pyth update bytes are fetched server-side by default — pass `priceUpdateData` + `priceSourcing` to skip the fetch.","parameters":[{"$ref":"#/components/parameters/Trader"},{"$ref":"#/components/parameters/Delegate"},{"$ref":"#/components/parameters/PairIndexRequired"},{"$ref":"#/components/parameters/TradeIndex"},{"name":"action","in":"query","required":true,"schema":{"type":"string","enum":["deposit","withdraw"]}},{"name":"collateralUsdc","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"$ref":"#/components/parameters/PriceUpdateData"},{"$ref":"#/components/parameters/PriceSourcing"}],"responses":{"200":{"description":"Encoded updateMargin call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/tpsl/update":{"get":{"tags":["tpsl"],"summary":"Build an updateTpAndSl call","parameters":[{"$ref":"#/components/parameters/Trader"},{"$ref":"#/components/parameters/Delegate"},{"$ref":"#/components/parameters/PairIndexRequired"},{"$ref":"#/components/parameters/TradeIndex"},{"name":"takeProfit","in":"query","required":true,"description":"New take-profit price (human decimal). Pass `0` to remove the TP — see avantis-contracts/docs/flows/position-updates.md ('`_newTp` … `0` = remove TP').","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"name":"stopLoss","in":"query","required":true,"description":"New stop-loss price. Pass `0` to clear the stop.","schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"$ref":"#/components/parameters/PriceUpdateData"},{"$ref":"#/components/parameters/PriceSourcing"}],"responses":{"200":{"description":"Encoded updateTpAndSl call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/delegate/set":{"get":{"tags":["delegate"],"summary":"Build a setDelegate call","parameters":[{"$ref":"#/components/parameters/Trader"},{"name":"delegate","in":"query","required":true,"schema":{"$ref":"#/components/schemas/EthAddress"}}],"responses":{"200":{"description":"Encoded setDelegate call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/delegate/remove":{"get":{"tags":["delegate"],"summary":"Build a removeDelegate call","parameters":[{"$ref":"#/components/parameters/Trader"}],"responses":{"200":{"description":"Encoded removeDelegate call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/token/approve":{"get":{"tags":["token"],"summary":"Build a USDC approve call","description":"Defaults the spender to TradingStorage. Omit `amountUsdc` for unlimited (`type(uint256).max`) approval.","parameters":[{"$ref":"#/components/parameters/Trader"},{"name":"amountUsdc","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d+(\\.\\d+)?$"}},{"name":"spender","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EthAddress"}}],"responses":{"200":{"description":"Encoded approve call data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/docs":{"get":{"tags":["docs"],"summary":"Swagger UI","responses":{"200":{"description":"Interactive API documentation","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/openapi.json":{"get":{"tags":["docs"],"summary":"OpenAPI 3.1 specification (JSON)","responses":{"200":{"description":"This spec, served verbatim","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"parameters":{"Trader":{"name":"trader","in":"query","required":true,"description":"EIP-55 Ethereum address that ultimately owns the position.","schema":{"$ref":"#/components/schemas/EthAddress"}},"Delegate":{"name":"delegate","in":"query","required":false,"description":"If provided, wraps the call in `Trading.delegatedAction(trader, calldata)`. The returned `from` is then the delegate (who must sign), not the trader.","schema":{"$ref":"#/components/schemas/EthAddress"}},"PairIndex":{"name":"pairIndex","in":"query","required":false,"description":"Numeric pair index. Either `pairIndex` or `pair` is required.","schema":{"type":"integer","minimum":0,"example":1}},"PairIndexRequired":{"name":"pairIndex","in":"query","required":true,"schema":{"type":"integer","minimum":0}},"Pair":{"name":"pair","in":"query","required":false,"description":"Pair symbol. Accepts `/`, `-`, or `_` as separator: `BTC/USD`, `btc-usd`, `eth_usd`. Either `pairIndex` or `pair` is required.","schema":{"type":"string","example":"BTC/USD"}},"TradeIndex":{"name":"tradeIndex","in":"query","required":true,"description":"Per-pair index of the trade (returned at open time / by `core.avantisfi.com/user-data`).","schema":{"type":"integer","minimum":0}},"PriceUpdateData":{"name":"priceUpdateData","in":"query","required":false,"description":"0x-prefixed Pyth update bytes. Up to 16 KB. If omitted, the server fetches it from `feed-v3.avantisfi.com`.","schema":{"type":"string","pattern":"^0x[0-9a-fA-F]*$"}},"PriceSourcing":{"name":"priceSourcing","in":"query","required":false,"description":"Override the price-source enum: `0` = Pyth Hermes (legacy), `1` = Pyth Pro / Lazer. Auto-detected when omitted.","schema":{"type":"string","enum":["0","1"]}},"SkipValidation":{"name":"skipValidation","in":"query","required":false,"description":"If `true`, bypass server-side liquidity / min-position / leverage checks. Use with care.","schema":{"type":"boolean","default":false}}},"responses":{"BadRequest":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"leverageOutOfRange":{"summary":"Leverage outside pair envelope","value":{"ok":false,"error":{"code":"BAD_REQUEST","message":"Leverage 200x is outside the fixed-fee range [1x, 75x] for BTC/USD"}}},"minPosition":{"summary":"Position size below pair minimum","value":{"ok":false,"error":{"code":"BAD_REQUEST","message":"Position size 5 USDC is below the minimum of 100 USDC for BTC/USD (collateral 1 × leverage 5)"}}},"queryShape":{"summary":"Malformed query string","value":{"ok":false,"error":{"code":"VALIDATION_ERROR","message":"Invalid query parameters","details":{"fieldErrors":{"trader":["Invalid Ethereum address"]}}}}}}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"schemas":{"EthAddress":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","example":"0x1111111111111111111111111111111111111111"},"HexBytes":{"type":"string","pattern":"^0x[0-9a-fA-F]*$","example":"0xabcdef00"},"HexUint":{"type":"string","pattern":"^0x[0-9a-fA-F]+$","description":"Big integer encoded as 0x-prefixed hex to avoid JS number precision loss.","example":"0x13e52b9abe000"},"SuccessEnvelope":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{}}},"ErrorEnvelope":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["BAD_REQUEST","VALIDATION_ERROR","NOT_FOUND","UPSTREAM_ERROR","INTERNAL_ERROR"]},"message":{"type":"string"},"details":{}}}}},"CallData":{"type":"object","description":"Ready-to-sign EVM call data. `nonce` and `gas` are intentionally omitted — the caller's wallet manages them.","required":["to","from","data","value","chainId","description"],"properties":{"to":{"allOf":[{"$ref":"#/components/schemas/EthAddress"}],"description":"Destination contract."},"from":{"allOf":[{"$ref":"#/components/schemas/EthAddress"}],"description":"Address that must sign (the delegate for delegated calls, otherwise the trader). Informational."},"data":{"$ref":"#/components/schemas/HexBytes"},"value":{"$ref":"#/components/schemas/HexUint"},"chainId":{"type":"integer","const":8453},"description":{"type":"string","example":"Open long BTC/USD 10x with 100 USDC (market)"},"meta":{"type":"object","additionalProperties":true,"description":"Endpoint-specific context. For `/trade/open` this includes `validation` (see ValidationSummary)."}}},"CallDataResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CallData"}}}]},"ValidationSummary":{"type":"object","description":"Pre-trade summary emitted in `/trade/open` responses (under `meta.validation`). `null` when `skipValidation=true`.","required":["positionSizeUsdc","pairAvailableUsdc","availableUsdc","minLeverage","maxLeverage","minPositionUsdc","isZfp","marketOpen","nextOpenSec","nextCloseSec"],"properties":{"positionSizeUsdc":{"type":"number","description":"collateral × leverage"},"pairAvailableUsdc":{"type":"number","description":"pairMaxOI − pairOI"},"groupAvailableUsdc":{"type":["number","null"],"description":"groupMaxOI − groupOI (null when the group record was unavailable)"},"availableUsdc":{"type":"number","description":"min(pairAvail, groupAvail)"},"minLeverage":{"type":"number"},"maxLeverage":{"type":"number"},"minPositionUsdc":{"type":"number"},"isZfp":{"type":"boolean","description":"True when orderType is market_zero_fee (PnL envelope)."},"marketOpen":{"type":"boolean","description":"Whether the pair's market accepts immediate-execution orders right now. Crypto pairs are always true; for FX / commodities / equities this reflects the feed's schedule. Reported regardless of order type; only enforced as a hard reject for market / market_zero_fee."},"nextOpenSec":{"type":["integer","null"],"description":"Unix seconds for the next scheduled market open, or null when the pair has no schedule (crypto / 24-7)."},"nextCloseSec":{"type":["integer","null"],"description":"Unix seconds for the next scheduled market close, or null when the pair has no schedule (crypto / 24-7)."}}},"PairSchedule":{"type":"object","description":"Trading-hours metadata from the pair's underlying price feed. nextOpen/nextClose are unix seconds; both 0 means the market has no schedule (crypto / 24-7).","required":["isOpen","nextOpen","nextClose"],"properties":{"isOpen":{"type":"boolean"},"nextOpen":{"type":"integer"},"nextClose":{"type":"integer"}}},"PairSummary":{"type":"object","required":["index","symbol","from","to","lazerStable"],"properties":{"index":{"type":"integer"},"symbol":{"type":"string","example":"BTC/USD"},"from":{"type":"string","example":"BTC"},"to":{"type":"string","example":"USD"},"lazerStable":{"type":"boolean"},"schedule":{"oneOf":[{"$ref":"#/components/schemas/PairSchedule"},{"type":"null"}]}}}}}}