> For the complete documentation index, see [llms.txt](https://dedge-1.gitbook.io/dedge-sol-analyzer/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dedge-1.gitbook.io/dedge-sol-analyzer/api-documentation/readme/wallet-batch-api.md).

# Wallet Batch API

## Overview

The Wallet Batch API provides endpoints for analyzing multiple Solana wallet addresses in batch. It offers a comprehensive analysis of trading performance, including metrics like PnL (Profit and Loss), trading patterns, and fee analysis.

### Key Features

* **Batch Processing**: Analyze up to 5 wallet addresses simultaneously
* **Asynchronous Processing**: Since batch processing can be time-consuming, we use asynchronous processing to prevent delays and ensure that requests are handled correctly, avoiding timeouts.
* **Comprehensive Analysis**: Detailed metrics including:
  * General trading performance
  * Closed trades analysis
  * Fee analysis
  * Trading venue usage
  * Time-based trading patterns

### Available Endpoints

1. **Process Wallet Batch** (`POST /process_wallet_batch`)
   * Initiates analysis for a batch of wallet addresses
   * Returns a task ID for tracking progress
2. **Check Batch Status** (`GET /batch_status/{task_id}`)
   * Retrieves the status and results of a batch processing task
   * Provides detailed analysis results when processing is complete

### Rate Limits

* Maximum 5 wallet addresses per batch request
* Requests limites are based on the API key tier defined below

## Process Wallet Batch

Process multiple wallet addresses in a single batch request.

### Endpoint

`POST /process_wallet_batch`

### Request Body

```json
{
  "wallet_addresses": ["address1", "address2", "address3"]
}
```

### Response

When request is accepted:

```json
{
  "task_id": "uuid-string",
  "message": "Processing started",
  "status_endpoint": "/batch_status/{task_id}"
}
```

## Check Batch Status

Check the status of a batch processing task.

### Endpoint

`GET /batch_status/{task_id}`

### Response

When processing:

```json
{
  "task_id": "uuid-string",
  "status": "processing"
}
```

When complete with some errors:

```json
{
    "task_id": "uuid-string",
    "status": "completed",
    "created_at": "2024-03-21T15:30:00Z",
    "completed_at": "2024-03-21T15:31:00Z",
    "results": [
        {
            "duration": 30,
            "wallet_address": "wallet-address-1",
            "summary": {
                "general_performance": {
                    "first_trade_timestamp": "2024-03-20T10:00:00Z",
                    "last_trade_timestamp": "2024-03-21T15:30:00Z",
                    "tokens_traded": 10,
                    "trades_closed": 8,
                    "trades_open": 2,
                    "total_sol_spent": 50.12345,
                    "total_sol_received": 55.54321,
                    "net_sol": 5.41976
                },
                "closed_trades_overview": {
                    "winners": 6,
                    "losses": 2,
                    "win_rate_percent": 75.0,
                    "average_trade_size_sol": 6.26543,
                    "mean_pnl_sol": 0.67747,
                    "mean_pnl_percent": 10.8234,
                    "std_pnl_sol": 0.32156,
                    "std_pnl_percent": 5.1234,
                    "min_pnl_sol": -1.23456,
                    "min_pnl_percent": -15.6789,
                    "10th_percentile_pnl_sol": -0.54321,
                    "10th_percentile_pnl_percent": -8.7654,
                    "25th_percentile_pnl_sol": 0.12345,
                    "25th_percentile_pnl_percent": 2.3456,
                    "50th_percentile_pnl_sol": 0.65432,
                    "50th_percentile_pnl_percent": 9.8765,
                    "75th_percentile_pnl_sol": 1.23456,
                    "75th_percentile_pnl_percent": 18.7654,
                    "90th_percentile_pnl_sol": 1.87654,
                    "90th_percentile_pnl_percent": 25.4321,
                    "max_pnl_sol": 2.34567,
                    "max_pnl_percent": 35.6789,
                    "total_pnl_sol": 5.41976,
                    "total_pnl_percent": 86.5432
                },
                "fees": {
                    "total_fee_spent_sol": 0.12345,
                    "avg_fee_per_trade_sol": 0.01543
                },
                "wallet": {
                    "wallet": "wallet-address"
                },
                "venues": {
                    "venues_list": "Jupiter, Raydium, Orca"
                },
                "deltas": {
                    "overall_mean_delta": 3600,
                    "average_trades_per_token": 2.5,
                    "overall_min_delta": 300,
                    "10th_percentile": 600,
                    "25th_percentile": 1800,
                    "50th_percentile": 3600,
                    "75th_percentile": 7200,
                    "90th_percentile": 14400,
                    "overall_max_delta": 86400
                }
            }
        },
        {
            "wallet_address": "wallet-address-2",
            "error": "No swaps found"
        }
    ]
}
```

When all wallets fail:

```json
{
    "task_id": "uuid-string",
    "status": "completed",
    "created_at": "2024-03-21T15:30:00Z",
    "completed_at": "2024-03-21T15:31:00Z",
    "results": [
        {
            "wallet_address": "wallet-address-1",
            "error": "No swaps found"
        },
        {
            "wallet_address": "wallet-address-2",
            "error": "Invalid wallet address"
        }
    ]
}
```

When task not found:

```json
{
  "detail": "Task not found"
}
```

### Common Error Messages

| Error Message             | Description                                                |
| ------------------------- | ---------------------------------------------------------- |
| "No swaps found"          | The wallet has no swap transactions in the analyzed period |
| "Invalid wallet address"  | The provided address is not a valid Solana address         |
| "Error processing wallet" | Generic error occurred while processing the wallet         |

### Error Responses

* `400 Bad Request`: When more than 5 wallet addresses are provided

```json
{
  "detail": "Maximum of 5 wallet addresses allowed per batch"
}
```

* `500 Internal Server Error`: When an error occurs during processing

## Summary Fields Documentation

### General Performance

These fields provide an overview of the wallet's trading activity:

| Field                   | Type         | Description                                                       |
| ----------------------- | ------------ | ----------------------------------------------------------------- |
| `first_trade_timestamp` | ISO datetime | Date and time of the wallet's first trade in the analyzed period  |
| `last_trade_timestamp`  | ISO datetime | Date and time of the wallet's most recent trade                   |
| `tokens_traded`         | integer      | Total number of unique tokens traded                              |
| `trades_closed`         | integer      | Number of completed trading positions                             |
| `trades_open`           | integer      | Number of currently open positions                                |
| `total_sol_spent`       | float        | Total amount of SOL used for purchases                            |
| `total_sol_received`    | float        | Total amount of SOL received from sales                           |
| `net_sol`               | float        | Net profit/loss in SOL (total\_sol\_received - total\_sol\_spent) |

### Closed Trades Overview

These fields analyze the performance of completed trades:

| Field                    | Type    | Description                                                        |
| ------------------------ | ------- | ------------------------------------------------------------------ |
| `winners`                | integer | Number of trades that resulted in profit                           |
| `losses`                 | integer | Number of trades that resulted in loss                             |
| `win_rate_percent`       | float   | Percentage of winning trades (winners / (winners + losses) \* 100) |
| `average_trade_size_sol` | float   | Average amount of SOL used per trade                               |
| `mean_pnl_sol`           | float   | Average profit/loss per trade in SOL                               |
| `mean_pnl_percent`       | float   | Average profit/loss per trade as a percentage                      |
| `std_pnl_sol`            | float   | Standard deviation of profit/loss in SOL (volatility measure)      |
| `std_pnl_percent`        | float   | Standard deviation of profit/loss percentage                       |
| `min_pnl_sol`            | float   | Largest loss in SOL                                                |
| `min_pnl_percent`        | float   | Largest loss as a percentage                                       |
| `max_pnl_sol`            | float   | Largest profit in SOL                                              |
| `max_pnl_percent`        | float   | Largest profit as a percentage                                     |
| `total_pnl_sol`          | float   | Total profit/loss in SOL                                           |
| `total_pnl_percent`      | float   | Total profit/loss as a percentage                                  |

#### Percentile Metrics

These fields show the distribution of profits/losses:

| Field                         | Type  | Description                                        |
| ----------------------------- | ----- | -------------------------------------------------- |
| `10th_percentile_pnl_sol`     | float | 10% of trades performed worse than this SOL value  |
| `10th_percentile_pnl_percent` | float | 10% of trades performed worse than this percentage |
| `25th_percentile_pnl_sol`     | float | 25% of trades performed worse than this SOL value  |
| `25th_percentile_pnl_percent` | float | 25% of trades performed worse than this percentage |
| `50th_percentile_pnl_sol`     | float | Median profit/loss in SOL                          |
| `50th_percentile_pnl_percent` | float | Median profit/loss percentage                      |
| `75th_percentile_pnl_sol`     | float | 75% of trades performed worse than this SOL value  |
| `75th_percentile_pnl_percent` | float | 75% of trades performed worse than this percentage |
| `90th_percentile_pnl_sol`     | float | 90% of trades performed worse than this SOL value  |
| `90th_percentile_pnl_percent` | float | 90% of trades performed worse than this percentage |

### Fees

Information about transaction fees:

| Field                   | Type  | Description                                   |
| ----------------------- | ----- | --------------------------------------------- |
| `total_fee_spent_sol`   | float | Total amount spent on transaction fees in SOL |
| `avg_fee_per_trade_sol` | float | Average fee per trade in SOL                  |

### Wallet

Wallet identification:

| Field    | Type   | Description                       |
| -------- | ------ | --------------------------------- |
| `wallet` | string | The wallet address being analyzed |

### Venues

Trading venue information:

| Field         | Type   | Description                                                                     |
| ------------- | ------ | ------------------------------------------------------------------------------- |
| `venues_list` | string | Comma-separated list of trading platforms used (e.g., "Jupiter, Raydium, Orca") |

### Deltas

Time-based analysis of trading patterns:

| Field                      | Type    | Description                                            |
| -------------------------- | ------- | ------------------------------------------------------ |
| `overall_mean_delta`       | integer | Average time between trades in seconds                 |
| `average_trades_per_token` | float   | Average number of trades performed per unique token    |
| `overall_min_delta`        | integer | Shortest time between any two trades in seconds        |
| `overall_max_delta`        | integer | Longest time between any two trades in seconds         |
| `10th_percentile`          | integer | 10% of trade intervals are shorter than this (seconds) |
| `25th_percentile`          | integer | 25% of trade intervals are shorter than this (seconds) |
| `50th_percentile`          | integer | Median time between trades in seconds                  |
| `75th_percentile`          | integer | 75% of trade intervals are shorter than this (seconds) |
| `90th_percentile`          | integer | 90% of trade intervals are shorter than this (seconds) |

**Notes:**

* All SOL values are rounded to 5 decimal places
* Percentages are expressed as floating-point numbers (e.g., 75.0 for 75%)
* Time deltas are in seconds
* Timestamps are in ISO 8601 format
* PnL stands for Profit and Loss

## Example Usage

### Python Example

```python
import requests
import time

# Your API key
API_KEY = "your_api_key_here"

# Headers for authentication
headers = {
    "Content-Type": "application/json",
    "X-API-Key": API_KEY
}

# Start batch processing
batch_request = {
    "wallet_addresses": [
        "wallet1address",
        "wallet2address"
    ]
}

# Make request with API key in headers
response = requests.post(
    "https://api.dedge.pro/process_wallet_batch",
    headers=headers,
    json=batch_request
)
task_id = response.json()["task_id"]

# Poll status until complete
while True:
    status_response = requests.get(
        f"https://api.dedge.pro/batch_status/{task_id}",
        headers=headers
    )
    status_data = status_response.json()
    
    if status_data["status"] == "processing":
        time.sleep(15)  # Wait 15 seconds before checking again
        continue
        
    if status_data["status"] == "completed":
        print("Processing complete!")
        print("Results:", status_data["results"])
        break
        
    if status_data["status"] == "error":
        print("Error occurred:", status_data["error"])
        break

# Handle rate limits and errors
if status_response.status_code == 429:
    print("Rate limit exceeded. Please wait before making more requests.")
elif status_response.status_code == 403:
    print("Invalid API key")
```

### JavaScript/Node.js Example

```javascript
const axios = require('axios');

const API_KEY = 'your_api_key_here';

const headers = {
  'Content-Type': 'application/json',
  'X-API-Key': API_KEY
};

async function analyzeBatch() {
  try {
    // Start batch processing
    const batchResponse = await axios.post('https://api.dedge.pro/process_wallet_batch', {
      wallet_addresses: ['wallet1address', 'wallet2address']
    }, { headers });

    const taskId = batchResponse.data.task_id;

    // Poll status until complete
    while (true) {
      const statusResponse = await axios.get(
        `https://api.dedge.pro/batch_status/${taskId}`,
        { headers }
      );
      
      const statusData = statusResponse.data;
      
      if (statusData.status === 'processing') {
        await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
        continue;
      }
      
      if (statusData.status === 'completed') {
        console.log('Processing complete!');
        console.log('Results:', statusData.results);
        break;
      }
      
      if (statusData.status === 'error') {
        console.error('Error occurred:', statusData.error);
        break;
      }
    }
  } catch (error) {
    if (error.response) {
      if (error.response.status === 429) {
        console.error('Rate limit exceeded. Please wait before making more requests.');
      } else if (error.response.status === 403) {
        console.error('Invalid API key');
      } else {
        console.error('Error:', error.response.data);
      }
    }
  }
}
```

### cURL Example

```bash
# Start batch processing
curl -X POST "https://api.dedge.pro/process_wallet_batch" \
     -H "Content-Type: application/json" \
     -H "X-API-Key: your_api_key_here" \
     -d '{
           "wallet_addresses": [
             "wallet1address",
             "wallet2address"
           ]
         }'

