Skip to content

Deposit to Perps

Moves an asset from one of the portfolio's trading vaults into the perps account. Unlike withdrawals, no wallet signature is required: the trading vault is custodied by Definitive, so a WRITE-scoped API key is sufficient and the transfer is executed server-side.

  1. POST /perps/deposit/vault-fund-hl/quote — prices the transfer and returns a quoteId.
  2. POST /perps/deposit/vault-fund-hl — executes the quoted transfer and returns a requestId.

Endpoints

Portfolio API: POST https://ddp.definitive.fi/v2/portfolio/perps/deposit/vault-fund-hl/quote and POST https://ddp.definitive.fi/v2/portfolio/perps/deposit/vault-fund-hl

Organization API: Replace /v2/portfolio/ with /v2/organization/portfolios/{portfolioId}/. See Portfolio vs. Organization API.

Both require a WRITE-scoped API key (all POST endpoints do).

Identifying the source and destination

FieldWhere it comes from
sourceVaultIdA vault of the key's portfolio — vaults[].vaultId on Portfolio Details. The asset is sent from this vault.
fromAssetAddressContract address of the asset to send, on the source vault's own chain. Unrecognized addresses return 400.
destinationPortfolioIdThe portfolio whose perps account receives the funds. It must already have a perps account — check Account Status.

Step 1 — Quote the transfer

POST /perps/deposit/vault-fund-hl/quote

FieldTypeRequiredDescription
sourceVaultIdstringYesUUID of the trading vault funding the deposit
destinationPortfolioIdstringYesUUID of the portfolio whose perps account receives the funds
fromAssetAddressstringYesContract address of the asset to send, on the source vault's chain
fromAmountstringYesAmount to send as a positive decimal string, e.g. "250"
const quote = await AuthHelpers.signAndSend({
  path: "/v2/portfolio/perps/deposit/vault-fund-hl/quote",
  method: "POST",
  body: {
    sourceVaultId: "00000000-0000-0000-0000-000000000003",
    destinationPortfolioId: "00000000-0000-0000-0000-000000000001",
    fromAssetAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    fromAmount: "250",
  },
  apiKey: process.env.API_KEY,
  apiSecret: process.env.API_SECRET,
});

Response:

{
  quoteId: "0x9f2c...",
  provider: "relay",
  toAmount: "249.62",
  toAmountRaw: "249620000",
  fromAmountQuotedRaw: "250000000",
  serviceTime: 45,
  gasFeesUsd: 0.38,
  protocols: ["relay"],
  fromAssetInstanceId: "...",
  toAssetInstanceId: "...",
  destinationPerpsVaultId: "..."
}

toAmount is what lands in the perps account after routing and gas; it is normally lower than fromAmount. gasInFromAsset, nativeAssetFromAssetNotional and maxGasCostInNative appear only when the route charges gas in the sent asset.

Step 2 — Execute the transfer

POST /perps/deposit/vault-fund-hl

Repeat the four quote fields exactly as sent in step 1 and add the quoteId you received.

FieldTypeRequiredDescription
quoteIdstringYesThe quoteId returned by step 1
sourceVaultIdstringYesSame value as step 1
destinationPortfolioIdstringYesSame value as step 1
fromAssetAddressstringYesSame value as step 1
fromAmountstringYesSame value as step 1
const json = await AuthHelpers.signAndSend({
  path: "/v2/portfolio/perps/deposit/vault-fund-hl",
  method: "POST",
  body: {
    quoteId: quote.quoteId,
    sourceVaultId: "00000000-0000-0000-0000-000000000003",
    destinationPortfolioId: "00000000-0000-0000-0000-000000000001",
    fromAssetAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    fromAmount: "250",
  },
  apiKey: process.env.API_KEY,
  apiSecret: process.env.API_SECRET,
});

Response:

{
  requestId: "..."
}

The transfer settles asynchronously. Poll /perps/account and watch the account balance rather than treating the response as final settlement.

Errors

StatusMeaningWhat to do
400Invalid body, or fromAssetAddress is not a recognized asset on the source vault's chainCheck the address against the source vault's chain
401Organization API: {portfolioId} is not in your organization; or the source vault does not belong to it, or the destination portfolio is in another organizationUse a portfolio and vault of your own organization
403READ-scoped keyUse a WRITE-scoped key
404Source vault not found, destination portfolio not found, or the destination portfolio has no perps accountCheck the vault id, and Account Status for the destination

Deposit errors are returned by the transfers backend, not the perps service, so they do not carry the errorType field used by the rest of the perps surface — a destination without a perps account is a 404 here and a 422 PERPS_ACCOUNT_NOT_CONFIGURED on the read endpoints.

Notes

  • The deposit endpoints are not behind the perps 20 requests/second limiter; on the Portfolio API they fall under the standard per-key limit.
  • Get the funds back out with Withdraw, which returns USDC to the portfolio's Arbitrum trading vault.