Prerequisites
Complete these once per customer before running the flow below. They are not part of the numbered steps.
PRESubmit the customer for onboardingPOST
/api/FE/NewClient

Your app sends the customer's details; RAMFi runs KYC, opens the account, and returns a client record with Active status when verification passes.

Request Body Parameters — enter values to build the request
FieldTypeRequiredDescriptionValue
firstNamestringREQUIREDClient's legal first name.
lastNamestringREQUIREDClient's legal last name.
addressstringREQUIREDStreet address.
citystringREQUIREDCity.
statestringREQUIREDState code.
zipstringREQUIREDZIP code.
taxIDstringREQUIREDSSN (or EIN for business accounts).
dobstring (date)REQUIREDDate of birth (YYYY-MM-DD).
clientIDstringREQUIREDYour external identifier for this client.
emailstringREQUIREDEmail address (validated).
curl --request POST \ --url 'https://FQDN/api/FE/NewClient' \ --header 'Authorization: Bearer <SHORT_TERM_TOKEN>' \ --header 'X-OTP: <X_OTP>' \ --header 'Content-Type: application/json' \ --data '{ "firstName": "string", "lastName": "string", "taxID": "string", "clientID": "sender-id", "email": "user@example.com" }'
const options = { method: 'POST', headers: { 'Authorization': 'Bearer <SHORT_TERM_TOKEN>', 'X-OTP': '<X_OTP>', 'Content-Type': 'application/json' }, body: JSON.stringify({ "firstName": "string", "lastName": "string", "taxID": "string", "clientID": "sender-id", "email": "user@example.com" }) }; fetch('https://FQDN/api/FE/NewClient', options) .then(r => r.json()) .then(console.log) .catch(console.error);
import requests url = "https://FQDN/api/FE/NewClient" headers = { "Authorization": "Bearer <SHORT_TERM_TOKEN>", "X-OTP": "<X_OTP>", "Content-Type": "application/json" } payload = { "firstName": "string", "lastName": "string", "taxID": "string", "clientID": "sender-id", "email": "user@example.com" } resp = requests.post(url, headers=headers, json=payload) print(resp.json())
{ "id": "string", "clientID": "sender-id", "accountStatus": "Active", "email": "user@example.com" }
firstName / lastName
Customer's legal name, used for KYC.
taxID
SSN / tax identifier for identity verification.
clientID
Your unique identifier for this customer, used on every later call.
email
Customer contact email.
accountStatus
Active means the client is verified and can transact.
PREWhitelist the recipient walletPOST
/api/FE/AddWalletAddress?address=recipient-wallet&addressIdentifier=Recipient

Register and AML-screen the recipient's address before sending.

Query Parameters — enter values to build the request
FieldTypeRequiredDescriptionValue
addressstringoptionalThe wallet address.
addressIdentifierstringoptionalA friendly name for the address.
curl --request POST \ --url 'https://FQDN/api/FE/AddWalletAddress?address=recipient-wallet&addressIdentifier=Recipient' \ --header 'Authorization: Bearer <SHORT_TERM_TOKEN>' \ --header 'X-OTP: <X_OTP>'
const options = { method: 'POST', headers: { 'Authorization': 'Bearer <SHORT_TERM_TOKEN>', 'X-OTP': '<X_OTP>' } }; fetch('https://FQDN/api/FE/AddWalletAddress?address=recipient-wallet&addressIdentifier=Recipient', options) .then(r => r.json()) .then(console.log) .catch(console.error);
import requests url = "https://FQDN/api/FE/AddWalletAddress?address=recipient-wallet&addressIdentifier=Recipient" headers = { "Authorization": "Bearer <SHORT_TERM_TOKEN>", "X-OTP": "<X_OTP>" } resp = requests.post(url, headers=headers) print(resp.json())
{ "isSuccess": true, "result": "approved", "errorMessage": null }
address
Recipient's wallet address (query parameter).
addressIdentifier
A label, e.g. the recipient's name (query parameter).
Value flow
USD in, stablecoin across, delivered to the recipient.
  • 1
    Sender AppFund in USD
    ACH or card (see funding methods)
  • RAMFiCredit USD balance
    RAMFi clears funds
  • 2
    Sender AppRequest conversion
    POST /ConvertClientFunds
  • RAMFiExecute conversion
    RAMFi converts to USDC
  • 3
    Sender AppRequest delivery
    POST /SendFundsToAddress
  • RAMFiBroadcast transfer
    RAMFi sends on-chain
  • RecipientRecipient receives
    wallet, or RAMFi off-ramp to USD
