Indodax API - Complete Crypto Conversion Integration
The Indodax API provides comprehensive cryptocurrency conversion functionality for Indonesian market including IDR to USDC conversion, automated trading, crypto wallet management, and real-time job tracking. Built for enterprise-grade crypto operations with multi-stage conversion flow and automated withdrawal support.
🎯 What Can You Manage?
Your complete crypto conversion ecosystem with these powerful tools:
- Crypto Wallets: Multi-network wallet management (ERC-20, TRC-20, BEP-20, Polygon, Solana)
- Conversion Jobs: Automated IDR to USDC conversion with multi-stage processing
- Balance Polling: Real-time Indodax balance monitoring and confirmation
- Trade Execution: Automated USDC trading on Indodax exchange
- Job Tracking: Complete conversion job status monitoring and history
- Network Support: Multiple blockchain networks for USDC withdrawal
- Admin Operations: Batch conversion processing and manual job execution
🧩 Your Crypto Conversion Building Blocks
💼 Crypto Wallet Blocks
POST /indodax/crypto-wallet/save- Save or update crypto walletGET /indodax/crypto-wallet/list- List all user walletsGET /indodax/crypto-wallet/primary- Get primary walletPOST /indodax/crypto-wallet/delete- Delete crypto walletGET /indodax/crypto-wallet/networks- Get supported networks
🔄 Conversion Operations Blocks
POST /indodax/conversion/run-daily- Trigger daily conversion (Admin)POST /indodax/conversion/execute/:job_id- Execute specific job (Admin)GET /indodax/conversion/pending- Get pending conversions (Admin)POST /indodax/conversion/poll-balance- Run balance polling (Admin)POST /indodax/conversion/poll-job/:job_id- Poll specific job (Admin)POST /indodax/conversion/run-trades- Run trade execution (Admin)POST /indodax/conversion/execute-trade/:job_id- Execute specific trade (Admin)GET /indodax/conversion/status/:job_id- Get job status
💸 Disbursement Blocks
POST /indodax/disbursement/start- Start manual disbursement to Indodax
🏗️ Common Conversion Patterns
Pattern 1: "I want to add my crypto wallet for USDC withdrawal"
Add wallet → Set as primary → Verify network support
Use: /indodax/crypto-wallet/save → /indodax/crypto-wallet/primary
Pattern 2: "I want to convert IDR to USDC automatically"
Daily conversion trigger → Balance polling → Trade execution → USDC withdrawal
Use: /indodax/conversion/run-daily → /indodax/conversion/poll-balance → /indodax/conversion/run-trades
Pattern 3: "I want to track my conversion job status"
Get job status → Monitor progress → Check completion
Use: /indodax/conversion/status/:job_id
Pattern 4: "I want to manage pending conversions (Admin)"
Get pending list → Execute specific jobs → Monitor completion
Use: /indodax/conversion/pending → /indodax/conversion/execute/:job_id → /indodax/conversion/status/:job_id
💼 Crypto Wallet Operations
Save Crypto Wallet
Save or Update Crypto Wallet
Save or update user's crypto wallet address for USDC withdrawal. Supports multiple blockchain networks (ERC-20, TRC-20, BEP-20, Polygon, Solana) with format validation. Automatically updates existing wallet if network already registered.
Parameters
wallet_addressstringrequiredCrypto wallet address
networkstringrequiredNetwork type: ERC20, TRC20, BEP20, POLYGON, SOLANA
set_as_primarybooleanSet as primary wallet (default: true)
Request Body
{
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "ERC20",
"set_as_primary": true
}Response
{
"success": true,
"message": "Crypto wallet updated successfully",
"data": {
"bw_id": 123,
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "Ethereum (ERC-20)",
"chain_id": "erc20",
"is_primary": true,
"action": "updated"
}
}{
"success": true,
"message": "Crypto wallet created successfully",
"data": {
"bw_id": 123,
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "Ethereum (ERC-20)",
"chain_id": "erc20",
"is_primary": true,
"action": "created"
},
"timestamp": "2024-01-15T10:00:00Z"
}{
"success": false,
"error_code": "INVALID_WALLET_FORMAT",
"message": "Invalid Ethereum (ERC-20) address format",
"details": {
"example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"supported": [
"ERC20",
"TRC20",
"BEP20",
"POLYGON",
"SOLANA"
]
}
}{
"error": "Failed to save crypto wallet"
}curl -X POST https://api.brdz.link/api/indodax/crypto-wallet/save \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "ERC20",
"set_as_primary": true
}'Get Crypto Wallet List
Get User's Crypto Wallets
Retrieve all active crypto wallets for the authenticated user including primary wallet designation. Returns wallets sorted by primary status and creation date.
Response
{
"success": true,
"message": "Crypto wallets retrieved successfully",
"data": {
"total": 3,
"wallets": [
{
"bw_id": 123,
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "Ethereum (ERC-20)",
"chain_id": "erc20",
"is_primary": true,
"status": "ACTIVE",
"created_at": "2024-01-15T10:00:00Z"
},
{
"bw_id": 124,
"wallet_address": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
"network": "Tron (TRC-20)",
"chain_id": "trc20",
"is_primary": false,
"status": "ACTIVE",
"created_at": "2024-01-14T09:00:00Z"
}
],
"primary_wallet": {
"bw_id": 123,
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "Ethereum (ERC-20)",
"chain_id": "erc20"
}
},
"timestamp": "2024-01-15T10:30:00Z"
}{
"error": "Failed to fetch crypto wallets"
}curl -X GET https://api.brdz.link/api/indodax/crypto-wallet/list \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Get Primary Wallet
Get Primary Crypto Wallet
Get user's primary crypto wallet used for USDC withdrawals in conversion process. Returns error if no primary wallet is set.
Response
{
"success": true,
"message": "Primary wallet retrieved successfully",
"data": {
"bw_id": 123,
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "Ethereum (ERC-20)",
"chain_id": "erc20"
},
"timestamp": "2024-01-15T10:00:00Z"
}{
"success": false,
"error_code": "NO_PRIMARY_WALLET",
"message": "No primary wallet found. Please add a crypto wallet first.",
"timestamp": "2024-01-15T10:00:00Z"
}{
"error": "Failed to fetch primary wallet"
}curl -X GET https://api.brdz.link/api/indodax/crypto-wallet/primary \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Delete Crypto Wallet
Delete Crypto Wallet
Soft delete (deactivate) a crypto wallet. Wallet is marked as inactive but not permanently removed from database.
Parameters
bw_idnumberrequiredBlockchain wallet ID to delete
Request Body
{
"bw_id": 123
}Response
{
"success": true,
"message": "Wallet deleted successfully",
"timestamp": "2024-01-15T10:00:00Z"
}{
"success": false,
"error_code": "INVALID_WALLET_ID",
"message": "Valid wallet ID is required"
}{
"success": false,
"error_code": "WALLET_NOT_FOUND",
"message": "Wallet not found or already deleted"
}{
"error": "Failed to delete crypto wallet"
}curl -X POST https://api.brdz.link/api/indodax/crypto-wallet/delete \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"bw_id": 123
}'Get Supported Networks
Get Supported Networks
Get list of all supported blockchain networks for USDC withdrawal including format examples and Indodax network codes.
Response
{
"success": true,
"message": "Supported networks retrieved successfully",
"data": {
"total": 5,
"networks": [
{
"code": "ERC20",
"name": "Ethereum (ERC-20)",
"example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"indodax_code": "erc20"
},
{
"code": "TRC20",
"name": "Tron (TRC-20)",
"example": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
"indodax_code": "trc20"
},
{
"code": "BEP20",
"name": "BSC (BEP-20)",
"example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"indodax_code": "bep20"
},
{
"code": "POLYGON",
"name": "Polygon",
"example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"indodax_code": "polygon"
},
{
"code": "SOLANA",
"name": "Solana",
"example": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
"indodax_code": "solana"
}
]
},
"timestamp": "2024-01-15T10:00:00Z"
}{
"error": "Failed to fetch supported networks"
}curl -X GET https://api.brdz.link/api/indodax/crypto-wallet/networks \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"💸 Disbursement Operations
Start Disbursement to Indodax
Start Manual Disbursement to Indodax
Manually trigger disbursement from Xendit balance to Indodax VA for crypto conversion. User can initiate their own disbursement without waiting for daily cron. Performs pre-disbursement reconciliation, creates conversion job, and initiates Xendit payout.
Parameters
wallet_idnumberrequiredUser's IDR wallet ID
amount_idrnumberrequiredAmount in IDR (minimum 200,000)
Request Body
{
"wallet_id": 59,
"amount_idr": 500000
}Response
{
"success": true,
"message": "Disbursement to Indodax initiated successfully",
"data": {
"job_id": 123,
"disbursement_id": "disb_1234567890abcdef",
"reference_id": "INDODAX-DISB-123-1705308000000",
"amount_idr": 500000,
"status": "DISBURSING",
"reconciliation": {
"reconciliation_id": 456,
"status": "MATCHED",
"requires_admin_attention": false
}
},
"timestamp": "2024-01-15T10:00:00Z"
}{
"success": false,
"error_code": "AMOUNT_BELOW_MINIMUM",
"message": "Minimum disbursement amount is IDR 200,000",
"timestamp": "2024-01-15T10:00:00Z"
}{
"success": false,
"error_code": "RECONCILIATION_FAILED",
"message": "Pre-disbursement reconciliation failed",
"reconciliation_id": 789,
"details": {
"ledger_balance": 5000000,
"xendit_balance": 4900000,
"difference_amount": 100000
},
"timestamp": "2024-01-15T10:00:00Z"
}{
"success": false,
"error_code": "DISBURSEMENT_FAILED",
"message": "Failed to start disbursement",
"details": "Xendit API error",
"timestamp": "2024-01-15T10:00:00Z"
}curl -X POST https://api.brdz.link/api/indodax/disbursement/start \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"wallet_id": 59,
"amount_idr": 500000
}'🔄 Conversion Operations
Run Daily Conversion
Run Daily Conversion Process
Trigger automated daily conversion process for all eligible users. Creates conversion jobs, initiates Xendit disbursements to Indodax VA, and starts the conversion pipeline. Admin only operation, typically run by cron job.
Response
{
"success": true,
"message": "Daily conversion completed successfully",
"data": {
"total_users": 45,
"jobs_created": 42,
"total_idr": 150000000,
"disbursements_initiated": 42,
"failed_jobs": 0,
"processing_time_ms": 8500,
"summary": {
"pending": 42,
"waiting_indodax": 0,
"trading": 0,
"completed": 0,
"failed": 0
}
},
"timestamp": "2024-01-15T02:00:00Z"
}{
"success": false,
"error_code": "DAILY_CONVERSION_FAILED",
"message": "Failed to run daily conversion",
"details": "Xendit API error"
}curl -X POST https://api.brdz.link/api/indodax/conversion/run-daily \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Execute Conversion Job
Execute Specific Conversion Job
Manually execute a specific conversion job by ID. Runs pre-disbursement reconciliation, initiates Xendit disbursement to Indodax VA, and updates job status. Admin only operation.
Parameters
job_idnumberrequiredConversion job ID to execute (path parameter)
Response
{
"success": true,
"message": "Conversion job executed successfully",
"data": {
"job_id": 123,
"user_id": 456,
"batch_amount_idr": 1000000,
"disbursement_id": "disb_1234567890",
"status": "WAITING_INDODAX",
"reconciliation_passed": true,
"executed_at": "2024-01-15T10:00:00Z"
},
"timestamp": "2024-01-15T10:00:01Z"
}{
"success": false,
"error_code": "RECONCILIATION_FAILED",
"message": "Pre-disbursement reconciliation failed",
"reconciliation_id": 789,
"details": {
"ledger_balance": 5000000,
"xendit_balance": 4900000,
"difference_amount": 100000
}
}{
"success": false,
"error_code": "JOB_EXECUTION_FAILED",
"message": "Failed to execute conversion job"
}curl -X POST https://api.brdz.link/api/indodax/conversion/execute/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Get Pending Conversions
Get Pending Conversions
Get list of all users with pending conversions eligible for processing. Returns user details and conversion amounts. Admin only operation.
Response
{
"success": true,
"message": "Pending conversions retrieved successfully",
"data": {
"total": 5,
"users": [
{
"user_id": 456,
"email": "user1@example.com",
"total_amount_idr": 2000000,
"eligible_for_conversion": true,
"has_primary_wallet": true,
"wallet_network": "Ethereum (ERC-20)"
},
{
"user_id": 457,
"email": "user2@example.com",
"total_amount_idr": 1500000,
"eligible_for_conversion": true,
"has_primary_wallet": true,
"wallet_network": "Tron (TRC-20)"
}
]
},
"timestamp": "2024-01-15T10:00:00Z"
}{
"error": "Failed to fetch pending conversions"
}curl -X GET https://api.brdz.link/api/indodax/conversion/pending \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Run Balance Polling
Run Indodax Balance Polling
Poll Indodax account balance to confirm funds received after Xendit disbursement. Checks all jobs in WAITING_INDODAX status, compares Indodax balance with expected amounts, and updates job status to TRADING when confirmed. Admin only, typically run by cron job every hour.
Response
{
"success": true,
"message": "Balance polling completed successfully",
"data": {
"jobs_checked": 15,
"balance_confirmed": 12,
"still_waiting": 3,
"timeout_exceeded": 0,
"indodax_balance": {
"idr": 50000000,
"usdc": 250.5
},
"processing_time_ms": 2500
},
"timestamp": "2024-01-15T11:00:00Z"
}{
"success": false,
"error_code": "POLLING_FAILED",
"message": "Failed to run balance polling"
}curl -X POST https://api.brdz.link/api/indodax/conversion/poll-balance \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Poll Job Balance
Poll Balance for Specific Job
Manually poll Indodax balance for a specific conversion job. Checks if disbursement amount has arrived at Indodax account and updates job status accordingly. Admin only operation.
Parameters
job_idnumberrequiredConversion job ID to poll (path parameter)
Response
{
"success": true,
"message": "Balance polling completed",
"data": {
"job_id": 123,
"status": "TRADING",
"balance_confirmed": true,
"expected_amount": 1000000,
"indodax_balance": 50000000,
"confirmed_at": "2024-01-15T11:00:00Z"
},
"timestamp": "2024-01-15T11:00:01Z"
}{
"success": false,
"error_code": "INVALID_JOB_ID",
"message": "Valid job ID is required"
}{
"success": false,
"error_code": "JOB_POLL_FAILED",
"message": "Failed to poll job balance"
}curl -X POST https://api.brdz.link/api/indodax/conversion/poll-job/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Run Trade Execution
Run Trade Execution for All Ready Jobs
Execute USDC trades on Indodax for all jobs in TRADING status. Gets current USDC/IDR price, executes buy orders, polls trade status, and triggers USDC withdrawal to user wallets. Admin only, typically run by cron job.
Response
{
"success": true,
"message": "Trade execution completed successfully",
"data": {
"jobs_checked": 12,
"trades_executed": 10,
"trades_failed": 2,
"total_idr_spent": 12000000,
"total_usdc_received": 848.5,
"withdrawals_initiated": 10,
"processing_time_ms": 45000
},
"timestamp": "2024-01-15T12:00:00Z"
}{
"success": false,
"error_code": "TRADE_EXECUTION_FAILED",
"message": "Failed to run trade execution"
}curl -X POST https://api.brdz.link/api/indodax/conversion/run-trades \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Execute Trade for Specific Job
Execute Trade for Specific Job
Manually execute USDC trade for a specific conversion job. Gets current USDC/IDR price, executes buy order on Indodax, polls trade status until completion, and initiates USDC withdrawal. Admin only operation.
Parameters
job_idnumberrequiredConversion job ID to execute trade for (path parameter)
Response
{
"success": true,
"message": "Trade executed successfully",
"data": {
"job_id": 123,
"trade_id": "trade_9876543210",
"status": "WITHDRAWING",
"usdc_price": 14150,
"idr_spent": 1000000,
"usdc_received": 70.67,
"trade_fee": 707,
"withdrawal_id": "withdraw_1234567890",
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "erc20",
"executed_at": "2024-01-15T12:00:00Z"
},
"timestamp": "2024-01-15T12:00:30Z"
}{
"success": false,
"error_code": "INSUFFICIENT_INDODAX_BALANCE",
"message": "Insufficient Indodax balance. Available: 500000, Required: 1000000"
}{
"success": false,
"error_code": "TRADE_EXECUTION_FAILED",
"message": "Failed to execute trade"
}curl -X POST https://api.brdz.link/api/indodax/conversion/execute-trade/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Get Conversion Status
Get Conversion Job Status
Get detailed status and progress of a conversion job. Users can check their own jobs, admins can check any job. Returns complete job details including amounts, status transitions, and timestamps.
Parameters
job_idnumberrequiredConversion job ID (path parameter)
Response
{
"success": true,
"message": "Conversion status retrieved successfully",
"data": {
"job_id": 123,
"user_id": 456,
"status": "COMPLETED",
"batch_amount_idr": 1000000,
"disbursement_id": "disb_1234567890",
"disbursement_amount_idr": 1000000,
"trade_id": "trade_9876543210",
"usdc_received": 70.67,
"trade_fee": 707,
"withdrawal_id": "withdraw_1234567890",
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"network": "erc20",
"status_history": [
{
"status": "PENDING",
"timestamp": "2024-01-15T02:00:00Z"
},
{
"status": "WAITING_INDODAX",
"timestamp": "2024-01-15T02:01:00Z"
},
{
"status": "TRADING",
"timestamp": "2024-01-15T11:00:00Z"
},
{
"status": "WITHDRAWING",
"timestamp": "2024-01-15T12:00:00Z"
},
{
"status": "COMPLETED",
"timestamp": "2024-01-15T12:30:00Z"
}
],
"created_at": "2024-01-15T02:00:00Z",
"updated_at": "2024-01-15T12:30:00Z"
},
"timestamp": "2024-01-15T13:00:00Z"
}{
"success": false,
"error_code": "INVALID_JOB_ID",
"message": "Valid job ID is required"
}{
"success": false,
"error_code": "JOB_NOT_FOUND",
"message": "Conversion job not found or access denied"
}{
"error": "Failed to get conversion status"
}curl -X GET https://api.brdz.link/api/indodax/conversion/status/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"🚀 Complete Conversion Workflows
Workflow 1: Setup Crypto Wallet for Conversion
// Complete wallet setup workflow
async function setupWalletForConversion(walletAddress, network) {
console.log('Setting up crypto wallet for conversions...');
try {
// Step 1: Check supported networks
const networksResponse = await fetch('https://api.brdz.link/api/indodax/crypto-wallet/networks', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const networks = await networksResponse.json();
const supportedNetwork = networks.data.networks.find(
n => n.code.toUpperCase() === network.toUpperCase()
);
if (!supportedNetwork) {
throw new Error(\`Network \${network} is not supported\`);
}
console.log('✅ Network', supportedNetwork.name, 'is supported');
console.log('Example format:', supportedNetwork.example);
// Step 2: Save wallet
const saveResponse = await fetch('https://api.brdz.link/api/indodax/crypto-wallet/save', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify({
wallet_address: walletAddress,
network: network,
set_as_primary: true
})
});
const wallet = await saveResponse.json();
console.log('✅ Wallet', wallet.data.action + ':', wallet.data.bw_id);
console.log('Network:', wallet.data.network);
console.log('Primary:', wallet.data.is_primary);
// Step 3: Verify primary wallet
const primaryResponse = await fetch('https://api.brdz.link/api/indodax/crypto-wallet/primary', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const primary = await primaryResponse.json();
console.log('✅ Primary wallet confirmed:', primary.data.wallet_address);
// Step 4: Get all wallets
const listResponse = await fetch('https://api.brdz.link/api/indodax/crypto-wallet/list', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const allWallets = await listResponse.json();
console.log('Total wallets:', allWallets.data.total);
return {
success: true,
wallet_id: wallet.data.bw_id,
network: wallet.data.network,
is_primary: wallet.data.is_primary
};
} catch (error) {
console.log('❌ Setup failed:', error.message);
return {
success: false,
error: error.message
};
}
}
// Usage
await setupWalletForConversion(
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'ERC20'
);
Workflow 2: Track Conversion Job Progress
// Monitor conversion job from start to finish
async function trackConversionJob(jobId) {
console.log('Tracking conversion job', jobId);
const statusMap = {
'PENDING': 'Waiting for disbursement to Indodax',
'WAITING_INDODAX': 'Waiting for Indodax balance confirmation',
'TRADING': 'Executing USDC trade',
'WITHDRAWING': 'Withdrawing USDC to wallet',
'COMPLETED': 'Conversion completed successfully',
'FAILED': 'Conversion failed'
};
let lastStatus = '';
let attempts = 0;
const maxAttempts = 120; // 10 minutes with 5-second intervals
while (attempts < maxAttempts) {
try {
const response = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const status = await response.json();
const currentStatus = status.data.status;
// Display status change
if (currentStatus !== lastStatus) {
const time = new Date().toLocaleTimeString();
console.log(\`[\${time}] Status: \${currentStatus}\`);
console.log('Description:', statusMap[currentStatus]);
// Display relevant details
if (status.data.disbursement_id) {
console.log('Disbursement ID:', status.data.disbursement_id);
}
if (status.data.trade_id) {
console.log('Trade ID:', status.data.trade_id);
console.log('USDC Received:', status.data.usdc_received);
}
if (status.data.withdrawal_id) {
console.log('Withdrawal ID:', status.data.withdrawal_id);
console.log('Network:', status.data.network);
}
lastStatus = currentStatus;
}
// Check if completed or failed
if (currentStatus === 'COMPLETED') {
console.log('✅ Conversion completed successfully!');
console.log('Amount:', status.data.batch_amount_idr.toLocaleString(), 'IDR');
console.log('USDC Received:', status.data.usdc_received);
console.log('Wallet:', status.data.wallet_address);
// Calculate total processing time
const created = new Date(status.data.created_at);
const completed = new Date(status.data.updated_at);
const totalMinutes = Math.round((completed - created) / 1000 / 60);
console.log('Total Processing Time:', totalMinutes, 'minutes');
return status.data;
} else if (currentStatus === 'FAILED') {
console.log('❌ Conversion failed');
return status.data;
}
// Wait 5 seconds before next check
await new Promise(resolve => setTimeout(resolve, 5000));
attempts++;
} catch (error) {
console.log('Error checking status:', error.message);
break;
}
}
console.log('⏰ Timeout: Job still in progress');
return null;
}
// Usage
await trackConversionJob(123);
Workflow 3: Admin Daily Conversion Process
// Complete admin workflow for daily conversions
async function performDailyConversionProcess() {
console.log('=== DAILY CONVERSION PROCESS ===');
const headers = {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};
// Step 1: Check pending conversions
console.log('Step 1: Checking pending conversions...');
const pendingResponse = await fetch('https://api.brdz.link/api/indodax/conversion/pending', {
headers
});
const pending = await pendingResponse.json();
console.log('Total pending users:', pending.data.total);
const totalAmount = pending.data.users.reduce(
(sum, user) => sum + user.total_amount_idr,
0
);
console.log('Total pending amount:', totalAmount.toLocaleString(), 'IDR');
// Check for users without wallets
const noWallet = pending.data.users.filter(u => !u.has_primary_wallet);
if (noWallet.length > 0) {
console.log('⚠️ ', noWallet.length, 'users missing primary wallet');
}
// Step 2: Run daily conversion
console.log('Step 2: Running daily conversion...');
const conversionResponse = await fetch('https://api.brdz.link/api/indodax/conversion/run-daily', {
method: 'POST',
headers
});
const conversion = await conversionResponse.json();
console.log('✅ Jobs created:', conversion.data.jobs_created);
console.log('Disbursements initiated:', conversion.data.disbursements_initiated);
console.log('Processing time:', conversion.data.processing_time_ms, 'ms');
// Wait for balance confirmations
await new Promise(resolve => setTimeout(resolve, 2000));
// Step 3: Run balance polling
console.log('Step 3: Running balance polling...');
const pollingResponse = await fetch('https://api.brdz.link/api/indodax/conversion/poll-balance', {
method: 'POST',
headers
});
const polling = await pollingResponse.json();
console.log('Jobs checked:', polling.data.jobs_checked);
console.log('Balance confirmed:', polling.data.balance_confirmed);
console.log('Still waiting:', polling.data.still_waiting);
// Step 4: Run trade execution
if (polling.data.balance_confirmed > 0) {
console.log('Step 4: Running trade execution...');
const tradesResponse = await fetch('https://api.brdz.link/api/indodax/conversion/run-trades', {
method: 'POST',
headers
});
const trades = await tradesResponse.json();
console.log('Trades executed:', trades.data.trades_executed);
console.log('IDR spent:', trades.data.total_idr_spent.toLocaleString());
console.log('USDC received:', trades.data.total_usdc_received);
console.log('Withdrawals initiated:', trades.data.withdrawals_initiated);
}
console.log('=== PROCESS COMPLETE ===');
return {
pending: pending.data.total,
jobs_created: conversion.data.jobs_created,
balance_confirmed: polling.data.balance_confirmed,
trades_executed: trades?.data.trades_executed || 0
};
}
// Usage (run as cron job)
await performDailyConversionProcess();
Workflow 4: Manual Job Execution (Admin)
// Manually execute specific conversion job
async function manualJobExecution(jobId) {
console.log('=== MANUAL JOB EXECUTION:', jobId, '===');
const headers = {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};
try {
// Step 1: Check current status
console.log('Step 1: Checking current job status...');
let statusResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers
});
let status = await statusResponse.json();
console.log('Current Status:', status.data.status);
console.log('Amount:', status.data.batch_amount_idr.toLocaleString(), 'IDR');
// Step 2: Execute based on current status
if (status.data.status === 'PENDING') {
console.log('Step 2: Executing conversion job...');
const executionResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/execute/\${jobId}\`, {
method: 'POST',
headers
});
const execution = await executionResponse.json();
console.log('✅ Disbursement initiated:', execution.data.disbursement_id);
console.log('New Status:', execution.data.status);
// Wait for status update
await new Promise(resolve => setTimeout(resolve, 3000));
statusResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers
});
status = await statusResponse.json();
}
// Step 3: Poll balance if waiting
if (status.data.status === 'WAITING_INDODAX') {
console.log('Step 3: Polling Indodax balance...');
const pollingResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/poll-job/\${jobId}\`, {
method: 'POST',
headers
});
const polling = await pollingResponse.json();
if (polling.data.balance_confirmed) {
console.log('✅ Balance confirmed at Indodax');
console.log('New Status:', polling.data.status);
} else {
console.log('⏳ Balance not yet confirmed');
console.log('Expected:', polling.data.expected_amount.toLocaleString(), 'IDR');
return;
}
// Wait for status update
await new Promise(resolve => setTimeout(resolve, 3000));
statusResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers
});
status = await statusResponse.json();
}
// Step 4: Execute trade if ready
if (status.data.status === 'TRADING') {
console.log('Step 4: Executing USDC trade...');
const tradeResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/execute-trade/\${jobId}\`, {
method: 'POST',
headers
});
const trade = await tradeResponse.json();
console.log('✅ Trade executed:', trade.data.trade_id);
console.log('USDC Received:', trade.data.usdc_received);
console.log('Withdrawal initiated:', trade.data.withdrawal_id);
console.log('New Status:', trade.data.status);
}
// Step 5: Final status check
console.log('Step 5: Final status check...');
const finalStatusResponse = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers
});
const finalStatus = await finalStatusResponse.json();
console.log('Final Status:', finalStatus.data.status);
if (finalStatus.data.status === 'COMPLETED') {
console.log('✅ Job completed successfully!');
console.log('Summary:');
console.log(' IDR Amount:', finalStatus.data.batch_amount_idr.toLocaleString());
console.log(' USDC Received:', finalStatus.data.usdc_received);
console.log(' Trade Fee:', finalStatus.data.trade_fee, 'IDR');
console.log(' Wallet:', finalStatus.data.wallet_address);
console.log(' Network:', finalStatus.data.network);
} else {
console.log('Current Status:', finalStatus.data.status);
console.log('Continue monitoring job status');
}
return finalStatus.data;
} catch (error) {
console.log('❌ Manual execution failed:', error.message);
throw error;
}
}
// Usage
await manualJobExecution(123);
Workflow 5: User Conversion Monitoring
// Simple user workflow to monitor their conversion
async function monitorMyConversion(jobId) {
console.log('Monitoring your conversion...');
const response = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const status = await response.json();
// Simple status display
const statusText = {
'PENDING': '⏳ Your conversion is being processed',
'WAITING_INDODAX': '⏳ Waiting for exchange confirmation',
'TRADING': '📊 Trading USDC on exchange',
'WITHDRAWING': '💸 Sending USDC to your wallet',
'COMPLETED': '✅ Conversion completed!',
'FAILED': '❌ Conversion failed'
};
console.log(statusText[status.data.status]);
console.log('Amount:', status.data.batch_amount_idr.toLocaleString(), 'IDR');
// Show relevant info based on status
if (status.data.status === 'COMPLETED') {
console.log('Your USDC has been sent!');
console.log('USDC Received:', status.data.usdc_received);
console.log('Wallet:', status.data.wallet_address);
console.log('Network:', status.data.network);
console.log('Check your wallet to confirm receipt.');
} else if (status.data.status === 'FAILED') {
console.log('Something went wrong with your conversion.');
console.log('Please contact support for assistance.');
} else {
console.log('Your conversion is in progress.');
console.log('You will be notified when it completes.');
// Estimated time remaining
const statusSteps = ['PENDING', 'WAITING_INDODAX', 'TRADING', 'WITHDRAWING'];
const currentStep = statusSteps.indexOf(status.data.status);
const totalSteps = statusSteps.length;
const progressPercent = Math.round((currentStep / totalSteps) * 100);
console.log('Progress:', progressPercent + '%');
console.log('Estimated completion: 2-12 hours');
}
return status.data;
}
// Usage
await monitorMyConversion(123);
🔐 Authentication & Authorization
All Indodax endpoints require authentication and specific role permissions:
// Authentication headers required for all requests
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_JWT_TOKEN', // Required for all endpoints
'x-api-key': 'YOUR_API_KEY' // Required for all endpoints
};
// User-level operations (user or admin role)
- Save/list/delete crypto wallets
- Get supported networks
- Get conversion status
- Start manual disbursement
// Admin-only operations (admin role required)
- Run daily conversion
- Execute conversion jobs
- Get pending conversions
- Run balance polling
- Execute trades
🌍 Supported Networks & Features
Blockchain Network Support
| Network | Code | Address Format | Example | Indodax Code |
|---|---|---|---|---|
| Ethereum (ERC-20) | ERC20 | 0x + 40 hex chars | 0x742d35Cc... | erc20 |
| Tron (TRC-20) | TRC20 | T + 33 alphanumeric | TN3W4H6rK2... | trc20 |
| BSC (BEP-20) | BEP20 | 0x + 40 hex chars | 0x742d35Cc... | bep20 |
| Polygon | POLYGON | 0x + 40 hex chars | 0x742d35Cc... | polygon |
| Solana | SOLANA | 32-44 base58 chars | 7EcDhSYGx... | solana |
Conversion Features
- Automated Daily Conversion: Scheduled conversion from IDR to USDC
- Multi-stage Processing: PENDING → WAITING_INDODAX → TRADING → WITHDRAWING → COMPLETED
- Balance Polling: Automatic confirmation of Indodax balance
- Real-time Trading: Live USDC/IDR price fetching and trade execution
- Automatic Withdrawal: USDC sent directly to user's crypto wallet
- Job Tracking: Complete status monitoring and history
Processing Stages
- PENDING: Conversion job created, awaiting disbursement
- WAITING_INDODAX: Funds sent to Indodax, waiting for balance confirmation
- TRADING: Balance confirmed, executing USDC buy order
- WITHDRAWING: Trade completed, sending USDC to user wallet
- COMPLETED: USDC successfully delivered to wallet
- FAILED: Error occurred, manual review required
💡 Pro Tips for Indodax Integration
Wallet Management Best Practices
// Always verify primary wallet before conversions
async function ensurePrimaryWallet() {
const response = await fetch('https://api.brdz.link/api/indodax/crypto-wallet/primary', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const result = await response.json();
if (result.success) {
console.log('✅ Primary wallet set:', result.data.wallet_address);
return true;
} else {
console.log('❌ No primary wallet - user must add wallet first');
return false;
}
}
Conversion Job Monitoring
// Poll job status with exponential backoff
async function smartJobMonitoring(jobId) {
const delays = [5, 10, 30, 60, 300]; // seconds
let delayIndex = 0;
while (true) {
const response = await fetch(\`https://api.brdz.link/api/indodax/conversion/status/\${jobId}\`, {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const status = await response.json();
if (['COMPLETED', 'FAILED'].includes(status.data.status)) {
return status.data;
}
const delay = delays[Math.min(delayIndex, delays.length - 1)];
console.log('Status:', status.data.status, '- checking again in', delay, 's');
await new Promise(resolve => setTimeout(resolve, delay * 1000));
delayIndex++;
}
}
Error Handling
// Robust error handling for conversions
class IndodaxErrorHandler {
static async safeConversion(jobId) {
try {
const response = await fetch(\`https://api.brdz.link/api/indodax/conversion/execute/\${jobId}\`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
return await response.json();
} catch (error) {
return this.handleConversionError(error);
}
}
static handleConversionError(error) {
const errorMap = {
'NO_PRIMARY_WALLET': {
message: 'User has not set up crypto wallet',
action: 'Prompt user to add wallet via saveCryptoWallet',
retry: false
},
'INVALID_WALLET_FORMAT': {
message: 'Wallet address format is invalid',
action: 'Verify wallet address format for selected network',
retry: false
},
'RECONCILIATION_FAILED': {
message: 'Balance reconciliation failed',
action: 'Admin must review and resolve reconciliation',
retry: false
},
'INSUFFICIENT_INDODAX_BALANCE': {
message: 'Indodax account has insufficient balance',
action: 'Top up Indodax account before trading',
retry: false
},
'TRADE_EXECUTION_FAILED': {
message: 'Trade execution failed on Indodax',
action: 'Check Indodax API status and retry',
retry: true
}
};
const errorCode = error.error_code || 'UNKNOWN_ERROR';
const errorInfo = errorMap[errorCode] || {
message: error.message,
action: 'Review error logs and contact support',
retry: false
};
console.log('Error:', errorInfo.message);
console.log('Action:', errorInfo.action);
return {
success: false,
error_code: errorCode,
...errorInfo
};
}
}
// Usage
const result = await IndodaxErrorHandler.safeConversion(123);
if (!result.success && result.retry) {
console.log('Safe to retry this operation');
}
Cron Job Schedule
// Recommended cron schedule for automated operations
const cron = require('node-cron');
const headers = {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};
// Daily conversion at 2 AM
cron.schedule('0 2 * * *', async () => {
console.log('Running daily conversion...');
await fetch('https://api.brdz.link/api/indodax/conversion/run-daily', {
method: 'POST',
headers
});
});
// Balance polling every hour
cron.schedule('0 * * * *', async () => {
console.log('Running balance polling...');
await fetch('https://api.brdz.link/api/indodax/conversion/poll-balance', {
method: 'POST',
headers
});
});
// Trade execution every 2 hours
cron.schedule('0 */2 * * *', async () => {
console.log('Running trade execution...');
await fetch('https://api.brdz.link/api/indodax/conversion/run-trades', {
method: 'POST',
headers
});
});
🔄 Complete Conversion Flow Diagram
┌─────────────────────────────────────────────────────────────────┐
│ INDODAX CONVERSION FLOW │
└─────────────────────────────────────────────────────────────────┘
USER SETUP:
┌──────────────┐
│ User adds │
│ crypto wallet│
│ (ERC20, etc) │
└──────┬───────┘
│
v
┌──────────────┐
│ Set as │
│ primary │
│ wallet │
└──────┬───────┘
│
▼
[Ready for Conversion]
═══════════════════════════════════════════════════════════════
AUTOMATED CONVERSION (Admin/Cron):
STEP 1: JOB CREATION
┌──────────────┐
│ Daily Cron │
│ (2 AM) │
└──────┬───────┘
│
v
┌──────────────────────────┐
│ Get eligible users │
│ with IDR balance │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Create conversion_jobs │
│ Status: PENDING │
└──────────┬───────────────┘
│
▼
STEP 2: DISBURSEMENT
┌──────────────────────────┐
│ Pre-disbursement │
│ reconciliation │
└──────────┬───────────────┘
│
v [PASSED]
┌──────────────────────────┐
│ Xendit disburse IDR │
│ to Indodax VA │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Update Status: │
│ WAITING_INDODAX │
└──────────┬───────────────┘
│
▼
STEP 3: BALANCE POLLING (Every hour)
┌──────────────────────────┐
│ Check Indodax balance │
│ via API │
└──────────┬───────────────┘
│
v [CONFIRMED]
┌──────────────────────────┐
│ Update Status: │
│ TRADING │
└──────────┬───────────────┘
│
▼
STEP 4: TRADE EXECUTION (Every 2 hours)
┌──────────────────────────┐
│ Get USDC/IDR price │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Execute buy order │
│ IDR → USDC │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Poll trade status │
│ (10s interval, 5min max) │
└──────────┬───────────────┘
│
v [COMPLETED]
┌──────────────────────────┐
│ Update Status: │
│ WITHDRAWING │
└──────────┬───────────────┘
│
▼
STEP 5: WITHDRAWAL
┌──────────────────────────┐
│ Indodax withdrawCoin() │
│ to user's wallet │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Wait for Indodax │
│ withdrawal callback │
└──────────┬───────────────┘
│
v [SUCCESS]
┌──────────────────────────┐
│ Update Status: │
│ COMPLETED │
└──────────┬───────────────┘
│
▼
[✅ DONE]
═══════════════════════════════════════════════════════════════
USER MONITORING:
┌──────────────────────────┐
│ User checks job status │
│ via API │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Get status, USDC amount, │
│ wallet address, network │
└──────────────────────────┘
═══════════════════════════════════════════════════════════════
FAILURE HANDLING:
┌──────────────────────────┐
│ Any stage fails │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Update Status: FAILED │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Admin notification │
│ Manual review required │
└──────────────────────────┘
📊 Conversion Statistics & Monitoring
// Get conversion statistics for monitoring
async function getConversionStats(startDate, endDate) {
const headers = {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};
// Get all conversions in date range
const response = await fetch('https://api.brdz.link/api/indodax/conversion/pending', {
headers
});
const pending = await response.json();
// Calculate metrics
const stats = {
total_users: pending.data.total,
total_pending_idr: pending.data.users.reduce(
(sum, u) => sum + u.total_amount_idr,
0
),
users_with_wallets: pending.data.users.filter(
u => u.has_primary_wallet
).length,
users_without_wallets: pending.data.users.filter(
u => !u.has_primary_wallet
).length,
network_distribution: {}
};
// Calculate network distribution
pending.data.users.forEach(user => {
if (user.has_primary_wallet) {
const network = user.wallet_network;
stats.network_distribution[network] =
(stats.network_distribution[network] || 0) + 1;
}
});
return stats;
}
// Usage
const stats = await getConversionStats('2024-01-01', '2024-01-31');
console.log('Conversion Statistics:');
console.log('Total Users:', stats.total_users);
console.log('Total Pending:', stats.total_pending_idr.toLocaleString(), 'IDR');
console.log('With Wallets:', stats.users_with_wallets);
console.log('Without Wallets:', stats.users_without_wallets);
console.log('Network Distribution:');
Object.entries(stats.network_distribution).forEach(([network, count]) => {
console.log(\` \${network}: \${count}\`);
});
⚠️ Important Notes & Warnings
The current Indodax implementation uses pooled custody which may not be compliant with POJK 27/2024 (Indonesia's crypto regulation). This is for TESTING PURPOSES ONLY. Production deployment requires proper licensing or partnership with a licensed DFA (Digital Financial Asset) Trader.
Users must add and verify their crypto wallet before any conversion can be processed. Always check for primary wallet existence before initiating conversions.
Complete conversion process typically takes 2-12 hours depending on:
- Xendit disbursement processing time (1-2 hours)
- Indodax balance confirmation (1 hour polling interval)
- Trade execution timing (2 hour execution interval)
- USDC withdrawal processing (varies by network)
Admin should monitor Indodax account balance to ensure sufficient IDR is available for trading. Set up alerts when balance falls below threshold (e.g., 50M IDR).
Always run pre-disbursement reconciliation to prevent balance discrepancies. Any reconciliation failures require manual admin resolution before proceeding.
🔧 Environment Configuration
Required Environment Variables
# Indodax API Credentials
INDODAX_PUBLIC_API_URL=https://indodax.com/api
INDODAX_TRADE_API_URL=https://indodax.com/tapi
INDODAX_API_KEY=your_indodax_api_key
INDODAX_API_SECRET=your_indodax_api_secret
# Indodax Virtual Account (via Xendit)
INDODAX_XENDIT_VA_NUMBER=8888012345678901
INDODAX_XENDIT_VA_BANK=PERMATA
INDODAX_XENDIT_VA_NAME=ANANTLA TECH
# Polling Configuration
INDODAX_POLLING_INTERVAL_MS=3600000 # 1 hour
INDODAX_POLLING_MAX_ATTEMPTS=24 # 24 hours timeout
INDODAX_TRADE_POLLING_INTERVAL_MS=10000 # 10 seconds
INDODAX_TRADE_MAX_WAIT_MS=300000 # 5 minutes
# Xendit Configuration (required for disbursement)
XENDIT_MODE=test # or 'live'
API_KEY_XENDIT_TEST=your_xendit_test_key
API_KEY_XENDIT_LIVE=your_xendit_live_key
XENDIT_BASE_URL=https://api.xendit.co
🚨 Troubleshooting Guide
Common Issues & Solutions
Issue 1: "No primary wallet found"
Cause: User hasn't set up crypto wallet
Solution:
// Prompt user to add wallet
await fetch('https://api.brdz.link/api/indodax/crypto-wallet/save', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify({
wallet_address: '0x...',
network: 'ERC20',
set_as_primary: true
})
});
Issue 2: "Invalid wallet format"
Cause: Wallet address doesn't match network format
Solution:
// Check supported networks first
const response = await fetch('https://api.brdz.link/api/indodax/crypto-wallet/networks', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
const networks = await response.json();
// Validate address format against network.example
Issue 3: "Reconciliation failed"
Cause: Balance mismatch between ledger and Xendit
Solution: Admin must review and manually resolve reconciliation before proceeding
Issue 4: "Job stuck in WAITING_INDODAX"
Cause: Funds not yet arrived at Indodax or balance polling not running
Solution:
// Manually poll job
await fetch(\`https://api.brdz.link/api/indodax/conversion/poll-job/\${job_id}\`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
});
// Check balance polling cron is running
Issue 5: "Trade execution failed"
Cause: Indodax API error or insufficient balance
Solution:
- Check Indodax API status
- Verify Indodax account has sufficient IDR
- Check trade execution logs for specific error
Issue 6: "Withdrawal stuck in WITHDRAWING"
Cause: Waiting for Indodax withdrawal callback
Solution: Monitor Indodax withdrawal status, callback may be delayed
📚 API Reference Summary
Quick Reference Table
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/crypto-wallet/save | POST | User/Admin | Save crypto wallet |
/crypto-wallet/list | GET | User/Admin | List all wallets |
/crypto-wallet/primary | GET | User/Admin | Get primary wallet |
/crypto-wallet/delete | POST | User/Admin | Delete wallet |
/crypto-wallet/networks | GET | User/Admin | Get supported networks |
/disbursement/start | POST | User/Admin | Start manual disbursement |
/conversion/run-daily | POST | Admin | Run daily conversion |
/conversion/execute/:job_id | POST | Admin | Execute specific job |
/conversion/pending | GET | Admin | Get pending conversions |
/conversion/poll-balance | POST | Admin | Run balance polling |
/conversion/poll-job/:job_id | POST | Admin | Poll specific job |
/conversion/run-trades | POST | Admin | Run trade execution |
/conversion/execute-trade/:job_id | POST | Admin | Execute specific trade |
/conversion/status/:job_id | GET | User/Admin | Get job status |
💬 Support & Feedback
For technical support, API issues, or feature requests related to Indodax integration:
- Check the documentation above
- Review error codes and troubleshooting guide
- Contact Anantla technical support
- Report bugs via support channels