diff --git a/docs.json b/docs.json
index fa2962d..d91fa81 100644
--- a/docs.json
+++ b/docs.json
@@ -119,6 +119,12 @@
"references/api/api_guides/webhooks"
]
},
+ {
+ "group": "Migration Guides",
+ "pages": [
+ "references/api/api_guides/migrating-to-requests-v3"
+ ]
+ },
{
"group": "Chains, Tokens, Contracts",
"pages": [
@@ -155,6 +161,7 @@
{
"group": "Deprecated",
"pages": [
+ "references/api/get-requests-v2",
"references/api/get-price",
"references/api/get-config",
"references/api/get-intents-status",
diff --git a/references/api/api_core_concepts/fees.mdx b/references/api/api_core_concepts/fees.mdx
index bb14095..f238963 100644
--- a/references/api/api_core_concepts/fees.mdx
+++ b/references/api/api_core_concepts/fees.mdx
@@ -115,25 +115,29 @@ _Please note that the above fee structure applies to standard cases. In certain
## Fees in the API
-Both the quote API and the requests API return a request's fees in the `expandedPriceImpact` object, which breaks them down into the following components:
+[`GET /requests/v3`](/references/api/get-requests) returns a request's fees in the `data.fees` object, with `quoted` (estimated at quote time) and `actual` (computed at fill time) values. It breaks fees down into the following components:
**execution** - Execution fees covering network gas on the origin and/or destination chain plus the flat fee.
**swap** - Swap costs from cross-currency and cross-chain exchange, including DEX fees, swap slippage, and solver rebalancing.
-**relay** - The Relay fee, the flat basis-point fee charged by Relay for routing and meta-aggregation services.
+**platform** - The platform fee, the flat basis-point fee charged by Relay for routing and meta-aggregation services.
**app** - App fees added on top by the integrator, when present.
**sponsored** - The portion of fees the integrator subsidizes on behalf of the user via [Fee Sponsorship](/features/fee-sponsorship).
-When displaying fees to users, we recommend mapping the `expandedPriceImpact` fields as follows:
-- **relay** → Provider Fee
+When displaying fees to users, we recommend mapping the `data.fees` fields as follows:
+- **platform** → Provider Fee
- **app** → Your App's Fee
- **swap** + **execution** → Swap Impact
+
+In the quote API and [`GET /requests/v2`](/references/api/get-requests-v2), this same breakdown is returned as the `expandedPriceImpact` object, and the **platform** component is named **relay**.
+
+
## Fee Sponsorship
Integrators with [Fee Sponsorship](/features/fee-sponsorship) enabled can subsidize fees for their users. By default, setting **`subsidizeFees`** to `true` sponsors all fee components.
@@ -147,9 +151,9 @@ See the [Fee Sponsorship Doc](/features/fee-sponsorship) for setup details.
## Deprecated: Fees Object
-The `fees` object is deprecated. It is still returned from the quote API and the [`GET /requests/v2`](/references/api/get-requests) API for backwards compatibility, but it only reports Relay-related fees and does not reflect the full cost of a request. Do not rely on it for new integrations.
+The `fees` object is deprecated. It is still returned from the quote API and the [`GET /requests/v2`](/references/api/get-requests-v2) API for backwards compatibility, but it only reports Relay-related fees and does not reflect the full cost of a request. Do not rely on it for new integrations.
-To understand or display the complete fee breakdown of a request, use the [`expandedPriceImpact`](#fees-in-the-api) object instead, which covers execution, swap, relay, app, and sponsored fees.
+To understand or display the complete fee breakdown of a request, use the [`data.fees`](#fees-in-the-api) object in `GET /requests/v3` (or `expandedPriceImpact` in the quote API and `GET /requests/v2`) instead, which covers execution, swap, platform, app, and sponsored fees.
The deprecated `fees` object is segmented into the following fields:
diff --git a/references/api/api_guides/migrating-to-requests-v3.mdx b/references/api/api_guides/migrating-to-requests-v3.mdx
new file mode 100644
index 0000000..58f0058
--- /dev/null
+++ b/references/api/api_guides/migrating-to-requests-v3.mdx
@@ -0,0 +1,505 @@
+---
+title: "Migrating to Requests v3"
+description: "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.
+
+
+ `x-api-key` is now required. Every v3 request authenticates against an active API key. See [API Keys](/references/api/api-keys) for details.
+
+
+## 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.
+
+
+
+ ```json expandable
+ {
+ "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"
+ }
+ ```
+
+
+ ```json expandable
+ {
+ "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"
+ }
+ ```
+
+
+ ```jsonc expandable
+ {
+ "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 ++]
+ }
+ }
+ ```
+
+
+
+
+ The full OpenAPI schema lives at [api.relay.link/documentation/json](https://api.relay.link/documentation/json).
+
+
+
+ **`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.
+
+
+## What changed
+
+Every individual change, grouped by request side and response side.
+
+### Request & querying
+
+
+
+ ```bash
+ GET /requests/v3
+ Headers:
+ x-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.
+
+
+
+ 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` |
+
+
+ `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.
+
+
+ **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
+ # "(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"]}]
+ ```
+
+ OR groups support identity, address, chain, currency, and status-style fields. Range filters and `features` are top-level only.
+
+ **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`.
+
+
+
+
+### Response fields
+
+
+
+ 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
+ "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 ++]
+ ```
+
+
+
+ `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
+ "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 ++]
+ ```
+
+
+
+ `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
+ "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 ++]
+ }
+ ```
+
+
+
+ The parallel `appFees` (quoted) and `paidAppFees` (actual) arrays are consolidated into one object with explicit `quoted` / `actual` keys and a hoisted `currency`.
+
+ ```jsonc
+ "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 ++]
+ ```
+
+
+
+ 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
+ "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 ++]
+ ```
+
+
+
+ Inside `inTxs[]` and `outTxs[]`, the `hash` field is renamed to `txHash`. The array names themselves are unchanged.
+
+ ```jsonc
+ "inTxs": [ { "hash": "0xcd4d70..." } ], // [!code --]
+ "outTxs": [ { "hash": "0x1c0089..." } ] // [!code --]
+ "inTxs": [ { "txHash": "0xcd4d70..." } ], // [!code ++]
+ "outTxs": [ { "txHash": "0x1c0089..." } ] // [!code ++]
+ ```
+
+
+
+ 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
+ status ∈ { pending, waiting, delayed, success, failure, refund } // [!code --]
+ status ∈ { pending, waiting, depositing, submitted, success, failure, refund } // [!code ++]
+ ```
+
+
+
+ - `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).
+ - **`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"`.
+
+
+
+## Field migration reference
+
+
+
+ | 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}` |
+
+
+ | 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` |
+
+
+ | 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) |
+
+
+
+## Migration checklist
+
+
+
+ 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).
+
+
+ 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`.
+
+
+ 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.
+
+
+ Read `data.appFees.quoted` / `data.appFees.actual`. Replace `subsidizedRequest`/`subsidizedFee` with `data.feeSponsorship`, and rename its `relay` bucket to `platform`.
+
+
+ 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"`.
+
+
+ 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).
+
+
+
+
+ Authenticated data is only returned when you pass `includeAuthenticatedData=true` and authenticate with an API key tied to those requests.
+
+
+
diff --git a/references/api/changelog.mdx b/references/api/changelog.mdx
index e2193d3..fe501e4 100644
--- a/references/api/changelog.mdx
+++ b/references/api/changelog.mdx
@@ -3,6 +3,11 @@ title: "API Changelog"
description: "Record of breaking changes, deprecations, and notable additions to the Relay API"
---
+## 2026-07-22 — `GET /requests/v3` is live; `GET /requests/v2` deprecated & scheduled for sunset
+
+**Added** — `GET /requests/v3`: the recommended Requests API. It requires `x-api-key`, adds a broad filter/search/sort surface, and returns a cleaner, consolidated response. See the [migration guide](/references/api/api_guides/migrating-to-requests-v3).
+
+**Deprecated** — `GET /requests/v2` is deprecated as of today. It keeps working for now, but its rate limit will be progressively reduced each month until it is **fully retired on November 24, 2026**. Migrate to v3 before then — see the [sunset timeline](/references/api/api_guides/migrating-to-requests-v3#sunset-timeline).
## 2026-07-09 — Solana quote size check reserves compute-budget headroom
**Behavior change** — `POST /quote/v2`: the Solana deposit-transaction size check on cross-chain Solana-origin quotes now reserves 60 bytes of headroom for the compute-budget instructions wallets and SDKs prepend at send time, so quotes are rejected when the compiled deposit transaction would exceed **1172 bytes** (1232 minus 60). Previously the check ran at the raw 1232-byte limit and could return `200` with calldata that no longer fit once the client added its compute-budget instructions. The `400` response body now names the effective limit and the reserved-bytes reason. Continue to use **`maxRouteLength`** or **`includedOriginSwapSources`** to keep transactions under the limit — see [Solana Support](/references/api/api_guides/solana#transaction-size-optimization).
diff --git a/references/api/get-requests-v2.mdx b/references/api/get-requests-v2.mdx
new file mode 100644
index 0000000..f8ea6c0
--- /dev/null
+++ b/references/api/get-requests-v2.mdx
@@ -0,0 +1,9 @@
+---
+title: "Get Requests (v2)"
+description: "Deprecated. Returns cross-chain transactions. Use GET /requests/v3 for new integrations."
+openapi: get /requests/v2
+---
+
+
+ `GET /requests/v2` is **deprecated as of July 22, 2026** and is being sunset: its rate limit is reduced each month until it is **fully retired on November 24, 2026**. New integrations should use [`GET /requests/v3`](/references/api/get-requests), which requires authentication and offers a richer filter surface and a cleaner response. See the [migration guide](/references/api/api_guides/migrating-to-requests-v3#sunset-timeline) for the full timeline and how to upgrade.
+
diff --git a/references/api/get-requests.mdx b/references/api/get-requests.mdx
index f634021..6a4a98f 100644
--- a/references/api/get-requests.mdx
+++ b/references/api/get-requests.mdx
@@ -1,5 +1,5 @@
---
title: "Get Requests"
description: "This API returns all the cross-chain transactions."
-openapi: get /requests/v2
+openapi: get /requests/v3
---
diff --git a/style.css b/style.css
index 04f321a..5f24e53 100644
--- a/style.css
+++ b/style.css
@@ -387,4 +387,4 @@
callout), adding an unwanted gap. Zero it out. */
.callout .prose > :first-child {
margin-top: 0;
- }
\ No newline at end of file
+ }