Skip to content

Before you can create a payment, you request a quote collection: a set of priced quotes for a proposed transfer, one for each payment rail supported for the requested corridor. Each quote locks in an exchange rate, fee breakdown, and validity window so you can review the terms before committing to a payment.

This guide covers:

  1. Creating a quote collection, quoting by source or destination amount.
  2. Reading and comparing the response across multiple payment rails.
  3. Handling quote expiry.
  4. Filtering to a specific payment rail.
  5. Retrieving a quote collection or individual quote after creation.

For conceptual background, see Quotes and exchange rates.


Before you begin

To follow this guide, you need:

  • Access to the Payments Direct API UAT environment.
  • A valid OAuth2 access token with the quote_collections:write scope. See Request an access token.
  • The source and destination currencies and countries for the proposed payment.
  • A payinCategory that matches your funding model (PRE_FUNDING, CREDIT_FUNDING, or JIT_FUNDING). See Funding methods.
Enablement required

Access to the /v3/quotes/quote-collection endpoint requires explicit enablement by Ripple. If you attempt to use this endpoint before enablement is complete, requests will fail. Contact your Ripple representative to confirm your account is configured for V3 quotes before beginning integration.


Step 1: Create a quote collection

POST /v3/quotes/quote-collection

A quote collection request specifies the corridor and amount you want to price. The response contains one quote per payment rail supported for that corridor.

Request parameters

ParameterRequiredDescription
quoteAmountYesThe amount to quote.
quoteAmountTypeYesWhether quoteAmount is the send amount (SOURCE_AMOUNT) or the receive amount (DESTINATION_AMOUNT).
sourceCurrencyYesThe currency you are sending (ISO 4217, 3–5 characters).
destinationCurrencyYesThe currency the beneficiary receives (ISO 4217, 3–5 characters).
payinCategoryYesYour funding model: PRE_FUNDING, CREDIT_FUNDING, or JIT_FUNDING.
sourceCountryNoThe sender country (ISO 3166-1 alpha-2).
destinationCountryNoThe beneficiary country (ISO 3166-1 alpha-2).
paymentRailNoFilter quotes to a specific rail. When omitted, all supported rails are returned.

Use SOURCE_AMOUNT when you control how much you want to send. The API calculates how much the beneficiary receives after applying the exchange rate and fees.

In this example, the sender wants to send 1,000 USD to a beneficiary in Germany who receives EUR.

curl -i -X POST \
  https://api.test.ripple.com/v3/quotes/quote-collection \
  -H "Authorization: Bearer <YOUR_JWT_HERE>" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteAmount": 1000.00,
    "quoteAmountType": "SOURCE_AMOUNT",
    "sourceCurrency": "USD",
    "destinationCurrency": "EUR",
    "sourceCountry": "US",
    "destinationCountry": "DE",
    "payinCategory": "PRE_FUNDING"
  }'

Step 2: Review the response

A successful request returns HTTP 201 with a quote collection. The top-level quoteCollectionId identifies the collection; the quotes array contains one entry per supported payment rail.

{
  "quoteCollectionId": "11111111-aaaa-2222-bbbb-222222222222",
  "quotes": [
    {
      "quoteId": "7ea3399c-1234-5678-8d8f-d320ea406630",
      "quoteStatus": "ACTIVE",
      "quoteAmountType": "SOURCE_AMOUNT",
      "sourceAmount": 1000.00,
      "destinationAmount": 921.45,
      "sourceCurrency": "USD",
      "destinationCurrency": "EUR",
      "destinationCountry": "DE",
      "payinCategory": "PRE_FUNDING",
      "paymentRail": "SEPA_INSTANT",
      "adjustedExchangeRate": {
        "adjustedRate": 0.9238
      },
      "fees": [
        {
          "totalFee": 8.50,
          "feeCurrency": "USD",
          "feeBreakdown": [
            {
              "calculatedFee": 0.50,
              "feeName": "Fixed service fee",
              "feeDescription": "Fixed service fee for payment rail SEPA_INSTANT.",
              "paymentRail": "SEPA_INSTANT"
            },
            {
              "calculatedFee": 8.00,
              "feeName": "Variable service fee",
              "feeDescription": "Variable service fee for payment rail SEPA_INSTANT.",
              "paymentRail": "SEPA_INSTANT"
            }
          ]
        }
      ],
      "createdAt": "2025-11-02T18:26:00.000Z",
      "expiresAt": "2025-11-02T18:41:00.000Z"
    },
    {
      "quoteId": "9fb4500d-2345-6789-ae9f-e431fb517741",
      "quoteStatus": "ACTIVE",
      "quoteAmountType": "SOURCE_AMOUNT",
      "sourceAmount": 1000.00,
      "destinationAmount": 921.45,
      "sourceCurrency": "USD",
      "destinationCurrency": "EUR",
      "destinationCountry": "DE",
      "payinCategory": "PRE_FUNDING",
      "paymentRail": "SEPA_STANDARD",
      "adjustedExchangeRate": {
        "adjustedRate": 0.9238
      },
      "fees": [
        {
          "totalFee": 5.25,
          "feeCurrency": "USD",
          "feeBreakdown": [
            {
              "calculatedFee": 0.25,
              "feeName": "Fixed service fee",
              "feeDescription": "Fixed service fee for payment rail SEPA_STANDARD.",
              "paymentRail": "SEPA_STANDARD"
            },
            {
              "calculatedFee": 5.00,
              "feeName": "Variable service fee",
              "feeDescription": "Variable service fee for payment rail SEPA_STANDARD.",
              "paymentRail": "SEPA_STANDARD"
            }
          ]
        }
      ],
      "createdAt": "2025-11-02T18:26:00.000Z",
      "expiresAt": "2025-11-02T18:41:00.000Z"
    }
  ]
}

