On-Ramp (Fiat to Stablecoin)
On-ramp (fiat to stablecoin)
The on-ramp flow turns a fiat deposit into a payout to the user’s or corporate’s onramp target address—the stablecoin destination you configure in Onboarding (e.g. target_address, and target_solana_address where you support Solana). You create a stablecoin fiat account in the right fiat currency. The payer sends fiat into that account. Bakkt converts to stablecoin using token preferences and spot rates, then sends to the onramp target address.
Prerequisites (individuals and corporates)
- Onboarding:
POST /userorPOST /corporate(see the Onboarding API). - KYC / KYB: The user or corporate must be allowed to transact—for individuals, that includes status
full_user. No conversion is processed until then. - Onramp target address: Set via Onboarding (e.g.
target_address,target_solana_addresswhere you support Solana). The Stablecoin API does not set the payout address. - Token preferences (optional): If there is no token preference configuration for a given fiat
currency, the product default is USDC on Polygon. PATCH the token-preference endpoints in this guide to change that.
Note: Supported create currencies for a stablecoin fiat account and funding instructions (IBAN for many EUR cases; other fields for NGN, GBP, USD, and so on) are defined in the published OpenAPI and Supported assets & currencies.
Fiat-to-stablecoin (on-ramp) flow
The same logical steps run in production and Sandbox: create the stablecoin fiat account, show bank details, then a fiat credit to that account (real transfer in production, simulated in Sandbox—see step 4 and Sandbox: simulate a fiat deposit), then conversion runs.
-
Create a stablecoin fiat account
POST a stablecoin fiat account in the right currency (e.g. NGN, USD, EUR, or GBP—see the API and Supported assets & currencies). IBAN-style details appear in responses where the rail uses them (for example many EUR cases). The product can accept:- 1st party funding (same person or entity as the Bakkt user or corporate), and
- 3rd party funding if your program allows it.
- Users:
POST /stablecoin/user/bank-account/bakkt - Corporates:
POST /stablecoin/corporate/{corporate_uuid}/bank-account/bakkt
-
Retrieve and share bank account details
GET what the payer needs (e.g. IBAN for EUR, account and routing for USD):- Users:
GET /stablecoin/user/bank-account/bakktorGET /stablecoin/user/bank-account/bakkt/{account_uuid} - Corporates:
GET /stablecoin/corporate/{corporate_uuid}/bank-account/bakktor.../bank-account/bakkt/{account_uuid}
The payer sends money using the returned instructions. For USD and ACH Pull, see Fund USD with a bank transfer or ACH Pull.
- Users:
-
(Optional) Set token preferences
PATCH so each fiatcurrencymaps to a chain and token for conversion. If you skip this, the default is USDC on Polygon for that configuration. See Token preferences (optional). Confirm the onramp target address in Onboarding is the one you want. -
Deposit
- Production: The payer sends a real bank transfer using the details you showed in step 2. When fiat credits the stablecoin fiat account, the flow continues.
- Sandbox: There is no real bank rail; you simulate a fiat credit on the Sandbox host. See Sandbox: simulate a fiat deposit for routes, request body,
curl, and how to authenticate.
-
Conversion and on-chain transfer (automatic)
When fiat is credited (or simulated in Sandbox), conversion uses token preferences (or USDC on Polygon by default) and spot rates. Converted value is sent to the onramp target address. -
Status
Subscribe to webhooks withtypefiatToCrypto.subTypevalues such asIN_PROGRESS,CRYPTO_TRANSFER_ISSUED,SUCCESS,ON_HOLD,FAILED, andREFUNDEDare examples—the full set and payloads are in the Webhooks guide.
Fund USD with a bank transfer or ACH Pull
- Push: e.g. wire or ACH where the user pushes from their bank.
- ACH Pull (Accounts API): The stablecoin fiat account should exist first; then the user links a bank and you initiate a pull per Accounts API — Payments and the Accounts API guide.
Token preferences (optional)
PATCH sets, per user or corporate and per input fiat currency, the chain and token for conversion. With no configuration, the product uses USDC on Polygon by default.
Example: EUR → USDC on Polygon
curl --request PATCH \
--url 'https://api.bakkt.com/stablecoin/user/token-preferences' \
--header 'Authorization: API-Key YOUR_API_KEY' \
--header 'bakkt-session-id: YOUR_SESSION_ID' \
--header 'Content-Type: application/json' \
--data '{
"currency": "EUR",
"chain": "polygon",
"token": "USDC"
}'Corporates: PATCH /stablecoin/corporate/{corporate_uuid}/token-preferences (see the API reference for corporate rules).
Onramp target address (onboarding)
The payout address is not set by the Stablecoin API. Set it in Onboarding (at create or PATCH for user or corporate). See the Onboarding API.
Sandbox: simulate a fiat deposit
Sandbox only: after a stablecoin fiat account exists, you can call the simulate operation on the Stablecoin API so a credited fiat amount triggers the on-ramp without a real transfer.
- Routes (Stablecoin API, Sandbox):
- Users:
POST /stablecoin/user/bank-account/bakkt/{account_uuid}/simulate - Corporates:
POST /stablecoin/corporate/{corporate_uuid}/bank-account/bakkt/{account_uuid}/simulate
- Users:
account_uuid: theuuidfromPOST /stablecoin/.../bank-account/bakktwhen the account was created.- Host: e.g.
https://sandbox.api.bakkt.com(Sandbox setup).
Example—simulate 100 units in the account’s currency (non-USD may use a minimal body):
curl --request POST \
--url 'https://sandbox.api.bakkt.com/stablecoin/user/bank-account/bakkt/ACCOUNT_UUID_FROM_CREATE_RESPONSE/simulate' \
--header 'Authorization: API-Key YOUR_SANDBOX_API_KEY' \
--header 'accept: application/json' \
--header 'bakkt-session-id: YOUR_SESSION_ID' \
--header 'Content-Type: application/json' \
--data '{"value": 100}'USD in Sandbox: optional payment_method in the body (ACH or WIRE). See the Testing & Simulation section in the published Stablecoin OpenAPI for all fields.
Examples (Stablecoin API)
In JavaScript, set the Authorization header the same way: e.g. `API-Key ${apiKey}` (template string) in your request headers.
User: create a stablecoin fiat account and set token preferences
// User in Onboarding: full_user, target_address set
const auth = `API-Key ${apiKey}`;
// 1) Create stablecoin fiat account
const created = await fetch('https://api.bakkt.com/stablecoin/user/bank-account/bakkt', {
method: 'POST',
headers: {
'Authorization': auth,
'bakkt-session-id': sessionId,
'Content-Type': 'application/json'
},
body: JSON.stringify({ currency: 'EUR' })
});
if (!created.ok) return;
const { uuid: accountUuid } = await created.json();
// 2) GET details to show the payer
const details = await fetch(
`https://api.bakkt.com/stablecoin/user/bank-account/bakkt/${accountUuid}`,
{ headers: { 'Authorization': auth, 'bakkt-session-id': sessionId } }
);
const bank = await details.json();
// 3) Optional: token preferences
await fetch('https://api.bakkt.com/stablecoin/user/token-preferences', {
method: 'PATCH',
headers: { 'Authorization': auth, 'bakkt-session-id': sessionId, 'Content-Type': 'application/json' },
body: JSON.stringify({ currency: 'EUR', chain: 'polygon', token: 'USDC' })
});
// 4) Payer funds account — or Sandbox: POST .../stablecoin/user/bank-account/bakkt/.../simulate
// 5) Webhook type fiatToCrypto — /guides/webhooksCorporate: same pattern
const auth = `API-Key ${apiKey}`;
const corporateUuid = 'YOUR_CORPORATE_UUID';
const created = await fetch(
`https://api.bakkt.com/stablecoin/corporate/${corporateUuid}/bank-account/bakkt`,
{
method: 'POST',
headers: { 'Authorization': auth, 'bakkt-session-id': sessionId, 'Content-Type': 'application/json' },
body: JSON.stringify({ currency: 'EUR' })
}
);
const { uuid: accountUuid } = await created.json();
const details = await fetch(
`https://api.bakkt.com/stablecoin/corporate/${corporateUuid}/bank-account/bakkt/${accountUuid}`,
{ headers: { 'Authorization': auth, 'bakkt-session-id': sessionId } }
);
const bank = await details.json();Next steps
- Webhooks:
fiatToCryptoand full payload reference - Onboarding: Merchant webhook endpoints
- Off-ramp: Stablecoin → fiat to a bank account
- Supported assets & currencies: Currencies, rails, and
account_details - Quick start: Sandbox key,
curlsamples, and auth - Accounts API — Payments: USD ACH Pull details
Updated 3 days ago
