---
name: soroswap
description: Integrate the Soroswap Aggregator API to quote, build and submit token swaps on Stellar across Soroswap, Aquarius, SushiSwap V3, Comet and SDEX, plus prices, balances, pools, Soroswap AMM liquidity, partner fees and calling the aggregator from a Soroban contract. Use for endpoint choice, request shapes, units, errors and production hardening.
metadata:
  author: soroswap
  version: "1.0.0"
---

# Soroswap Aggregator API

**Base URL**: `https://api.soroswap.finance`, both networks. Always send `?network=mainnet` or
`?network=testnet`; leaving it out means mainnet.
**Auth**: `Authorization: Bearer sk_...` on every call. Get a key at
https://api.soroswap.finance/register. Missing or invalid key: **403** `Forbidden resource`,
never 401. Keep the key on the server.
**Limits**: Free 1 request/s (burst 5), Starter 10, Professional 50, Business 100.
`GET /rate-limits/tiers` returns them live, no key needed.

## Fresh Context Policy

This file is a summary written by hand. When it disagrees with a page you fetched from
https://docs.soroswap.finance (append `.md` to any page) or with the live OpenAPI at
https://api.soroswap.finance/api-json, the fetched source wins. Fetch before you rely on a
field name, a limit or a fee you have not seen in this session.

## Use / do not use

Use when:
- The task swaps, quotes or prices Stellar assets through Soroswap, or mentions
  `api.soroswap.finance`, `@soroswap/sdk` or the Soroswap aggregator.
- The task reads balances, pools or Soroswap AMM liquidity positions through the API.
- The task sets a partner fee on swaps, or calls Aggregator v3 from a Soroban contract.
- The user is debugging a Soroswap API error.

Do not use when:
- The task is generic Stellar work with no swap (payments, account creation, anchors, SEP flows).
- The task is about another chain.
- The user wants Soroswap app (UI) help with no code: point them to https://docs.soroswap.finance/getting-started.

## Intent router

| User intent | First call | Then |
|---|---|---|
| Swap, convert, buy, sell | `POST /quote` | `POST /quote/build` → sign → `POST /send` |
| Swap in one call | `POST /swap` (quote fields plus `from`) | Handle `action`, sign → `POST /send` |
| Price of an asset | `GET /price?network=&asset=C...&referenceCurrency=USD` | `price` is a plain number, not stroops |
| How much would I get | `POST /quote` with no wallet | Report `amountOut` ÷ 10^decimals |
| Balances of an address | `GET /balances/{address}?network=` | `amount`/`available` decimal, `rawAmount`/`availableRaw` stroops |
| Venues available | `GET /protocols?network=` | Use the result as `protocols` |
| Pools | `GET /pools?network=&protocol=` or `GET /pools/{tokenA}/{tokenB}?network=&protocol=` | |
| Add or remove AMM liquidity | `POST /liquidity/add` or `/liquidity/remove` | Sign → `POST /send` |
| Liquidity positions | `GET /liquidity/positions/{address}?network=` | |
| Monetize swaps (partner fee) | `GET /partner` | `PUT /partner/rate` (25 to 300 bps, or 0), `PUT /partner/payout-address` |
| Partner payouts | `GET /partner/statements` | `GET /partner/statements/{payoutId}` |
| Swap from a Soroban contract or smart wallet | `POST /quote` without `sdex` | Pass `rawTrade.distribution` to Aggregator v3 `swap_exact_in` / `swap_exact_out`. Guide: https://docs.soroswap.finance/aggregator/technical-reference/cross-contract-integration.md |
| User has no XLM for a trustline | `POST /quote` with `gaslessTrustline: "create"` and `sdex` | `/quote/build` with `sponsor`; user and sponsor sign. Guide: https://docs.soroswap.finance/api/gasless-trustline.md |

## Execution contracts

### Swap (the API builds the transaction)

1. `POST /quote?network=mainnet` with `assetIn`, `assetOut` (contract addresses `C...`),
   `amount` (integer string, smallest unit), `tradeType` (`EXACT_IN` or `EXACT_OUT`),
   `protocols` (`["soroswap","aqua","sushi","comet","sdex"]`), optional `slippageBps`
   (default 50).
2. Read `platform`: `aggregator`, `router` or `sdex`. Show `amountOut` and
   `otherAmountThreshold` (the minimum) to the user.
3. `POST /quote/build?network=mainnet` with `{ quote, from }`, the quote unchanged. `to` defaults to
   `from` and must equal it on Soroban routes.
4. The user signs `xdr` with their wallet. Do it right away: a Soroban XDR is valid for 180 s,
   an SDEX one for about an hour.
