Skip to main content
POST
Opens an overcollateralized loan. The borrower pledges security tokens and receives the market’s borrow asset, and the borrower’s wallet signs every step. How the collateral is secured depends on the market’s mode: FREEZE locks the tokens in the borrower’s own wallet, CUSTODY escrows them in the adapter. The maximum borrow is the collateral value multiplied by the market’s collateral factor. Quote it first with Get Max Borrow. On a market that charges an opening fee, the borrower receives the borrow amount less the fee and owes the full borrow amount.

Path Parameters

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

Body Parameters

string
Security tokens to pledge, as a positive decimal string. Parsed at the collateral token’s decimals. Required when building calldata. Not needed on the confirm call, where the pledge is read from the mined transaction. On a token whose ERC-1400 granularity() is above one base unit, it must be a whole multiple of the granularity.
string
Amount to borrow, as a positive decimal string. Parsed at the borrow asset’s decimals. Must be at least the market’s minBorrowAmount. This is the debt the loan records, before any opening fee is withheld from the payout. Required when building calldata, not needed on the confirm call.
string
Wallet that will sign the loan and hold the collateral. Required when building calldata. Every collateral, identity and supply-cap check runs against this address, and there is no loan to resolve it from yet. Omitting it returns BORROWER_ADDRESS_REQUIRED. Not needed on the confirm call, where the borrower is taken from the mined transaction.
object
EIP-712 signed price from Sign Price, applied atomically with the loan. Omit to price against the stored oracle value, which must not be stale. A market that prices from an external feed refuses a signed price with EXTERNAL_FEED_ACTIVE, and a market with a fixed price refuses one with FIXED_PRICE_ACTIVE, because its oracle accepts none.
string
The client this loan is for, as the customer’s referenceKey, its externalId or its customer ID. Up to 120 characters, matched against the customers of your instance that are not archived. Create the record first with Create Customer.Send it on the build call and again on the confirm call. The build call checks the client before anything is signed and refuses an ineligible one with 409 CLIENT_NOT_ELIGIBLE, see Client of record. The confirm call checks it again and records the attribution. A loan built without it can be signed and mined for a client the confirm call then refuses, and such a loan can only be recorded without a client. The fields customerId, clientId, clientReferenceKey and externalId are refused with CLIENT_REFERENCE_FIELD, and onBehalfOf with KEY_MATERIAL_REJECTED.
string
Wallet that receives the borrowed amount instead of the signing wallet. The signer stays the borrower of record. See Pay the proceeds to another wallet. Omitted, null, an empty string or the borrower’s own address pays the borrower. Build call only: the confirm call reads the payee from the mined transaction.
boolean
Set true on the confirm call to move a loan that is already attributed to another client of your instance. Without it that confirm is refused with CLIENT_REFERENCE_CONFLICT. The change is recorded against both clients with the time it was made.
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.

Transaction Shape by Mode

When txHash is omitted the response is always SIGN_TRANSACTIONS with a mode field, and the step count depends on the market. CUSTODY returns two steps: approve on the collateral token for the adapter, then openLoan. Broadcast in order. FREEZE returns one step: openLoan. No approval exists because the tokens never leave the borrower’s wallet. Both shapes carry confirmStepIndex, the index of the openLoan step whose hash confirms the loan, and confirmWith, which names this route and the body to confirm with.

What the loan will cost and when it is due

The calldata response carries an offering block whenever the market runs loan terms or stamps a fixed rate. A market on the default curve with no term returns no offering at all. Show it before the borrower signs: it is the only place the due date and the stamped rate appear ahead of the loan existing.
object
The opening fee is the other cost fixed at signing. A market may carry a flat opening fee, stamped when it was deployed and never changeable afterwards. Read it from transactionFees on Get Fee Split. Each charge is the flat fee or 0.5 percent of the amount borrowed, whichever is smaller. When it is not zero, the calldata response carries a transactionFee block.
object

Warnings

The calldata response carries a warnings array when a preflight found something the borrower should see but that does not block the loan. The array is absent when there is nothing to say. Object entries carry kind, enforcement, message and note. enforcement is OFF_CHAIN on every one of these. The contract does not know about them, so acting on a warning is the caller’s decision. When the market charges an opening fee, the array also carries transactionFee.message as a plain string rather than an object. With a payToAddress, that string is the statement of who receives the proceeds instead, and transactionFee.message names the payee.

Professional borrowers

On a MARKET-priced market the API builds no loan until the market’s borrower register qualifies as a professional gate, and refuses with 409 PROFESSIONAL_BORROWER_GATE_REQUIRED, details.field: "borrowerRegistry". The register qualifies when at least one verification profile admits wallets to it, and every profile that does, on any instance of the market’s network and environment, is limited to professional clients and has its admissions signed by its own instance. See Professional borrowers. The check runs right after the lender-of-record check, before the adapter, pause and term checks. It reads the market’s price source and borrower register from the chain, and the profiles from Trusset’s records. When either read fails the call answers 503, MARKET_STATE_UNAVAILABLE or STATE_UNAVAILABLE, and builds nothing. The market contract does not apply this rule, so it holds only for transactions built through this API.

Client of record

