> ## Documentation Index
> Fetch the complete documentation index at: https://yieldxyz.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Borrow against collateral

> Supply collateral, borrow, and manage a Borrow API position end to end, including the isolated-market health-factor path.

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](/documentation/borrow/core-concepts/index): 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.

<Note>
  Borrow is not [Earn's Lending](/documentation/earn/defi/lending/index). 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.
</Note>

## 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](/guides/transaction-signing/index) for chain-specific signing code.

<Note>
  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.
</Note>

## 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:

```bash cURL theme={null}
curl --request GET \
  --url https://borrow.yield.xyz/v1/integrations \
  --header "x-api-key: $BORROW_API_KEY"
```

```json Response (excerpt) theme={null}
{
  "id": "aave-borrow",
  "providerId": "aave",
  "name": "Aave V3",
  "networks": ["ethereum", "base", "arbitrum", "optimism"],
  "actions": [
    { "id": "supply", "label": "Supply", "schema": "JSON_SCHEMA" },
    { "id": "borrow", "label": "Borrow", "schema": "JSON_SCHEMA" },
    { "id": "repay", "label": "Repay", "schema": "JSON_SCHEMA" },
    { "id": "withdraw", "label": "Withdraw", "schema": "JSON_SCHEMA" }
  ]
}
```

## 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`:

```bash cURL theme={null}
curl --request GET \
  --url 'https://borrow.yield.xyz/v1/markets?integrationId=aave-borrow&network=base' \
  --header "x-api-key: $BORROW_API_KEY"
```

```json Response (excerpt) theme={null}
{
  "id": "aave-v3-base-usdc",
  "integrationId": "aave-borrow",
  "network": "base",
  "type": "pool",
  "loanToken": { "symbol": "USDC", "address": "0x..." },
  "collateralTokens": [
    {
      "token": { "symbol": "WETH", "address": "0x..." },
      "maxLtv": "0.80",
      "liquidationThreshold": "0.825",
      "liquidationPenalty": "0.05",
      "supplyRate": "0.02"
    }
  ],
  "borrowRate": "0.0567",
  "availableLiquidity": "1250000.00",
  "isBorrowEnabled": true,
  "minLoan": null
}
```

`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`:

```bash cURL theme={null}
curl --request POST \
  --url https://borrow.yield.xyz/v1/actions \
  --header "x-api-key: $BORROW_API_KEY" \
  --header 'content-type: application/json' \
  --data '{
    "integrationId": "aave-borrow",
    "action": "supply",
    "address": "0xYOUR_WALLET_ADDRESS",
    "args": { "marketId": "aave-v3-base-usdc", "tokenAddress": "0xYOUR_WETH_ADDRESS", "amount": "0.5" }
  }'
```

```json Response (excerpt, example values) theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "action": "supply",
  "status": "CREATED",
  "transactions": [
    { "id": "6f1c2b7e-3a4d-4e8f-9b1a-2c5d7e9f0a11", "type": "APPROVAL", "status": "CREATED", "signingFormat": "EVM_TRANSACTION", "signablePayload": "..." },
    { "id": "9d3e5a1c-7b2f-4c60-8a4e-1f6b0c2d8e22", "type": "SUPPLY", "status": "CREATED", "signingFormat": "EVM_TRANSACTION", "signablePayload": "..." }
  ],
  "hasNextStep": false,
  "metadata": {
    "currentHealthFactor": null,
    "predictedHealthFactor": null,
    "currentLtv": "0.00",
    "predictedLtv": "0.00"
  }
}
```

`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:

```bash cURL theme={null}
curl --request POST \
  --url https://borrow.yield.xyz/v1/transactions/$TRANSACTION_ID/submit \
  --header "x-api-key: $BORROW_API_KEY" \
  --header 'content-type: application/json' \
  --data '{ "transactionHash": "0xYOUR_TRANSACTION_HASH" }'
```

```json Response (excerpt) theme={null}
{ "transactionHash": "0x...", "link": "https://basescan.org/tx/0x...", "status": "BROADCASTED" }
```

<Warning>
  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.
</Warning>

## 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`:

```bash cURL theme={null}
curl --request POST \
  --url https://borrow.yield.xyz/v1/actions \
  --header "x-api-key: $BORROW_API_KEY" \
  --header 'content-type: application/json' \
  --data '{
    "integrationId": "aave-borrow",
    "action": "borrow",
    "address": "0xYOUR_WALLET_ADDRESS",
    "args": { "marketId": "aave-v3-base-usdc", "tokenAddress": "0xYOUR_USDC_ADDRESS", "amount": "500" }
  }'
```

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.

<Note>
  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.
</Note>

## Read the position

`GET /v1/positions` requires `integrationId`, `network`, and `address`:

```bash cURL theme={null}
curl --request GET \
  --url 'https://borrow.yield.xyz/v1/positions?integrationId=aave-borrow&network=base&address=0xYOUR_WALLET_ADDRESS' \
  --header "x-api-key: $BORROW_API_KEY"
```

```json Response (excerpt) theme={null}
{
  "totalSuppliedUsd": "1400.00",
  "totalCollateralUsd": "1400.00",
  "totalBorrowedUsd": "500.00",
  "healthFactor": "2.31",
  "currentLtv": "0.36",
  "availableToBorrowUsd": "620.00",
  "supplyBalances": [
    { "marketId": "aave-v3-base-usdc", "tokenSymbol": "WETH", "balance": "0.5", "isCollateral": true, "pendingActions": [ { "type": "withdraw", "label": "Withdraw", "args": { "marketId": "aave-v3-base-usdc" } } ] }
  ],
  "debtBalances": [
    { "marketId": "aave-v3-base-usdc", "tokenSymbol": "USDC", "balance": "500.00", "pendingActions": [ { "type": "repay", "label": "Repay", "args": { "marketId": "aave-v3-base-usdc" } } ] }
  ]
}
```

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.

<Warning>
  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.
</Warning>

## 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:

```bash cURL theme={null}
curl --request POST \
  --url https://borrow.yield.xyz/v1/actions \
  --header "x-api-key: $BORROW_API_KEY" \
  --header 'content-type: application/json' \
  --data '{
    "integrationId": "aave-borrow",
    "action": "repay",
    "address": "0xYOUR_WALLET_ADDRESS",
    "args": { "marketId": "aave-v3-base-usdc", "tokenAddress": "0xYOUR_USDC_ADDRESS", "repayAll": true }
  }'
```

Pool integrations (Aave, SparkLend) also support `enableCollateral` / `disableCollateral` to toggle whether a supplied asset counts toward borrowing power, without moving any funds.

<Note>
  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.
</Note>

<Note>
  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](/documentation/borrow/monetization) for the fee it can carry.
</Note>

## 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

<Columns cols={2}>
  <Card title="Core concepts" icon="shapes" href="/documentation/borrow/core-concepts/index">
    The market, position, and action model behind every integration.
  </Card>

  <Card title="Coverage" icon="table" href="/documentation/borrow/coverage">
    Every integration, market type, and network live today.
  </Card>

  <Card title="Monetization" icon="percent" href="/documentation/borrow/monetization">
    How Morpho Blue fee wrappers affect the amounts in this guide.
  </Card>

  <Card title="Transaction signing" icon="pen-nib" href="/guides/transaction-signing/index">
    Chain-specific signing code for the transactions this guide returns.
  </Card>
</Columns>

The Borrow widget is coming soon; see [Borrow widget](/guides/widgets-dashboard/borrow-widget).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.