Show full interaction diagram
Sender AppRAMFiRecipient1Fund in USDACH or card (see funding methods)Credit USD balanceRAMFi clears funds2Request conversioncall POST /ConvertClientFundsExecute conversionRAMFi converts to USDC3Request deliverycall POST /SendFundsToAddressBroadcast transferRAMFi sends on-chainRecipient receiveswallet, or RAMFi off-ramp to USD

Remittance sequence to a recipient wallet. When the recipient is a RAMFi client, the send is replaced by an internal transfer (see Delivery patterns).

Your application orchestrates; RAMFi performs. Every call below runs against RAMFi. RAMFi performs KYC, moves the money, AML-screens addresses, and settles. Your app issues the requests; it never performs KYC or holds funds or keys itself.
Funding in USD: bring fiat in by ACH (Bank Connection SDK + AddClientFunds), see Funding methods.
Steps
1Fund the sender in USDPOST
/api/FE/AddClientFunds

Bring the remittance amount in by ACH (open banking, shown) or a card pull (PullFromCard). RAMFi credits the sender's USD balance.

Request Body Parameters — enter values to build the request
FieldTypeRequiredDescriptionValue
clientIDstringREQUIREDThe client to fund.
amountnumberREQUIREDUSD amount to draft via ACH.
transactionDatestring (date)optionalDate to initiate the ACH draft (YYYY-MM-DD).
externalReferencestringREQUIREDYour unique reconciliation key.
curl --request POST \ --url 'https://FQDN/api/FE/AddClientFunds' \ --header 'Authorization: Bearer <SHORT_TERM_TOKEN>' \ --header 'X-OTP: <X_OTP>' \ --header 'Content-Type: application/json' \ --data '{ "clientID": "sender-id", "amount": 500.00, "transactionDate": "2026-01-15", "externalReference": "rem-001" }'
const options = { method: 'POST', headers: { 'Authorization': 'Bearer <SHORT_TERM_TOKEN>', 'X-OTP': '<X_OTP>', 'Content-Type': 'application/json' }, body: JSON.stringify({ "clientID": "sender-id", "amount": 500.00, "transactionDate": "2026-01-15", "externalReference": "rem-001" }) }; fetch('https://FQDN/api/FE/AddClientFunds', options) .then(r => r.json()) .then(console.log) .catch(console.error);
import requests url = "https://FQDN/api/FE/AddClientFunds" headers = { "Authorization": "Bearer <SHORT_TERM_TOKEN>", "X-OTP": "<X_OTP>", "Content-Type": "application/json" } payload = { "clientID": "sender-id", "amount": 500.00, "transactionDate": "2026-01-15", "externalReference": "rem-001" } resp = requests.post(url, headers=headers, json=payload) print(resp.json())
1101
amount
USD amount being sent.
externalReference
Your unique reference for this remittance.
2Convert to a stablecoinPOST
/api/FE/ConvertClientFunds

Convert the cleared USD to USDC for transfer.

