> ## Documentation Index
> Fetch the complete documentation index at: https://docs.route.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# Solana

> Quotes, swap transactions, gasless swaps, standing orders and agent trades on Solana from the partner API.

Route routes Solana swaps from the same partner API, under `/solana`. Your partner key works here with the same rate limit it has
on Robinhood Chain (counted separately). Quotes are priced by running every pool's real program on current account state, and
that state is kept current by a real-time account stream of every routed pool, so a quote reflects the pools as they are now.

```
https://partners.route.fun/solana
```

| Endpoint | Status |
| - | - |
| `GET /solana/quote` | Live |
| `GET /solana/build` (swap transaction; keys with build permission) | Live |
| `GET /solana/build?...&gasless=true`, `POST /solana/gasless/submit`, `GET /solana/gasless/status`, `GET /solana/gasless/info` | Live |
| `GET /solana/orders/prepare`, `POST /solana/orders`, `GET /solana/orders`, `GET /solana/orders/revoke` (limit, stop-loss, DCA, TWAP) | Live |
| `GET /solana/delegate/trade` (agent trades; keys with build permission) | Live |
| `GET /solana/health` | Live |

Transactions go through two Route programs on Solana mainnet. Both can be upgraded only by Route's treasury multisig.

| Program | Address | Used for |
| - | - | - |
| route-exec | `6Fjz5w34GB4otWHR12Hrni2tDRZme97dGcNbTU7dY8ho` | Swaps (`/build`) and gasless swaps |
| route-delegate | `AfeNwe9GoDXzLnXG3hrJpu1esXTHS9JatxsAb71cBNgL` | Standing orders and agent trades |

The Route fee on Solana is 0.

## Quote

```bash theme={null}
curl -G "https://partners.route.fun/solana/quote" \
  -H "Authorization: Bearer $ROUTE_KEY" \
  --data-urlencode "input=So11111111111111111111111111111111111111112" \
  --data-urlencode "output=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" \
  --data-urlencode "amount=1000000000"
```

**input** `string` *required*

Input mint (base58). Use the wrapped SOL mint `So11111111111111111111111111111111111111112` for SOL.

**output** `string` *required*

Output mint (base58). Must differ from `input`.

**amount** `integer` *required*

Exact input amount in raw units (1 SOL = `1000000000`).

**exclude** `string`

Comma-separated venue names or program ids the quote must not use.

### Response

```json theme={null}
{
  "amount_out": 103538554,
  "hops": ["So11111111111111111111111111111111111111112", "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"],
  "legs": [
    {
      "venue": "PancakeSwap",
      "program": "HpNfyc2Saw7RKkQd8nEL4khUcuPhQ7WwY1B2qjx8jxFq",
      "input_mint": "So11111111111111111111111111111111111111112",
      "output_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "vault_in": "bHHnvxhkzBebvqxpnzVaXSdQ1GdFeZFg8yi9YKgL7zE",
      "vault_out": "CRKZr6Y9t2hzVNWY4gJk5eig8uznyykB4RTuGSqJDw7n",
      "amount_in": 1000000000,
      "amount_out": 103538554,
      "cu": 65601
    }
  ],
  "cu": 65601,
  "slot": 460581226,
  "micros": 90166
}
```

| Field | Meaning |
| - | - |
| `amount_out` | Output in raw units of `output`, from an exact simulation of the whole route at `slot`. |
| `legs` | One entry per pool: the venue, its program, the pool's two vaults, and the amounts in and out. A route can split one amount over several pools and paths. |
| `hops` | The mints along the main path. |
| `paths` | Present when the trade is split across paths (part direct, part through another token): each path's mints, input and output. |
| `cu` | Compute units the venue calls used in the simulation. |
| `slot` | The slot whose state the quote was simulated on. |
| `micros` | Server time for the quote. |

Other fields (`plans_estimated`, `plans_simulated`, `search_us`, `sims`, `sim_us`) are diagnostics and may change.

A trade whose price would be more than 10% below the pair's rate at a small size is refused (`422`) rather than quoted at a
price no one should accept.

Live quote streams (`stream=`) are available on Robinhood Chain only; on Solana, poll `/solana/quote`.

## Build a swap

`/build` returns the quote and an unsigned transaction for `user`. Before returning it, Route runs the whole transaction
(route-exec and every venue program) on current state. A transaction that fails that run is never returned. The run gives the
wallet the input amount, so it does not check the wallet's balance. The user signs and sends the transaction.

