Quote
The first step in every sweep is requesting a quote. The quote locks in:
- The fee breakdown (protocol fee + builder fee)
- The unsigned
SweepOrderthe user will sign - The expiry time
Request
POST https://api.sweepster.xyz/quote
Content-Type: application/jsonBody
typescript
interface QuoteRequestWire {
owner: string; // "0x..." — user's wallet address (40-hex 0x address)
tokenIn: string; // "0x..." — source token contract address
amountIn: string; // decimal string, e.g. "1000000" (1 USDC)
tokenOut: string; // "0x..." — destination token contract address
destination: string; // "0x..." — recipient address on destination chain
destChainId: number; // destination chain ID (e.g. 42161 for Arbitrum)
tier: "tier1" | "tier2" | "tier3"; // token risk tier
route: string; // hint, e.g. "base->arbitrum" or "base->base"
subscriptionActive: boolean;
userId: string; // unique user identifier for fee policy
apiKey?: string; // optional — your builder API key for attribution
}Example
typescript
const quoteBody = {
owner: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
tokenIn: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
amountIn: "1000000", // 1 USDC (6 decimals)
tokenOut: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
destination: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
destChainId: 42161,
tier: "tier1",
route: "base->arbitrum",
subscriptionActive: false,
userId: "user_abc",
apiKey: "sk_live_...",
};
const res = await fetch("https://api.sweepster.xyz/quote", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(quoteBody),
});Response
typescript
interface QuoteResponseWire {
quote: {
id: string; // quote / intent ID (UUID)
crossChain: boolean; // true if destChainId != source chain
expiresAtMs: number; // UNIX ms — quote expires at this time
total: string; // total fee as decimal string (protocolFee + builderFee)
builderId?: string; // builder ID if attributed
};
order: SweepOrderWire; // the unsigned order to sign
}The order returned is the SweepOrderWire with all uint256 fields serialized as decimal strings:
typescript
interface SweepOrderWire {
owner: string; // "0x..."
tokenIn: string; // "0x..."
amountIn: string; // decimal string
feeAmount: string; // decimal string — protocol fee
builder: string; // "0x..." — builder address (zero address if unattributed)
builderFee: string; // decimal string — builder's cut
tokenOut: string; // "0x..."
minAmountOut: string; // decimal string (0 for cross-chain)
destination: string; // "0x..."
swapTarget: string; // "0x..." — DEX router / bridge address
swapCalldata: string; // "0x..." — encoded swap/bridge call
deadline: string; // decimal string — UNIX seconds
nonce: string; // decimal string
destChainId: string; // decimal string
}Error responses
| Status | Meaning |
|---|---|
| 422 | Invalid input (field validation failed) or token declined by risk engine |
| 429 | Rate limit exceeded (100 req/min per IP by default) |
json
HTTP 422
{ "error": "token declined: insufficient liquidity" }Quote expiry
Quotes expire at expiresAtMs. A user must sign and submit before expiry. The orchestrator rejects submissions for expired quotes.