Skip to main content
POST
Python (SDK)

Authorizations

x-api-key
string
header
required

Your Compass API Key. Get your key here.

Body

application/json

Open a leveraged loop: repeatedly supply collateral, borrow, and swap the borrow back to collateral — all in ONE atomic transaction from the Credit Account.

owner
string
default:0x5e5b00ed886A6879C2B934612D2312975427fcAf
required

The address that owns the Credit Account.

Example:

"0x5e5b00ed886A6879C2B934612D2312975427fcAf"

chain
enum<string>
default:ethereum
required

Blockchain network. Not every protocol is deployed on every chain — see the protocol field — and a chain with no credit venue at all returns a 422 naming the chains that do.

Available options:
arbitrum,
base,
bsc,
ethereum,
hyperevm,
tempo
Example:

"ethereum"

collateral_token
string
default:WETH
required

Token supplied as collateral each iteration. Must already be in the Credit Account for the initial amount. For MORPHO it must be the market's collateral token.

Examples:

"wstETH"

"WETH"

borrow_token
string
default:USDC
required

Token borrowed each iteration and swapped back to the collateral token. For MORPHO it must be the market's loan token.

Examples:

"WETH"

"USDC"

initial_collateral_amount
default:1
required

Collateral (in token units) that the Credit Account must ALREADY hold when this is called — the loop never pulls from the owner's wallet mid-transaction. Fund the account first via /v2/credit/transfer (action=DEPOSIT).

Required range: x > 0
Example:

1.5

multiplier
default:2
required

Target leverage: total collateral exposure = multiplier × initial_collateral_amount. Must be achievable at the requested loan_to_value (max ≈ 0.9 / (1 − LTV)).

Required range: x > 1
Example:

2

loan_to_value
default:70
required

Per-iteration borrow LTV in percent. Must not exceed the protocol's maximum for the market (Aave reserve/e-mode LTV; Morpho LLTV with a safety margin; Euler's borrow LTV for the collateral vault); borrows are sized slightly inside the requested value so no leg sits on the protocol's revert boundary.

Required range: 0 < x <= 100
Example:

70

protocol
enum<string>
default:AAVE

Lending protocol to loop into: AAVE, MORPHO, or EULER. On chain=hyperevm, AAVE is Hyperlend and MORPHO is Felix; EULER is not deployed there.

Available options:
AAVE,
EULER,
MORPHO
Example:

"AAVE"

market_id
string | null

Morpho only: the bytes32 market id (from /v2/credit/morpho_markets). Required when protocol=MORPHO.

collateral_vault
string | null

Euler only: the EVK vault address collateral is supplied to (from /v2/credit/euler_markets). Required when protocol=EULER.

borrow_vault
string | null

Euler only: the EVK vault address borrowed from (the sub-account's controller). Required when protocol=EULER.

sub_account_id
integer
default:0

Euler only: the EVC sub-account (0-255) holding this isolated looped position. 0 is the Credit Account itself.

Required range: 0 <= x <= 255
max_slippage_percent
default:0.5

Per-swap slippage tolerance in percent. Loop dust is bounded by this per iteration, so tighter slippage means less dust.

Required range: 0 < x <= 10
Example:

0.3

emode_category
integer | null

Aave only: e-mode category to enable before looping (higher LTV for correlated pairs, e.g. ETH-correlated). Both tokens must belong to the category or the build returns a 422. On Hyperlend (chain=hyperevm) category 1 is the HYPE-correlated set covering wstHYPE and WHYPE.

Required range: x >= 0
gas_sponsorship
boolean
default:false

If true, returns EIP-712 typed data for gas-sponsored execution instead of an unsigned transaction.

Example:

false

preview
boolean
default:false

If true, build a display ESTIMATE: no firm RFQ quote is ever requested (quote_expires_at stays null). NOTE that this guarantees only that no firm quote was spent — it does not guarantee an absent transaction: on a pair no firm provider covers, and under pricing=market, the call still falls through to the aggregator and returns a signable transaction. How the estimate is priced follows pricing: on a firm-covered pair under 'auto' or 'firm' it is computed from the firm provider's live price levels (indicative); otherwise swap legs are priced by the default aggregator. Set it on every call made while a user is exploring parameters, and leave it false only for the build they actually intend to sign — firm quotes are single-use maker commitments, and requesting them for displays that are never executed degrades the pricing this API is offered.

pricing
enum<string>
default:auto

Swap-leg routing policy. 'auto': firm quotes where a firm venue covers the pair, transparent fallback to the market aggregator otherwise. 'firm': never price on the market route — previews whose target the firm venue cannot serve return the coverage advisory alone (preview=null, zero aggregator calls), and executions fail with a typed error instead of silently substituting market pricing. 'market': never route through the firm venue; every leg is priced by the aggregator and bounded by max_slippage_percent (which firm legs ignore). 'firm' is incompatible with gas_sponsorship (sponsored loops force market routing).

Available options:
auto,
firm,
market

Response

Successful Response

The atomic loop transaction plus its guaranteed-floor preview.

preview
CreditLoopPreview · object | null
required

Projected end state, computed on guaranteed swap floors. Null only on pricing='firm' preview responses whose target the firm venue cannot serve: no leg was priced on any venue, and the response carries the coverage advisory (max_firm_multiplier) alone.

transaction
UnsignedTransaction · object | null

Unsigned transaction for direct execution by the owner. Present when gas_sponsorship=false — except firm-priced previews (preview=true on a firm-priced build), which carry numbers only: the firm quotes are fetched at execution time, so there is no payload to sign yet.

Example:
eip_712
BatchedSafeOperationsResponse · object | null

EIP-712 typed data for gas-sponsored execution. Present when gas_sponsorship=true.

Example:
pt_maturity
string | null

Maturity of the Pendle principal token supplied as collateral, ISO-8601 UTC. Present only for principal-token collateral, whose yield is fixed until this date; after it the position can be unwound (by redemption at par) but not increased.

swap_provider
enum<string>
default:market

Identifies which route priced the swap leg(s): 'market' — a DEX aggregator (iterative loop across pool liquidity, slippage-bounded floors) — or 'firm' — zero-slippage quotes, one per swap leg, each partially filled at the leg's size (exact fills, zero dust). On preview=true responses 'firm' means the numbers are INDICATIVE, computed from live maker price levels without spending any quote; execution fetches the firm quotes at signing time. Always present, including on fallbacks. This is the authoritative firm-vs-market signal and clients do need to read it: pricing is only what was REQUESTED (under 'auto' a firm build can fall back to market transparently), and quote_expires_at is absent on every preview — so neither substitutes for this field.

Available options:
market,
firm
quote_expires_at
string<date-time> | null

Deadline of the firm swap quotes (the earliest across the loop's swap legs) — sign and broadcast before it or the transaction reverts on-chain; refresh by re-calling this endpoint (discard the previous payload). Present only on executable firm-priced builds; null on previews (no quote is spent for a preview).

max_firm_multiplier
string | null

Multiplier bound firm zero-slippage quotes can fill for the requested position size, LTV and target (estimated without spending any quote). The requested multiplier is firm-servable iff it is <= this value; above it the loop executes at market rate with slippage-bounded floors instead. Present only on preview=true responses when a firm-quote venue covers the pair; null otherwise. Recompute per parameter change - minimum-size floors make reachability target-dependent.