ドラランプ・デジタルドル
dolaramp
blog
en
← all posts

a complete api for digital dollars.

// tl;dr a stablecoin API is complete when it covers the whole life of a payment, not just "create an address". that means six jobs: give each customer an address, tell you when money landed, consolidate balances, pay out, move funds between networks and close the books. the dolaramp API does the six with one key, on Solana, TRON, gram(TON), Base and Arbitrum, for USDT, USDC and PYUSD. you never buy SOL, TRX, TON or ETH: the fee comes out of the stablecoin, from $0.10 per operation on the free plan. receiving is free. this post walks through each job with the real calls, what each costs, and what the API does not do.

what "complete" means

most teams start with one need, usually "show a deposit address at checkout". a month later they are running a node, an indexer, a gas wallet per network and a spreadsheet to reconcile it all. these are the jobs that show up sooner or later:

jobthe question it answerscall
addresseswhere does this customer pay?POST /hotwallets/{network}/children
detectiondid the money arrive, and is it final?webhook deposit.confirmed · GET /deposits
consolidationhow do I gather 500 small balances?POST /sweep
payouthow do I pay a supplier or a merchant?POST /hotwallet/withdraw
network movemy USDC is on Solana and I need it on BasePOST /bridge
bookswhat moved this month, and what did it cost?GET /ledger · GET /statement

around them sit the small calls that save support tickets: POST /address/validate and POST /address/detect before a payout, GET /balance/{network}/{address}/{token} for a live balance, and GET /quote for the exact fee before anything moves.

from signup to the first address

sign up in the panel with Google, GitHub or an email code. the first key (dr_live_...) is issued there, on the free plan, and goes in the X-Api-Key header of every call. the base URL is https://api.dolaramp.com/v1.

1. create a hotwallet, one per network:

curl https://api.dolaramp.com/v1/hotwallets \
  -H "X-Api-Key: dr_live_..." \
  -H "Content-Type: application/json" \
  -d '{"network":"base","label":"acme main"}'

the response brings a wallet_secret (ws_...) once. it encrypts the key of the hotwallet and of every child; we keep only the ciphertext. without it, not even dolaramp can move the funds, so store it outside the application server. on Base and Arbitrum the hotwallet is one address valid on both networks.

2. generate a deposit address and tag it with your own id:

curl https://api.dolaramp.com/v1/hotwallets/base/children \
  -H "X-Api-Key: dr_live_..." \
  -H "Content-Type: application/json" \
  -d '{"wallet_secret":"ws_...","count":1,"external_refs":["order-10432"]}'

up to 100 children per call. the external_ref is yours: an order number, a user id, merchant:invoice. it comes back in every deposit, so you credit the right customer with no lookup.

arriving is not confirmed

this is the part that costs money when done wrong. a deposit has two moments:

  • arriving: the transfer was seen on the network. it means "a transaction exists", not "it cannot be undone". webhook deposit.detected.
  • confirmed: the network's own rule was met. webhook deposit.confirmed. release the order here, never before.
networkwhat "confirmed" waits for
tronsolidification
solanafinalized
base · arbitrumsafe head
gram (ton)final on inclusion

a deposit that never settles within the deadline fires deposit.abandoned: treat it as not received.

webhooks are HTTPS only, retried up to 8 times with a growing interval (30 seconds, then doubling) and signed with HMAC-SHA256. the secret is shown once when you register the endpoint with POST /webhooks. the signature arrives in the X-DolaRamp-Signature header, as the hex HMAC of the raw body. check it before you believe the payload:

import { createHmac, timingSafeEqual } from 'node:crypto';

function isFromDolaramp(rawBody, header, secret) {
  const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(header ?? '');
  return a.length === b.length && timingSafeEqual(a, b);
}

compute it over the raw bytes you received, not over a re-serialized JSON. if your queue was down, GET /webhooks/deliveries shows what was sent and GET /deposits gives the same facts by polling.

sweep and withdraw, without a gas tank

the classic pain of deposit addresses: to move 20 USDT out of a child, the child needs the network's coin. multiply by a few thousand addresses and you are running a gas operation. here the gas is sponsored and the fee is taken inside the transfer, in the stablecoin.

POST /sweep consolidates children into the hotwallet in batch: by default the 20 most recent, or up to 20 you name in child_addresses. on Solana, gram(TON), Base and Arbitrum it answers confirmed with the tx_hash. on TRON it answers accepted in 1 to 2 seconds and the confirmation follows by webhook (sweep.confirmed).

a payout is one call:

curl https://api.dolaramp.com/v1/hotwallet/withdraw \
  -H "X-Api-Key: dr_live_..." \
  -H "Content-Type: application/json" \
  -d '{"network":"base","token":"USDC","to":"0x...","amount":"10000000",
       "wallet_secret":"ws_...","idempotency_key":"payout-inv-10432"}'

