VantaCrestAlpineVantaCrest
Access →
Alpine/Develop/Transfers
POST /v1/transfers

Transfers

A transfer is two calls and a poll: quote it to see the fee, create it against that quote, then read its status until it settles. Amounts are minor-unit strings; writes carry an Idempotency-Key.

Live in the sandbox

Quote, accept, move, then poll to settled.

Request
POST/v1/transfers/quote
Authorization: Bearer ak_live_7Q4…
{
  "sourceAccountRef": "acc_8xK2",
  "sourceEndpointRef": "ep_7Q4",
  "sourceHoldingRef": "hld_USD",
  "destination": {
    "kind": "internal-endpoint",
    "accountRef": "acc_2Kp9",
    "endpointRef": "ep_2Kp"
  },
  "valueUnit": { "kind": "fiat", "currency": "USD" },
  "amountMinorUnits": "240000",
  "feeInstruction": {
    "kind": "request_application_fee",
    "bearer": "sender_pays",
    "amountMinorUnits": "600"
  }
}
Response200 OK
{
  "quoteBasisTransferRef": "tr_3Vd7Q",
  "amountMinorUnits": "240000",
  "lines": [
    {
      "kind": "app_fee",
      "amountMinorUnits": "600",
      "applicability": "applicable"
    },
    {
      "kind": "platform_fee",
      "amountMinorUnits": "30",
      "applicability": "applicable"
    }
  ],
  "totals": [
    { "amountMinorUnits": "650" }
  ],
  "noFeeReason": null
}
Quote · the fee, up front
Request
POST/v1/transfers
Authorization: Bearer ak_live_7Q4…
Idempotency-Key: 5f3c-tr-3Vd7Q
{
  "sourceAccountRef": "acc_8xK2",
  "sourceEndpointRef": "ep_7Q4",
  "sourceHoldingRef": "hld_USD",
  "destination": {
    "kind": "internal-endpoint",
    "accountRef": "acc_2Kp9",
    "endpointRef": "ep_2Kp"
  },
  "valueUnit": { "kind": "fiat", "currency": "USD" },
  "amountMinorUnits": "240000",
  "feeInstruction": {
    "kind": "request_application_fee",
    "bearer": "sender_pays",
    "amountMinorUnits": "600"
  }
}
Response201 Created
{
  "transferRef": "tr_3Vd7Q",
  "stage": "reservation_pending",
  "revision": 1,
  "amountMinorUnits": "240000",
  "valueUnit": { "kind": "fiat", "currency": "USD" },
  "requestedBy": "key_7Q4"
}
Move money
Request
GET/v1/transfers/tr_3Vd7Q/status
Authorization: Bearer ak_live_7Q4…
Response200 OK
{
  "transferRef": "tr_3Vd7Q",
  "status": "completed",
  "isTerminal": true,
  "isSuccessful": true,
  "fees": {
    "status": "settled",
    "lines": [
      { "kind": "app_fee", "amountMinorUnits": "600" },
      { "kind": "platform_fee", "amountMinorUnits": "30" }
    ]
  }
}
Status · to settled

The reservation lifecycle.

accepted

The request is valid and admitted.

reservation_pending

The reserve is being placed on the source: value held before it moves.

awaiting_provider_dispatch

On its way to the provider rail.

awaiting_finality

Submitted; waiting on the provider's finality signal.

completed

Final on the rail. The fee is collected and the reserve released.

Operations
POST/v1/transfers/quoteQuote a transfer: every fee, up front.
POST/v1/transfersCreate a transfer.idempotent
GET/v1/transfers/{transferRef}/statusRead a transfer's status.

Quote before you move

POST the same body to /v1/transfers/quote first. It returns every fee line, your application_fee and the platform_fee, and a total, so the cost is known before a single unit moves. A waiver (intrabank, policy, or no configured fee) comes back as a noFeeReason.

Accept the quote, exactly

Pass the quote back as acceptedQuote with a tolerance. The default, kind: "exact", refuses to move if the price has shifted by a unit. You can instead allow_increase_by_unit within stated limits. The price you saw is the price you pay.

Idempotent by header

Every write — create, lifecycle, sandbox credit — requires an Idempotency-Key. Retry the same key and you get the same transfer back, never a second one. The network can fail; the ledger will not double.

Reserved, then settled

The 201 returns the transfer at stage reservation_pending: the reserve is being placed on the source, value held before it moves. Finality comes from the provider rail; poll the status until isTerminal is true. Then the fee is collected and the reserve released.

When it fails
400invalid-InputThe body fails validation, or the accepted quote no longer holds within tolerance.
401unauthorized-MissingCredentialMissing or invalid bearer key.
403forbidden-PermissionDeniedThe key lacks TransferCreate.
409conflict-…The state has moved, or an Idempotency-Key was reused with a different body: the original wins.