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-key or Authorization header.

  • 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-key header 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 (not ethereum or eth)
  • 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 OK within 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-After header
  • 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:

  1. Check this documentation for the specific error code
  2. Verify your request format matches the examples
  3. Test with a simplified request (e.g., just authentication)
  4. Check the API status page for any ongoing incidents
  5. Contact support with the full error response and your request details (redact sensitive data)

Was this page helpful?