Volver al blog

Cómo obtener estadísticas de uso de proxies a través de API: automatización del seguimiento de tráfico

Guía detallada sobre el uso de API de proveedores de proxy para obtener estadísticas de uso: ejemplos de código, métodos de automatización e integración en procesos empresariales.

📅16 de febrero de 2026
```html

Si trabajas con una gran cantidad de proxies — para arbitraje, scraping o multi-cuentas — el control manual del gasto de tráfico se convierte en una pesadilla. La API de los proveedores de proxy permite automatizar la obtención de estadísticas: saldo de tráfico, sesiones activas, consumo por direcciones IP e historial de uso. En esta guía, analizaremos cómo integrar la API para el seguimiento de estadísticas con ejemplos de código en Python, Node.js y cURL.

Por qué es necesaria la automatización de estadísticas de proxy

Cuando gestionas de 10 a 50 proxies para diferentes proyectos, la verificación manual del saldo y el consumo de tráfico a través del panel del proveedor se vuelve ineficaz. La API resuelve varias tareas críticas:

Principales tareas de la API de estadísticas:

  • Monitoreo del saldo de tráfico — notificaciones automáticas al alcanzar el límite
  • Control del consumo por proyectos — distribución de costos entre clientes o tareas
  • Análisis de eficiencia — qué proxies consumen más tráfico y por qué
  • Prevención de inactividad — recarga del saldo antes de que se agote el tráfico
  • Integración en CRM/facturación — contabilización automática de gastos en proxies en procesos de negocio

Para los arbitrajistas que lanzan publicidad a través de múltiples cuentas, es crítico saber qué proxies están activos y cuánto tráfico queda — un bloqueo repentino debido a un límite agotado puede costar miles de dólares en ganancias perdidas. Para las agencias de SMM que gestionan cuentas de clientes en Instagram o TikTok, la automatización permite emitir facturas precisas por el uso de proxies.

Los scrapers de marketplaces (Wildberries, Ozon, Avito) pueden cambiar automáticamente a proxies de respaldo al agotarse el límite en los principales. La API permite construir sistemas tolerantes a fallos que funcionan 24/7 sin intervención manual.

Fundamentos del trabajo con API de proveedores de proxy

La mayoría de los proveedores de proxy modernos ofrecen una API RESTful para gestionar el servicio. La API funciona según un esquema estándar: envías una solicitud HTTP a un endpoint específico con parámetros de autenticación, y el servidor devuelve un JSON con los datos.

Componente de la API Descripción Ejemplo
Base URL Dirección base de la API del proveedor https://api.provider.com/v1
Autenticación Clave API o Bearer Token Authorization: Bearer YOUR_API_KEY
Endpoints Rutas específicas para diferentes operaciones /statistics, /balance
Formato de respuesta Estructura de datos JSON con campos status, data, error
Rate Limits Límite de solicitudes por minuto 60-300 solicitudes/minuto

La estructura típica de la respuesta JSON de la API del proveedor de proxy se ve así:

{
  "status": "success",
  "data": {
    "balance": 1250.50,
    "traffic_used_gb": 45.2,
    "traffic_remaining_gb": 54.8,
    "active_proxies": 15,
    "last_updated": "2024-01-15T10:30:00Z"
  },
  "error": null
}

Al trabajar con la API, es importante tener en cuenta los rate limits (límites en la cantidad de solicitudes). La mayoría de los proveedores permiten de 60 a 300 solicitudes por minuto. Para monitorear estadísticas, esto es más que suficiente — generalmente, las solicitudes se realizan cada 5 a 15 minutos.

Autenticación y obtención de la clave API

El primer paso para trabajar con la API es obtener la clave de autenticación. El proceso varía entre proveedores, pero la lógica general es la misma:

Instrucciones paso a paso para obtener la clave API:

  1. Inicia sesión en el panel del proveedor de proxy
  2. Busca la sección "API" o "Configuraciones" → "Acceso API"
  3. Haz clic en el botón "Crear clave API" o "Generar token"
  4. Copia la clave y guárdala en un lugar seguro (se muestra solo una vez)
  5. Configura la lista blanca de IP, si el proveedor requiere vinculación a direcciones IP
  6. Verifica la clave con una solicitud de prueba a través de cURL o Postman

Existen dos métodos principales de autenticación en las API de proveedores de proxy:

Método Cómo funciona Ejemplo de encabezado
Bearer Token El token se envía en el encabezado Authorization Authorization: Bearer abc123...
Clave API en parámetros La clave se envía como parámetro GET/POST ?api_key=abc123...

Importante: nunca almacenes claves API en el código que se sube a un repositorio de Git. Utiliza variables de entorno (archivos .env) o gestores de secretos (AWS Secrets Manager, HashiCorp Vault). Si la clave se filtra, revócala inmediatamente en el panel y genera una nueva.

Principales endpoints para obtener estadísticas

Aunque cada proveedor tiene su propia estructura de API, la mayoría ofrece un conjunto estándar de endpoints para obtener estadísticas. Veamos los métodos típicos:

Endpoint Método Qué devuelve
/balance GET Saldo actual y saldo de tráfico
/statistics GET Estadísticas generales de uso durante un período
/statistics/proxy/{id} GET Estadísticas de un proxy específico
/sessions/active GET Lista de sesiones activas de proxies
/traffic/history GET Historial de consumo de tráfico por días
/proxies/list GET Lista de todos los proxies con sus estados

Los parámetros de las solicitudes generalmente incluyen rangos de tiempo y filtros:

GET /statistics?from=2024-01-01&to=2024-01-15&proxy_type=residential
GET /traffic/history?period=7d&group_by=day
GET /sessions/active?status=online&country=US

Para trabajar con proxies residenciales, el endpoint para obtener estadísticas de sesiones es especialmente importante, ya que a menudo utilizan rotación de IP. La API permite rastrear cuántas IP únicas se han utilizado durante un período y qué volumen de tráfico ha pasado por cada sesión.

Ejemplos de código en Python para obtener estadísticas

Python es el lenguaje más popular para automatizar el trabajo con proxies gracias a la biblioteca requests. Veamos ejemplos prácticos para obtener estadísticas a través de la API.

Solicitud básica de saldo y tráfico

import requests
import os
from datetime import datetime

# Credenciales de API desde variables de entorno
API_KEY = os.getenv('PROXY_API_KEY')
BASE_URL = 'https://api.proxyprovider.com/v1'

def get_balance_statistics():
    """Obtención de saldo y estadísticas generales"""
    headers = {
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.get(
            f'{BASE_URL}/balance',
            headers=headers,
            timeout=10
        )
        response.raise_for_status()
        
        data = response.json()
        
        print(f"=== Estadísticas de proxy a {datetime.now().strftime('%Y-%m-%d %H:%M')} ===")
        print(f"Saldo: ${data['balance']:.2f}")
        print(f"Tráfico utilizado: {data['traffic_used_gb']:.2f} GB")
        print(f"Saldo de tráfico: {data['traffic_remaining_gb']:.2f} GB")
        print(f"Proxies activos: {data['active_proxies']}")
        
        return data
        
    except requests.exceptions.RequestException as e:
        print(f"Error en la solicitud: {e}")
        return None

# Llamada a la función
stats = get_balance_statistics()

Obtención de estadísticas detalladas por período

from datetime import datetime, timedelta
import requests

def get_traffic_history(days=7):
    """Obtención del historial de consumo de tráfico durante N días"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    # Cálculo del rango temporal
    end_date = datetime.now()
    start_date = end_date - timedelta(days=days)
    
    params = {
        'from': start_date.strftime('%Y-%m-%d'),
        'to': end_date.strftime('%Y-%m-%d'),
        'group_by': 'day'
    }
    
    response = requests.get(
        f'{BASE_URL}/traffic/history',
        headers=headers,
        params=params,
        timeout=10
    )
    
    if response.status_code == 200:
        data = response.json()
        
        print(f"\n=== Consumo de tráfico en los últimos {days} días ===")
        for day in data['daily_stats']:
            print(f"{day['date']}: {day['traffic_gb']:.2f} GB "
                  f"({day['requests']} solicitudes)")
        
        total = sum(day['traffic_gb'] for day in data['daily_stats'])
        print(f"\nTotal durante el período: {total:.2f} GB")
        
        return data
    else:
        print(f"Error {response.status_code}: {response.text}")
        return None

# Obtención de estadísticas durante una semana
history = get_traffic_history(7)

Monitoreo de estadísticas por proxies individuales

def get_proxy_statistics(proxy_id):
    """Obtención de estadísticas de un proxy específico"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    response = requests.get(
        f'{BASE_URL}/statistics/proxy/{proxy_id}',
        headers=headers,
        timeout=10
    )
    
    if response.status_code == 200:
        data = response.json()
        
        print(f"\n=== Estadísticas del proxy {proxy_id} ===")
        print(f"Dirección IP: {data['ip_address']}")
        print(f"País: {data['country']}")
        print(f"Tipo: {data['proxy_type']}")
        print(f"Estado: {data['status']}")
        print(f"Tráfico utilizado: {data['traffic_used_mb']:.2f} MB")
        print(f"Número de solicitudes: {data['total_requests']}")
        print(f"Última actividad: {data['last_activity']}")
        
        return data
    else:
        print(f"Proxy {proxy_id} no encontrado")
        return None

def get_all_proxies_stats():
    """Obtención de estadísticas de todos los proxies"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    # Primero obtenemos la lista de todos los proxies
    response = requests.get(
        f'{BASE_URL}/proxies/list',
        headers=headers,
        timeout=10
    )
    
    if response.status_code == 200:
        proxies = response.json()['proxies']
        
        print(f"\n=== Estadísticas de {len(proxies)} proxies ===\n")
        
        total_traffic = 0
        for proxy in proxies:
            stats = get_proxy_statistics(proxy['id'])
            if stats:
                total_traffic += stats['traffic_used_mb']
        
        print(f"\n=== Consumo total de tráfico: {total_traffic/1024:.2f} GB ===")
        
        return proxies
    else:
        print("Error al obtener la lista de proxies")
        return None

# Obtención de estadísticas de todos los proxies
all_stats = get_all_proxies_stats()

Estos ejemplos muestran el trabajo básico con la API. Para sistemas de producción, agrega manejo de errores, lógica de reintentos en caso de fallos de red y almacenamiento en caché de resultados para no exceder los límites de tasa del proveedor.

Ejemplos de código en Node.js para monitoreo de tráfico

Node.js es excelente para crear microservicios de monitoreo que funcionan en segundo plano y envían notificaciones en eventos críticos. Usamos la biblioteca axios para solicitudes HTTP.

Clase básica para trabajar con la API de proxy

const axios = require('axios');
require('dotenv').config();

class ProxyAPIClient {
  constructor() {
    this.baseURL = 'https://api.proxyprovider.com/v1';
    this.apiKey = process.env.PROXY_API_KEY;
    
    this.client = axios.create({
      baseURL: this.baseURL,
      timeout: 10000,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async getBalance() {
    try {
      const response = await this.client.get('/balance');
      return response.data;
    } catch (error) {
      console.error('Error al obtener el saldo:', error.message);
      throw error;
    }
  }

  async getStatistics(params = {}) {
    try {
      const response = await this.client.get('/statistics', { params });
      return response.data;
    } catch (error) {
      console.error('Error al obtener estadísticas:', error.message);
      throw error;
    }
  }

  async getTrafficHistory(days = 7) {
    const endDate = new Date();
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - days);

    const params = {
      from: startDate.toISOString().split('T')[0],
      to: endDate.toISOString().split('T')[0],
      group_by: 'day'
    };

    try {
      const response = await this.client.get('/traffic/history', { params });
      return response.data;
    } catch (error) {
      console.error('Error al obtener el historial de tráfico:', error.message);
      throw error;
    }
  }

  async getProxyStats(proxyId) {
    try {
      const response = await this.client.get(`/statistics/proxy/${proxyId}`);
      return response.data;
    } catch (error) {
      console.error(`Error al obtener estadísticas del proxy ${proxyId}:`, error.message);
      throw error;
    }
  }
}

module.exports = ProxyAPIClient;

Monitoreo automático con notificaciones

const ProxyAPIClient = require('./ProxyAPIClient');
const nodemailer = require('nodemailer');

class ProxyMonitor {
  constructor(checkIntervalMinutes = 15) {
    this.api = new ProxyAPIClient();
    this.checkInterval = checkIntervalMinutes * 60 * 1000;
    this.thresholds = {
      trafficWarning: 10, // GB - advertencia
      trafficCritical: 5,  // GB - nivel crítico
      balanceWarning: 50   // USD - advertencia de saldo
    };
  }

  async checkAndNotify() {
    try {
      const balance = await this.api.getBalance();
      
      console.log(`[${new Date().toISOString()}] Comprobando estadísticas...`);
      console.log(`Saldo: $${balance.balance.toFixed(2)}`);
      console.log(`Saldo de tráfico: ${balance.traffic_remaining_gb.toFixed(2)} GB`);

      // Comprobación de umbrales críticos
      const alerts = [];

      if (balance.traffic_remaining_gb <= this.thresholds.trafficCritical) {
        alerts.push({
          level: 'critical',
          message: `¡CRÍTICAMENTE POCO TRÁFICO: quedan ${balance.traffic_remaining_gb.toFixed(2)} GB!`
        });
      } else if (balance.traffic_remaining_gb <= this.thresholds.trafficWarning) {
        alerts.push({
          level: 'warning',
          message: `Poco tráfico: quedan ${balance.traffic_remaining_gb.toFixed(2)} GB`
        });
      }

      if (balance.balance <= this.thresholds.balanceWarning) {
        alerts.push({
          level: 'warning',
          message: `Saldo bajo: $${balance.balance.toFixed(2)}`
        });
      }

      // Envío de notificaciones
      if (alerts.length > 0) {
        await this.sendAlerts(alerts, balance);
      }

      return { balance, alerts };
    } catch (error) {
      console.error('Error en el monitoreo:', error);
      await this.sendErrorNotification(error);
    }
  }

  async sendAlerts(alerts, balance) {
    console.log('\n⚠️  ¡ATENCIÓN! Se han detectado problemas:');
    alerts.forEach(alert => {
      console.log(`[${alert.level.toUpperCase()}] ${alert.message}`);
    });

    // Envío de email (configura SMTP)
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
      }
    });

    const emailBody = `
      Se han detectado problemas con los proxies:
      
      ${alerts.map(a => `- ${a.message}`).join('\n')}
      
      Estadísticas actuales:
      - Saldo: $${balance.balance.toFixed(2)}
      - Saldo de tráfico: ${balance.traffic_remaining_gb.toFixed(2)} GB
      - Utilizado: ${balance.traffic_used_gb.toFixed(2)} GB
      - Proxies activos: ${balance.active_proxies}
      
      Se recomienda recargar el saldo o reducir la carga.
    `;

    await transporter.sendMail({
      from: process.env.ALERT_FROM_EMAIL,
      to: process.env.ALERT_TO_EMAIL,
      subject: '⚠️ Advertencia sobre proxies',
      text: emailBody
    });
  }

  start() {
    console.log(`Iniciando monitoreo de proxies (comprobación cada ${this.checkInterval / 60000} minutos)`);
    
    // Primera comprobación de inmediato
    this.checkAndNotify();
    
    // Comprobaciones periódicas
    setInterval(() => {
      this.checkAndNotify();
    }, this.checkInterval);
  }
}

// Iniciar monitoreo
const monitor = new ProxyMonitor(15); // comprobación cada 15 minutos
monitor.start();

Este código crea un servicio en segundo plano que verifica las estadísticas cada 15 minutos y envía notificaciones por email al alcanzar umbrales críticos. Para proxies móviles, que suelen ser más caros que los residenciales, este monitoreo es especialmente importante para controlar gastos.

Ejemplos de solicitudes a través de cURL

cURL es una herramienta universal para probar APIs desde la línea de comandos. Es útil para una rápida verificación de endpoints y depuración de integraciones.

Obtención de saldo

# Solicitud básica de saldo
curl -X GET "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# Con formato JSON bonito (a través de jq)
curl -X GET "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.'

# Extracción de un campo específico
curl -s "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.traffic_remaining_gb'

Obtención de estadísticas por período

# Estadísticas de los últimos 7 días
curl -X GET "https://api.proxyprovider.com/v1/traffic/history?from=2024-01-08&to=2024-01-15&group_by=day" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.daily_stats'

# Estadísticas por tipo de proxy específico
curl -X GET "https://api.proxyprovider.com/v1/statistics?proxy_type=residential&country=US" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.'

Obtención de lista de proxies activos

# Lista de todos los proxies activos
curl -X GET "https://api.proxyprovider.com/v1/proxies/list?status=active" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.proxies[] | {id, ip_address, country, proxy_type}'

# Conteo de la cantidad de proxies activos
curl -s "https://api.proxyprovider.com/v1/proxies/list?status=active" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.proxies | length'

Script Bash para verificación automática

#!/bin/bash

# Configuración
API_KEY="YOUR_API_KEY"
BASE_URL="https://api.proxyprovider.com/v1"
TRAFFIC_THRESHOLD=10  # GB - umbral de advertencia

# Obtención de estadísticas
response=$(curl -s "${BASE_URL}/balance" \
  -H "Authorization: Bearer ${API_KEY}")

# Análisis de JSON
traffic_remaining=$(echo "$response" | jq -r '.traffic_remaining_gb')
balance=$(echo "$response" | jq -r '.balance')
active_proxies=$(echo "$response" | jq -r '.active_proxies')

# Salida de estadísticas
echo "=== Estadísticas de proxy $(date '+%Y-%m-%d %H:%M:%S') ==="
echo "Saldo de tráfico: ${traffic_remaining} GB"
echo "Saldo: \$${balance}"
echo "Proxies activos: ${active_proxies}"

# Comprobación de umbrales
if (( $(echo "$traffic_remaining < $TRAFFIC_THRESHOLD" | bc -l) )); then
  echo "⚠️  ¡ATENCIÓN: Poco tráfico! Quedan ${traffic_remaining} GB"
  
  # Envío de notificación (por ejemplo, a través de Telegram)
  # curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
  #   -d chat_id="${TELEGRAM_CHAT_ID}" \
  #   -d text="⚠️ Poco tráfico en proxy: ${traffic_remaining} GB"
fi

Guarda este script como check_proxy_stats.sh, dale permisos de ejecución (chmod +x check_proxy_stats.sh) y añádelo a cron para que se ejecute automáticamente cada hora:

0 * * * * /path/to/check_proxy_stats.sh >> /var/log/proxy_monitor.log 2>&1

Automatización del monitoreo y notificaciones

La verificación manual de estadísticas es ineficaz — se necesita automatización con notificaciones inteligentes. Consideremos un sistema completo de monitoreo con integraciones.

Integración con Telegram para notificaciones

import requests
import os
from datetime import datetime

class TelegramNotifier:
    def __init__(self):
        self.bot_token = os.getenv('TELEGRAM_BOT_TOKEN')
        self.chat_id = os.getenv('TELEGRAM_CHAT_ID')
        self.base_url = f'https://api.telegram.org/bot{self.bot_token}'
    
    def send_message(self, text, parse_mode='Markdown'):
        """Envía un mensaje a Telegram"""
        url = f'{self.base_url}/sendMessage'
        payload = {
            'chat_id': self.chat_id,
            'text': text,
            'parse_mode': parse_mode
        }
        
        try:
            response = requests.post(url, json=payload, timeout=10)
            return response.status_code == 200
        except Exception as e:
            print(f"Error al enviar a Telegram: {e}")
            return False

def monitor_proxy_with_telegram():
    """Monitoreo con notificaciones en Telegram"""
    api = ProxyAPIClient()
    notifier = TelegramNotifier()
    
    try:
        balance = api.get_balance()
        
        # Formulación del mensaje
        message = f"""
📊 *Estadísticas de proxy* ({datetime.now().strftime('%H:%M %d.%m.%Y')})

💰 Saldo: ${balance['balance']:.2f}
📈 Utilizado: {balance['traffic_used_gb']:.2f} GB
📉 Restante: {balance['traffic_remaining_gb']:.2f} GB
🔌 Proxies activos: {balance['active_proxies']}
        """
        
        # Comprobación de umbrales críticos
        if balance['traffic_remaining_gb'] < 5:
            message += "\n⚠️ *¡CRÍTICAMENTE POCO TRÁFICO!*"
            notifier.send_message(message)
        elif balance['traffic_remaining_gb'] < 10:
            message += "\n⚡ Se recomienda recargar tráfico"
            notifier.send_message(message)
        
        return balance
        
    except Exception as e:
        error_msg = f"❌ *Error en el monitoreo de proxies*\n\n{str(e)}"
        notifier.send_message(error_msg)
        raise

# Iniciar monitoreo
monitor_proxy_with_telegram()

Integración con Slack

import requests
import json

class SlackNotifier:
    def __init__(self, webhook_url):
        self.webhook_url = webhook_url
    
    def send_alert(self, title, message, level='warning'):
        """Envía una notificación a Slack"""
        color = {
            'info': '#36a64f',
            'warning': '#ff9900',
            'critical': '#ff0000'
        }.get(level, '#cccccc')
        
        payload = {
            'attachments': [{
                'color': color,
                'title': title,
                'text': message,
                'footer': 'Monitor de Proxies',
                'ts': int(datetime.now().timestamp())
            }]
        }
        
        try:
            response = requests.post(
                self.webhook_url,
                data=json.dumps(payload),
                headers={'Content-Type': 'application/json'},
                timeout=10
            )
            return response.status_code == 200
        except Exception as e:
            print(f"Error al enviar a Slack: {e}")
            return False

def check_proxy_health():
    """Verificación de salud de proxies con notificaciones"""
    api = ProxyAPIClient()
    slack = SlackNotifier(os.getenv('SLACK_WEBHOOK_URL'))
    
    balance = api.get_balance()
    proxies = api.get_all_proxies()
    
    # Análisis del estado
    offline_proxies = [p for p in proxies if p['status'] != 'active']
    
    if len(offline_proxies) > 0:
        message = f"Se han detectado {len(offline_proxies)} proxies inactivos:\n"
        for proxy in offline_proxies[:5]:  # primeros 5
            message += f"- {proxy['ip_address']} ({proxy['country']})\n"
        
        slack.send_alert(
            'Proxies inactivos',
            message,
            level='warning'
        )
    
    if balance['traffic_remaining_gb'] < 5:
        slack.send_alert(
            '¡Críticamente poco tráfico!',
            f"Quedan {balance['traffic_remaining_gb']:.2f} GB. "
            f"Saldo: ${balance['balance']:.2f}",
            level='critical'
        )

check_proxy_health()

Configuración de recarga automática

Algunos proveedores permiten a través de la API no solo obtener estadísticas, sino también recargar automáticamente el saldo al alcanzar un umbral:

def auto_topup_if_needed(threshold_gb=10, topup_amount_usd=100):
    """Recarga automática al saldo bajo"""
    api = ProxyAPIClient()
    
    balance = api.get_balance()
    
    if balance['traffic_remaining_gb'] < threshold_gb:
        print(f"Tráfico por debajo del umbral ({threshold_gb} GB), iniciando recarga...")
        
        # Solicitud de recarga a través de la API
        topup_response = requests.post(
            f'{api.base_url}/billing/topup',
            headers={'Authorization': f'Bearer {api.api_key}'},
            json={
                'amount': topup_amount_usd,
                'payment_method': 'card',
                'auto_topup': True
            },
            timeout=10
        )
        
        if topup_response.status_code == 200:
            print(f"✅ Saldo recargado en ${topup_amount_usd}")
            
            # Envío de notificación
            notifier = TelegramNotifier()
            notifier.send_message(
                f"💳 Recarga automática\n\n"
                f"Monto: ${topup_amount_usd}\n"
                f"Saldo de tráfico: {balance['traffic_remaining_gb']:.2f} GB\n"
                f"Razón: alcanzado umbral de {threshold_gb} GB"
            )
        else:
            print(f"❌ Error en la recarga: {topup_response.text}")
    else:
        print(f"Tráfico suficiente: {balance['traffic_remaining_gb']:.2f} GB")

# Iniciar verificación (puede añadirse a cron)
auto_topup_if_needed()

Creación de un panel de estadísticas personal

Para visualizar datos de la API, se puede crear un panel web con gráficos de consumo de tráfico, distribución por países y tipos de proxy. Veamos un ejemplo simple en Flask + Chart.js.

Backend en Flask

from flask import Flask, jsonify, render_template
from datetime import datetime, timedelta
import requests

app = Flask(__name__)

class ProxyDashboard:
    def __init__(self):
        self.api_key = os.getenv('PROXY_API_KEY')
        self.base_url = 'https://api.proxyprovider.com/v1'
    
    def get_dashboard_data(self):
        """Obtención de todos los datos para el panel"""
        headers = {'Authorization': f'Bearer {self.api_key}'}
        
        # Saldo y estadísticas generales
        balance = requests.get(
            f'{self.base_url}/balance',
            headers=headers
        ).json()
        
        # Historial de los últimos 30 días
        end_date = datetime.now()
        start_date = end_date - timedelta(days=30)
        
        history = requests.get(
            f'{self.base_url}/traffic/history',
            headers=headers,
            params={
                'from': start_date.strftime('%Y-%m-%d'),
                'to': end_date.strftime('%Y-%m-%d'),
                'group_by': 'day'
            }
        ).json()
        
        # Lista de proxies
        proxies = requests.get(
            f'{self.base_url}/proxies/list',
            headers=headers
        ).json()
        
        # Agregación de datos
        traffic_by_country = {}
        traffic_by_type = {}
        
        for proxy in proxies.get('proxies', []):
            country = proxy.get('country', 'Desconocido')
            proxy_type = proxy.get('proxy_type', 'Desconocido')
            traffic = proxy.get('traffic_used_mb', 0) / 1024  # en GB
            
            traffic_by_country[country] = traffic_by_country.get(country, 0) + traffic
            traffic_by_type[proxy_type] = traffic_by_type.get(proxy_type, 0) + traffic
        
        return {
            'balance': balance,
            'history': history.get('daily_stats', []),
            'traffic_by_country': traffic_by_country,
            'traffic_by_type': traffic_by_type,
            'total_proxies': len(proxies.get('proxies', []))
        }

dashboard = ProxyDashboard()

@app.route('/')
def index():
    """Página principal del panel"""
    return render_template('dashboard.html')

@app.route('/api/stats')
def get_stats():
    """Endpoint API para obtener estadísticas"""
    try:
        data = dashboard.get_dashboard_data()
        return jsonify(data)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True, port=5000)

Frontend con gráficos (dashboard.html)

<!DOCTYPE html>
<html>
<head>
  <title>Panel de Estadísticas de Proxy</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <style>
    body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
    .stats-card { background: white; padding: 20px; margin: 10px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
    .stat-value { font-size: 2rem; font-weight: bold; color: #2563eb; }
    .chart-container { height: 300px; margin: 20px 0; }
  </style>
</head>
<body>
  <h1>📊 Panel de Estadísticas de Proxy</h1>
  
  <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;">
    <div class="stats-card">
      <div>Saldo</div>
      <div class="stat-value" id="balance">-</div>
    </div>
    <div class="stats-card">
      <div>Saldo de tráfico</div>
      <div class="stat-value" id="traffic-remaining">-</div>
    </div>
    <div class="stats-card">
      <div>Utilizado</div>
      <div class="stat-value" id="traffic-used">-</div>
    </div>
    <div class="stats-card">
      <div>Proxies activos</div>
      <div class="stat-value" id="active-proxies">-</div>
    </div>
  </div>

  <div class="chart-container">
    <canvas id="trafficChart"></canvas>
  </div>

  <script>
    const ctx = document.getElementById('trafficChart').getContext('2d');
    const trafficChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: [], // Aquí irán las fechas
        datasets: [{
          label: 'Tráfico utilizado (GB)',
          data: [], // Aquí irán los datos de tráfico
          borderColor: 'rgba(75, 192, 192, 1)',
          borderWidth: 2,
          fill: false
        }]
      },
      options: {
        responsive: true,
        scales: {
          y: {
            beginAtZero: true
          }
        }
      }
    });

    async function fetchData() {
      const response = await fetch('/api/stats');
      const data = await response.json();
      document.getElementById('balance').innerText = data.balance.balance.toFixed(2);
      document.getElementById('traffic-remaining').innerText = data.balance.traffic_remaining_gb.toFixed(2);
      document.getElementById('traffic-used').innerText = data.balance.traffic_used_gb.toFixed(2);
      document.getElementById('active-proxies').innerText = data.balance.active_proxies;

      data.history.forEach(day => {
        trafficChart.data.labels.push(day.date);
        trafficChart.data.datasets[0].data.push(day.traffic_gb);
      });
      trafficChart.update();
    }

    fetchData();
  </script>
</body>
</html>
```