Skip to main content
Request a signed quote to lock a conversion rate for a set window. A quote-based Autoramp holds several active quotes at once, so you keep one Autoramp running over time without recreating it.

How It Works

A quote binds a conversion rate between two currencies for a limited window. You request a quote with GET /api/autoramps/quote, then pass the signed result to POST /api/autoramps to create an Autoramp that executes at the locked rate. Once the Autoramp exists, keep attaching new quotes to it with POST /api/autoramps/{autoramp_id}/quotes. Each attached quote stays active until its own valid_until passes. When a deposit arrives, MoonPay Enterprise picks the newest active quote whose amount_in value and source currency match the deposit. Deposits that match no quote, or only an expired one, are returned to the sender. When a deposit matches a quote whose rate lock has expired but whose valid_until has not, the quote’s rate_expiry_policy decides what happens (see Expiry policies).
Without a quote, a standing Autoramp converts at the current market rate when the deposit is processed. With one or more active quotes, the deposit executes at the locked rate of the matching quote. See Standing or quote-based.

Key parameters

Rate lock duration: the window where the quoted rate and fee are guaranteed. Deposits that match within it execute at the quoted price. Validity period: the total time the quote stays usable, ending at valid_until. Deposits arriving after it don’t match the quote. Exact amount: a deposit must equal the quote’s amount_in exactly. A transfer that arrives short, for example after bank charges taken off a SEPA or wire transfer, matches no quote and is returned. Validity cap: valid_until is at most 24 hours after the quote, whatever the rate lock allows. Minimum amount: a quote must be worth at least 1 EUR. Smaller amounts return 400 with "Quote amount must be at least 1 EUR".

Rate lock duration caps

The rate_lock_duration_minutes parameter is optional. If omitted, the quote uses the maximum allowed for the pair. Larger values are silently clamped to the cap.

Expiry policies

What happens when funds arrive after the rate lock expires depends on the rate_expiry_policy you set.
The quote is valid until the rate lock or expiry_in_hours ends, whichever comes first. Funds arriving after that are returned.Example:
  • Quote: 100 EUR for 108 USDC
  • Rate lock: 10 minutes, validity: 10 minutes
  • Funds arrive at 12 minutes
  • Result: returned (both windows expired)

Prerequisites

1

The customer is Active

The customer’s status is Active: terms signed, identification approved, and nothing outstanding in GET /api/customers/{customer_id}/required-signings. Otherwise POST /api/autoramps returns 403 with "Customer is not active". See Onboarding.
2

The rail is Active for this customer

An Active customer can still be waiting on a specific rail. Read GET /api/customers/{customer_id}/abilities and create the Autoramp only once its rail reads Active. A rail that isn’t Active yet returns 422 with "Customer is unable to complete the action. Consult the customer abilities API". Subscribe to the customer_fiat_abilities webhook instead of polling. See Ability Status.
3

The recipient is registered

Register the wallet or bank account that receives the converted funds before you create the Autoramp, and pass the same details in recipient_account:
  • Wallet: see Crypto Addresses. An unknown wallet returns 400 with "Recipient wallet not verified for customer".
  • Bank account: see Fiat Addresses. It must reach Registered. An account that isn’t registered yet returns 400 with "recipient fiat account not verified".
Quote requests take the registered recipient’s ID as recipient_account_id. They fail if it points to an address that isn’t registered yet.

Create an Autoramp with a quote

1

Create a quote

GET /api/autoramps/quoteRequest a signed quote that defines the conversion rate, lock duration, validity period, and fees. Pass it unchanged when you create the Autoramp.
Example response:
The fee object is trimmed. amount_in is what your customer sends to receive exactly amount_out.
2

Create the Autoramp with the quote

POST /api/autorampsSubmit the signed quote payload to create a quote-based Autoramp. The Autoramp matches inbound deposits against the active quotes attached to it.
Example response:
The Autoramp starts in Authorized with empty deposit_rails, like any Autoramp. Show the deposit details once it’s Approved. The quotes array lists every active quote on the Autoramp. The legacy quote field is deprecated; read quotes instead.
POST /api/autoramps requires an Idempotency-Key header. A missing key returns 400. Only successful responses are cached, so a retry after an error runs again. See Idempotency.
The quote is digitally signed. Pass it verbatim into POST /api/autoramps. Any change, such as edited values or omitted fields, returns 400 with "Invalid signature". The quote’s rate lock must also still be running when you submit it: a quote past rate_lock_valid_until returns 400 with "Rate lock has expired", even under the Slippage policy.
For offramp quotes, send is_third_party=false. A quote requested with is_third_party=true carries that flag into the Autoramp, and creating it fails, because only onramp Autoramps accept third-party sources.

