Data
API reference
Two endpoints, both public, both the same ones the interface itself calls. They read the chain and build calldata. They never hold a key, never sign anything and never see funds.
No authentication and no rate plan. There is also no stability promise yet: these routes exist to serve this site, and a field can change while the product is unfinished.
GET /api/quote?list=1
What can actually be routed right now. Add &token=EURC to ask about one asset.
curl "https://app.usespecie.xyz/api/quote?list=1&token=EURC"| Field | Meaning |
|---|---|
| tokens[].symbol | the asset, always quoted against USDC |
| tokens[].tradable | a pool with liquidity exists and prices a small order |
| tokens[].smallOnly | a thousand unit order cannot be filled near the pool mid |
| tokens[].impactPercent | what a thousand unit order would cost against that mid |
| tokens[].hops | 1 for a direct pool, 2 through USDC |
| reference | always pool-mid |
GET /api/quote
A price for an exact amount. side=buy spends USDC, side=sell spends the asset.
curl "https://app.usespecie.xyz/api/quote?token=EURC&amount=100&side=buy"POST /api/swap
The same quote, plus the calldata to sign and a simulation of it from your address. Nothing is signed here: the answer is a transaction you may choose to send.
curl -X POST https://app.usespecie.xyz/api/swap \
-H "content-type: application/json" \
-d '{
"token": "EURC",
"side": "buy",
"amount": "100",
"address": "0xYourAddress",
"slippageBps": 50
}'What comes back
| Field | Meaning |
|---|---|
| routable | false when no pool with liquidity exists, with reason |
| safe | false when the fill lands more than 3% under the pool mid; no calldata is returned |
| amountOut | what the pool returns before the fee |
| lossPercent | price impact against midRate, the pool priced at one unit |
| feeBps | the Specie fee in basis points, taken from the output |
| minimums.gross | minimum the pool must return, enforced on the swap |
| minimums.net | minimum that must reach your wallet after the fee |
| pool | the winning route: fee tier and pool id, or the hops and legs |
| approvals[] | ERC-20 and Permit2 steps to send first, each with to and data |
| tx | the swap transaction: to, value, data |
| preflight.ok | the simulation passed; the interface arms only on true |
| preflight.willReceive | what the simulation says lands in your wallet |
| preflight.feeTaken | what the simulation says the fee takes |
| preflight.gasUsed | gas the simulated transaction used |
| quotedAt | when this answer was built, in milliseconds |
Status codes
| Code | When |
|---|---|
| 200 | answered, including the honest refusals: routable: false and safe: false |
| 400 | unknown asset, missing address, or an amount that is not a positive number |
| 502 | the chain could not be read |
| 503 | Uniswap is not deployed at the configured addresses; the error names what is missing |
A 503 is the answer you will get on this network today, and it is the reason the swap panel says swaps are not open instead of drawing an empty market.
Sending a swap yourself
- Post to
/api/swapand checkpreflight.okis true. - Send every entry in
approvalsin order, waiting for each. - Send
tx. - Re-post before signing if more than a few seconds passed. A quote and its simulation are statements about one block.