```bash theme={null}
curl -G "https://partners.route.fun/solana/build" \
  -H "Authorization: Bearer $ROUTE_KEY" \
  --data-urlencode "input=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" \
  --data-urlencode "output=So11111111111111111111111111111111111111112" \
  --data-urlencode "amount=5000000" \
  --data-urlencode "user=<wallet>"
```

**input** `string` *required*

Input mint.

**output** `string` *required*

Output mint.

**amount** `integer` *required*

Exact input in raw units.

**user** `string` *required*

The wallet that signs, pays and receives.

**slippageBps** `integer`

Default `50`. `min_out` is the quote less this.

**cuPrice** `integer`

Priority fee in micro-lamports per compute unit. Default `10000`.

**split** `boolean`

Allow routes split across paths. Default `false`.

**gasless** `boolean`

See [Gasless swaps](#gasless-swaps).

| Field | Meaning |
| - | - |
| `tx` | The versioned transaction, base64, unsigned. Deserialize it, have the wallet sign it, send it. |
| `amount_out` | The quoted output. |
| `min_out` | The least output the transaction accepts. Below it the transaction fails and nothing is swapped. |
| `expiry_slot` | The transaction fails after this slot (about 60 s). Build again instead of resending an old one. |
| `fee_bps` | The Route fee: 0 on Solana. |
| `program` | route-exec. |
| `legs`, `hops`, `paths` | The route, as in a quote. |
| `lookup_tables` | Address lookup tables the transaction uses. |
| `simulation` | The pre-send run: `cu` (compute units used) and `out` (what the user's output account gained in that run). |

If the user's output token account does not exist, the transaction creates it. SOL output arrives as native SOL: the wallet's
wSOL account is closed at the end, so any wSOL already in it is unwrapped too and arrives with the output.

## Gasless swaps

With `gasless=true`, Route's relayer is the transaction's fee payer and pays for new token accounts. The user repays the relayer
in the input token inside the same transaction, before the swap. The user needs no SOL.

1. `GET /solana/build?...&gasless=true`. The response has a `gasless` object: `relayer`, `fee_in` (the repayment, in raw units
   of the input token), `fee_lamports` (what it covers) and `amount_routed` (`amount` less `fee_in`).
2. The user signs `tx`. The relayer's signature slot stays empty.
3. `POST /solana/gasless/submit` with `{"tx": "<base64 signed transaction>"}`. Route checks that it is the exact transaction it
   built in the last 90 seconds and that the user signed it, then signs as fee payer and sends it. The response has `signature`.
4. `GET /solana/gasless/status?sig=<signature>` returns the chain's status of the transaction.

The fee covers the network fee (2 signatures plus the priority fee at the transaction's compute limit), rent for accounts the
relayer funds and does not get back, and 10% on top. A trade whose fee would be more than 30% of its input is refused. The wallet
must already hold a token account for the input token. A wallet can submit up to 10 gasless swaps a minute.
`GET /solana/gasless/info` returns the relayer address and these limits.

| `submit` status | When |
| - | - |
| `200` | Sent. |
| `400` | Not a transaction Route built, changed after it was built, expired (build again), or a missing or bad user signature. |
| `409` | Already submitted. |
| `429` | Too many gasless swaps for this wallet this minute. |
| `502` | The chain refused it (its own simulation failed). Nothing was charged. |

## Standing orders

A standing order is a policy account in route-delegate, owned by the user. The user's tokens stay in the wallet: the user makes
the policy's authority a delegate for the order's total, and Route's keeper fills the order when it is due. The program enforces
the order on chain on every fill: the input and output tokens, the slice and the total, the price floor (the least output per
slice), the interval, the expiry, the cap on the keeper's fee, and that the output goes to the user. The keeper cannot move funds
in any other way.

| `kind` | Fills |
| - | - |
| `limit` | One slice once the output reaches `minOut`. |
| `stop` | Once the output falls to the trigger (`triggerOut`, set when registering), and only while it is still at least `minOut`. |
| `dca` | `slice` every `intervalS` seconds until `amount` is filled, each at no less than the floor. |
| `twap` | Same as `dca`. Use it for one order spread over a short time. |

1. `GET /solana/orders/prepare` returns the create transaction for the owner to sign and send:

```bash theme={null}
curl -G "https://partners.route.fun/solana/orders/prepare" \
  -H "Authorization: Bearer $ROUTE_KEY" \
  --data-urlencode "owner=<wallet>" \
  --data-urlencode "input=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" \
  --data-urlencode "output=So11111111111111111111111111111111111111112" \
  --data-urlencode "amount=5000000" \
  --data-urlencode "kind=dca" \
  --data-urlencode "slice=1000000" \
  --data-urlencode "intervalS=3600"
```

**owner** `string` *required*

The wallet. Output always goes back to it.

**input** `string` *required*

Input mint.

**output** `string` *required*

Output mint.

**amount** `integer` *required*

The order's total input.

**kind** `string` *required*

`limit`, `stop`, `dca` or `twap`.

**slice** `integer`

Input per fill. Default: all of `amount` at once.

**intervalS** `integer`

Seconds between fills. Required for `dca` and `twap`.

**minOut** `integer`

The least output for one slice (raw units). Required for `limit` and `stop`. For `dca` and `twap` the default is 10% below the current price.

**expiryS** `integer`

Seconds until the order expires. Default 30 days.

**gasless** `boolean`

The relayer pays to create the order. The owner signs, then sends it with `POST /solana/gasless/submit`.

The response has `policy` (the order's address), `tx`, `min_out_per_slice`, `max_fee` (the most the keeper may take per fill, in
the input token), `approve` (the delegation the transaction sets: the total of all the owner's live orders on that token) and
`payer`. For SOL input, the transaction wraps the SOL into the wallet's wSOL account.

2. After the transaction lands, register the order with the keeper: `POST /solana/orders` with `{"policy": "<policy>"}`. Stop
   orders also pass `"triggerOut": <output for one slice at which to sell>`.

3. `GET /solana/orders?owner=<wallet>` lists the owner's orders (`owner` is required). Each has `order` and `policy_state` (the policy as it is on
   chain). `order` holds `status` (`active`, `done` or `revoking`), `last_error`, and `fills`, where each fill has its `signature`,
   `amount_in`, `fee` and `simulated_out`.

Each fill pays the keeper its network fee in the input token, taken from the slice and capped by `max_fee`. The keeper simulates
every fill before sending it, so a fill that would fail or miss the floor is not sent.

### Cancel

`GET /solana/orders/revoke?policy=<policy>` returns a transaction for the owner to sign. It revokes and closes the policy (the
rent goes back to whoever paid it), and sets the token delegation to what the owner's other live orders still need, or removes it.

## Agent trades

An agent policy lets another key, such as an AI agent or a bot, trade from the owner's wallet within limits the owner signs: the
tokens, the most per trade and in total, the price floor (10% below the current price by default), the interval and the expiry.
Output always goes to the owner. The agent cannot send funds anywhere else.

1. `GET /solana/orders/prepare?...&kind=agent&agent=<agent public key>`, with the same parameters as above (`slice` = the most per
   trade). The owner signs and sends the transaction. Do not register agent policies with `POST /solana/orders`.
2. For each trade: `GET /solana/delegate/trade?policy=<policy>&input=<mint>&output=<mint>&amount=<raw>` (optional `minOut`).
   The response has `tx`, `quote_out`, `simulated_out` and `fee` (the keeper's fee, in the input token).
3. The agent signs `tx` and sends it with `POST /solana/gasless/submit`. Route's keeper pays the network fee.

Cancel an agent policy with `/solana/orders/revoke`, as for orders.

## Errors

Errors are JSON `{"error": "..."}` with these statuses:

| Status | When |
| - | - |
| `400` | Bad mint, the same mint for `input` and `output`, `amount` of 0, or `stream` (not available on Solana). |
| `401` | Missing or unknown key. |
| `403` | The endpoint is not available to partner keys, or the key has no build permission (`/build`, `/delegate/trade`). |
| `422` | No route between the two mints, or the price impact is too high. |
| `429` | Rate limit or too many requests in flight. |
| `503` | The router is starting up; retry shortly. |

`/build`, `/orders/*` and `/delegate/trade` use these statuses too: `400` for bad or missing parameters (including a gasless trade too
small for its fee, a `limit` or `stop` order without `minOut`, or `GET /orders` without `owner`), `404` for an unknown policy, and
`422` when the transaction cannot be built (no route, or the pre-send run failed).

## Venues

Quotes route through the open venues on Solana (Raydium, Orca Whirlpool, Meteora, PancakeSwap, Pump.fun, Manifest, SolFi, GoonFi
and many more, including stake-pool routes for liquid staking tokens). Some private market makers only accept calls from routers
they have approved; Route does not route through them until they approve the Route program, so every quote is one Route can
execute.

`GET /solana/health` returns `ok`, `ready`, the current `slot` and `chain_clock_lag_s` (seconds behind wall time).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.