# Check status (replace {task_id} with the actual task ID from the previous response)
curl "https://api.dedge.pro/batch_status/{task_id}" \
     -H "X-API-Key: your_api_key_here"
```

### Rate Limits and API Keys

Different API key tiers have different rate limits:

| Tier      | Rate Limit | Daily Limit |
| --------- | ---------- | ----------- |
| Ultimate  | 5 req/min  | 100/day     |
| Unlimited | 10 req/min | Unlimited   |

When rate limits are exceeded, the API will return a 429 status code with an error message. It's recommended to implement exponential backoff in your client code to handle rate limiting gracefully.

### Error Handling

Common error responses:

```json
// Rate limit exceeded (HTTP 429)
{
  "detail": "Rate limit exceeded. Maximum 300 requests per minute."
}

// Invalid API key (HTTP 403)
{
  "detail": "Invalid API key"
}

// Daily limit exceeded (HTTP 429)
{
  "detail": "Daily limit exceeded. Maximum 10,000 requests per day."
}
```

### Best Practices

1. **Store API Keys Securely**: Never expose your API key in client-side code or public repositories.
2. **Handle Rate Limits**: Implement proper error handling and backoff strategies for rate limits.
3. **Batch Efficiently**: Group wallet addresses into batches of up to 5 to minimize API calls.
4. **Monitor Usage**: Keep track of your API usage to stay within your tier's limits.
5. **Use Async Endpoints**: The batch processing is asynchronous - always check the task status endpoint for results.
