> ## Documentation Index
> Fetch the complete documentation index at: https://docs.relay.link/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating to Requests v3

> What changed in GET /requests/v3 and how to upgrade from v2.

`GET /requests/v3` is the latest version of the Requests API. It gives you a richer query surface with advanced filtering across status, chains, amounts, addresses, time, and more, plus a cleaner and more consistent response. This guide covers every change and how to upgrade. `GET /requests/v2` remains available during a deprecation window (see the [sunset timeline](#sunset-timeline) below) — migrate before it's retired.

<Warning>
  `x-api-key` is now required. Every v3 request authenticates against an active API key. See [API Keys](/references/api/api-keys) for details.
</Warning>

## Sunset timeline

`GET /requests/v2` is **deprecated as of July 22, 2026**. It keeps working, but migrate to `GET /requests/v3` before it's fully retired on **November 24, 2026**.

| Date                   | What changes                                                                                |
| ---------------------- | ------------------------------------------------------------------------------------------- |
| **Jul 22, 2026**       | v2 is deprecated; v3 is the recommended version. v2 keeps working.                          |
| **Sep 1, 2026 onward** | v2's rate limit is progressively reduced each month; requests over the limit receive `429`. |
| **Nov 24, 2026**       | v2 is fully retired — all traffic must be on v3.                                            |

## Response shape

The same request shown in full for v2 and v3, plus a focused diff of what moved.

<Tabs>
  <Tab title="v2">
    ```json expandable theme={null}
    {
      "id": "0x0000348634...",
      "status": "success",
      "user": "0xe7a2052a...",
      "recipient": "0x07082933...",
      "depositAddress": null,
      "moonpayId": null,
      "referrer": "my-app|user-123",
      "data": {
        "slippageTolerance": "0",
        "failReason": "N/A",
        "refundFailReason": "N/A",
        "subsidizedRequest": true,
        "price": "10000000000",
        "currency": "usdc",
        "currencyObject": { "chainId": 8453, "address": "0x833589...", "symbol": "USDC", "name": "USD Coin", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } },
        "feeCurrency": "usdc.e",
        "feeCurrencyObject": { "chainId": 137, "address": "0x2791bc...", "symbol": "USDC.e", "name": "USDCoin (bridged)", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } },
        "appFeeCurrencyObject": { "chainId": 137, "address": "0x2791bc...", "symbol": "USDC.e", "name": "USDCoin (bridged)", "decimals": 6 },
        "fees": { "gas": "1160", "fixed": "0", "price": "1999930" },
        "feesUsd": { "gas": "0.001159", "fixed": "0.000000", "price": "1.999162" },
        "appFees": [ { "recipient": "0xdfd877...", "bps": "5", "amount": "5000000", "amountUsd": "4.997980", "amountUsdCurrent": "4.998080" } ],
        "paidAppFees": [ { "recipient": "0xdfd877...", "bps": "5", "amount": "5000000", "amountUsd": "4.997980", "amountUsdCurrent": "4.998080" } ],
        "subsidizedFee": {
          "origin": { "amount": "7001090", "address": "0x2791bc...", "chainId": 137 },
          "sponsor": { "amount": "7000949", "address": "0x833589...", "chainId": 8453 },
          "amountUsd": "6.998261",
          "amountUsdCurrent": "6.998401"
        },
        "expandedPriceImpact": {
          "quoted": { "swap": { "usd": "-1.999380" }, "execution": { "usd": "-0.001160" }, "relay": { "usd": "0.000000" }, "app": { "usd": "-4.998625" }, "sponsored": { "usd": "6.999165" } },
          "actual": { "swap": { "usd": "-1.999380" }, "execution": { "usd": "-0.001160" }, "relay": { "usd": "0.000000" }, "app": { "usd": "-4.998625" }, "sponsored": { "usd": "6.999165" } }
        },
        "feeSponsorship": {
          "quoted": {
            "selectedComponents": ["execution", "swap", "relay", "app"],
            "capHit": false,
            "components": {
              "execution": { "selected": true, "total": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "1160", "amountFormatted": "0.00116", "amountUsd": "0.001160", "minimumAmount": "1160" }, "sponsored": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "1160", "amountUsd": "0.001160" }, "userPays": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "0", "amountUsd": "0" } },
              "swap": { "selected": true, "total": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "1999380", "amountUsd": "1.999380" }, "sponsored": { "amount": "1999380", "amountUsd": "1.999380" }, "userPays": { "amount": "0", "amountUsd": "0" } },
              "relay": { "selected": true, "total": { "amount": "0", "amountUsd": "0.000000" }, "sponsored": { "amount": "0", "amountUsd": "0" }, "userPays": { "amount": "0", "amountUsd": "0" } },
              "app": { "selected": true, "total": { "amount": "5000000", "amountUsd": "4.998625" }, "sponsored": { "amount": "5000000", "amountUsd": "4.998625" }, "userPays": { "amount": "0", "amountUsd": "0" } }
            },
            "sponsoredTotal": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "7001090", "amountFormatted": "7.00109", "amountUsd": "6.999165" },
            "userPaysTotal": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "0", "amountUsd": "0" }
          },
          "actual": { "selectedComponents": ["execution", "swap", "relay", "app"], "capHit": false, "components": { "execution": "…", "swap": "…", "relay": "…", "app": "…" }, "sponsoredTotal": { "amount": "7001090", "amountUsd": "6.999165" }, "userPaysTotal": { "amount": "0", "amountUsd": "0" } }
        },
        "inTxs": [ { "hash": "0xcd4d70...", "fee": "139725000000000", "block": 87433122, "type": "onchain", "chainId": 137, "timestamp": 1779747672, "status": "success", "data": {}, "stateChanges": [] } ],
        "outTxs": [ { "hash": "0x1c0089...", "fee": "433800000000", "block": 46479163, "type": "onchain", "chainId": 8453, "timestamp": 1779747673, "status": "success", "data": {}, "stateChanges": [] } ],
        "usesExternalLiquidity": false,
        "timeEstimate": 4,
        "metadata": {
          "sender": "0xE7a205...",
          "recipient": "0x070829...",
          "currencyIn": { "currency": { "chainId": 137, "address": "0x2791bc...", "symbol": "USDC.e", "name": "USDCoin (bridged)", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } }, "amount": "10000000000", "amountFormatted": "10000.0", "amountUsd": "9997.600000", "amountUsdCurrent": "9996.000000", "minimumAmount": "10000000000" },
          "currencyOut": { "currency": { "chainId": 8453, "address": "0x833589...", "symbol": "USDC", "name": "USD Coin", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } }, "amount": "10000000000", "amountFormatted": "10000.0", "amountUsd": "9997.600000", "amountUsdCurrent": "9996.000000", "minimumAmount": "10000000000" },
          "rate": "1",
          "route": {
            "origin": { "inputCurrency": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "10000000000" }, "outputCurrency": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "10000000000" }, "router": "relay" },
            "destination": { "inputCurrency": { "currency": { "chainId": 8453, "symbol": "USDC", "decimals": 6 }, "amount": "10000000000" }, "outputCurrency": { "currency": { "chainId": 8453, "symbol": "USDC", "decimals": 6 }, "amount": "10000000000" }, "router": "relay" }
          }
        }
      },
      "protocol": {
        "orderId": "0x...",
        "hubType": "onchain",
        "isWithdrawable": false,
        "solver": { "address": "0x...", "protocolChainId": "8453", "chainId": 8453 },
        "deposit": { "origin": { "amount": "10000000000", "chainId": 137, "currency": "0x2791bc...", "depositor": "0xe7a205...", "depository": "0x...", "onchainId": "0x...", "transactionId": "0xcd4d70..." } },
        "settlement": { "destination": { "fills": [ { "chainId": 8453, "transactionId": "0x1c0089..." } ], "refunds": [] } }
      },
      "createdAt": "2026-05-25T22:21:11.161Z",
      "updatedAt": "2026-05-25T22:21:51.291Z"
    }
    ```
  </Tab>

  <Tab title="v3">
    ```json expandable theme={null}
    {
      "id": "0x0000348634...",
      "status": "success",
      "user": "0xe7a2052a...",
      "sender": "0xE7a205...",
      "recipient": "0x07082933...",
      "refundTo": null,
      "depositAddress": null,
      "requestType": "Bridge",
      "data": {
        "slippageTolerance": "0",
        "failReason": null,
        "refundFailReason": null,
        "failedTxHash": null,
        "failedTxBlockNumber": null,
        "failedCallData": null,
        "usesExternalLiquidity": false,
        "timeEstimate": 4,
        "triggeredByFastFill": null,
        "inTxs": [ { "txHash": "0xcd4d70...", "fee": "139725000000000", "block": 87433122, "type": "onchain", "chainId": 137, "timestamp": 1779747672, "status": "success", "data": {}, "stateChanges": [] } ],
        "outTxs": [ { "txHash": "0x1c0089...", "fee": "433800000000", "block": 46479163, "type": "onchain", "chainId": 8453, "timestamp": 1779747673, "status": "success", "data": {}, "stateChanges": [] } ],
        "appFees": {
          "quoted": [ { "recipient": "0xdfd877...", "bps": "5", "amount": "5000000", "amountFormatted": "5.0" } ],
          "actual": [ { "recipient": "0xdfd877...", "bps": "5", "amount": "5000000", "amountFormatted": "5.0", "amountUsd": "4.997980" } ],
          "currency": { "chainId": 137, "address": "0x2791bc...", "symbol": "USDC.e", "name": "USDCoin (bridged)", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } }
        },
        "fees": {
          "quoted": { "swap": { "usd": "-1.999380", "amount": "1999380", "amountFormatted": "1.99938" }, "execution": { "usd": "-0.001160", "amount": "1160", "amountFormatted": "0.00116" }, "platform": { "usd": "0.000000", "amount": "0", "amountFormatted": "0" }, "app": { "usd": "-4.998625", "amount": "5000000", "amountFormatted": "5.0" }, "sponsored": { "usd": "6.999165", "amount": "7001090", "amountFormatted": "7.00109" } },
          "actual": { "swap": { "usd": "-1.999380" }, "execution": { "usd": "-0.001160" }, "platform": { "usd": "0.000000" }, "app": { "usd": "-4.998625" }, "sponsored": { "usd": "6.999165" } },
          "currency": { "chainId": 137, "address": "0x2791bc...", "symbol": "USDC.e", "name": "USDCoin (bridged)", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } }
        },
        "feeSponsorship": {
          "quoted": {
            "selectedComponents": ["execution", "swap", "platform", "app"],
            "maxSubsidizationAmount": null,
            "capHit": false,
            "components": {
              "execution": { "selected": true, "total": { "amount": "1160", "amountFormatted": "0.00116", "amountUsd": "0.001160", "minimumAmount": "1160" }, "sponsored": { "amount": "1160", "amountUsd": "0.001160" }, "userPays": { "amount": "0", "amountUsd": "0" } },
              "swap": { "selected": true, "total": { "amount": "1999380", "amountUsd": "1.999380" }, "sponsored": { "amount": "1999380", "amountUsd": "1.999380" }, "userPays": { "amount": "0", "amountUsd": "0" } },
              "platform": { "selected": true, "total": { "amount": "0", "amountUsd": "0" }, "sponsored": { "amount": "0", "amountUsd": "0" }, "userPays": { "amount": "0", "amountUsd": "0" } },
              "app": { "selected": true, "total": { "amount": "5000000", "amountUsd": "4.998625" }, "sponsored": { "amount": "5000000", "amountUsd": "4.998625" }, "userPays": { "amount": "0", "amountUsd": "0" } }
            },
            "sponsoredTotal": { "amount": "7001090", "amountFormatted": "7.00109", "amountUsd": "6.999165" },
            "userPaysTotal": { "amount": "0", "amountFormatted": "0", "amountUsd": "0" }
          },
          "actual": { "selectedComponents": ["execution", "swap", "platform", "app"], "capHit": false, "components": { "execution": "…", "swap": "…", "platform": "…", "app": "…" }, "sponsoredTotal": { "amount": "7001090", "amountUsd": "6.999165" }, "userPaysTotal": { "amount": "0", "amountUsd": "0" }, "sponsorPayment": { "amount": "7000949", "address": "0x833589...", "chainId": 8453 } },
          "currency": { "chainId": 137, "address": "0x2791bc...", "symbol": "USDC.e", "decimals": 6 }
        },
        "route": {
          "includedSwapSources": [],
          "includedOriginSwapSources": [],
          "includedDestinationSwapSources": [],
          "quoted": {
            "origin": { "inputCurrency": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "10000000000" }, "outputCurrency": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "10000000000" }, "router": "relay" },
            "destination": { "inputCurrency": { "currency": { "chainId": 8453, "symbol": "USDC", "decimals": 6 }, "amount": "10000000000" }, "outputCurrency": { "currency": { "chainId": 8453, "symbol": "USDC", "decimals": 6 }, "amount": "10000000000" }, "router": "relay" }
          },
          "actual": {
            "rate": "1",
            "origin": { "inputCurrency": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "10000000000" }, "outputCurrency": { "currency": { "chainId": 137, "symbol": "USDC.e", "decimals": 6 }, "amount": "10000000000" }, "router": "relay" },
            "destination": { "inputCurrency": { "currency": { "chainId": 8453, "symbol": "USDC", "decimals": 6 }, "amount": "10000000000" }, "outputCurrency": { "currency": { "chainId": 8453, "address": "0x833589...", "symbol": "USDC", "name": "USD Coin", "decimals": 6, "metadata": { "logoURI": "https://...", "verified": true } }, "amount": "10000000000", "amountFormatted": "10000.0", "amountUsd": "9997.600000" }, "router": "relay" }
          }
        },
        "platformFee": null,
        "quoteOraclePrice": null,
        "referrer": "my-app|user-123",
        "refundCurrencyData": null,
        "externalMetadata": { "moonpayId": null }
      },
      "protocol": {
        "orderId": "0x...",
        "hubType": "onchain",
        "isWithdrawable": false,
        "solver": { "address": "0x...", "protocolChainId": "8453", "chainId": 8453 },
        "deposit": { "origin": { "amount": "10000000000", "chainId": 137, "currency": "0x2791bc...", "depositor": "0xe7a205...", "depository": "0x...", "onchainId": "0x...", "transactionId": "0xcd4d70..." } },
        "settlement": { "destination": { "fills": [ { "chainId": 8453, "transactionId": "0x1c0089..." } ], "refunds": [] } }
      },
      "features": ["app_fees"],
      "createdAt": "2026-05-25T22:21:11.161Z",
      "updatedAt": "2026-05-25T22:21:51.291Z"
    }
    ```
  </Tab>

  <Tab title="Difference">
    ```jsonc expandable theme={null}
    {
      "id": "0x0000348634...",
      "status": "success",
      "moonpayId": null,                          // [!code --]
      "sender": "0xE7a205...",                    // [!code ++] promoted from data.metadata.sender
      "refundTo": null,                           // [!code ++]
      "requestType": "Bridge",                    // [!code ++]
      "depositAddress": null,                     // now an object: { address, type, depositor, depositTxHash, recoveryAddress }
      "referrer": "my-app|user-123",              // [!code --] moved to data.referrer (authenticated)
      "features": ["app_fees"],                   // [!code ++]
      "data": {
        "failReason": "N/A",                      // [!code --]
        "refundFailReason": "N/A",                // [!code --]
        "failReason": null,                       // [!code ++]
        "refundFailReason": null,                 // [!code ++]
        "subsidizedRequest": true,                // [!code --]
        "price": "10000000000",                   // [!code --] removed; read data.route.actual.destination.inputCurrency
        "fees": { "gas": "1160", "fixed": "0", "price": "1999930" }, // [!code --]
        "feesUsd": { "gas": "0.001159" },         // [!code --]
        "currency": "usdc",                       // [!code --]
        "currencyObject": { },                    // [!code --]
        "feeCurrency": "usdc.e",                  // [!code --]
        "feeCurrencyObject": { },                 // [!code --]
        "appFees":     [ { "bps": "5", "amount": "5000000", "amountUsd": "4.99" } ], // [!code --]
        "paidAppFees": [ { "bps": "5", "amount": "5000000", "amountUsd": "4.99" } ], // [!code --]
        "appFees": {                              // [!code ++]
          "quoted": [ { "bps": "5", "amount": "5000000" } ], // [!code ++]
          "actual": [ { "bps": "5", "amount": "5000000", "amountUsd": "4.99" } ], // [!code ++]
          "currency": { "symbol": "USDC.e", "decimals": 6 } // [!code ++]
        },                                        // [!code ++]
        "subsidizedFee": { "amountUsd": "6.99" }, // [!code --]
        "expandedPriceImpact": { "quoted": { "relay": { "usd": "0" } } }, // [!code --]
        "fees": {                                 // [!code ++]
          "quoted": { "swap": {}, "execution": {}, "platform": {}, "app": {}, "sponsored": {} }, // [!code ++]
          "actual": { },                          // [!code ++]
          "currency": { "symbol": "USDC.e", "decimals": 6 } // [!code ++]
        },                                        // [!code ++]
        "feeSponsorship": {
          "quoted": { "selectedComponents": ["execution","swap","relay","app"], "components": { "relay": {} } } // [!code --]
          "quoted": { "selectedComponents": ["execution","swap","platform","app"], "components": { "platform": {} } }, // [!code ++]
          "actual": { "sponsorPayment": { "amount": "...", "chainId": 8453 } }, // [!code ++]
          "currency": { "symbol": "USDC.e", "decimals": 6 } // [!code ++]
        },
        "inTxs":  [ { "hash": "0xcd4d70..." } ],     // [!code --]
        "outTxs": [ { "hash": "0x1c0089..." } ],     // [!code --]
        "inTxs":  [ { "txHash": "0xcd4d70..." } ],   // [!code ++]
        "outTxs": [ { "txHash": "0x1c0089..." } ],   // [!code ++]
        "metadata": { "sender": "…", "currencyIn": {}, "currencyOut": {}, "rate": "1", "route": {} }, // [!code --]
        "route": {                                // [!code ++]
          "includedSwapSources": [],              // [!code ++]
          "quoted": { "origin": {}, "destination": {} }, // [!code ++]
          "actual": { "rate": "1", "origin": {}, "destination": {} } // [!code ++]
        },                                        // [!code ++]
        "referrer": "my-app|user-123",            // [!code ++] authenticated; moved from root
        "externalMetadata": { "moonpayId": null }  // [!code ++]
      }
    }
    ```
  </Tab>
</Tabs>

<Info>
  The full OpenAPI schema lives at [api.relay.link/documentation/json](https://api.relay.link/documentation/json).
</Info>

<Warning>
  **`data.fees` has changed meaning.** The key `fees` is reused for a different shape. In v2, `data.fees` was raw wei (`gas`/`fixed`/`price`/`gateway`). In v3 that object is removed, and `data.fees` now holds the per-component USD breakdown that v2 called `expandedPriceImpact`. Code reading `data.fees.gas` will break — read `data.fees.quoted` / `data.fees.actual` instead.
</Warning>

## What changed

Every individual change, grouped by request side and response side.

### Request & querying

<AccordionGroup>
  <Accordion title="Authentication" icon="key">
    ```bash theme={null}
    GET /requests/v3
    Headers:
    x-api-key: <your-api-key>        # now required [!code ++]
    ```

    The `x-api-key` request header is now required. Every request authenticates against an active API key. See [API Keys](/references/api/api-keys) for details.
  </Accordion>

  <Accordion title="Filtering, search & sorting" icon="magnifying-glass">
    v3 exposes a broad filter surface. All parameters are optional and combine with AND semantics unless noted.

    | Category             | Parameters                                                                                                                         |
    | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
    | **Search**           | `term` (request id, wallet, deposit address, every tx hash), `id`, `orderId`, `depositTxHash`, `fillTxHash`, `refundTxHash`        |
    | **Chain**            | `originChainId`, `destinationChainId`, `chainId` (either direction), `privateChainsToInclude`                                      |
    | **Address**          | `user`, `depositAddress`, `recipient`                                                                                              |
    | **Status / routing** | `status`, `failReason`, `refundFailReason`, `apiKey`, `requestType`                                                                |
    | **Currency**         | `currencyInChainId`, `currencyOutChainId`, `currencyInAddress`, `currencyOutAddress`, `currencyInSymbol`, `currencyOutSymbol`      |
    | **Ranges**           | `startTimestamp`, `endTimestamp`, `startBlock`, `endBlock`, `amountUsdMin`/`Max`, `appFeesAmountUsdMin`/`Max`, `fillTimeMin`/`Max` |
    | **Other**            | `features`, `includeChildRequests`, `filters` (AND/OR), `sortBy`, `sortDirection`, `includeAuthenticatedData`                      |

    <Tip>
      `term` is a single unified search across request id, wallet, deposit address, and every transaction hash (deposit, fill, refund, failed, chain-entry). It replaces the v2 pattern of running separate `user` / `hash` / `id` lookups and merging the results.
    </Tip>

    **Sorting.** `sortBy` accepts `createdAt` (default), `updatedAt`, or `amountUsd`. `sortDirection` is `asc` or `desc` (defaults to `desc` for time fields, `asc` for `amountUsd`).

    **Advanced filtering (AND / OR / negation).** The `filters` parameter takes a JSON-encoded array of groups. Fields **within** a group are AND'd; the groups themselves are OR'd. Any key can be negated with a `not:` prefix, and a field's value may be an array (OR within that field). Top-level parameters still apply.

    ```bash theme={null}
    # "(depositAddress=0xabc AND originChainId=8453) OR (depositAddress=0x123 AND originChainId=1)"
    GET /requests/v3?filters=[{"depositAddress":"0xabc","originChainId":8453},{"depositAddress":"0x123","originChainId":1}]

    # negation + array value: everything except failures and refunds
    GET /requests/v3?filters=[{"not:status":["failure","refund"]}]
    ```

    <Note>OR groups support identity, address, chain, currency, and status-style fields. Range filters and `features` are top-level only.</Note>

    **Removed & changed parameters.**

    * `hash` is removed; use `term`, or the targeted `depositTxHash` / `fillTxHash` / `refundTxHash`.
    * `referrer` is no longer a query parameter; it's still returned in the response, but only when `includeAuthenticatedData=true`.
  </Accordion>
</AccordionGroup>

### Response fields

<AccordionGroup>
  <Accordion title="Currencies — unified to a single object" icon="coins">
    The `currency` (string) + `currencyObject` (object) duality is removed everywhere, along with `feeCurrency`/`feeCurrencyObject` and `appFeeCurrencyObject`. Every currency is a single object: `{ chainId, address, symbol, name, decimals, metadata }`. Amount objects carry that currency plus `amount`, `amountFormatted`, `amountUsd`, and where relevant `amountUsdCurrent`, `minimumAmount`.

    ```jsonc theme={null}
    "currency": "usdc", // [!code --]
    "currencyObject": { "chainId": 137, "symbol": "USDC", "decimals": 6 } // [!code --]
    // read the currency object directly off the amount, [!code ++]
    // e.g. data.route.actual.origin.inputCurrency.currency [!code ++]
    ```
  </Accordion>

  <Accordion title="Fees — expandedPriceImpact → data.fees, relay → platform" icon="receipt">
    `data.expandedPriceImpact` is renamed to **`data.fees`** (and the old wei `data.fees` / `data.feesUsd` are removed). Each phase (`quoted`, `actual`) breaks fees into `swap`, `execution`, `platform`, `app`, and `sponsored`, with the shared currency hoisted to `data.fees.currency`. The `relay` component is renamed to **`platform`**, and per-component values now include `amount` and `amountFormatted` in addition to `usd`.

    ```jsonc theme={null}
    "expandedPriceImpact": { "quoted": { "swap": { "usd": "-1.99" }, "relay": { "usd": "0" } } } // [!code --]
    "fees": { // [!code ++]
      "quoted": { "swap": { "usd": "-1.99", "amount": "...", "amountFormatted": "..." }, "platform": { "usd": "0" } }, // [!code ++]
      "actual": { "...": "..." }, // [!code ++]
      "currency": { "symbol": "USDC.e" } // [!code ++]
    } // [!code ++]
    ```
  </Accordion>

  <Accordion title="Fee sponsorship — single source of truth" icon="hand-holding-dollar">
    `data.subsidizedRequest` and `data.subsidizedFee` are removed. `data.feeSponsorship` is now the only sponsorship source — determine whether a request was sponsored from `feeSponsorship.{quoted,actual}.sponsoredTotal.amountUsd`. The `relay` bucket is renamed to **`platform`**, the shared `currency` is hoisted to `feeSponsorship.currency`, and the `actual` phase gains a `sponsorPayment` object.

    ```jsonc theme={null}
    "subsidizedRequest": true, // [!code --]
    "subsidizedFee": { "amountUsd": "6.99" }, // [!code --]
    "feeSponsorship": {
      "quoted": { "selectedComponents": ["execution","swap","relay","app"], "components": { "relay": {} } } // [!code --]
      "quoted": { "selectedComponents": ["execution","swap","platform","app"], "components": { "platform": {} } }, // [!code ++]
      "actual": { "sponsorPayment": { "amount": "...", "chainId": 8453 } }, // [!code ++]
      "currency": { "symbol": "USDC.e" } // [!code ++]
    }
    ```
  </Accordion>

  <Accordion title="App fees — consolidated into one object" icon="layer-group">
    The parallel `appFees` (quoted) and `paidAppFees` (actual) arrays are consolidated into one object with explicit `quoted` / `actual` keys and a hoisted `currency`.

    ```jsonc theme={null}
    "appFees":     [ { "bps": "5", "amount": "5000000" } ], // [!code --]
    "paidAppFees": [ { "bps": "5", "amount": "5000000", "amountUsd": "4.99" } ], // [!code --]
    "appFees": { // [!code ++]
      "quoted": [ { "bps": "5", "amount": "5000000" } ], // [!code ++]
      "actual": [ { "bps": "5", "amount": "5000000", "amountUsd": "4.99" } ], // [!code ++]
      "currency": { "symbol": "USDC.e" } // [!code ++]
    } // [!code ++]
    ```
  </Accordion>

  <Accordion title="Swap & route — metadata folds into data.route" icon="route">
    The `data.metadata` catch-all is removed. `sender` is promoted to the **root** (next to `recipient`), and everything else moves into **`data.route`**, which now has two phases:

    * `data.route.quoted` — the route as quoted at request time.
    * `data.route.actual` — what actually executed. Carries `rate`, and `actual` falls back to `quoted` when there's no execution data yet (e.g. same-chain swaps).

    Each phase has `origin` and `destination` sides, and each side has `inputCurrency` / `outputCurrency` (each a full amount object) plus `router` (on the `actual` route, `router` reflects the provider that actually filled the leg, not always `"relay"`). `includedSwapSources` / `includedOriginSwapSources` / `includedDestinationSwapSources` are hoisted to the top of `data.route`.

    There is **no `data.swap`** and **no `data.quotedOutputAmount`** — read amounts from the route instead:

    * Amount deposited: `data.route.actual.origin.inputCurrency` (→ `quoted`).
    * Amount received: `data.route.actual.destination.outputCurrency` (→ `quoted`). For same-chain swaps there is no destination side, so fall back to `origin.outputCurrency`.

    ```jsonc theme={null}
    "metadata": { "sender": "…", "currencyIn": {}, "currencyOut": {}, "rate": "1", "route": {} } // [!code --]
    // sender → promoted to the root [!code ++]
    "route": { // [!code ++]
      "includedSwapSources": [], // [!code ++]
      "quoted": { "origin": {}, "destination": {} }, // [!code ++]
      "actual": { "rate": "1", "origin": {}, "destination": {} } // [!code ++]
    } // [!code ++]
    ```
  </Accordion>

  <Accordion title="Transaction hashes — hash → txHash" icon="hashtag">
    Inside `inTxs[]` and `outTxs[]`, the `hash` field is renamed to `txHash`. The array names themselves are unchanged.

    ```jsonc theme={null}
    "inTxs":  [ { "hash": "0xcd4d70..." } ], // [!code --]
    "outTxs": [ { "hash": "0x1c0089..." } ] // [!code --]
    "inTxs":  [ { "txHash": "0xcd4d70..." } ], // [!code ++]
    "outTxs": [ { "txHash": "0x1c0089..." } ] // [!code ++]
    ```
  </Accordion>

  <Accordion title="Statuses — new values" icon="signal">
    The response `status` enum is now `pending`, `waiting`, `depositing`, `submitted`, `success`, `failure`, `refund`. `depositing` and `submitted` are new; the v2 `delayed` value is gone. The `status` **filter** accepts `success`, `failure`, `refund`, `pending`, `depositing`.

    ```jsonc theme={null}
    status ∈ { pending, waiting, delayed, success, failure, refund } // [!code --]
    status ∈ { pending, waiting, depositing, submitted, success, failure, refund } // [!code ++]
    ```
  </Accordion>

  <Accordion title="Moved, added & nulled fields" icon="arrows-up-down-left-right">
    * `moonpayId` moves from the root to **`data.externalMetadata.moonpayId`**.
    * `sender` is **promoted to the root** (next to `recipient`); it previously lived in `data.metadata.sender`.
    * `referrer` moves into **`data.referrer`** and is returned **only when `includeAuthenticatedData=true`**. It's also no longer a query parameter.
    * **`refundTo`** (refund target for deposit-address transactions) is **added** at the root.
    * **`requestType`** (`Bridge`, `Crosschain Swap`, `Same-chain Swap`, `Send`, `Wrap`, `Unwrap`, `Call`) is **added** at the root.
    * **`features`** (e.g. `gasless_execution`, `fast_fill`, `gas_top_up`, `app_fees`, `deposit_address`) is **added** at the root.
    * **`depositAddress`** is now a structured object: `{ address, type: "strict" | "open", depositor, depositTxHash, recoveryAddress }`. `recoveryAddress` is the origin-chain address that can recover deposit-address funds if the recipient wallet is later blocked (`null` when not set).
    * **`supersededByRequestId`** is **promoted to the root**; it previously lived at `data.supersededByRequestId` in v2. When a deposit-address request is regenerated (currently Bitcoin/BVM only), the original request's `supersededByRequestId` points to the regenerated `requestId` that owns the sweep and fill. `null` otherwise.
    * **`data.quoteOraclePrice`** is **added** — the oracle price snapshot at quote time (`{ rate, observedAt, inputCurrency, outputCurrency }`), returned only for fixed-BPS oracle integrators; `null` otherwise.
    * `data.price` is **removed** — read the quoted output amount from `data.route.actual.destination.inputCurrency` (distinct from the actual received amount in `data.route.actual.destination.outputCurrency`).
    * `failReason` / `refundFailReason` use **`null`** instead of the string `"N/A"`.
  </Accordion>
</AccordionGroup>

## Field migration reference

<AccordionGroup>
  <Accordion title="Renamed & restructured" icon="pen-to-square">
    | v2                                                             | v3                                                               |
    | -------------------------------------------------------------- | ---------------------------------------------------------------- |
    | `data.expandedPriceImpact`                                     | `data.fees` (component `relay` → `platform`)                     |
    | `data.metadata.sender`                                         | `sender` (root)                                                  |
    | `data.metadata.recipient`                                      | `recipient` (root)                                               |
    | `data.metadata.{currencyIn,currencyOut,rate,currencyGasTopup}` | `data.route.{quoted,actual}.*`                                   |
    | `data.metadata.route`                                          | `data.route.{quoted,actual}`                                     |
    | `data.appFees` (quoted) + `data.paidAppFees` (actual)          | `data.appFees.{quoted,actual,currency}`                          |
    | `inTxs[].hash` / `outTxs[].hash`                               | `inTxs[].txHash` / `outTxs[].txHash`                             |
    | `feeSponsorship…components.relay`                              | `feeSponsorship…components.platform`                             |
    | `moonpayId` (root)                                             | `data.externalMetadata.moonpayId`                                |
    | `depositAddress` (nullable)                                    | `depositAddress` object `{address,type,depositor,depositTxHash}` |
    | `data.supersededByRequestId`                                   | `supersededByRequestId` (root)                                   |
  </Accordion>

  <Accordion title="Removed" icon="trash">
    | Removed in v3                                     | Replacement                                                                              |
    | ------------------------------------------------- | ---------------------------------------------------------------------------------------- |
    | `data.fees` (wei `gas`/`fixed`/`price`/`gateway`) | `data.fees` (now USD price-impact)                                                       |
    | `data.feesUsd`                                    | `data.fees`                                                                              |
    | `data.currency` / `data.currencyObject`           | currency object on each amount                                                           |
    | `data.feeCurrency` / `data.feeCurrencyObject`     | currency hoisted into fee objects                                                        |
    | `data.appFeeCurrencyObject`                       | `data.appFees.currency`                                                                  |
    | `data.subsidizedRequest` / `data.subsidizedFee`   | `data.feeSponsorship`                                                                    |
    | `data.metadata` (catch-all)                       | `data.route.{quoted,actual}` (`sender` promoted to root)                                 |
    | `data.price`                                      | read `data.route.actual.destination.inputCurrency`                                       |
    | `referrer` (query parameter)                      | removed as a filter; still returned in the response when `includeAuthenticatedData=true` |
    | `?hash`                                           | `term` / `depositTxHash` / `fillTxHash` / `refundTxHash`                                 |
    | status `delayed`                                  | `depositing` / `submitted`                                                               |
  </Accordion>

  <Accordion title="Added" icon="plus">
    | Added in v3                            | Notes                                                                                                                            |
    | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
    | `requestType`                          | request type (`Bridge`, `Crosschain Swap`, `Same-chain Swap`, `Send`, `Wrap`, `Unwrap`, `Call`)                                  |
    | `sender` (root)                        | promoted from `data.metadata.sender`                                                                                             |
    | `features` (root)                      | request feature flags (`gasless_execution`, `fast_fill`, `app_fees`, …)                                                          |
    | `refundTo`                             | refund target for deposit-address flows                                                                                          |
    | `depositAddress.recoveryAddress`       | origin-chain address that can recover deposit-address funds if the recipient is later blocked                                    |
    | `data.quoteOraclePrice`                | oracle price snapshot at quote time (`rate`, `observedAt`, `inputCurrency`, `outputCurrency`); fixed-BPS oracle integrators only |
    | `data.route.actual`                    | executed route (with `rate`); falls back to `quoted`                                                                             |
    | `data.externalMetadata`                | partner correlation IDs (e.g. `moonpayId`)                                                                                       |
    | `feeSponsorship.actual.sponsorPayment` | what the sponsor actually paid                                                                                                   |
    | broad filter/sort surface              | see [Filtering, search & sorting](#what-changed)                                                                                 |
  </Accordion>
</AccordionGroup>

## Migration checklist

<Steps>
  <Step title="Switch the endpoint and headers">
    Point requests at `GET /requests/v3` and send `x-api-key` (now required). Drop the `referrer` query parameter. Set `includeAuthenticatedData=true` only from a trusted server context to receive authenticated fields (see the note at the end).
  </Step>

  <Step title="Update fee reads">
    Stop reading `data.fees.gas` / `feesUsd`. Read the per-component USD breakdown from `data.fees.quoted` / `data.fees.actual`, and rename the `relay` component to `platform`.
  </Step>

  <Step title="Repoint currency & route reads">
    Replace `data.metadata.*` reads: `sender` is now at the root, and currencies/rate come from `data.route.{quoted,actual}` (prefer `actual`, fall back to `quoted`). Read the deposited amount from `route.actual.origin.inputCurrency` and the received amount from `route.actual.destination.outputCurrency` (fall back to `origin.outputCurrency` for same-chain swaps). Drop `currency`/`currencyObject` string handling — read the single currency object.
  </Step>

  <Step title="Consolidate app fees & sponsorship">
    Read `data.appFees.quoted` / `data.appFees.actual`. Replace `subsidizedRequest`/`subsidizedFee` with `data.feeSponsorship`, and rename its `relay` bucket to `platform`.
  </Step>

  <Step title="Fix tx hashes, statuses & nulls">
    Rename `inTxs[].hash` / `outTxs[].hash` to `txHash`. Handle the new `depositing` / `submitted` statuses (and remove `delayed`). Treat `failReason` / `refundFailReason` as `null` rather than `"N/A"`.
  </Step>

  <Step title="Adopt the new querying surface">
    Replace separate `user`/`hash`/`id` lookups with a single `term` search where it fits, and take advantage of the new filter/sort parameters. Pagination is unchanged — keep passing `continuation` back for the next page (`limit` max 50).
  </Step>
</Steps>

<Tip>
  Authenticated data is only returned when you pass `includeAuthenticatedData=true` and authenticate with an API key tied to those requests.
</Tip>
