Hosted Fynd API (Beta)
Get routing quotes in minutes from Propeller Heads' hosted Fynd API — no local setup required.
Beta. The hosted Fynd API is in beta. Limits, supported chains, and the surface area may change as we scale the service. There is no SLA during beta — status and incidents are posted in our Telegram group. For production workloads with strict uptime or throughput requirements, see Scaling beyond the hosted tiers.
Fynd is an open-source DEX aggregator: you send it a token pair and amount, it finds the best on-chain route across the liquidity venues it tracks, and returns the expected output plus a ready-to-submit transaction. You can run Fynd on your own hardware (see Self-host quickstart) — or you can use our hosted API and skip the setup entirely. This page covers the hosted path: get an API key, send a request, get a route.
The hosted API runs the latest released Fynd with routing settings tuned per chain by the Fynd team, so you always track the newest routing improvements without managing releases or worker pools yourself.
Prefer a UI? A hosted web frontend is coming soon. Today the API is the integration surface.
What you get
One endpoint, all chains.
https://fynd-api.propellerheads.xyzroutes/v1/{chain}/…to a per-chain Fynd backend. No per-chain infrastructure on your side.Latest Fynd version. The hosted backends track the newest Fynd release; you don't pin or upgrade anything. (During beta, the surface area may change — see the FAQ for version and deprecation notes.)
Optimized routing. Worker-pool and algorithm configuration are tuned per chain by the Fynd team. Hosted backends run the full default protocol set — see the list of supported protocols.
Same quote API as self-hosted. The per-chain request/response bodies are identical to running
fynd serveyourself — see API reference. The hosted gateway adds a/{chain}path segment and API-key auth; a self-hosted instance serves one chain at/v1/…with no auth.
Get an API key
Open @fynd_portal_bot on Telegram.
Run
/startand follow the prompts. You'll receive a Fynd API key (also valid for the Tycho liquidity indexer that feeds Fynd).Save the key immediately. The bot won't show it again, and you get 3 self-service revocations (rotations of your key) before you need to contact support in our Telegram group.
export FYND_API_KEY=your-api-keyKeep the key server-side. The Authorization header is a raw secret. Never ship it in browser/client code. Proxy Fynd requests through your backend; do not call the hosted API directly from a frontend. (A hosted web frontend is coming soon — until then, all API access is server-to-server.)
The key is sent as the raw Authorization header value on every request — no Bearer prefix:
Quickstart
1. Health check
The -i flag also prints the response headers, including X-User-Plan: fynd-basic (your current plan) and Retry-After on 429s.
Health fields:
healthy
Overall solver readiness.
last_update_ms
Milliseconds since the last market-state update from Tycho. 0 means no update received yet (the stream is stalled — quotes will return no_route_found); non-zero and small is healthy.
num_solver_pools
Number of parallel algorithm worker pools running. Not liquidity pools — internal solver workers.
derived_data_ready
Whether derived graph data (token pairs, routes) is built and ready to serve.
gas_price_age_ms
Age of the cached gas price estimate, in milliseconds.
2. Instance info
chain_id— the EVM chain ID this backend serves (e.g.1for Ethereum). Corresponds to thechainpath segment in the request URL.router_address— the on-chain contract that executes swaps. Submit your encoded swap transaction to this address (it's already set astransaction.toin an encoded quote — you don't set it yourself). It is chain-specific: each chain returns its own router address.version— the Fynd binary version serving this chain (the example value is illustrative). Hosted backends are updated on each production release, so the running version may lag the newest published Fynd release.
3. Request a quote
Sell 1 WETH for USDC on Ethereum. Amounts are in the token's smallest unit (wei for WETH, micro-units for USDC):
Sell orders only. Fynd currently supports side: "sell" (exact input). Buy orders (exact output) are not yet supported.
sender — the address that will submit the swap transaction. The quote (and any encoded calldata) is bound to this sender. The 0x0000…0001 above is a dummy; replace it with your wallet address for any quote you intend to execute.
Quote options (options field — all optional):
timeout_ms
server default
Max time the solver spends finding a route. On timeout, the server returns the best route found so far (or a timeout status if none).
min_responses
server default
Minimum number of solver pools that must respond before the server returns. 1 returns as soon as one pool has a route (fastest). Higher values wait for more pools to compete, improving price at the cost of latency.
max_gas
null
Cap on gas units the route may use. Routes exceeding it are rejected.
The response contains the route, the expected amount_out, gas estimate, and the solve_time_ms the server spent finding the route:
Response fields:
solve_time_ms
Server-side time spent finding the route (excludes network/proxy overhead). Top-level, per response.
total_gas_estimate
Sum of gas_estimate across all orders in the response. Top-level, per response.
amount_in
The input amount for this order, in token_in's smallest unit (echoes the requested amount).
amount_out
Expected output, in the token_out's smallest unit.
amount_out_net_gas
amount_out minus the gas cost of executing the route, denominated in token_out. Use this to compare routes.
gas_estimate
Gas units the swap will consume.
gas_price
Gas price (wei) used for the amount_out_net_gas calculation.
price_impact_bps
Price impact of the swap in basis points (100 bps = 1%).
route.swaps[].component_id
Internal ID for the liquidity venue used (pool/curve/vault). Not directly an on-chain address.
route.swaps[].protocol
Protocol name. The vm: prefix denotes a virtual-machine venue. See supported protocols.
route.swaps[].split
Fraction of the input amount routed through this swap. "0" means "the remainder of the input" (the last leg of a split group), not 0%. A single-swap route shows split: "0".
block
The block the quote is valid against. Submit the encoded transaction promptly — see Quote validity.
transaction
null unless encoding_options is set. See step 4.
order_id
Correlation ID for this quote. Not queryable after the fact.
One order per request is the supported path today. The orders array shape exists for future batch quoting; for now, send exactly one order.
4. Encode and approve
To get a ready-to-submit transaction, pass encoding_options with your slippage tolerance (a fraction, as a string, e.g. "0.005" = 0.5%):
Replace sender with your wallet address. The encoded calldata is bound to the sender you provide — a transaction encoded for 0xYourWalletAddress will revert if submitted by any other address.
The response now includes a populated transaction and a fee_breakdown:
transaction.tois the chain'srouter_address(already set — submit as-is).transaction.datais the calldata for the swap.transaction.gasmay or may not be populated — if absent, estimate gas separately witheth_estimateGasbefore submitting.fee_breakdown.router_fee— the fee Fynd charges on the swap, intoken_outunits. The default Fynd fee is 0.1 bps (0.001%) of swap output; quotes are free. See Fynd Fees for volume discounts and the full fee arithmetic.fee_breakdown.client_fee— integrator fee (0 unless you setclient_fee_paramsinencoding_options; see Charge Fees on your Swaps).fee_breakdown.max_slippage— the slippage allowance intoken_outunits, applied to the post-fee amount.min_amount_received=amount_out − router_fee − client_fee − max_slippage. Verify the settled output is ≥min_amount_receivedafter the transaction confirms.
Approvals
Before submitting the swap transaction, the token_in must be spendable by the router. The path depends on the transfer_type (default "transfer_from"):
transfer_from(default) — standard ERC-20 approval. Callapprove(router_address, amount)on thetoken_incontract, granting the Fynd router an allowance ≥amount_in. The router pulls the exactamount_inat execution.transfer_from_permit2— gasless Permit2 signature. Sign aPermitSingleoff-chain and pass it viaencoding_options.permit+permit2_signature. No on-chainapprove()to the router is needed, but the token must first be approved to the Permit2 contract (permit2_address), not the router. See Encoding Options for the full Permit2 flow.
Native-token sells skip approval entirely. If token_in is the zero address (0x0000000000000000000000000000000000000000), the router wraps native ETH/BNB/POL for you — no approval needed.
Quick approval with cast (Foundry) — for the default transfer_from path:
With approval in place, sign and broadcast transaction (the {to, value, data} object) from your sender wallet. If transaction.gas is absent, estimate with eth_estimateGas first.
Quote validity
The quote is valid against the block in the response. Encoded calldata includes a deadline, but market state moves every block — re-quote within ~1 block (12s on Ethereum, faster on L2s) before submitting. For execution-critical flows, quote → sign → submit in a single sequence; don't cache quotes for later.
5. Sign and execute with a Fynd client
For the full approve → sign → submit → settle flow, the Fynd clients (@kayibal/fynd-client for TypeScript, fynd-client for Rust) support the hosted API directly — pass your API key and chain to the client builder and the rest is handled.
The typed clients expose camelCase equivalents of the REST fields (amountOut, solveTimeMs, amountOutNetGas, etc.). The REST reference uses snake_case (amount_out, solve_time_ms).
Full example: clients/typescript/examples/tutorial/main.ts.
Full example: clients/rust/examples/swap_erc20.rs.
Supported chains
Each chain is served from its own Fynd backend behind the shared gateway. Send the chain name in the URL path (/v1/{chain}/…). With the typed clients, set the chain option (TypeScript) or .with_chain("…") (Rust).
Chain
chain path segment
Chain ID
Native token
Ethereum
ethereum
1
ETH
Base
base
8453
ETH
Arbitrum
arbitrum
42161
ETH
BNB Smart Chain
bsc
56
BNB
Polygon
polygon
137
POL
Unichain
unichain
130
ETH
A request to /v1/{chain}/… for a chain that isn't configured returns 404 with {"error": "unknown_chain", ...}.
Native token swaps
Use the zero address (0x0000000000000000000000000000000000000000) as token_in or token_out to swap the chain's native gas token (ETH on Ethereum/Base/Arbitrum/Unichain, BNB on BSC, POL on Polygon). Native-token token_in skips the approval step — the router wraps native gas for you.
API key limits by tier
Your API key belongs to a plan that sets your rate limit. Limits are enforced per key by a token-bucket limiter at the gateway.
Burst is the bucket capacity = rps × burst_multiplier. A fynd-basic key can briefly sustain 20 requests in one second before being throttled back to the steady-state 10 rps. All requests count against the bucket — /health, /info, and /quote alike. The bucket is per key, shared across all chains.
When you exceed the limit you get 429 Too Many Requests with a Retry-After header (seconds). The hosted API is REST-only today (no WebSocket); for higher throughput, run your own stack (see below) or talk to us about a dedicated instance.
Pricing: The hosted API is free to use during beta — no platform fee on top of Fynd's standard 0.1 bps router fee on executed swaps (see Fynd Fees). Quotes are always free. scale is allocated case-by-case — reach out to discuss volume and needs.
Checking your plan
The gateway returns your plan in the X-User-Plan response header on every authenticated request (use curl -i to see it). If you're unsure which plan your key is on, message @fynd_portal_bot or ask in our Telegram group.
Errors
400
Malformed request body, bad token address, or invalid slippage type
JSON: {"error": "...", "code": "BAD_REQUEST"}
401
Missing or invalid API key, or plan not recognized
Plain text: Unauthorized or Missing authorization token
403
Your plan doesn't allow this service
Plain text: Forbidden
404
Unknown chain path segment
JSON: {"error": "unknown_chain", ...}
429
Rate limit exceeded
Plain text: Too Many Requests, plus Retry-After: <seconds> header
5xx
Backend or gateway failure
varies — check health and retry with backoff
Error body formats differ by layer. Gateway errors (401, 403, 429) return plain text; backend errors (400, 404, 5xx) return JSON. If your client assumes JSON on every non-2xx, it will throw a parse error on the auth and rate-limit paths you most need to handle. Parse defensively.
A 200 with orders[0].status: "no_route_found" is not an HTTP error — it means the solver ran but couldn't find a profitable route for the pair at the requested size. Check /v1/{chain}/health (last_update_ms: 0 means the Tycho stream isn't delivering live state yet), try a different token pair or size, or confirm the tokens have Tycho-indexed liquidity on that chain.
Scaling beyond the hosted tiers
The hosted API is a shared, beta-rate-limited service designed for getting started and for moderate-volume integrations. If you need:
Higher or unlimited rate limits — run Fynd on your own hardware. The self-host quickstart has you serving in minutes, and there's no rate limiter in front of your own instance.
Custom algorithms, custom protocol sets, or RFQ integration — self-host and pass
--protocols/ your algorithm config. See Server Configuration and Custom Algorithm.A dedicated hosted instance with guaranteed capacity and SLA — reach out to our business team. Message @tanay_j on Telegram, or email us at Propeller Heads.
What the hosted API buys you (vs. self-hosting): no infrastructure to run, no Tycho indexer endpoint to source, no release tracking, and per-chain routing tuned by the Fynd team. Self-hosting gives you ~1,000 RPS on commodity hardware (see Performance) and full control — pick the tradeoff that fits your scale.
FAQ
Is the hosted API the same software as self-hosted Fynd? Yes. Identical binary, same quote API. The hosted gateway adds a /{chain} path segment, API-key auth, and rate limiting — none of which exist in the self-hosted binary. The per-chain request/response bodies are identical.
How do I know which Fynd version is running? The unauthenticated endpoint https://fynd-api.propellerheads.xyz/api-docs/openapi.json exposes the version under info.version. We update the hosted backends shortly after each release. During beta the surface area may change; we post breaking changes in our Telegram group ahead of rollout.
Can I use one key for all chains? Yes. A single API key works against every /v1/{chain}/… path. The rate-limit bucket is shared across chains.
Why did my quote return no_route_found? The solver found no profitable route for the pair at the requested size on that chain. Common causes: thin Tycho-indexed liquidity for the pair, an amount too large or too small, or the chain's backend is still warming up. Check /v1/{chain}/health — last_update_ms: 0 indicates the Tycho stream isn't delivering live state yet.
Can I bring my own RPC and Tycho endpoint with the hosted API? No — the hosted API uses Propeller Heads' Tycho endpoints. To use your own, self-host.
Next steps
API reference — full OpenAPI spec
Encoding Options — turn a quote into a submittable transaction (Permit2, transfer types, price guard)
Fynd Fees — fees Fynd charges on executed swaps
Charge Fees on your Swaps — add an integrator fee
Self-host Fynd — when you're ready to outgrow the hosted tiers
Last updated