---
title: "Create a transfer quote"
method: POST
path: "/agents/me/quotes"
tags: ["Agent Operations"]
---

# Create a transfer quote

`POST /agents/me/quotes`

Generate a quote for a cross-currency transfer on behalf of the authenticated agent's customer. Accounts referenced in the request must belong to the agent's customer. Requires the CREATE_QUOTES permission in the agent's policy.
If the agent's defaultExecutionMode is APPROVAL_REQUIRED, or the quote amount exceeds the agent's approvalThresholds, the resulting transaction will require explicit approval before funds move.

## Headers

- `Idempotency-Key` string

## Request body

- QuoteRequest
  - `lookupId` string — Lookup ID from a previous receiver lookup request. If provided, this can make the quote creation more efficient by reusing cached lookup data. NOTE: This is required for UMA destinations due to counterparty institution requirements. See `senderCustomerInfo` for more information.
  - `source` union, required
    - AccountQuoteSource — Source account details
      - `sourceType` 'ACCOUNT', required — Type of quote funding source
      - `accountId` string, required — Source account identifier
      - `customerId` string — Required when funding from an FBO account to identify the customer on whose behalf the transaction is being initiated. Otherwise, will default to the customerId of the account owner.
    - RealtimeFundingQuoteSource — Fund the quote using a real-time funding source (RTP, SEPA Instant, Spark, Stables, etc.). This will require manual just-in-time funding using `paymentInstructions` in the response. Because quotes expire quickly, this option is only valid for instant payment methods. Do not try to fund a quote with a non-instant payment method (ACH, etc.).
      - `sourceType` 'REALTIME_FUNDING', required — Type of quote funding source
      - `customerId` string — Source customer ID. If this transaction is being initiated on behalf of a customer, this is required. If customerId is not provided, the quote will be created on behalf of the platform itself.
      - `currency` string, required — Currency code for the funding source. See [Supported Currencies](https://docs.lightspark.com/platform-overview/core-concepts/currencies-and-rails) for the full list of supported fiat and crypto currencies.
      - `cryptoNetwork` string — The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit on, so the correct deposit address can be generated. Example values: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `SPARK`, `LIGHTNING`, `BITCOIN`.
  - `destination` union, required
    - AccountDestination — Destination account details
      - `destinationType` 'ACCOUNT', required — Type of payment destination
      - `accountId` string, required — Destination account identifier
      - `paymentRail` 'ACH' | 'ACH_COLOMBIA' | 'BANK_TRANSFER' | 'BRE_B' | 'CIPS' | 'FAST' | 'FASTER_PAYMENTS' | 'FEDNOW' | 'INSTAPAY' | 'MOBILE_MONEY' | 'NEFT' | 'PAYNOW' | 'PESONET' | 'PIX' | 'RTGS' | 'RTP' | 'SEPA' | 'SEPA_INSTANT' | 'SPEI' | 'SWIFT' | 'UNIONPAY' | 'UPI' | 'WIRE' — The payment rail to use for the transfer. Must be one of the rails supported by the destination account. If not specified, the system will select a default rail.
    - UmaAddressDestination — UMA address destination details
      - `destinationType` 'UMA_ADDRESS', required — Type of payment destination
      - `umaAddress` string, required — UMA address of the recipient
      - `currency` string — Currency code for the destination. See [Supported Currencies](https://docs.lightspark.com/platform-overview/core-concepts/currencies-and-rails) for the full list of supported fiat and crypto currencies.
  - `lockedCurrencySide` 'SENDING' | 'RECEIVING', required — The side of the quote which should be locked and specified in the `lockedCurrencyAmount`. For example, if I want to send exactly $5 MXN from my wallet, I would set this to "sending", and the `lockedCurrencyAmount` to 500 (in cents). If I want the receiver to receive exactly $10 USD, I would set this to "receiving" and the `lockedCurrencyAmount` to 10000 (in cents).
  - `lockedCurrencyAmount` integer, required — The amount to send/receive in the smallest unit of the locked currency (eg. cents). See `lockedCurrencySide` for more information.
  - `immediatelyExecute` boolean — Whether to immediately execute the quote after creation. If true, the quote will be executed and the transaction will be created at the current exchange rate. It should only be used if you don't want to lock and view rate details before executing the quote. If you are executing a pre-existing quote, use the `/quotes/{quoteId}/execute` endpoint instead. This is false by default. This can only be used for quotes with a `source` which is either an internal account, or has direct pull functionality (e.g. ACH pull with an external account). Not supported when the `source` is an internal account of type `EMBEDDED_WALLET`: those transfers require a `Grid-Wallet-Signature` over the `payloadToSign` returned in the quote response, which is not available in a combined create-and-execute call. Create the quote first with `immediatelyExecute: false` and then call `POST /quotes/{quoteId}/execute` with the `Grid-Wallet-Signature` stamp header.
  - `description` string — Optional description/memo for the transfer
  - `remittanceInformation` string — Free-form information about the payment that travels with it to the recipient. The field this populates depends on the payment rail: for ACH it populates the Addenda record, for FedNow and RTP it populates the remittanceInformation field, and for wires it populates the OBI (Originator to Beneficiary Information) / beneficiary information.
  - `purposeOfPayment` 'GIFT' | 'SELF' | 'GOODS_OR_SERVICES' | 'EDUCATION' | 'HEALTH_OR_MEDICAL' | 'REAL_ESTATE_PURCHASE' | 'TAX_PAYMENT' | 'LOAN_PAYMENT' | 'UTILITY_BILL' | 'DONATION' | 'TRAVEL' | 'FAMILY_SUPPORT' | 'SALARY_PAYMENT' | 'OTHER' — The purpose of the payment. This may be required when sending to certain geographies (e.g. India).
  - `platformFeeOverride` PlatformFeeOverride — Overrides the platform-collected fee for this transaction. When present, it replaces any configured platform-collected fees that would otherwise apply to the transaction. Currently only supported when the quote's source currency is USD; the fixed fee must be denominated in the source currency.
    - `platformFixedFee` FixedFee, required — Fixed fee charged per transaction.
      - `amount` integer, required — Fee amount in the smallest unit of the fixed fee's `currency` (e.g., cents for USD).
      - `currency` string, required — Three-letter currency code (ISO 4217) the fixed fee is denominated in. Some cryptocurrencies may use their own ticker symbols (e.g. "BTC" for Bitcoin, "USDC" for USDC, etc.)
    - `platformVariableFeeBps` integer, required — Variable fee in basis points (1 bps = 0.01%) to apply to the transaction's source-currency amount.
  - `scaFactor` 'SMS_OTP' | 'TOTP' | 'PASSKEY' — A Strong Customer Authentication factor. | Factor | Description | |--------|-------------| | `SMS_OTP` | One-time code sent by SMS to the customer's verified phone. Requires no prior enrollment. | | `TOTP` | Time-based one-time code from an authenticator app. Requires enrollment. Not valid for per-transaction challenges (cannot carry dynamic linking). | | `PASSKEY` | WebAuthn passkey assertion. Requires enrollment. |
  - `senderCustomerInfo` object — Key-value pairs of additional information about the sender which was requested by the destination. This is relevant when the destination requires more sender info than was provided during customer creation. Any fields specified in `requiredPayerDataFields` from the response of the `/receiver/uma/{receiverUmaAddress}` (lookupUma) or `/receiver/external-account/{accountId}` (lookupExternalAccount) endpoints MUST be provided here if they were requested. If the destination did not request any additional information, this field can be omitted.

## Response `201`

Transfer quote created successfully

- Quote
  - `id` string, required — Unique identifier for this quote
  - `status` 'PENDING' | 'PENDING_AUTHORIZATION' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED', required — Current status of the quote. `PENDING_AUTHORIZATION` occurs only for customers in a region where Strong Customer Authentication is required (e.g. EU): the quote carries an `scaChallenge` that must be authorized before execution, and for realtime-funding sources `paymentInstructions` are withheld until it is satisfied.
  - `createdAt` string, date-time, required — When this quote was created
  - `expiresAt` string, date-time, required — Absolute UTC timestamp when the rate locked in this quote becomes invalid and the quote can no longer be executed. The window depends on the rail and corridor: instant rails (Lightning, Spark, USDC on Solana/Base/Polygon, RTP, SEPA Instant) typically expire in 1–5 minutes; corridors with longer settlement guarantees may have longer windows. Always rely on this timestamp rather than assuming a fixed window.
  - `source` union, required
    - AccountQuoteSource — Source account details
      - `sourceType` 'ACCOUNT', required — Type of quote funding source
      - `accountId` string, required — Source account identifier
      - `customerId` string — Required when funding from an FBO account to identify the customer on whose behalf the transaction is being initiated. Otherwise, will default to the customerId of the account owner.
    - RealtimeFundingQuoteSource — Fund the quote using a real-time funding source (RTP, SEPA Instant, Spark, Stables, etc.). This will require manual just-in-time funding using `paymentInstructions` in the response. Because quotes expire quickly, this option is only valid for instant payment methods. Do not try to fund a quote with a non-instant payment method (ACH, etc.).
      - `sourceType` 'REALTIME_FUNDING', required — Type of quote funding source
      - `customerId` string — Source customer ID. If this transaction is being initiated on behalf of a customer, this is required. If customerId is not provided, the quote will be created on behalf of the platform itself.
      - `currency` string, required — Currency code for the funding source. See [Supported Currencies](https://docs.lightspark.com/platform-overview/core-concepts/currencies-and-rails) for the full list of supported fiat and crypto currencies.
      - `cryptoNetwork` string — The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit on, so the correct deposit address can be generated. Example values: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `SPARK`, `LIGHTNING`, `BITCOIN`.
  - `destination` union, required
    - AccountDestination — Destination account details
      - `destinationType` 'ACCOUNT', required — Type of payment destination
      - `accountId` string, required — Destination account identifier
      - `paymentRail` 'ACH' | 'ACH_COLOMBIA' | 'BANK_TRANSFER' | 'BRE_B' | 'CIPS' | 'FAST' | 'FASTER_PAYMENTS' | 'FEDNOW' | 'INSTAPAY' | 'MOBILE_MONEY' | 'NEFT' | 'PAYNOW' | 'PESONET' | 'PIX' | 'RTGS' | 'RTP' | 'SEPA' | 'SEPA_INSTANT' | 'SPEI' | 'SWIFT' | 'UNIONPAY' | 'UPI' | 'WIRE' — The payment rail to use for the transfer. Must be one of the rails supported by the destination account. If not specified, the system will select a default rail.
    - UmaAddressDestination — UMA address destination details
      - `destinationType` 'UMA_ADDRESS', required — Type of payment destination
      - `umaAddress` string, required — UMA address of the recipient
      - `currency` string — Currency code for the destination. See [Supported Currencies](https://docs.lightspark.com/platform-overview/core-concepts/currencies-and-rails) for the full list of supported fiat and crypto currencies.
  - `sendingCurrency` Currency, required
    - `code` string — Three-letter currency code (ISO 4217) for fiat currencies. Some cryptocurrencies may use their own ticker symbols (e.g. "BTC" for Bitcoin, "USDC" for USDC, etc.)
    - `name` string — Full name of the currency
    - `symbol` string — Symbol of the currency
    - `decimals` integer — Number of decimal places for the currency
  - `receivingCurrency` Currency, required
    - `code` string — Three-letter currency code (ISO 4217) for fiat currencies. Some cryptocurrencies may use their own ticker symbols (e.g. "BTC" for Bitcoin, "USDC" for USDC, etc.)
    - `name` string — Full name of the currency
    - `symbol` string — Symbol of the currency
    - `decimals` integer — Number of decimal places for the currency
  - `totalSendingAmount` integer, required — The total amount that will be sent in the smallest unit of the sending currency (eg. cents).
  - `totalReceivingAmount` integer, required — The total amount that will be received in the smallest unit of the receiving currency (eg. cents).
  - `exchangeRate` number, required — Number of sending currency units per receiving currency unit.
  - `feesIncluded` integer, required — The fees associated with the quote in the smallest unit of the sending currency (eg. cents). Note: this value may fluctuate between quotes — some underlying fee components are defined in the receiving currency, so their equivalent in the sending currency moves with the FX rate. The fees shown here are locked only for the lifetime of this quote.
  - `platformFeesIncluded` integer — The portion of `feesIncluded` collected by the platform (platform-configured transaction fees), in the smallest unit of the sending currency. 0 when the platform has no applicable fee configured. Already included in `feesIncluded`. May be omitted from payloads produced before platform fees existed.
  - `paymentInstructions` PaymentInstructions[] — Payment instructions for executing the payment. This is not required when using an internal account source. — unresolved $ref
  - `transactionId` string, required — The ID of the transaction created from this quote.
  - `counterpartyInformation` CounterpartyInformation — Additional information about the counterparty, if available and relevant to the transaction and platform.
  - `rateDetails` OutgoingRateDetails — Details about the rate and fees for an outgoing transaction or quote. Note: `counterpartyFixedFee` is denominated in the receiving currency, so its equivalent value in the sending currency fluctuates with the FX rate. As a result, the total fee on a subsequent quote for the same transfer may differ even if the underlying fee structure is unchanged.
    - `counterpartyMultiplier` number, double, required — The underlying multiplier from mSATs to the receiving currency as returned by the counterparty institution.
    - `counterpartyFixedFee` integer, required — The fixed fee charged by the counterparty institution to execute the quote in the smallest unit of the receiving currency (eg. cents).
    - `gridApiMultiplier` number, double, required — The underlying multiplier from the sending currency to mSATS, including variable fees.
    - `gridApiFixedFee` integer, required — The fixed fee charged by the Grid product to execute the quote in the smallest unit of the sending currency (eg. cents).
    - `gridApiVariableFeeRate` number, double, required — The variable fee rate charged by the Grid product to execute the quote as a percentage of the sending currency amount.
    - `gridApiVariableFeeAmount` number, required — The variable fee amount charged by the Grid product to execute the quote in the smallest unit of the sending currency (eg. cents). This is the sending amount times gridApiVariableFeeRate.
  - `scaChallenge` ScaChallenge — A Strong Customer Authentication challenge that must be satisfied before a money-movement operation can complete. This object is **only present when the customer is in a region where SCA is required** (the EU); for customers outside SCA-regulated regions it is omitted entirely and no action is needed. When present on a quote, authorize it by submitting an `ScaAuthorization` proof to `POST /quotes/{quoteId}/authorize`. **A single operation may require more than one authorization, in sequence.** Treat `scaChallenge` as *the challenge to satisfy now*, not "the only one". After each authorize, re-inspect the returned quote/transaction: if it is still `PENDING_AUTHORIZATION`, it carries the **next** `scaChallenge` (a new `id`) — authorize that too, and repeat until it leaves `PENDING_AUTHORIZATION`. Do not assume one authorization releases the transfer. The number of authorizations is flow-dependent and **may decrease in future**: for example, a cross-currency send today authorizes the currency conversion and the payout as two separate challenges; a future update may collapse them into one. A client written to loop on status handles any count unchanged.
    - `id` string, required — Unique identifier for this challenge. The server resolves the active challenge from the quote or transaction being authorized, so this field need not be supplied back; it is informational (e.g. for logging or correlation).
    - `expiresAt` string, date-time, required — Absolute UTC timestamp after which this challenge can no longer be authorized.
    - `factor` 'SMS_OTP' | 'TOTP' | 'PASSKEY', required — A Strong Customer Authentication factor. | Factor | Description | |--------|-------------| | `SMS_OTP` | One-time code sent by SMS to the customer's verified phone. Requires no prior enrollment. | | `TOTP` | Time-based one-time code from an authenticator app. Requires enrollment. Not valid for per-transaction challenges (cannot carry dynamic linking). | | `PASSKEY` | WebAuthn passkey assertion. Requires enrollment. |
    - `availableFactors` ScaFactor[], required — The factors the customer may use to satisfy this challenge.
    - `purpose` string, nullable — Optional, informational label for what this particular challenge in the sequence authorizes — useful for step UX (e.g. "Authorize the currency conversion" vs "Authorize the payout"). Known values include `CURRENCY_CONVERSION`, `PAYOUT`, and `TRANSFER`, but the set is **non-exhaustive and may grow** — treat unrecognized values as a generic authorization step and do not branch program logic on it. Omitted when steps are not distinguished (e.g. a single-authorization flow).
    - `passkeyAssertionOptions` object, nullable — Opaque WebAuthn assertion request options (including the relying-party id, challenge, and allowed credentials), present only when `factor` is `PASSKEY`. Pass to the device's WebAuthn API to produce the assertion submitted back in `ScaAuthorization.passkeyAssertion`.
    - `passkeyAllowedOrigins` string[], nullable — The origins the WebAuthn ceremony may run against. Populated for enrollment and login passkey challenges; the origin the assertion is produced against must be one of these and echoed back as `ScaAuthorization.origin`. Per-transaction passkey challenges omit this (they carry `passkeyAssertionOptions` only) — see `ScaAuthorization.origin` for how to source the origin in that case.

## Other responses

- `400` — Bad request - Missing or invalid parameters
- `401` — Unauthorized
- `403` — Forbidden - Agent policy does not permit this operation
- `412` — Counterparty doesn't support UMA version
- `424` — Counterparty issue
- `500` — Internal service error

---

[API](https://skmtc.net/stainless-api/apis/grid-api.md) · [All operations](https://skmtc.net/stainless-api/apis/grid-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/stainless-api/grid-api/revisions/27ff0fdca01c/schema)