Attach a new quote to an existing Autoramp

After the Autoramp exists, attach further quotes to keep it executing at locked rates over time. This works only on quote-based Autoramps (source is Quote) that are Approved. An Autoramp that is still Authorized returns 400 with "Autoramp is not approved", and a standing Autoramp returns "Cannot attach quotes to a standalone autoramp".
Use the right quote object. This endpoint takes the SignedAutorampRateQuote returned by GET /api/autoramps/{autoramp_id}/quote, not the SignedAutorampQuote returned by GET /api/autoramps/quote. The creation quote has no autoramp_id field, so submitting it here fails with Expected input type "string_uuid", found null.
1

Get a signed rate quote

GET /api/autoramps/{autoramp_id}/quoteReturns a SignedAutorampRateQuote. The Autoramp’s recipient, fee profile, and destination currency are reused automatically, so this endpoint has a smaller parameter surface than the initial quote endpoint.The source_currency_code must be one of the Autoramp’s allowed input currencies: the original source_currency plus any entries you registered in additional_in_currencies at creation time.
2

Attach the signed quote

POST /api/autoramps/{autoramp_id}/quotesSubmit the signed rate quote returned in the previous step. Requires an Idempotency-Key header. Returns 201 with the updated Autoramp (its quotes array now includes the new quote).
Attaching a new quote that shares amount_in value and source currency with an existing active quote supersedes the older one for incoming deposits. The older quote stays in quotes until its own valid_until passes; nothing is deleted retroactively.
Staged setup pattern. Create the Autoramp with any initial quote to surface the deposit details early, so the payer can whitelist them or finish their onboarding. Once the real amount is known, attach the production quote. If the initial quote expired first, the Autoramp reads Cancelled (dormant) with no webhook. Attaching the new quote still works and brings it back to Approved, so don’t wait for Approved before you attach.

When quotes run out

A quote-based Autoramp with no active quote left goes dormant: the API reports it as Cancelled, and deposits don’t match it. Attach a new quote and it returns to Approved with the same deposit details. A dormant onramp Autoramp is cancelled for good after 7 days. See Autoramp Status.

Fees on a quote

The quote’s fee object shows what the transfer carries, in the source currency. transaction_fee, banking_fee, and network_fee count only fees that are deducted from the transfer. Fees your fee profile settles later don’t appear in them: they show up on your monthly invoice instead. See Fees and Invoices and Fees.

Multi-currency input

By default, a quote-based Autoramp only accepts deposits in its original source_currency. To let it accept additional crypto input currencies, and request quotes for them later, pass additional_in_currency_codes and additional_in_currency_chains when you call GET /api/autoramps/quote. A fiat source can’t take additional currencies. The two parameters are index-aligned arrays of up to 16 entries each. The chain at position i describes the code at position i. The list must not include the source_currency itself and must not contain duplicates. After the Autoramp is created, request a quote for any of the additional currencies via GET /api/autoramps/{autoramp_id}/quote and attach it via POST /api/autoramps/{autoramp_id}/quotes.

Query parameters: GET /api/autoramps/quote

Every parameter above is part of the signed quote. On a quote-based Autoramp, set external_id, fee_profile_id, batch_payout, pay_by_reference, swift_purpose_code, and the payout reference fields here. Adding them later on POST /api/autoramps returns 400 with "Invalid signature".

Query parameters: GET /api/autoramps/{autoramp_id}/quote

The Autoramp’s recipient, destination currency, and fee profile are reused, so only pricing-related parameters are needed.
  • Check rate_lock_valid_until and valid_until before submitting. Expired quotes return 400.
  • Use idempotency keys for POST /api/autoramps and POST /api/autoramps/{autoramp_id}/quotes.

Error Handling

Client errors return a plain string body.
400 Bad Request

Autoramp

Create, edit, and cancel Autoramps

Autoramp Status

Every status an Autoramp moves through