# Quotes (v1)

> POST /v1/quotes. Ask every route for a price, as one JSON response or as an NDJSON stream.

> API v1 is deprecated. It stays supported, but new integrations should use the [Khalani API](/). See [Migrate to v2](/v1/migrate/).

```text
POST /v1/quotes
```

Asks every route for a price and stores each quote it returns. The response gives one `quoteId` and a list of `routes[]`; the build takes the `quoteId` and the `routeId` you choose.

**The native route wins when it quotes.** If `Hyperstream` or `HyperstreamUTXO` quotes, it is the only route returned, even when an external route would pay more. Name routes in `?routes=` to turn this off.

## Query parameters

| Parameter | Description |
|---|---|
| `mode` | `stream` returns NDJSON, one line per route. See [Streaming](#streaming). |
| `routes` | Comma-separated route ids, such as `Hyperstream,Across`. Only those routes are asked, and all of them are returned. Case-sensitive. |

## Headers

| Header | Description |
|---|---|
| `X-Integrator-Id` | Optional. Your integrator id, if Khalani gave you one. It selects your fee configuration. A malformed value is ignored. See [Limits and reliability](/v1/limits/). |

## Request body

| Field | Type | Required | Description |
|---|---|---|---|
| `tradeType` | string | Yes | `EXACT_INPUT` or `EXACT_OUTPUT`. |
| `fromChainId` | integer | Yes | Source chain id. See [Chains](/v1/reference/chains/). |
| `fromToken` | string | Yes | Source token address, as `GET /v1/tokens` lists it. |
| `toChainId` | integer | Yes | Destination chain id. |
| `toToken` | string | Yes | Destination token address. |
| `amount` | string | Yes | Integer base units, as a decimal string or `0x` hex. Must be above zero. The source amount for `EXACT_INPUT`, the destination amount for `EXACT_OUTPUT`. |
| `fromAddress` | string | No | The wallet that will deposit. Without it, Across, deBridge and Glacis do not quote, and the native route returns an indicative quote: the build then needs `from` and returns a `buildId`. |
| `recipient` | string | No | Receives the output. Defaults to the depositing address. Set it when the destination is not an EVM chain or the depositor is a smart-contract wallet. |
| `refundTo` | string | No | Receives a refund on the source chain. Defaults to the depositing address. |
| `referrer` | string | No | EVM address that receives the referrer fee. Required when `referrerFeeBps` is above zero. Native route only. |
| `referrerFeeBps` | integer | No | Referrer fee in basis points of the input. On exact-input quotes it is computed on the input amount; on exact-output quotes it is passed to the route as a percentage and the route computes the amount. Validation accepts 0 to 9999, but the native route quotes only up to 500: above that it drops out, and you may get only external routes or none. Native route only. |
| `filler` | string | No | EVM address written into the native route's intent as its filler. It does not restrict which routes quote. Native route only. |
| `integratorId` | string | No | The older form of `X-Integrator-Id`. The header wins when both are sent. |
| `depositMethods` | string[] | No | Returns only routes that accept at least one of these methods. See [Data types](/v1/reference/data-types/#depositmethod). |

## Example

```bash
curl -X POST https://api.hyperstream.dev/v1/quotes \
  -H "Content-Type: application/json" \
  -d '{
    "tradeType": "EXACT_INPUT",
    "fromChainId": 42161,
    "fromToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    "toChainId": 8453,
    "toToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "amount": "10000000",
    "fromAddress": "0x5b38da6a701c568545dcfcb03fcb875f56beddc4"
  }'
```

## Response

`200` with a `quoteId` and the routes that quoted. Values are illustrative.

```json
{
  "quoteId": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e9a4f61",
  "routes": [
    {
      "routeId": "Hyperstream",
      "type": "native-filler",
      "icon": "/image/route/Hyperstream.svg",
      "exactOutMethod": "native",
      "depositMethods": ["CONTRACT_CALL"],
      "quote": {
        "amountIn": "10000000",
        "amountOut": "9993000",
        "expectedDurationSeconds": 10,
        "validBefore": 1792443600,
        "quoteExpiresAt": 1792440060,
        "supportedDepositMethods": ["CONTRACT_CALL"],
        "estimatedGas": "2311000000000",
        "tags": ["needs-approval"]
      }
    }
  ]
}
```

When no route serves the pair and amount, the response is still `200`, with an empty `routes[]`.

| Field | Type | Description |
|---|---|---|
| `quoteId` | string | A UUID. Pass it to the build and the submit. |
| `routes[].routeId` | string | `Hyperstream`, `HyperstreamUTXO`, `Across`, `DeBridge` or `Glacis`. Pass it to the build and the submit. |
| `routes[].type` | string | `native-filler`, `liquidity-router` or `external-intent-router`. See [Data types](/v1/reference/data-types/#fillertype). |
| `routes[].icon` | string | Route icon path, relative to the API host. |
| `routes[].exactOutMethod` | string | `native` or `adaptive`: how the route handles `EXACT_OUTPUT`. |
| `routes[].depositMethods` | string[] | The deposit methods this route accepts for this quote. |
| `quote.amountIn` | string | What the user sends, in source base units. |
| `quote.amountOut` | string | What the user receives, in destination base units. |
| `quote.expectedDurationSeconds` | integer | Expected time to fill. An estimate. |
| `quote.validBefore` | integer | Unix seconds. The order's deadline. A native-route order not filled by then is refunded. The stored quote is deleted 60 seconds after it. |
| `quote.quoteExpiresAt` | integer | Unix seconds. The price is good until then; build before it or quote again. Usually much sooner than `validBefore`: about a minute on the native route. |
| `quote.supportedDepositMethods` | string[] | Optional. The route's deposit methods for this source chain. |
| `quote.estimatedGas` | string | Optional. The total network fee, in the source chain's smallest native unit (wei, lamports). Not gas units. |
| `quote.tags` | string[] | Optional. `needs-approval` (an approval comes before the deposit) or `1-click` (no approval). |

Routes that touch TRON add fee details to `quote`: `activationFee` (the source-token cost reserved for activating the TRON recipient, with `required`, `refundable` and amounts), `tronUsdtFees` (`activationRequired`, `activationFeeUsdt18`, `hasUsdtBalance`, `energyFeeUsdt18`), `totalOutputFeeUsdt18` and `feeBaseOutcomeAmount18`. Fields ending in `18` are 18-decimal amounts.

## Streaming

With `?mode=stream`, the response is `Content-Type: application/x-ndjson`: one JSON object per line, one line per route, written as each route answers. Every line carries the same `quoteId`.

```bash
curl -N -X POST "https://api.hyperstream.dev/v1/quotes?mode=stream&routes=Across,DeBridge" \
  -H "Content-Type: application/json" \
  -d '{ "tradeType": "EXACT_INPUT", "fromChainId": 42161, "fromToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", "toChainId": 8453, "toToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "amount": "10000000", "fromAddress": "0x5b38da6a701c568545dcfcb03fcb875f56beddc4" }'
```

```text
{"quoteId":"3f6c2a1e-8b4d-4e7a-9c15-2d0b7e9a4f61","routeId":"Across","type":"external-intent-router","icon":"/image/route/Across.svg","exactOutMethod":"native","depositMethods":["CONTRACT_CALL"],"quote":{"amountIn":"10000000","amountOut":"9988000","expectedDurationSeconds":4,"validBefore":1792443600,"quoteExpiresAt":1792440060}}
{"quoteId":"3f6c2a1e-8b4d-4e7a-9c15-2d0b7e9a4f61","routeId":"DeBridge","type":"external-intent-router","icon":"/image/route/DeBridge.svg","exactOutMethod":"native","depositMethods":["CONTRACT_CALL"],"quote":{"amountIn":"10000000","amountOut":"9981000","expectedDurationSeconds":10,"validBefore":1792443600,"quoteExpiresAt":1792440060}}
```

- Without `?routes=`, external quotes are held back until the native route answers. If it quotes, its line is the only one, and the stream closes. If it does not, the held-back external quotes are written, then the rest as they arrive.
- A route that fails or does not quote writes nothing, so when no route quotes, the stream is empty.
- An invalid body returns an ordinary JSON error instead of a stream.

## Errors

| Status | `name` | When |
|---|---|---|
| `400` | `ValidationException` | A field is missing or malformed, or `amount` is zero. |
| `400` | `BadRequestException` | The body is not JSON (`Malformed JSON body`). |
| `503` | `MaintenanceException` | Maintenance. Retry after `Retry-After: 300`. |

Unsupported tokens, chains and pairs do not raise errors here: those routes do not quote. See [Handling exceptions](/v1/handling-exceptions/).
