Errors
When working with the Crypto Deposits Platform API, you may encounter various error responses. This guide explains HTTP status codes, error formats, and common issues with blockchain transactions.
You can determine if your request was successful by checking the HTTP status code. Unsuccessful responses include error details to help you diagnose and resolve the issue.
Status codes
The API uses standard HTTP status codes to indicate success or failure.
- Name
200 OK- Description
The request was successful.
- Name
201 Created- Description
A new resource was successfully created (e.g., withdrawal, account).
- Name
400 Bad Request- Description
The request was malformed or missing required parameters.
- Name
401 Unauthorized- Description
Invalid or missing authentication credentials (API key or JWT token).
- Name
403 Forbidden- Description
Valid credentials but insufficient permissions for the requested operation.
- Name
404 Not Found- Description
The requested resource does not exist.
- Name
422 Unprocessable Entity- Description
The request was well-formed but contains semantic errors (e.g., invalid chain ID, insufficient balance).
- Name
429 Too Many Requests- Description
Rate limit exceeded. Retry after the time specified in the Retry-After header.
- Name
500 Internal Server Error- Description
An unexpected error occurred on the server.
- Name
503 Service Unavailable- Description
The service is temporarily unavailable (e.g., during maintenance).
Error response format
Error responses include a structured error object with details about what went wrong:
- Name
error- Type
- string
- Description
A short error code identifying the error type (e.g.,
INVALID_CHAIN,INSUFFICIENT_BALANCE).
- Name
message- Type
- string
- Description
A human-readable description of the error.
- Name
statusCode- Type
- number
- Description
The HTTP status code (also included in the response header).
- Name
details- Type
- object
- Description
Additional context about the error (optional, depending on error type).
Error response example
{
"error": "INVALID_CHAIN",
"message": "Chain ID 'eip155:999' is not supported",
"statusCode": 422,
"details": {
"providedChainId": "eip155:999",
"supportedChains": [
"eip155:1",
"eip155:137",
"eip155:56",
"bip122:000000000019d6689c085ae165831e93",
"tron:0x00000000000000000000000000000000",
"xrpl:mainnet"
]
}
}
Common error codes
Authentication errors
- Name
UNAUTHORIZED- Description
Missing or invalid API key or JWT token. Check the
x-api-keyorAuthorizationheader.
- Name
INVALID_API_KEY- Description
The provided API key is not valid or has been rotated.
- Name
INVALID_TOKEN- Description
The JWT token is expired or invalid. Login again to get a new token.
- Name
INVALID_TOTP- Description
The two-factor authentication code is incorrect or expired.
Chain and token errors
- Name
INVALID_CHAIN- Description
The specified chain ID is not recognized. Use CAIP-2 format (e.g.,
eip155:1).
- Name
CHAIN_NOT_ENABLED- Description
The chain exists but is disabled for your organization.
- Name
INVALID_TOKEN- Description
The specified token ID is not recognized. Use CAIP-19 format.
- Name
TOKEN_NOT_ENABLED- Description
The token exists but is disabled for deposits or withdrawals.
Deposit errors
- Name
FAILED_TO_CREATE_DEPOSIT_ACCOUNT- Description
Failed to generate a deposit address. This may indicate a configuration issue.
- Name
INVALID_USER_ID- Description
The provided external user ID is invalid or too long (max 255 characters).
- Name
DUPLICATE_DEPOSIT- Description
This transaction has already been processed. Deposits are idempotent by transaction hash.
Withdrawal errors
- Name
INSUFFICIENT_BALANCE- Description
The account does not have enough balance to complete the withdrawal.
- Name
INVALID_ADDRESS- Description
The destination address is not a valid blockchain address for the specified chain.
- Name
WITHDRAWAL_BELOW_MINIMUM- Description
The withdrawal amount is below the minimum allowed for this token.
- Name
WITHDRAWAL_ABOVE_MAXIMUM- Description
The withdrawal amount exceeds the maximum allowed limit.
- Name
INSUFFICIENT_APPROVALS- Description
The withdrawal requires more approvals before it can be processed.
- Name
WITHDRAWAL_ALREADY_PROCESSED- Description
This withdrawal has already been executed and cannot be modified.
- Name
INSUFFICIENT_GAS- Description
The gas wallet does not have enough native tokens (ETH, MATIC, etc.) to pay transaction fees.
Organization errors
- Name
INVALID_WEBHOOK_URL- Description
The provided webhook URL is not valid. Must be HTTPS.
- Name
INVALID_MIN_SIGNERS- Description
The minimum withdrawal signers value is invalid (must be between 1 and total number of signers).
Blockchain-specific errors
EVM chains (Ethereum, Polygon, BSC)
Insufficient gas funds
{
"error": "INSUFFICIENT_GAS",
"message": "Insufficient ETH in gas wallet to pay for transaction fees",
"statusCode": 422,
"details": {
"chainId": "eip155:1",
"gasWalletBalance": "0.001",
"estimatedGasNeeded": "0.005",
"nativeToken": "ETH"
}
}
XRP Ledger
Missing destination tag
{
"error": "MISSING_DESTINATION_TAG",
"message": "XRP withdrawals to this address require a destination tag",
"statusCode": 400,
"details": {
"chainId": "xrpl:mainnet",
"toAddress": "rN7n7otQDd6FczFgLdlqtyMVrn3HMtthca"
}
}
Bitcoin
Unconfirmed UTXOs
{
"error": "INSUFFICIENT_CONFIRMED_BALANCE",
"message": "Bitcoin balance contains unconfirmed transactions",
"statusCode": 422,
"details": {
"chainId": "bip122:000000000019d6689c085ae165831e93",
"totalBalance": "0.5",
"confirmedBalance": "0.3",
"unconfirmedBalance": "0.2"
}
}
Troubleshooting
Authentication issues
Problem: 401 Unauthorized or INVALID_API_KEY
Solutions:
- Verify your API key is correct and hasn't been rotated
- Check the
x-api-keyheader is properly set - Ensure you're using the correct base URL (production vs development)
# Correct usage
curl https://api.coinspayd.io/payments \
-H "x-api-key: your-actual-api-key-here"
Chain and token validation
Problem: INVALID_CHAIN or INVALID_TOKEN
Solutions:
- Use the GET /chains and GET /tokens endpoints to list supported values
- Ensure you're using CAIP format:
eip155:1(notethereumoreth) - Check that the chain/token is enabled for your organization
// Get valid chain IDs
const chains = await fetch('https://api.coinspayd.io/chains', {
headers: { 'x-api-key': 'your-api-key' }
}).then(r => r.json())
console.log('Supported chains:', chains.map(c => c.id))
Insufficient balance
Problem: INSUFFICIENT_BALANCE when creating withdrawals
Solutions:
- Check portfolio balances with GET /portfolio
- Remember amounts are in base units (e.g., 1 USDC = 1000000 with 6 decimals)
- Account for transaction fees (withdrawn amount + fees must be <= balance)
// Check balance before withdrawal
const portfolio = await getPortfolio()
const usdcBalance = portfolio.find(
p => p.tokenId === 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
)
console.log(`USDC balance: ${usdcBalance.balance / 1e6} USDC`)
Gas wallet issues
Problem: INSUFFICIENT_GAS when withdrawals fail
Solutions:
- Monitor gas wallets with GET /gas-station
- Maintain minimum balances (1-2 ETH on Ethereum, 50-100 MATIC on Polygon, etc.)
- Refill gas wallets before they run too low
# Check gas wallet balances
curl https://api.coinspayd.io/gas-station \
-H "x-api-key: your-api-key"
Webhook failures
Problem: Webhooks not being received or failing verification
Solutions:
- Ensure your webhook endpoint returns
200 OKwithin 30 seconds - Verify signatures using HMAC SHA-256 (see Webhooks security)
- Use HTTPS (not HTTP) for webhook URLs
- Check webhook URL is publicly accessible (not localhost)
Rate limiting
Problem: 429 Too Many Requests
Solutions:
- Implement exponential backoff when retrying failed requests
- Respect the
Retry-Afterheader - Cache responses where appropriate (e.g., supported chains/tokens rarely change)
- Consider batching requests if making many at once
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options)
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000))
continue
}
return response
}
throw new Error('Max retries exceeded')
}
Getting help
If you encounter persistent errors:
- Check this documentation for the specific error code
- Verify your request format matches the examples
- Test with a simplified request (e.g., just authentication)
- Check the API status page for any ongoing incidents
- Contact support with the full error response and your request details (redact sensitive data)