Skip to main content
A conversion moves money from your balance in one asset to your balance in a different asset. It has two steps. You get a quote, and then you execute the quote. Money moves only at the second step.

Get a quote

POST /v2/conversions/quotes takes from_asset, to_asset, and from_amount. You fix what you pay. Hermes tells you what you receive.
  • to_amount is what you receive. Hermes does not change it. A conversion delivers exactly to_amount, or it fails as a whole.
  • rate is for display. It is from_amount divided by to_amount, at eight decimal places. If you calculate from_amount from rate, your result can be one minor unit different. The two amounts are the truth.
  • A quote holds no money. Hermes checks your balance when you execute.
  • from_amount has a maximum of four decimal places. More than four gets 400 validation_error.
The pair must be one fiat asset and one stablecoin. Fiat to fiat, and stablecoin to stablecoin, get unsupported_pair (422). The same asset on both sides gets the same code. You can get as many quotes as you want, up to 30 in each minute. Above that rate you get 429 rate_limited. There is no Idempotency-Key on a quote. Hermes does not list quotes.

Execute the quote

POST /v2/conversions takes { quote_id } and needs an Idempotency-Key header. A request with no key gets 400.
The call waits for the result. In the normal case the response is completed or failed. Hermes debits from_amount from your from_asset balance and credits to_amount to your to_asset balance in one movement.

Expiry, and a used quote

A quote is valid until expires_at. The window is short, about 25 seconds. Execute soon after you get the quote.
  • Execute after expires_at gets quote_expired (422). Get a new quote.
  • Execute a quote a second time, with a different Idempotency-Key, gets quote_used (409). The first execution stands. Read it with GET.
  • Execute a quote a second time, with the same key, returns the first response again. This is the safe way to send a request again after a timeout.
A quote is for one execution. Get a new quote for each conversion.

The processing status

In rare cases the response shows status: "processing". This means that Hermes accepted the conversion, but does not have the result yet. It lasts seconds, not hours. Read GET /v2/conversions/{id} again until the status is completed or failed. Do not send the request again with a new key. The first conversion exists and gets to a result on its own. If you send the same key again, you get the current state of the same conversion.

When a conversion fails

A failed conversion moved no money. Your from_asset balance is as it was before. The failure object gives one of four codes: Everything that you can correct yourself is a 4xx at quote time or at execute time, and makes no conversion. See Errors.

How to learn the result

Webhooks (recommended) — Hermes sends conversion.completed or conversion.failed. The delivery carries api_version: "v2", and data is the conversion in the shape above. See Webhooks. A poll — read GET /v2/conversions/{id}. GET /v2/conversions lists your conversions, newest first, with keyset pagination. Filter with asset, which matches from_asset or to_asset.

Limits

Each asset has a minimum and a maximum for one conversion. Hermes checks them at quote time, before it gives you a quote.
  • Below the minimum gets amount_below_minimum (422).
  • Above the maximum gets limit_exceeded (422).
Your available in from_asset is the other ceiling. If it is too low at execute time, you get insufficient_funds (402), and no money moves.
A conversion has no fee field. What you pay is from_amount. What you receive is to_amount. The economics are in the two figures.