5. `POST /send?network=mainnet` with `{ xdr: signedXdr }`, or submit through your own RPC. Read
   `txHash` and `success`.

Never re-simulate or `prepareTransaction` the built XDR: it is already simulated and sized for
its route.

### Swap in one call

`POST /swap` takes the `/quote` fields plus `from` (and optional `to`, `sponsor`,
`inlinePrerequisites`). It returns 200 with the quote and an `action`:
`SIGN_TRANSACTION` (sign `xdr` and send it), or `CREATE_TRUSTLINE` / `RESTORE_BALANCE` /
`RESTORE_CONTRACT` (sign and submit that `xdr`, then call `/swap` again).

### AMM liquidity

`POST /liquidity/add` with `assetA`, `assetB`, `amountA`, `amountB` (stroops) and `to`. Read the
pool ratio first from `GET /pools/{tokenA}/{tokenB}`: `amountB` outside the ratio by more than
`slippageBps` (default 1%) returns 400. `POST /liquidity/remove` takes `liquidity` (LP shares to burn)
plus the `amountA` and `amountB` you expect back; the minimums are those less `slippageBps`
(default 1%). Soroswap AMM pools only: another pair returns 404 `Pool not found`.

## Units and addresses

- Amounts are integer strings in the smallest unit. XLM, USDC, EURC, AQUA and every classic
  asset: 7 decimals, so 1 USDC = `"10000000"`. Soroban-native tokens can differ (some have 18):
  read `decimals` from `GET /asset-list?name=SOROSWAP`.
- SDEX quotes carry decimal strings (`"0.5000000"`) in `rawTrade`; the top-level amounts are
  still stroops.
- Mainnet contracts: XLM `CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA`, USDC
  `CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75`, EURC
  `CDTKPWPLOURQA2SGTKTUQOWRCBZEORB4BWBOMJ3D3ZTQQSGE5F6JBQLV`. Testnet XLM is
  `CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC`.
- `CODE:ISSUER` returns 400 `Invalid Stellar address`. Convert with
  `new Asset(code, issuer).contractId(Networks.PUBLIC)` or
  `stellar contract id asset --asset CODE:ISSUER --network mainnet`.

## Errors

| Status | Message | Retry | Do |
|---|---|---|---|
| 400 | `No path found` | No | Add venues, lower the amount |
| 400 | `Invalid Stellar address` | No | Send `C...` asset addresses |
| 400 | `amount must be a positive integer number of stroops` | No | Positive integer string |
| 400 | `Simulation Failed` (`errorCode` 10 = insufficient balance) | No | Fix balance or reserve, build again |
| 400 | `Soroban routes deliver to the signing account only` | No | Drop `to` |
| 400 | `Transaction Failed` | No | Quote and build again, never resend the same XDR |
| 403 | `Forbidden resource` | No | Send a valid `Bearer sk_...` key |
| 409 | `Quote stale` | No | Quote again (partner fee changed) |
| 428 | `CREATE_TRUSTLINE` | After the prerequisite | Sign and submit `actionData.xdr`, build again |
| 429 | `Rate limit exceeded` | Yes | Wait `Retry-After` seconds |
| 500 | `Internal server error` on a decimal `amount` | No | Send an integer string |
| 503 | `Routing unavailable` | Yes | Backoff. Also returned for a `G...` asset address |

Full table: https://docs.soroswap.finance/api/errors.md

## Gotchas

- A successful POST returns 201. Treat any 2xx as success.
- A `C...` account (smart wallet) cannot be `from` on `/quote/build`; use the contract path and
  sign the authorization entry with the wallet.
- SDEX cannot pay a contract: leave `sdex` out of `protocols` for `C...` accounts.
- `feeBps` and `referralId` in a request body are ignored; the partner fee belongs to the
  account (`PUT /partner/rate`).
- Testnet quotes come only from Soroswap pools, carry no fee and use testnet addresses.
- Keep XLM for the reserve: 0.5 XLM per trustline plus 1 XLM for the account.
  `available` in `/balances` is already net of it.

Details: https://docs.soroswap.finance/api/stellar-gotchas.md

## Production checklist

- Key on the server; timeouts on every call.
- `?network=mainnet` explicit.
- `slippageBps` set on purpose; show `otherAmountThreshold` before the user signs.
- Quote, build and sign in one go; re-quote after 409 or an expired build.
- Retry only 429 and 503, with backoff.
- After `/send`, confirm the received amount against the quote and log `txHash`.
- Never submit to mainnet without the user's explicit confirmation.