A clientReference is checked on the build call and on the confirm call, before anything else: before the market’s own checks on the build call, and before the transaction is read on the confirm call. Send it on both. The build call is the one that refuses an ineligible client before anything is signed. The loan is refused with 409 CLIENT_NOT_ELIGIBLE when the client:
  • is recorded as rejected or revoked (details.reason is REJECTED or REVOKED);
  • is recorded in a country that the verification profile it was onboarded under blocks, or that a profile behind the market’s borrower register blocks (COUNTRY_BLOCKED). A profile in the EXTERNAL mode is not counted;
  • is not a professional client, on a MARKET-priced market (NOT_PROFESSIONAL, or NOT_VERIFIED for a client typed professional whose verification on your instance is not complete).
A client counts as professional when one of its wallets is admitted to a profile of your instance limited to professional clients. It also counts when it is verified on your instance under a profile that is limited to professional clients or registers its investors as Professional or Eligible Counterparty. Verified on your instance means the record reads verified and carries the verifiedAt of a verification completed here (a verify, an ID link or a registration confirmed on this instance), with no revocation since. A verified status set through Update Customer marks the record only and does not count. An admission recorded by another instance does not count either, even to this market’s own borrower register. details.clientReference names the client. The borrower register is read from the market at call time, so a register the market admin changed after the market was recorded is the one applied. When it cannot be read the call answers 503 MARKET_STATE_UNAVAILABLE and builds nothing.

Pay the proceeds to another wallet

payToAddress sends the borrowed amount, less any opening fee, to a wallet other than the one that signs. The signer stays the borrower of record: it provides the collateral, owes the debt, and receives every collateral return, any liquidation surplus and every escrow or surplus claim. The payee is fixed for the life of the loan and receives every later Borrow More draw as well. The calldata calls the openLoan overload that takes the payee.
The market examines the payee against its borrower register, exactly as it examines the borrower, at opening and at every later draw. A payee the register no longer admits blocks every further draw on the loan until it is admitted again, because the payee cannot be changed. Repaying, adding collateral and closing stay open.
The build call refuses a payee the transaction could not pay:
  • A market whose implementation predates pay-to answers 409 PAY_TO_UNSUPPORTED. Its admin upgrades it with Upgrade Market. payToSupported on List Markets shows which markets take a payee.
  • The payee may not be one of the market’s own contracts or a contract it is wired to: the market, its liquidation router, its collateral adapter, its auction venue, its insurance fund, the settlement token (stablecoin), the collateral token, the oracle, the interest rate model or a vault registered on the market. That is refused with 400 PAY_TO_NOT_ALLOWED, and details.reason names which. The market itself refuses the first five. It would pay the others, and the proceeds would be lost to the borrower while the full debt stays owed.
  • A payee that the borrower register does not admit is refused with 400 PAYEE_NOT_VERIFIED. details carries payee, register, and requiredProfile or accessList when the register is one of your profiles’ eligibility registers or a whitelist. A payee whose removal from that register is pending is refused with 409 ELIGIBILITY_REMOVAL_PENDING. When that register is the previous Trusset ID Register, a payee it does not admit is refused with 409 IDENTITY_GATE_RETIRED instead, with details.gate borrower and details.payee, because that register takes no new identities.
The calldata response then carries payeeAddress and a payee block, and its warnings state who receives what. The confirm call returns the payee the market recorded for the loan, read from its LoanPayeeSet event, and the ledger books the draw and the opening fee against the payee.

Vault draws

Some markets draw on vault liquidity, shown as useVaultLiquidity on Get Market Metrics. There, a borrow larger than the pool’s borrowable liquidity pulls the shortfall from the registered vaults inside the borrower’s own transaction. The draw is the smallest amount that covers the shortfall with the reserve earmark intact. The confirm response lists each draw in vaultDraws. The API refuses such a loan only when no draw could fund it. INSUFFICIENT_LIQUIDITY then names what the connected vaults can draw right now. A market whose implementation still holds a draw into an empty pool to the first-deposit floor refuses a smaller draw with FIRST_DRAW_BELOW_FLOOR, and the message names the remedies.

Response Fields

Confirming returns 201.
object
Loans cannot be opened until the market has a lender of record and its collateral adapter is authorized on the token. A market still seeking a lender of record is refused on that ground first, with MARKET_PENDING_CURATOR. The token-side authorizations are the register provider’s to arrange, so naming them as the obstacle would send the borrower to the wrong party. Once the role is taken, an unauthorized adapter rejects with COLLATERAL_ADAPTER_NOT_AUTHORIZED or FREEZE_MODE_UNSUPPORTED_TOKEN. See Get Setup Steps.
Minimum and maximum borrow are checked when the calldata is built, not when you confirm. Broadcasting an out-of-range amount reverts on-chain rather than returning BELOW_MIN_BORROW or EXCEEDS_MAX_BORROW. With a signedPrice, the maximum borrow is computed at the signed price, because the contract applies it before it prices the collateral.

Error Codes

The price, supply-cap, collateral-value and liquidity checks run in the order the contract reverts in. A refusal therefore names the condition the borrower would otherwise have hit on-chain. Confirming with txHash can also return any transaction verification error.