Skip to main content
By default, you pay for a Relay quote with a transfer that the chain does not check against the quote terms, which keeps gas cost to a minimum. You can verify a supported quote locally before you send the transaction. This verification uses the quote data, the Relay settlement SDK, and the chain metadata from GET /chains. It does not require another API request at quote time. With the signature API, you asked Relay for a signature over a small set of intent fields and checked that signature onchain. A signature only proves that Relay said something; it does not let you confirm that what Relay said matches the transaction you are about to send. The verification on this page inverts that:
  1. Read the output amount, recipient, currency, and deadline from the order.
  2. Recompute the order ID from these properties.
  3. Confirm that the transaction commits to the recomputed order ID, and pays what the order says.
If all three checks pass and the order settles, settlement follows the order you inspected.
This method applies only to quotes that contain protocol.v2. It does not apply to deposit-address deposits. If your integration uses deposit addresses, contact Relay before you migrate from the signature API.

What you can verify

  • The recipient is who you expect, and is on your whitelist
  • The minimum output amount is acceptable
  • The input and output currencies and chains are correct
  • The amount you are being asked to pay matches the quoted input
  • The order has not expired
  • The deposit transaction pays Relay’s canonical depository, commits to this exact order, and transfers exactly the order’s input payment

Guide

1. Request a quote with protocol data

Pass includeProtocolData: true so the response includes the full protocol order alongside the quote.
The response carries a protocol.v2 block:
orderData is the complete, canonical description of the order. Everything else in this guide is derived from it.

2. Check the order properties

Read the values you care about from orderData and compare them against your own expectations. This is the step where you decide whether the order is acceptable — the checks that follow only bind the transaction to the properties you inspect here.
Compare minimumAmount, not expectedAmount. expectedAmount is the quoted estimate; minimumAmount is the floor the protocol enforces at settlement.

3. Recompute the order ID

The examples below assume quote is the parsed /quote/v2 response from step 1. Install the settlement SDK:
getOrderId needs a map from protocol chain ID to VM type. Build it from GET /chains rather than from the quote, and cache it — it changes only when Relay adds a chain. The same response carries the canonical depository address per chain, which step 4 needs.
getOrderId hashes the order data into the order ID. Recomputing it locally and comparing against protocol.v2.orderId confirms that the ID Relay returned corresponds to the properties you just inspected.

4. Confirm the transaction matches the order

The deposit transaction pays the protocol depository, passes the order ID as the deposit id, and transfers the order’s input payment. Check all three.
Select the deposit transaction using the depository address from GET /chains, not protocol.v2.depository from the quote. Using the quote’s own field to validate the quote proves nothing — a tampered response could name an attacker’s address in both places and still pass.
The order ID does not cover the currency, value, or token amount the transaction transfers, so those need checking separately — and which deposit function is correct follows from the order, not from the calldata.
At this point the transaction is bound to the order you inspected in step 2. If all the checks pass and the order settles, settlement uses the recipient, minimum output amount, currency, deadline, and destination chain encoded in the verified order. Verification confirms the encoded order. It does not guarantee that the order will fill.

Validating onchain

If you need the check to happen inside a contract rather than in your backend, use protocol.v2.orderSignature. It is the solver’s ECDSA signature over the 32 raw bytes of the order ID, following EIP-191, and it is produced by the Relay EVM solver wallet 0xf70da97812cb96acdf810712aa562db8dfa3dbef — the same address on every chain Relay supports.
The equivalent Solidity check:
The signature only attests to the order ID. It is not a substitute for steps 2 to 4 — recompute the order ID from orderData so you know which order the ID refers to, and check the transaction against it.

Deposit addresses

Deposit address deposits cannot yet be verified this way. The order ID checks above bind a transaction to an order; a deposit address has no calldata to bind, so verifying one requires deriving the address itself from the order properties. That derivation is not yet available to integrators. If you rely on deposit addresses and need to validate them before sending funds, contact Relay so your use case can be factored into that work.

Migrating from the signature API

GET /requests/:requestId/signature and GET /requests/:requestId/signature/v2 have been removed. Calls now return 404.
The signature API returned a solver signature over a small subset of intent fields — origin and destination chain, user, currency, and (on v2) destination currency. It had several problems that the deterministic flow does not:
  • It never covered the fields that matter most, such as the minimum output amount, so it could not tell you the trade was priced correctly.
  • It required a second API call after the quote, and returned only partial data until the request reached a terminal state.
  • Its behavior was inconsistent across chains.
  • It attested to a request shape that does not map cleanly onto protocol orders.
To migrate, replace the GET /requests/:requestId/signature/v2 call with includeProtocolData: true on your existing /quote/v2 request, and follow steps 2 to 4 above. The verification happens locally, so you remove a network round trip in the process.