Overview
The GetExactOutputRoutes endpoint retrieves available token routes for exact output swaps. Given a destination token, it returns all source tokens that can be swapped to achieve that exact output amount. This is essential for building UIs where users specify exactly how much they want to receive.
Use Cases
- Build “I want to receive exactly X tokens” interfaces
- Find which source tokens can route to a specific destination
- Payment flows where exact amounts are required
- Invoice payments requiring precise token amounts
- DeFi integrations with fixed deposit amounts
Request Parameters
Required Fields
- destinationChainId (number): The chain ID of the destination token
- destinationTokenAddress (string): The token address to receive
Optional Fields
- originChainId (number): Filter routes by source chain
- originTokenAddress (string): Filter to routes from a specific token
- ownerAddress (string): User’s wallet address (for balance-aware filtering)
Response
The response includes:
- tokens (TokenInfo[]): Array of source tokens that can route to the destination
TokenInfo Object Structure
Each token object contains:
- chainId (number): Chain where the token exists
- address (string): Token contract address
- name (string): Token name
- symbol (string): Token symbol
- decimals (number): Token decimals
- supportsBridging (boolean, optional): Whether the token supports cross-chain bridging
- logoUri (string, optional): URL to token logo
- featured (boolean): Whether this is a featured/popular token
- featureIndex (number): Sort order for featured tokens
Examples
Find Source Tokens for USDC on Base
const response = await fetch('https://trails-api.sequence.app/rpc/Trails/GetExactOutputRoutes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
destinationChainId: 8453, // Base
destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' // USDC on Base
})
});
const { tokens } = await response.json();
console.log('Tokens that can swap to USDC on Base:');
tokens.forEach(token => {
console.log(`- ${token.symbol} on chain ${token.chainId}`);
});
Filter by Source Chain
const response = await fetch('https://trails-api.sequence.app/rpc/Trails/GetExactOutputRoutes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
destinationChainId: 8453, // Base
destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
originChainId: 1 // Only show routes from Ethereum mainnet
})
});
const { tokens } = await response.json();
console.log('Ethereum tokens that can swap to USDC on Base:');
tokens.forEach(token => {
console.log(`- ${token.symbol}: ${token.address}`);
});
Build Payment Source Selector
import { useEffect, useState } from 'react';
interface TokenInfo {
chainId: number;
address: string;
name: string;
symbol: string;
decimals: number;
logoUri?: string;
featured: boolean;
}
interface PaymentSourceSelectorProps {
targetChainId: number;
targetTokenAddress: string;
userAddress: string;
onSelect: (token: TokenInfo) => void;
}
export const PaymentSourceSelector = ({
targetChainId,
targetTokenAddress,
userAddress,
onSelect
}: PaymentSourceSelectorProps) => {
const [tokens, setTokens] = useState<TokenInfo[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://trails-api.sequence.app/rpc/Trails/GetExactOutputRoutes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
destinationChainId: targetChainId,
destinationTokenAddress: targetTokenAddress,
ownerAddress: userAddress
})
})
.then(res => res.json())
.then(({ tokens }) => {
// Sort featured tokens first
const sorted = tokens.sort((a: TokenInfo, b: TokenInfo) => {
if (a.featured && !b.featured) return -1;
if (!a.featured && b.featured) return 1;
return 0;
});
setTokens(sorted);
setLoading(false);
});
}, [targetChainId, targetTokenAddress, userAddress]);
if (loading) return <div>Loading payment options...</div>;
return (
<div>
<h3>Pay with:</h3>
{tokens.map(token => (
<button
key={`${token.chainId}-${token.address}`}
onClick={() => onSelect(token)}
>
{token.logoUri && <img src={token.logoUri} alt={token.symbol} />}
{token.symbol} (Chain {token.chainId})
</button>
))}
</div>
);
};
Check Specific Route Availability
const response = await fetch('https://trails-api.sequence.app/rpc/Trails/GetExactOutputRoutes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
destinationChainId: 8453,
destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
originChainId: 42161, // Arbitrum
originTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' // USDC on Arbitrum
})
});
const { tokens } = await response.json();
if (tokens.length > 0) {
console.log('Route is available!');
} else {
console.log('No direct route found');
}
When to Use Exact Output
Use GetExactOutputRoutes when:
- User needs to receive a specific amount (e.g., paying a $100 invoice)
- Protocol requires exact deposit amounts
- NFT purchases with fixed prices
- Subscription payments with fixed amounts
Use GetExactInputRoutes when:
- User wants to spend a specific amount
- “Swap all” functionality
- User specifies how much to send
For the best UX, combine this with GetTokenPrices to show users the estimated cost in USD for each source token option.
Next Steps