Overview
Crypto withdrawals let your users move the available balance (availableBalance) in their account held in custody by DCS out over a blockchain network to an external on-chain address of their choice. As a licensed issuer with its own BINs, DCS handles the balance deduction, SMS security check, on-chain transfer, and status tracking for you, turning “available balance → funds credited on-chain” into a single path.
This is the reverse of a deposit: the user submits a withdrawal → the platform validates it (including the SMS code) and deducts the available balance → the funds are sent on-chain to the destination address → crediting is tracked through the transaction records.
Three core steps:
- Call
GET /crypto/v1/network-coin to confirm that the target chain and token have withdrawals enabled (withdrawEnable), and read the withdrawal fee and limits (withdrawFee / withdrawMin / withdrawMax) plus whether an address tag is required (withdrawIsTag).
- Have the user obtain an SMS verification code (
smsCode, see Prerequisites), then call POST /crypto/v1/withdraw-apply to submit the withdrawal.
- Call
POST /user-asset/v1/transactions to query crypto balance movements and follow the on-chain status and txHash of this withdrawal.
Prerequisites
Confirm the following before calling this endpoint:
- The user is onboarded and has passed KYC: the user has been assigned an
externalUserId. See Managing users.
- Withdrawals are enabled for the target chain and token: query
GET /crypto/v1/network-coin first, confirm that withdrawEnable = true for that network plus coin, and use withdrawIsTag to decide whether addressTag is mandatory.
- The available balance is sufficient: the user’s
availableBalance must be greater than or equal to the withdrawal amount plus the fee. For the balance model, see Account and asset model · Ledgering.
- SMS verification is complete: a withdrawal moves money out, so it is treated as high risk and requires an SMS verification code
smsCode (issued via POST /captcha/v1/send-mobile-code).
- Compliance groundwork: where the Travel Rule applies, its requirements must be satisfied first. See Travel Rule.
API flow
Submitting a withdrawal
POST /crypto/v1/withdraw-apply
Request fields
Amount precision: amount and fee in the request body are numbers. When storing and displaying them, mind the token’s on-chain precision so that no precision is lost.
Request example (redacted)
Authentication: the example above omits the authentication headers to keep the focus on business fields. Real calls must carry X-DAPI-API-KEY, X-DAPI-SIGN, X-DAPI-TIMESTAMP, and X-DAPI-NONCE (HMAC-SHA256 signature). The rules are documented once in the Authentication guide and are not repeated here.
All example values are placeholders. Never put a real on-chain address, externalUserId, smsCode, amount, cardholder personal data, or API key/secret into a request or a log. On-chain addresses and user identifiers are sensitive and must be redacted.
Response
The response uses the standard envelope { code, message, messageDetail, data } (no success boolean). On success, code = SYS_SUCCESS, meaning the withdrawal request has been accepted.
Base your business logic on the actual status in the transaction records. Do not treat code = SYS_SUCCESS in the envelope as proof that the withdrawal has been credited; code only confirms that the request was accepted, and the on-chain transfer happens asynchronously.
Tracking withdrawal progress
Once an on-chain withdrawal is accepted, track it with POST /user-asset/v1/transactions (query crypto balance movements) to read the on-chain status and the transaction hash txHash; for a single record, use POST /user-asset/v1/transaction-detail. For field definitions, see User Balance and Reporting field descriptions.
Status and time to credit
- Acceptance is not the same as crediting:
code = SYS_SUCCESS in the envelope only means DCS accepted the request and deducted the balance; the funds are only really at the destination once confirmed on-chain.
- Time to credit depends on on-chain confirmation speed: block times and confirmation counts differ by chain, so rely on the confirmation configuration in
network-coin and the actual state of the target network.
Error handling
Best practices
- Query
network-coin before every withdrawal: drive your front-end validation from withdrawEnable, withdrawFee, withdrawMin, withdrawMax, and withdrawIsTag to cut down invalid requests and failed credits.
- Enforce address and tag validation: validate the address format and tag against the chain’s rules while the user is still filling the form, and make the tag mandatory when
withdrawIsTag = true. A wrong address or a missing tag can make the funds unrecoverable.
- Never skip SMS verification: withdrawals move money out, so always require the second factor via
smsCode.
- Judge crediting by the on-chain status: acceptance is not crediting. Before telling the user the funds have arrived, check the on-chain confirmation status in the transaction records.
- Minimise PII: on-chain addresses and user identifiers are sensitive. Redact them in logs and retain no more than compliance requires.
Next steps
- Crypto Deposits — the opposite direction (on-chain deposit into the available balance), sharing the
network-coin chain and token matrix with this page
- Travel Rule — the compliance groundwork that withdrawals depend on
- User Balance — semantics of the
free / freeze / total balances and how to query balance movements
- Account and asset model · Ledgering — the
availableBalance / frozenBalance model
- Authentication guide — the shared reference for HMAC-SHA256 signature headers