Skip to main content
Supply collateral to a money market, borrow against it, and manage the resulting position through the Borrow API: discover a market, request an action, sign and submit its transactions, then track and unwind the position. This goes beyond Borrow core concepts: it walks one integration through supply, borrow, repay, and withdraw with real request and response shapes. One integration runs through every example: aave-borrow (Aave V3 Borrow), a pool-type market, on Base. Swap in whatever integrationId and marketId your own discovery step returns; nothing here should be hardcoded in your app.
Borrow is not Earn’s Lending. Lending supplies an asset to earn yield through the Yield API. Borrow supplies collateral and borrows against it through the Borrow API. A Borrow supply action and a lending yield are different positions, even on the same protocol, and their balance shapes are not interchangeable.

Prerequisites

  • Your project API key, sent as x-api-key on every request to https://borrow.yield.xyz/v1. The same project key authenticates the Yield, Perps, and Borrow APIs.
  • A signer for the target network (an EOA, smart account, MPC, or custodial signer). This guide uses a generic signAndBroadcast placeholder; see Transaction signing for chain-specific signing code.
We construct. You sign. Every action returns unsigned transactions; yield.xyz never holds keys and never signs on your behalf. Inspect signablePayload before signing it, and never modify it.

Discover integrations

GET /v1/integrations returns every Borrow integration, each with the actions your project can call and per-action argument schemas. Treat this response as authoritative over any table in these docs for what your project can actually call:
cURL
Response (excerpt)

Pick a market

GET /v1/markets is project-scoped by default (scope=enabled); pass scope=all to see every market the integration exposes regardless of your project’s configuration. Filter by integrationId and network:
cURL
Response (excerpt)
type is pool (Aave, SparkLend) where every eligible asset can be collateral, or isolated (Morpho Blue, Lista) where a market pairs exactly one collateral asset with one loan asset. Each collateralTokens entry carries maxLtv (the most you can borrow against it) and liquidationThreshold (the LTV at which the position becomes liquidatable); the market itself carries borrowRate, availableLiquidity, and isBorrowEnabled. Rates are decimals: "0.0567" means 5.67%. Check isBorrowEnabled and availableLiquidity before offering a market for borrowing.

Supply collateral

Call POST /v1/actions with the integration’s integrationId, action: "supply", the user’s address, and args containing the marketId, the tokenAddress of the asset you’re depositing (one of the market’s collateralTokens), and amount:
cURL
Response (excerpt, example values)
tokenAddress and amount are required for every pool-market supply, since a pool market accepts more than one eligible collateral asset; an isolated market infers the single collateral token from the marketId instead, so tokenAddress is not needed there. Depositing an asset that needs an ERC-20 allowance returns an APPROVAL transaction ahead of the SUPPLY transaction, in the order to sign them.

Read the preview before signing

An action response can carry metadata with currentHealthFactor / predictedHealthFactor and currentLtv / predictedLtv: the position’s risk before and after the action settles. currentHealthFactor and predictedHealthFactor are null when there’s no debt yet, as in a first supply with no prior borrow. Show the predicted values to the user before they sign, and refuse to proceed if predictedHealthFactor would drop to an unsafe level.

Sign and submit

Sign each transaction in transactions[] in the order returned, then submit it with POST /v1/transactions/{transactionId}/submit, passing either signedPayload (yield.xyz broadcasts it) or transactionHash (you already broadcast it, this just reports the hash). Wait for each transaction to reach CONFIRMED before signing the next one in the array:
cURL
Response (excerpt)
If hasNextStep is true on the action, the current transactions[] is only one step of a multi-step flow (for example an async cross-chain bridge). Confirm every transaction in the current step, then call POST /v1/actions/{id}/step to fetch the next one. None of the four public integrations in this guide (Aave, SparkLend, Morpho Blue, Lista) currently use multi-step flows, but check hasNextStep regardless of integration.

Borrow

Once collateral is supplied, request action: "borrow" the same way, with the marketId, the tokenAddress of the asset to borrow (the market’s loanToken on a pool market), and amount:
cURL
Sign and submit its transactions the same way as supply. Read metadata.predictedHealthFactor before signing: a borrow that pushes it below a level you’re comfortable with should be blocked client-side before the user ever signs.
On every integration, borrow also accepts collateralAmount (plus collateralTokenAddress on pool markets such as Aave and SparkLend; isolated markets infer the collateral token) alongside amount and tokenAddress, to supply that collateral and borrow against it in one action instead of two separate supply and borrow calls. repay accepts the same pair to withdraw collateral immediately after repaying.

Read the position

GET /v1/positions requires integrationId, network, and address:
cURL
Response (excerpt)
Each balance’s pendingActions entries carry pre-filled args for the action they name: pass one straight into POST /v1/actions instead of reconstructing it.
Account-level healthFactor and availableToBorrowUsd are always null for isolated-market integrations (Morpho Blue, Lista), because risk on those integrations is scoped per market, not per account. Read positionState.healthFactor and positionState.availableToBorrowUsd on each supplyBalances entry instead when your integrationId is morpho-blue-borrow or lista-borrow. A generic workflow that reads only the account-level fields will silently break on those two integrations: branch on integrationId (or check whether positionState is present) before deciding which fields to read.

Repay and withdraw

repay takes the tokenAddress of the borrowed asset with either a partial amount or repayAll: true to close the debt entirely. withdraw takes the tokenAddress and amount of a supplied asset to remove:
cURL
Pool integrations (Aave, SparkLend) also support enableCollateral / disableCollateral to toggle whether a supplied asset counts toward borrowing power, without moving any funds.
On Lista, each market’s minLoan is the smallest debt it allows. A borrow that would leave debt below it, or a partial repay that would leave dust below it, fails with 400. Use repayAll: true to close a Lista position instead of a partial repay near the minimum.
On Morpho Blue only, supplyAndBorrow combines both legs into one action, but it’s listed in GET /v1/integrations only when your project has a BlueBundle fee configuration. Don’t assume it’s available; check the integration’s actions list for your project rather than calling it unconditionally. See Monetization for the fee it can carry.

Verify

A position is fully entered once its collateral appears in supplyBalances with the expected balance, and, after a borrow, once the corresponding debtBalances entry shows the expected outstanding amount and healthFactor (or, for isolated markets, positionState.healthFactor) is where you expect it. A closed debt (after repayAll) drops off debtBalances on the next GET /v1/positions call. For Morpho Blue specifically, a position that reaches full liquidation stops appearing in GET /v1/positions entirely; GET /v1/positions/liquidations is the only place to retrieve that history for a borrower address.

Next steps

Core concepts

The market, position, and action model behind every integration.

Coverage

Every integration, market type, and network live today.

Monetization

How Morpho Blue fee wrappers affect the amounts in this guide.

Transaction signing

Chain-specific signing code for the transactions this guide returns.
The Borrow widget is coming soon; see Borrow widget.