Skip to main content
POST
Repays part or all of a loan’s outstanding debt. Accrued interest is settled before principal. A repayment that clears the whole debt closes the loan in the same transaction and releases the collateral, so no Close Loan call follows it. Anyone can repay any loan through the approve-then-repay steps, so a third party can rescue a position approaching liquidation. The single-transaction permit path is the borrower’s own. A repayment sent without a signedPrice reads no price, so neither a stale price nor a paused market blocks it.
To close a loan, repay with all: true. A payment of exactly the debt quoted earlier leaves the interest accrued since then outstanding. On a market with a repayment fee it also leaves a fee-sized remainder open. The loan then stays active and keeps accruing.

Path Parameters

string
required
The market’s record ID, as id on List Markets, not its contract address. See Market IDs.

Body Parameters

integer
required
On-chain loan ID. A positive integer. Accepted as a JSON number or as a numeric string, so the value Get Loan returns passes straight back.
string
Amount to pay, as a positive decimal string in borrow asset units. The contract caps the payment at the debt plus the repayment fee, so overpaying does not transfer more than that. An amount that covers the current debt plus the repayment fee closes the loan, so it is built as a full repayment: fullRepayment is true, a CUSTODY loan carries collateralRelease when the collateral would be escrowed, and a last step clears the leftover allowance. Required unless all is true or you are confirming with txHash.
boolean
Repay the loan in full. The API reads the current debt and adds a 20 basis point accrual buffer plus the repayment fee to the offer. Interest accruing between the quote and the mine therefore cannot leave dust behind. Use this instead of computing a payoff yourself.
object
EIP-712 signed price from Sign Price, carried on-chain by the repayment. A repayment is the most frequent transaction a market sees, so carrying a price here keeps the oracle fresh without a separate write. Omit it and the repayment stays on the entry point that no price can block, which is the path a borrower must always have. It is not carried on the permit path. A market that prices from an external feed refuses a signed price with EXTERNAL_FEED_ACTIVE, and a market with a fixed price with FIXED_PRICE_ACTIVE, because neither oracle takes one. Leave it out there.
object
An EIP-2612 permit over the settlement asset, signed by the borrower with the market as spender. It replaces the approval, so the repayment is one transaction. Get the payload to sign from Get Permit Quote. See Pay with a permit for the binding rules.
string
Hash of the transaction you broadcast for this operation. Send it to confirm the transaction and record the result. Omit it to receive the calldata.

Repayment fee

A market may carry a flat repayment fee, stamped when it was deployed and never changeable afterwards. Read it from transactionFees on Get Fee Split. The payer bears it. The fee comes out of the payment first, and only the rest reduces the debt. Each charge is capped at 0.5 percent of the debt it discharges. The contract caps a payment at the debt plus min(repayFee, debt / 200), which is exactly what closes the loan. A partial payment reduces the debt by the payment less a fee of at most one 201st of it. When the fee is not zero, the calldata response carries transactionFee and states the effect in warning.

Pay with a permit

The permit path exists only where the settlement asset provably implements EIP-2612. permitSupported on the standard response says whether this market’s asset qualifies. It is probed once per settlement asset and stored on the market, not asked per request. A token with a different permit shape, such as DAI’s, reads as unsupported, and a permit sent to it is refused with PERMIT_UNSUPPORTED. The permit must be signed by the loan’s borrower, name the market as spender, and carry the token’s current nonce and a future deadline. The borrower’s wallet also sends the transaction, because the market redeems the permit for the sender. A third party repays through the approve-then-repay steps instead. repayWithPermit binds the permit to the amount it repays, so the signed value decides what the calldata carries:
  • With amount, the permit covers exactly amount. A permit.value that differs is refused with INVALID_PERMIT.
  • With all: true, permit.value is required, or the call returns PERMIT_VALUE_REQUIRED. It becomes the amount the calldata offers, and it must cover the live debt plus the repayment fee, or the call returns INVALID_PERMIT.
  • A full-repayment value inside the 20 basis point buffer builds with a warning. If interest outgrows it before the transaction mines, the market takes the permit’s value as a partial repayment and the loan stays open.
Before any calldata is offered, the API recovers the signature against the token’s domain and the borrower’s nonce. A signature that does not recover to the borrower is refused with INVALID_PERMIT. When the token’s domain or the nonce cannot be read, the call returns PERMIT_UNVERIFIABLE.

Transaction Shape

A partial repayment returns two steps: approve on the borrow asset, then repay. A full repayment (all: true) returns three. The third resets the allowance to zero. repay caps the pull at what closes the loan, so without it the unused approval would stay live against the payer’s funds after the loan closed. With a permit, the approval disappears. A partial repayment is one step, repayWithPermit. A full repayment is two: repayWithPermit, then the same allowance reset, because the permit installs the whole signed value as an allowance and the repayment does not spend all of it. The repay and repayWithPermit steps carry a gasLimit sized from a simulation of the sequence you sign, run from the borrower’s wallet: the approval and then the repayment, or the permit call alone. The limit is the gas the simulated repayment used plus 50 percent, and never below 600000 for repay or 650000 for repayWithPermit. A repayment that uses less than two thirds of the floor therefore still carries the floor. gasLimitBasis says how it was set:
  • simulated: the sequence was simulated and the repayment succeeded in it.
  • floor: the sequence could not be simulated, or the repayment did not succeed in it, so the step carries the floor. Estimate the repayment’s gas once the approval is mined, and use the larger of that estimate and gasLimit.
The simulation runs from the borrower even when a third party pays, so a third-party payer should estimate from its own wallet as well.
The confirmable step is not always the last one, and it is not always at the same index. Read confirmStepIndex from the response rather than assuming a position. It is 1 on the approve-then-repay path and 0 on the permit path, and in both cases it names the step whose functionName starts with repay. Confirming with the allowance-reset hash returns TX_WRONG_TARGET.

Response Fields

object

Error Codes

Confirming with txHash can also return any transaction verification error.