Request Body Parameters — enter values to build the request
FieldTypeRequiredDescriptionValue
clientIDstring (UUID)REQUIREDThe client whose funds to convert.
amountnumberREQUIREDAmount to convert.
fromCurrencyIDCurrencyTypeREQUIREDSource currency (see CurrencyType enum).
toCurrencyIDCurrencyTypeREQUIREDTarget currency (see CurrencyType enum).
externalReferencestringREQUIREDYour unique reconciliation key.
curl --request POST \ --url 'https://FQDN/api/FE/ConvertClientFunds' \ --header 'Authorization: Bearer <SHORT_TERM_TOKEN>' \ --header 'X-OTP: <X_OTP>' \ --header 'Content-Type: application/json' \ --data '{ "clientID": "sender-id", "amount": 500.00, "fromCurrencyID": "USD", "toCurrencyID": "USDC", "externalReference": "rem-002" }'
const options = { method: 'POST', headers: { 'Authorization': 'Bearer <SHORT_TERM_TOKEN>', 'X-OTP': '<X_OTP>', 'Content-Type': 'application/json' }, body: JSON.stringify({ "clientID": "sender-id", "amount": 500.00, "fromCurrencyID": "USD", "toCurrencyID": "USDC", "externalReference": "rem-002" }) }; fetch('https://FQDN/api/FE/ConvertClientFunds', options) .then(r => r.json()) .then(console.log) .catch(console.error);
import requests url = "https://FQDN/api/FE/ConvertClientFunds" headers = { "Authorization": "Bearer <SHORT_TERM_TOKEN>", "X-OTP": "<X_OTP>", "Content-Type": "application/json" } payload = { "clientID": "sender-id", "amount": 500.00, "fromCurrencyID": "USD", "toCurrencyID": "USDC", "externalReference": "rem-002" } resp = requests.post(url, headers=headers, json=payload) print(resp.json())
1102
fromCurrencyID
USD.
toCurrencyID
Transfer stablecoin: USDC.
(response)
Numeric conversion transaction ID.
3Deliver to the recipientPOST
/api/FE/SendFundsToAddress?clientId=sender-id&address=recipient-wallet&amount=500.00&currency=USDC&externalReference=rem-003

Send the stablecoin to the recipient's wallet on-chain.

Query Parameters — enter values to build the request
FieldTypeRequiredDescriptionValue
addressstringREQUIREDDestination wallet address. Must already be whitelisted via Add Wallet Address.
clientIdstringoptionalThe client ID. Obtain via Create Client.
amountnumber (double)REQUIREDAmount to send. Must be greater than 0.00000001 (the smallest tradeable BTC unit).
currencyCurrencyTypeREQUIREDDigital-asset currency. Cannot be USD (1) or PUSD (2), and cannot be the unset default (0). See CurrencyType.
externalReferencestringREQUIREDYour transaction reference. Maximum 50 characters.
curl --request POST \ --url 'https://FQDN/api/FE/SendFundsToAddress?clientId=sender-id&address=recipient-wallet&amount=500.00&currency=USDC&externalReference=rem-003' \ --header 'Authorization: Bearer <SHORT_TERM_TOKEN>' \ --header 'X-OTP: <X_OTP>'
const options = { method: 'POST', headers: { 'Authorization': 'Bearer <SHORT_TERM_TOKEN>', 'X-OTP': '<X_OTP>' } }; fetch('https://FQDN/api/FE/SendFundsToAddress?clientId=sender-id&address=recipient-wallet&amount=500.00&currency=USDC&externalReference=rem-003', options) .then(r => r.json()) .then(console.log) .catch(console.error);
import requests url = "https://FQDN/api/FE/SendFundsToAddress?clientId=sender-id&address=recipient-wallet&amount=500.00&currency=USDC&externalReference=rem-003" headers = { "Authorization": "Bearer <SHORT_TERM_TOKEN>", "X-OTP": "<X_OTP>" } resp = requests.post(url, headers=headers) print(resp.json())
{ "isSuccess": true, "result": "0xhash...", "errorMessage": null }
address
Recipient wallet, must be whitelisted first.
currency
USDC.
amount
Amount to deliver.
Delivery patterns
Two ways to land the funds with the recipient.
A · Recipient holds a wallet. Whitelist the address and use SendFundsToAddress (steps 4–5). The recipient custodies the asset.
B · Recipient is a RAMFi client. Onboard the recipient with NewClient, deliver into their RAMFi balance, and let them off-ramp with ConvertClientFundsWithdrawClientFunds (see the off-ramp recipe).
Local-currency payout & FX. RAMFi's documented rails settle in USD fiat and digital assets. Non-USD local-currency payout and its FX are not part of the documented API, handled on the receiving side (a local off-ramp or partner). Do not assume in-API non-USD fiat payout.
RAMFi Developer Documentation · Version 1.1