Ramps

Fiat on-ramps and off-ramps — discover corridors, price a Ramp Quote just-in-time, and hand off to the provider's own execution flow.

SDP wraps ramp providers behind a single pricing step: a Ramp Quote, priced just-in-time against the provider. There is no execute endpoint — SDP quotes the ramp and hands the end-user to the provider's own flow (hosted redirect or funding instructions) to complete it.

Every quote is tied to a Counterparty — the KYC subject for the ramp — and a custody wallet you control. For per-provider configuration, see Ramp providers.

Prerequisites

  1. A Counterparty. Create one with POST /v1/counterparties before requesting a quote.
  2. Provider Requirements satisfied, if the provider needs them. Some providers require KYC or bank details collected against the counterparty before they will price or accept a quote. Check GET /v1/counterparties/{counterpartyId}/requirements?provider=…&direction=… and submit collected fields with POST to the same path until status reads ready.
  3. A custody wallet you control, used as the crypto leg — the onramp destination or the offramp source.

Discovering corridors

GET /v1/payments/ramps/onramp/currency and GET /v1/payments/ramps/offramp/currency list the fiat/crypto pairs SDP supports and which providers cover each one — the Corridor dimensions (currency, country coverage, entity type).

Terminal
curl "https://api.solana.com/v1/payments/ramps/onramp/currency?source=USD&dest=usdc.solana" \
  -H "Authorization: Bearer sk_test_..."
Query paramNotes
sourceOnramp: fiat currency (ISO code). Offramp: crypto rail (usdc.solana, sol.solana, …).
destOnramp: crypto rail. Offramp: fiat currency.
providerNarrow to one provider.

The response's pairs list which providers cover each source/dest combination; providerDetails gives each provider's country coverage and supported entity types for the direction.

Estimating a rate

POST /v1/payments/ramps/onramp/estimate and .../offramp/estimate return a rate preview without creating anything — no counterparty or wallet required. SDP calls every provider on the corridor concurrently and returns one result per provider: ok (with the estimate), unsupported, or error.

Terminal
curl -X POST https://api.solana.com/v1/payments/ramps/onramp/estimate \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "assetRail": "usdc.solana",
    "fiatCurrency": "USD",
    "fiatAmount": "100.00"
  }'

Each entry under estimates carries fiatAmount, cryptoAmount, exchangeRate, and fees when status is ok. Use this to show the user a rate before they commit to a quote.

Requesting a quote

POST /v1/payments/ramps/onramp/quote (fiat → crypto) and POST /v1/payments/ramps/offramp/quote (crypto → fiat) create the actual Ramp Quote against the named provider. This is the step that talks to the provider and, for most providers, produces a provider-side record — unlike estimate, it requires a resolved counterparty and wallet.

Terminal
curl -X POST https://api.solana.com/v1/payments/ramps/onramp/quote \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "moonpay",
    "counterpartyId": "cp_...",
    "destinationWallet": "wal_...",
    "cryptoToken": "USDC",
    "fiatCurrency": "USD",
    "fiatAmount": "100.00"
  }'

Request fields

FieldRequiredNotes
provideryesOne of moonpay, lightspark, bvnk, moneygram, coinbase, mural, stripe.
counterpartyIdyesAn existing Counterparty. Provider-side customer and payout-account state is resolved server-side from it, not passed on the request. Counterparties do not store identity or email fields.
destinationWallet (onramp) / sourceWallet (offramp)yesA custody wallet you control — its walletId or its Solana address, resolved against your API key's wallet scope. Same shape for every provider.
cryptoTokenyesToken symbol (USDC, USDT, SOL, …).
fiatCurrencyonramp: yes; offramp: conditionalRequired for onramp and for Lightspark/BVNK offramp; providers that resolve fiat currency during their own flow (MoneyGram) can omit it on offramp.
fiatAmount (onramp) / cryptoAmount (offramp)yesDecimal string greater than zero.
rampsMemonoUp to 20 key/value string pairs stored on the resulting transfer for your own correlation.

The quote also creates the underlying Payment Transfer record for the ramp; log the returned quote.id (the transfer's providerReference) for your own records.

Delivery mode

quote.deliveryMode tells you how to complete the flow with the named provider:

ProviderdeliveryModeWhat to do
MoonPayhostedRedirect the user to quote.hostedUrl.
Lightsparkmanual_instructionsDisplay the funding instructions in quote.paymentInstructions (bank or wallet details to send fiat to).
BVNKmanual_instructionsSame — display quote.paymentInstructions.
MoneyGramsession_widgetMount quote.widgetUrl using quote.sessionToken. Onramp and offramp both.
CoinbasehostedRedirect the user to quote.hostedUrl. Onramp only; quote creation is sandbox-only today.
Muralmanual_instructionsDisplay quote.paymentInstructions. Onramp only.
Stripesession_widgetMount the session with quote.clientSecret and quote.publishableKey. Onramp only.

There is no further SDP endpoint to call after this — the provider owns settlement from here. Watch for the resulting on-chain transfer on the destination wallet via GET /v1/payments/transfers?direction=inbound, or watch the provider's own side (dashboard or their webhook) for offramp payout confirmation.

Canceling a quote

POST /v1/payments/ramps/transfers/cancel cancels the transfer behind a quote while it is still pending or awaiting_payment — before the provider has moved money.

Terminal
curl -X POST https://api.solana.com/v1/payments/ramps/transfers/cancel \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "bvnk",
    "providerReference": "..."
  }'

A transfer past that window (already funded or settling) returns an error instead of canceling.

Status field

quote.status is one of pending, processing, completed, failed, reflecting the provider's reported state at the moment the quote is created — SDP does not subsequently poll the provider to refresh it, and there is no dedicated read endpoint for the quote itself. For the on-chain side of a successful onramp, observe the resulting inbound transfer on the destination wallet, surfaced via Accept payments.

Rate limits

Estimate and quote calls carry fail-closed quotas: estimate fans out one live call per provider on the corridor, quote creates a provider-side record.

EndpointPer-key limitPer-org limit
.../estimate30 / minute120 / minute
.../quote20 / minute60 / minute

Provider selection

You always pass provider explicitly; SDP does not auto-select. Choose based on:

  • Coverage — which providers your org has Provider Availability for.
  • Corridor — currency, country, and entity type; check with the currency-discovery endpoints above.
  • Sandbox needs — sandbox vs production is chosen per request from the calling API key's environment (see Sandbox vs production).

Fiat currency support

Fiat currency support is corridor-specific, not a fixed allowlist — use GET /v1/payments/ramps/onramp/currency and .../offramp/currency to see which fiat currencies a given provider covers for a given crypto rail.

Is this page helpful?