amount is in micro-units (6 decimals), so 10000000 is 10 USDC, and the recipient receives the amount minus the fee. three behaviors worth knowing before production:

  • idempotency. retry with the same idempotency_key and you get the original operation back with replayed: true. a timeout followed by a retry never pays twice.
  • no silent partial payout. a withdrawal larger than the balance is refused with 400 insufficient_balance. on TRON you can pass allow_partial: true to send what fits instead.
  • 202 pending. if the transfer was handed to the network but its landing was not seen in time, the call answers 202 with status: pending. the outcome arrives as withdraw.confirmed or withdraw.failed, usually within a minute.

moving usdc between networks

POST /bridge moves USDC between Solana, Base and Arbitrum through Circle's CCTP: burned on the origin, minted by Circle on the destination, one to one. it is a network move, not a swap: no pool, no slippage. the fast path takes 8 to 20 seconds. the ceiling is $10,000,000 per operation and the minimum amount is $10.

GET /bridge/quote itemizes the operation before you run it: our fee, Circle's fee (passed through without markup) and what the recipient receives. the longer story, with measured times, is in move USDC from Solana to Base.

what it costs

no monthly fee on the free plan, and receiving is free on every plan. you pay per sweep or withdrawal, in the stablecoin, inside the operation:

network · tokenfreeprowhat's inside
tron · USDT$1.60$1.55$1.50 network fee + our $0.10 / $0.05
base · USDC$0.10$0.05our fee only, the gas is on us
arbitrum · USDC, USD₮0$0.10$0.05our fee only, the gas is on us
solana · USDT, USDC, PYUSD~$0.10~$0.05network cost + 10% + our $0.10 / $0.05
gram (ton) · USDT~$0.18~$0.13network cost + 10% + our $0.10 / $0.05

the free plan watches 1,000 addresses and the pro plan 50,000. the bridge costs $2 + 0.3% on free and $2 + 0.2% on pro.

two costs that surprise people: the first move out of a brand-new Solana address also pays for its token accounts (~$0.65 on free), and an inactive TRON address pays a one-time activation of 1.50 USDT. if your customers pay on TRON, prefer a fixed address per customer over a throwaway address per order. where the 1.50 comes from is explained in send USDT without TRX.

values from pricing at 25 sep 2026 prices. Solana and gram(TON) follow the price of SOL and TON. GET /v1/quote returns the exact fee for your plan.

what the api does not do

better to know before you design around it:

  • no fiat. dolaramp does not convert currency, hold bank balances or send bank transfers. the local-currency side goes through a licensed exchange or payment provider. GET /rates gives a mid-market reference for USDT against fiat currencies; it is not an executable quote, so apply your own spread.
  • no swap. USDT does not become USDC here. the bridge moves the same asset, USDC, between networks.
  • no bridge for TRON or gram(TON). the bridge covers Solana, Base and Arbitrum only.
  • one hotwallet per network, and 20 children per sweep call. for thousands of children, loop.
  • rate limit: 120 requests per minute per key.
  • no test network. the API runs on the real networks. a cheap way to rehearse is a few dollars of USDC on Base, where an operation costs $0.10.

keys and safety

each API key has a scope: read (list, quote, poll) or operate (everything, including sweep, withdraw and bridge). a write with a read key answers 403 insufficient_scope, so dashboards and reports can run on a key that cannot move money. a key can also be locked to specific IPs.

the custody model is the point: the hotwallet keys are sealed in an envelope that opens only with your wallet_secret, and every call that moves funds has to carry it. more on security.

the seven integration profiles (store, gateway, exchange, on-ramp only, off-ramp only, mass payouts, crypto card) are drawn call by call in the integration flows, and every endpoint is in the API reference.

faq

What is a stablecoin API?

A REST API that lets your system receive, hold and pay out dollar stablecoins such as USDT and USDC without running nodes or indexers. A complete one covers deposit addresses, deposit detection, consolidation, payouts and reconciliation.

Do I need to buy TRX, SOL, TON or ETH to use the API?

No. The gas is sponsored and the fee is taken inside the operation, in the stablecoin itself. On TRON the network fee of 1.50 USDT is also paid in USDT.

How much does the dolaramp API cost?

Receiving is free and the free plan has no monthly fee. A sweep or withdrawal costs $0.10 on Base and Arbitrum and $1.60 on TRON on the free plan; $0.05 and $1.55 on the pro plan.

Does the API convert stablecoins to local currency?

No. It handles the stablecoin side only. Conversion to and from local currency goes through a licensed exchange or payment provider.

sources: dolaramp API reference (OpenAPI 1.1) · integration flows · pricing (25 sep 2026) · developers · Circle CCTP documentation · checked on 28 sep 2026.