/wallet/deposit
and /wallet/withdraw, and DimeTrades
holds the money. External wallet integration flips that: your platform
holds and manages your customers’ balances, and reserves funds against them
yourself — atomically, on your own side — before you ever call DimeTrades.
The five-minute summary. Your backend reserves the required amount
against the customer’s balance, then calls
POST /orders with a
clientOrderId. Before accepting a BUY limit order (or a
cost-increasing modification), DimeTrades calls you — a synchronous
API, not a webhook — to confirm that reservation exists. When a trade
actually moves money, DimeTrades sends a signed wallet.debit/
wallet.credit webhook, the same delivery mechanism documented in the
Partner webhooks guide. You release your own
reservation on order.cancelled/order.expired/order.rejected — all
generic, already-documented webhooks, nothing wallet-specific. Your own
/wallet/deposit//wallet/withdraw calls are blocked for these users,
since DimeTrades no longer holds their balance.1. Setup
External wallet integration is configured per brand by your DimeTrades account contact, alongside (and independently of) webhook delivery:- A
partnerApiBaseUrlis set on your brand — the base URL DimeTrades calls for the reservation check. - An API key id and signing secret are issued — the secret is shown to you exactly once, the same way the webhook signing secret is. It cannot be retrieved again, only rotated (which invalidates the old one).
externalWalletEnabledgates the whole feature — while it’s on, a BUY limit order or cost-increasing modification triggers the check below, and your users’ own deposit/withdraw calls to DimeTrades are rejected.
2. The API you expose
Full field-by-field reference is on the Confirm a wallet reservation page — this section covers the same contract as a narrative walkthrough. DimeTrades calls one endpoint on your side — a confirmation, not an instruction. Since your own backend already reserves funds atomically before it ever callsPOST /orders, DimeTrades is only asking “did you
actually reserve at least this much?”:
clientOrderIdis the idempotency key you supplied onPOST /orders— the correlation key for this check, since you generated it and already know it.amountCentsis the minimum you should already have reserved —price × quantityplus the worst-case (taker-rate) fee. Nothing more needs to be added on top. See “Reservation sizing is yours” below.externalCustomerIdis the same id you supplied when registering the customer through the partner provisioning API — present in both the URL and the body.
Reservation sizing is yours
amountCents already includes the worst-case fee: it’s the order’s cost
(price × quantity) plus the taker-rate fee, the higher of the two
rates DimeTrades ever charges. DimeTrades debits cost + fee on fill
(see wallet.debit below), and the actual fee applied on fill is always
this taker rate or the lower maker rate — never higher. So converting
amountCents straight into a settled debit never under-covers the fee;
no additional buffer is needed on your side. DimeTrades still has no
visibility into your actual reservation and can’t validate or enforce
your sizing from its side — this section just documents what
amountCents itself already accounts for.
Authenticating the request
TheX-DimeTrades-Signature header uses the same scheme as webhook
deliveries (see Verifying a delivery),
but with your external wallet secret, not your webhook secret — the two
are issued and rotated independently, and must never be confused:
Timeout and retries
DimeTrades retries the check up to 3 times with a short backoff (100ms, 500ms, 2s) before giving up — this happens within the lifetime of your customer’s order-placement request, so keep your response time well under your brand’s configured timeout (partnerApiTimeoutMs, 2000ms by
default). If all retries fail, the order is rejected — a partner
outage blocks that brand’s BUY flow rather than silently letting orders
through unchecked.
Rejection mapping
If your
POST /orders call itself fails or times out, retry it with the
same clientOrderId — DimeTrades’s idempotency guarantee (see
Conventions) means a retried submission is safe and won’t
double-place the order.
3. Wallet events (delivered as webhooks)
When a trade actually moves money, DimeTrades sends the acknowledgement as a webhook — same envelope, same signing, same retry/backoff schedule as every other event in the Partner webhooks guide, and structurally nothing like the synchronous check above. Only two event types are wallet-specific:
Every wallet event carries
externalCustomerId — the id you supplied when you
registered the customer — so you can route the movement to the right balance,
plus clientOrderId (the key you supplied on POST /orders) marketId and eventId, so
you can match it to your reservation without a lookup. amountCents is always a positive integer in US
cents; reason is trade_fill on a debit and settlement on a trade credit.
Trade debits and trade credits (not market-settlement credits) also split the
amount, so you don’t have to join to trade.executed: costCents, feeCents,
quantity, priceCents and role (maker or taker).
wallet.debit:costCents + feeCents = amountCents.wallet.creditfor a SELL fill: the fee is netted inside the credit, socostCents - feeCents = amountCents, wherecostCentsis the gross sale proceeds.wallet.creditfor an auto-merge payout after a BUY:feeCentsis0,costCents = amountCents,quantityis the number of merged pairs (which can be fewer than the trade quantity) andpriceCentsisnull.
clientOrderId (and marketId), so you can find
the reservation to release directly — you never need to map orderId yourself.
DimeTrades never tracks or instructs a release — you already know when to
release, from the same webhooks you’d watch anyway:
These are the same generic, brand-agnostic webhooks documented in the
Partner webhooks event catalog — nothing wallet-specific
was added for release.
Full request/response shapes are on the
wallet.debit and
wallet.credit reference pages.