Key fields

FieldDescription
quoteCollectionIdThe ID of this collection. Use it to retrieve the collection later with GET /v3/quotes/quote-collection/{quote-collection-id}.
quoteIdThe ID of an individual quote. Use the quoteId you select to create a payment.
quoteStatusACTIVE means the quote can be used. EXPIRED means the validity window has passed and a new quote collection is required.
paymentRailThe payment network for this quote (for example, SEPA_INSTANT, SEPA_STANDARD, SPEI, US_ACH). Each rail in the collection has its own quote.
adjustedExchangeRate.adjustedRateThe FX rate Ripple will apply. This rate is locked for the duration of the quote's validity window.
fees[].totalFee / feeBreakdownTotal service fee and a line-item breakdown. Fees vary by rail.
taxesApplicable consumption taxes on Ripple's fees (VAT, GST, and so on). Absent when no taxes apply.
createdAt / expiresAtThe quote's validity window. By default, quotes are valid for 15 minutes.

Comparing quotes across rails

When a corridor supports multiple rails, the quotes share the same exchange rate but typically differ in fees and processing speed. Use the totalFee and paymentRail values to select the quote that best fits your needs.

In the example above:

RailTotal feeSpeed
SEPA_INSTANT$8.50 USDSeconds
SEPA_STANDARD$5.25 USD1 business day

Select the quoteId for the rail you want to use and pass it to the Create payment operation.

quoteId and paymentId

The quoteId you select becomes the paymentId when you create the payment. Store it before moving to the next step.


Step 3: Handle quote expiry

Quotes are valid for a limited time (15 minutes by default). Before creating a payment, check that quoteStatus is ACTIVE.

  • If quoteStatus is ACTIVE, the quote can be used to create a payment.
  • If quoteStatus is EXPIRED, the quote can no longer be used. Request a new quote collection, which will reflect the current exchange rate and fees.

Use expiresAt to implement client-side refresh logic, for example, prompting a user to confirm before the quote lapses, or automatically re-quoting when the remaining time falls below a threshold.

remainingSeconds = expiresAt - now()
if remainingSeconds <= 0:
    request a new quote collection

Each quote in a collection shares the same expiresAt. Re-quoting generates a new quoteCollectionId and new quoteId values.


Step 4: Filter to a specific payment rail

If you already know which rail you want to use, include paymentRail in the request to receive a single-item collection. This simplifies response handling when rail selection is fixed by your integration.

curl -i -X POST \
  https://api.test.ripple.com/v3/quotes/quote-collection \
  -H "Authorization: Bearer <YOUR_JWT_HERE>" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteAmount": 10000,
    "quoteAmountType": "SOURCE_AMOUNT",
    "sourceCurrency": "USD",
    "destinationCurrency": "MXN",
    "sourceCountry": "US",
    "destinationCountry": "MX",
    "payinCategory": "PRE_FUNDING",
    "paymentRail": "SPEI"
  }'

The response contains a quotes array with a single entry for the SPEI rail. If the specified rail is not supported for the requested corridor, the API returns a CFG_ error.

For a full list of valid paymentRail values, see Payment rail reference.


Step 5: Retrieve a quote collection

GET /v3/quotes/quote-collection/{quote-collection-id}

Use this endpoint to retrieve a quote collection you created earlier, for example in an async flow where you stored the quoteCollectionId and are checking quote status before initiating a payment.

curl -i -X GET \
  https://api.test.ripple.com/v3/quotes/quote-collection/11111111-aaaa-2222-bbbb-222222222222 \
  -H "Authorization: Bearer <YOUR_JWT_HERE>"

The response schema is identical to the POST response. Check each quote's quoteStatus before proceeding; any quotes in the collection may have expired since they were created.


Step 6: Retrieve an individual quote

GET /v3/quotes/{quote-id}

Use this endpoint to retrieve a specific quote by ID.

curl -i -X GET \
  https://api.test.ripple.com/v3/quotes/7ea3399c-1234-5678-8d8f-d320ea406630 \
  -H "Authorization: Bearer <YOUR_JWT_HERE>"

The response contains the same fields as a single entry from the quotes array, without the quoteCollectionId wrapper.


Error handling

Quote errors return a structured response with a status and an errors array. Each error includes code, title, type, description, and timestamp.

Error codes use three prefixes:

PrefixCategoryCommon causes
USR_Validation errorMissing required fields, invalid currency codes, amounts outside the allowed range (1–100,000,000), or deprecated payinCategory values.
CFG_Configuration errorUnsupported corridor, missing tenant configuration, or a paymentRail value not supported for the requested corridor.
SYS_System errorInternal or upstream FX pricing failure. Retry the request; contact support if the error persists.

Common validation errors

Deprecated payinCategory values: The v3 endpoint does not accept FUNDED or T_PLUS_ONE. Use PRE_FUNDING in place of FUNDED, and CREDIT_FUNDING in place of T_PLUS_ONE.

Invalid currency or country codes: sourceCurrency and destinationCurrency must be 3–5 alphabetic characters. sourceCountry and destinationCountry must be ISO 3166-1 alpha-2 codes (exactly 2 characters).

Unsupported corridor: If the currency pair is not configured for your tenant, the API returns a CFG_ error. Verify the corridor is listed in the Payment rail reference and contact your Ripple representative if the error persists.


What's next

Once you have an ACTIVE quote and have selected a quoteId, you are ready to create a payment.

See Create a payment for a complete walkthrough of the payment creation step, including how to pass the quoteId alongside beneficiary identity and financial instrument IDs.