# Quotes

Quotes let you **preview the full cost and outcome of a proposed payment before you initiate it**. A quote reflects the **exchange rate**, **fees**, and **deliverable amount** between a source and destination currency, and it is **time-sensitive** (quotes expire after a defined period). Quotes are central to the Ripple Payments Direct 2.0 payment flow and should be created *before* you call the Payments endpoint.

## What a quote includes

A quote returns the key information you need to decide whether to proceed with a payment, including:

- **Source and destination amounts** (`sourceAmount`, `destinationAmount`) depending on whether you request a quote by source amount or destination amount. Amounts are rounded to the number of decimal places defined by the [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) standard for the relevant currency (for example, 2 for USD/EUR, 0 for JPY/KRW, 3 for BHD/KWD), using HALF_UP rounding.
- **Adjusted exchange rate** (`adjustedExchangeRate`) that reflects the rate used for conversion.
- **Fees** (`fees`) with a total fee and optional breakdown line items.
- **Taxes** (`taxes`) when applicable (taxes apply to Ripple service fees, not principal).
- **Timestamps and validity** (`createdAt`, `expiresAt`) and a **status** (`ACTIVE` or `EXPIRED`).


## How quotes fit into the payment flow

A typical flow is:

1. **Create a quote collection** for a proposed payment (returns one quote per supported payment rail for the requested corridor).
2. **Select a quote** (use the returned quoteId).
3. **Create the payment** using the quote information.


Important
In Ripple Payments Direct 2.0, a quote must be accepted/used before it expires. Expired quotes are marked `EXPIRED` and can’t be used to create payments.

Implementation note
Internally, quote IDs are used in payment creation such that the `quoteId` used becomes the `paymentId`. Make sure your integration treats quote identifiers consistently across quote → payment steps.

## Quote collections vs. quotes

A **quote collection** groups all available quotes for a proposed payment into a single response. Each quote in the collection represents a different payment rail available for the requested currency corridor. For example, a USD-to-EUR request may return separate quotes for `SEPA_INSTANT` and `SEPA_STANDARD`, each with its own fees and exchange rate.

If you specify a `paymentRail` in your request, the collection contains only that rail's quote. If you omit `paymentRail`, quotes are returned for all supported rails in your corridor.

Quote collections exist as a distinct resource to support retrieval, traceability, and comparison across rails. Use the quote collection ID to retrieve the original set of quotes; use an individual quote ID to retrieve or act on a specific quote.

V3 required
Multi-rail quote collections are available on the `/v3/quotes/quote-collection` endpoint only. If your integration uses the `/v2/` endpoint, you will continue to receive single-quote responses and will not see per-rail quotes until you migrate to `/v3/`.

## Quote expiration and status

Quotes are time-sensitive:

- `quoteStatus=ACTIVE` means the quote can be used to create a payment.
- `quoteStatus=EXPIRED` means the quote is no longer valid and must be regenerated.
- Use `expiresAt` to implement client-side logic (for example, refresh the quote if the expiration time is near).


## Taxes in quotes (fees only)

In jurisdictions where Ripple is required to comply with consumption tax regulations (VAT/GST, etc.), quote responses can include taxes applied to Ripple service fees (fixed/variable fee components), not to the principal payment amount.

**Key aspects:**

- Tax calculations provide upfront cost transparency.
- Taxes are calculated on the **fees portion**, not the amount being transferred.
- If no taxes apply (or the calculated tax is zero), the API will not include the `taxes` object in the response.


## Endpoints

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.

Use these endpoints to create and retrieve quotes:

- `POST /v3/quotes/quote-collection`: Create a quote collection for a proposed payment.
- `GET /v3/quotes/quote-collection/{quote-collection-id}`: Retrieve a previously created quote collection.
- `GET /v3/quotes/{quote-id}`: Retrieve a specific quote by ID.


## Funding model (payinCategory)

The `payinCategory` field specifies how you fund the payment. The following values are supported:

| Value | Description |
|  --- | --- |
| `PRE_FUNDING` | The payment is funded from a balance you have pre-deposited with Ripple. Use this for funded account models where you maintain a prefunded ledger balance. |
| `CREDIT_FUNDING` | The payment is settled via an outstanding invoice. Ripple executes the payment and invoices you for the amount afterward. |
| `JIT_FUNDING` | The payment is funded just-in-time: you must transfer the funds to your Ripple ledger account before the payment expires. See [JIT-funded payments](#jit-funded-payments) below. |


Migrating from v2?
The values `FUNDED` and `T_PLUS_ONE` were accepted by the v2 endpoint but are **not valid** for `/v3/quotes/quote-collection`. Sending either value to the v3 endpoint returns a validation error. Use `PRE_FUNDING` in place of `FUNDED`, and `CREDIT_FUNDING` in place of `T_PLUS_ONE`.

### JIT-funded payments

When you use `JIT_FUNDING`, the payment enters an `AWAITING_FUNDING` state after it is created. You must transfer the required funds to your Ripple ledger account before the `jitFundingExpiresAt` timestamp on the payment object. If funding is not received in time, the payment expires and you must create a new quote and payment.

For more information on payment states including `AWAITING_FUNDING`, see [Payment states](/products/payments-direct-2/api-docs/concepts/payment-states).

## Required inputs for quoting

To create a quote collection, provide:

- `quoteAmount` and `quoteAmountType` (`SOURCE_AMOUNT` or `DESTINATION_AMOUNT`)
- `sourceCurrency`, `destinationCurrency`
- `payinCategory` (`PRE_FUNDING`, `CREDIT_FUNDING`, or `JIT_FUNDING`)
- Optional: `sourceCountry`, `destinationCountry`
- Optional: `paymentRail`: filters quotes to a specific payment rail. When omitted, quotes are returned for all supported rails.


## Error handling

Authentication failures return standard HTTP 401/403 responses from the authorization layer. Quote Service-specific errors use three prefixes:

- **USR_xxx**: validation errors (missing or invalid request fields)
- **SYS_xxx**: internal or upstream failures
- **CFG_xxx**: configuration errors (for example, unsupported corridor or missing tenant configuration)


Errors return a structured object with a status and an `errors` array. Each entry in the array includes: `code`, `title`, `type`, `description`, and `timestamp`.

## Best practices

- Use `SOURCE_AMOUNT` when the sender knows what they want to send.
- Use `DESTINATION_AMOUNT` when the sender needs the beneficiary to receive an exact amount.


## Example: Create a quote collection

This example requests quotes for a USD-to-EUR payment. Because two payment rails are supported for this corridor (SEPA Instant and SEPA Standard), the response contains one quote per rail. You select the quote that best fits your needs before creating the payment.

**Request**


```bash
curl -i -X POST \
  https://{base-url}/v3/quotes/quote-collection \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "quoteAmount": 1000.00,
    "quoteAmountType": "SOURCE_AMOUNT",
    "sourceCurrency": "USD",
    "destinationCurrency": "EUR",
    "sourceCountry": "US",
    "destinationCountry": "DE",
    "payinCategory": "PRE_FUNDING"
  }'
```

**Response (excerpt)**


```json
{
  "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.000123Z",
      "expiresAt": "2025-11-02T18:41:00.000123Z"
    },
    {
      "quoteId": "9fb4500d-2345-6789-9e9g-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.000123Z",
      "expiresAt": "2025-11-02T18:41:00.000123Z"
    }
  ]
}
```