Skip to content

GET /v1/quote

Purpose

Aggregates swap quotes across configured providers and returns ranked routes.

When to Call

  • After user selects input token, output token, and amount.
  • After recipient address/party is known.
  • On amount/pair/provider filter changes.

Request

  • Method: GET
  • Path: /v1/quote

Required query params:

  • inputInstrumentId
  • inputInstrumentAdmin
  • outputInstrumentId
  • outputInstrumentAdmin
  • amount (positive decimal string, greater than 0)
  • recipient

Optional query params:

  • slippageTolerance (non-negative number)
  • referral (non-empty string)
  • whitelistedProviders (provider IDs)

Provider whitelist supports both patterns:

  • Repeated params: ...&whitelistedProviders=nightly&whitelistedProviders=tradecraft
  • Comma separated: ...&whitelistedProviders=nightly,tradecraft

Response

200 OK:

json
{
  "requestId": "f9f2cf47-5df6-4f15-a4f5-44cd6b626bb6",
  "totalTimeMs": 184,
  "swapType": "exactIn",
  "platformFeeBps": 0,
  "quotes": [
    {
      "inputInstrumentId": "Amulet",
      "inputInstrumentAdmin": "DSO::1220...",
      "outputInstrumentId": "USDCx",
      "outputInstrumentAdmin": "decentralized-usdc-interchain-rep::1220...",
      "inAmount": "10",
      "outAmount": "9.86",
      "minOutAmount": "9.72",
      "rate": "0.986",
      "priceImpact": "0.12",
      "provider": "nightly",
      "providerQuoteId": "provider-quote-id",
      "execution": {
        "executionMode": "magicAddress",
        "transferAddress": "some-provider-magic-address"
      }
    },
    {
      "inputInstrumentId": "Amulet",
      "inputInstrumentAdmin": "DSO::1220...",
      "outputInstrumentId": "USDCx",
      "outputInstrumentAdmin": "decentralized-usdc-interchain-rep::1220...",
      "inAmount": "10",
      "outAmount": "9.86",
      "minOutAmount": "9.72",
      "rate": "0.986",
      "priceImpact": "0.12",
      "provider": "nightly",
      "providerQuoteId": "provider-quote-id",
      "execution": {
        "executionMode": "transfer",
        "transferAddress": "some-provider-transfer-address",
        "memo": "provider-memo"
      }
    }
  ]
}

Execution modes:

  • magicAddress: send to transferAddress directly.
  • transfer: send to transferAddress and include memo.

QuoteItem Model

Each entry in quotes is a QuoteItem. A QuoteItem is one executable route variant for the current quote request.

Important details:

  • One provider can return multiple QuoteItem values for the same price route.
  • This happens when the provider supports both execution modes.
  • You should treat each item as independently selectable and executable.
  • Keep providerQuoteId as an opaque provider reference for logging/tracing.

Shape (as returned by this endpoint):

ts
type QuoteItem = {
  inputInstrumentId: string;
  inputInstrumentAdmin: string;
  outputInstrumentId: string;
  outputInstrumentAdmin: string;
  inAmount: string;
  outAmount: string;
  minOutAmount: string;
  rate: string;
  priceImpact: string;
  provider?: string;
  providerQuoteId?: string;
  execution:
    | {
        executionMode: 'magicAddress';
        transferAddress: string;
      }
    | {
        executionMode: 'transfer';
        transferAddress: string;
        memo: string;
      };
};

Interacting With QuoteItems

  1. Request quotes for the current pair, amount, and recipient.
  2. Render each QuoteItem as a route choice and show at least outAmount, minOutAmount, provider, rate, and priceImpact.
  3. Let users pick a specific item if you expose route choice; otherwise use the first item (quotes is already ranked by best outAmount).
  4. Execute according to execution.executionMode:
    • magicAddress: send funds to execution.transferAddress with no memo.
    • transfer: send funds to execution.transferAddress and include execution.memo.
  5. Re-quote when any execution-critical input changes, especially amount, token pair, selected provider set, or recipient.

Behavior guarantees:

  • Quotes are sorted by best outAmount first.
  • Provider failures/timeouts are tolerated.
  • If all providers fail or return no route, quotes is an empty array with 200 OK.

Errors

Validation error (400):

json
{
  "error": "Invalid quote request",
  "details": [
    {
      "field": "amount",
      "message": "amount must be a positive decimal string"
    }
  ]
}

Unknown provider in whitelist (400):

json
{
  "error": "Invalid quote request",
  "details": [
    {
      "field": "whitelistedProviders",
      "message": "provider unknown-provider is not supported"
    }
  ]
}

Rate limit (429):

json
{
  "error": "Too Many Requests",
  "details": "Rate limit exceeded for this route"
}

Integration Notes

  • Use token metadata from /v1/tokens to fill both token ID and admin fields.
  • Always handle both magicAddress and transfer execution modes.
  • Treat empty quotes as a valid no-route state.
  • Quote aggregation applies a provider timeout (currently 4900 ms per provider).
  • Default IP policy for /v1/quote is 30 requests per 60 seconds.
  • Need higher limits? Reach out on Discord.

Examples

Basic Quote (All Providers)

bash
curl "https://api.hermes.ag/v1/quote?inputInstrumentId=Amulet&inputInstrumentAdmin=DSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc&outputInstrumentId=USDCx&outputInstrumentAdmin=decentralized-usdc-interchain-rep::12208115f1e168dd7e792320be9c4ca720c751a02a3053c7606e1c1cd3dad9bf60ef&amount=10&recipient=user-address"

Quote with Repeated whitelistedProviders

bash
curl "https://api.hermes.ag/v1/quote?inputInstrumentId=Amulet&inputInstrumentAdmin=DSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc&outputInstrumentId=USDCx&outputInstrumentAdmin=decentralized-usdc-interchain-rep::12208115f1e168dd7e792320be9c4ca720c751a02a3053c7606e1c1cd3dad9bf60ef&amount=10&recipient=user-address&whitelistedProviders=nightly&whitelistedProviders=tradecraft"

Quote with Comma-Separated whitelistedProviders

bash
curl "https://api.hermes.ag/v1/quote?inputInstrumentId=Amulet&inputInstrumentAdmin=DSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc&outputInstrumentId=USDCx&outputInstrumentAdmin=decentralized-usdc-interchain-rep::12208115f1e168dd7e792320be9c4ca720c751a02a3053c7606e1c1cd3dad9bf60ef&amount=10&recipient=user-address&whitelistedProviders=nightly,tradecraft"
ts
const params = new URLSearchParams({
  inputInstrumentId: 'Amulet',
  inputInstrumentAdmin:
    'DSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc',
  outputInstrumentId: 'USDCx',
  outputInstrumentAdmin:
    'decentralized-usdc-interchain-rep::12208115f1e168dd7e792320be9c4ca720c751a02a3053c7606e1c1cd3dad9bf60ef',
  amount: '10',
  recipient: 'user-address',
  slippageTolerance: '0.5',
});

for (const providerId of ['nightly', 'tradecraft']) {
  params.append('whitelistedProviders', providerId);
}

const response = await fetch(`https://api.hermes.ag/v1/quote?${params.toString()}`);
const payload = await response.json();

if (!response.ok) {
  throw new Error(JSON.stringify(payload));
}

const quotes = Array.isArray(payload.quotes) ? payload.quotes : [];
if (quotes.length === 0) {
  // no route available
}