/v1/swarm/logs endpoint provides detailed information about your API usage history, including request timestamps, status codes, and execution details.
Logs are filtered to exclude any entries containing client IP addresses for privacy protection. Access is limited to logs associated with your API key.
Quick Start
- Python
- JavaScript
- cURL
import requests
import json
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("SWARMS_API_KEY")
BASE_URL = "https://api.swarms.world"
headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json"
}
def get_swarm_logs():
"""Get all API request logs"""
response = requests.get(
f"{BASE_URL}/v1/swarm/logs",
headers=headers
)
if response.status_code == 200:
return response.json()
else:
print(f"Error: {response.status_code} - {response.text}")
return None
# Get logs
logs_data = get_swarm_logs()
if logs_data:
print("â
Logs retrieved successfully!")
print(f"Total logs: {len(logs_data.get('logs', []))}")
print(json.dumps(logs_data, indent=2))
const API_KEY = process.env.SWARMS_API_KEY;
const BASE_URL = "https://api.swarms.world";
const headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json"
};
async function getSwarmLogs() {
try {
const response = await fetch(`${BASE_URL}/v1/swarm/logs`, {
method: 'GET',
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("â
Logs retrieved successfully!");
console.log(`Total logs: ${(data.logs || []).length}`);
console.log(JSON.stringify(data, null, 2));
return data;
} catch (error) {
console.error('Error:', error);
return null;
}
}
// Get logs
getSwarmLogs();
# Get API request logs
curl -X GET "https://api.swarms.world/v1/swarm/logs" \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json"
# Example response:
# {
# "status": "success",
# "count": null,
# "logs": [
# {
# "id": 12345,
# "created_at": "2026-07-01T10:30:00+00:00",
# "api_key": "sk-xxxxxxxx",
# "category": "completion",
# "data": {
# "job_id": "agent-abc123",
# "success": true,
# "name": "Research Assistant",
# "usage": {
# "input_tokens": 45,
# "output_tokens": 120,
# "total_tokens": 165,
# "total_cost": 0.002735
# },
# "timestamp": "2026-07-01T10:30:00+00:00"
# }
# }
# ],
# "timestamp": "2026-07-01T12:00:00+00:00"
# }
Understanding Log Response
The logs endpoint returns structured information about your API usage. Each log entry is a stored record with acategory (e.g. completion) and a data payload containing the completion response that was logged:
{
"status": "success",
"count": null,
"logs": [
{
"id": 12345,
"created_at": "2026-07-01T10:30:00+00:00",
"api_key": "sk-xxxxxxxx",
"category": "completion",
"data": {
"job_id": "agent-abc123",
"success": true,
"name": "Research Assistant",
"description": "An agent that researches topics",
"temperature": 0.5,
"outputs": "...",
"usage": {
"input_tokens": 45,
"output_tokens": 120,
"total_tokens": 165,
"img_cost": 0.0,
"total_cost": 0.002735
},
"timestamp": "2026-07-01T10:30:00+00:00"
}
}
],
"timestamp": "2026-07-01T12:00:00+00:00"
}
The top-level
count field is always returned as null â compute the number of entries from len(logs) (or logs.length in JavaScript) instead. The shape of data depends on what was logged: agent completions carry usage.total_cost, while swarm completions carry usage.billing_info.total_cost, swarm_name, and execution_time. Entries containing client IP data, telemetry, and raw request inputs are excluded.Log Analysis and Filtering
- Python
- JavaScript
from datetime import datetime, timedelta, timezone
from collections import Counter
def get_log_usage(log):
"""Extract the usage dict from a log entry's data payload."""
data = log.get('data') or {}
if isinstance(data, dict):
return data.get('usage') or {}
return {}
def get_log_cost(log):
"""Extract total cost from a log entry (agent or swarm completion)."""
usage = get_log_usage(log)
if 'total_cost' in usage:
return usage['total_cost'] or 0
# Swarm completions nest the cost under billing_info
return (usage.get('billing_info') or {}).get('total_cost', 0)
def analyze_logs(logs_data):
"""Analyze API usage logs"""
if not logs_data or not logs_data.get('logs'):
print("No logs available for analysis")
return
logs = logs_data['logs']
# Basic statistics
total_requests = len(logs)
print("đ API Usage Analysis")
print("=" * 50)
print(f"Total Logged Requests: {total_requests}")
print()
# Category usage (e.g. "completion")
category_counts = Counter(log.get('category', 'unknown') for log in logs)
print("đ Category Usage:")
for category, count in category_counts.most_common():
print(f" {category}: {count} requests")
print()
# Cost analysis
total_cost = sum(get_log_cost(log) for log in logs)
total_tokens = sum(get_log_usage(log).get('total_tokens', 0) for log in logs)
print("đ° Cost Analysis:")
print(f" Total Cost: ${total_cost:.4f}")
print(f" Total Tokens: {total_tokens}")
avg_cost = total_cost / total_requests if total_requests else 0
print(f" Average Cost per Request: ${avg_cost:.4f}")
print()
# Execution time analysis (present on swarm completion logs)
execution_times = [
log['data'].get('execution_time')
for log in logs
if isinstance(log.get('data'), dict) and log['data'].get('execution_time')
]
if execution_times:
avg_execution_time = sum(execution_times) / len(execution_times)
max_execution_time = max(execution_times)
min_execution_time = min(execution_times)
print("âąī¸ Execution Time Analysis:")
print(f" Average: {avg_execution_time:.2f}s")
print(f" Max: {max_execution_time:.2f}s")
print(f" Min: {min_execution_time:.2f}s")
def filter_logs_by_date(logs_data, days=7):
"""Filter logs by date range"""
if not logs_data or not logs_data.get('logs'):
return logs_data
cutoff_date = datetime.now(timezone.utc) - timedelta(days=days)
filtered_logs = []
for log in logs_data['logs']:
log_timestamp = datetime.fromisoformat(log['created_at'].replace('Z', '+00:00'))
if log_timestamp >= cutoff_date:
filtered_logs.append(log)
return {
**logs_data,
'logs': filtered_logs,
'count': len(filtered_logs)
}
def filter_logs_by_category(logs_data, categories):
"""Filter logs by category (e.g. ["completion"])"""
if not logs_data or not logs_data.get('logs'):
return logs_data
filtered_logs = [
log for log in logs_data['logs']
if log.get('category') in categories
]
return {
**logs_data,
'logs': filtered_logs,
'count': len(filtered_logs)
}
# Example usage
logs_data = get_swarm_logs()
if logs_data:
# Analyze all logs
analyze_logs(logs_data)
# Filter for last 7 days
recent_logs = filter_logs_by_date(logs_data, days=7)
print(f"\nđ
Recent Logs (7 days): {recent_logs['count']} requests")
# Filter for completions
completion_logs = filter_logs_by_category(logs_data, ["completion"])
print(f"â
Completion Logs: {completion_logs['count']} requests")
function getLogUsage(log) {
const data = log.data || {};
return data.usage || {};
}
function getLogCost(log) {
const usage = getLogUsage(log);
if (usage.total_cost !== undefined) return usage.total_cost || 0;
// Swarm completions nest the cost under billing_info
return (usage.billing_info || {}).total_cost || 0;
}
function analyzeLogs(logsData) {
if (!logsData || !logsData.logs) {
console.log("No logs available for analysis");
return;
}
const logs = logsData.logs;
// Basic statistics
const totalRequests = logs.length;
console.log("đ API Usage Analysis");
console.log("=".repeat(50));
console.log(`Total Logged Requests: ${totalRequests}`);
console.log();
// Category usage (e.g. "completion")
const categoryCounts = {};
logs.forEach(log => {
const category = log.category || 'unknown';
categoryCounts[category] = (categoryCounts[category] || 0) + 1;
});
console.log("đ Category Usage:");
Object.entries(categoryCounts)
.sort(([,a], [,b]) => b - a)
.forEach(([category, count]) => {
console.log(` ${category}: ${count} requests`);
});
console.log();
// Cost analysis
const totalCost = logs.reduce((sum, log) => sum + getLogCost(log), 0);
const totalTokens = logs.reduce((sum, log) => sum + (getLogUsage(log).total_tokens || 0), 0);
console.log("đ° Cost Analysis:");
console.log(` Total Cost: $${totalCost.toFixed(4)}`);
console.log(` Total Tokens: ${totalTokens}`);
console.log(` Avg Cost per Request: $${(totalCost/totalRequests).toFixed(6)}`);
console.log();
}
function filterLogsByDate(logsData, days = 7) {
if (!logsData || !logsData.logs) return logsData;
const cutoffDate = new Date(Date.now() - (days * 24 * 60 * 60 * 1000));
const filteredLogs = logsData.logs.filter(log => {
const logTimestamp = new Date(log.created_at);
return logTimestamp >= cutoffDate;
});
return {
...logsData,
logs: filteredLogs,
count: filteredLogs.length
};
}
function filterLogsByCategory(logsData, categories) {
if (!logsData || !logsData.logs) return logsData;
const filteredLogs = logsData.logs.filter(log =>
categories.includes(log.category)
);
return {
...logsData,
logs: filteredLogs,
count: filteredLogs.length
};
}
// Example usage
getSwarmLogs().then(logsData => {
if (logsData) {
// Analyze all logs
analyzeLogs(logsData);
// Filter for last 7 days
const recentLogs = filterLogsByDate(logsData, 7);
console.log(`\nđ
Recent Logs (7 days): ${recentLogs.count} requests`);
// Filter for completions
const completionLogs = filterLogsByCategory(logsData, ["completion"]);
console.log(`â
Completion Logs: ${completionLogs.count} requests`);
}
});
Log Export and Backup
- Python
- JavaScript
import csv
import json
from datetime import datetime
def export_logs_to_csv(logs_data, filename=None):
"""Export logs to CSV format"""
if not logs_data or not logs_data.get('logs'):
print("No logs to export")
return
if not filename:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"swarm_logs_{timestamp}.csv"
logs = logs_data['logs']
# Define CSV columns
fieldnames = [
'id', 'created_at', 'category',
'job_id', 'name', 'input_tokens', 'output_tokens',
'total_tokens', 'total_cost'
]
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for log in logs:
# Flatten the nested data payload
data = log.get('data') or {}
if not isinstance(data, dict):
data = {}
usage = data.get('usage') or {}
total_cost = usage.get('total_cost')
if total_cost is None:
total_cost = (usage.get('billing_info') or {}).get('total_cost', '')
row = {
'id': log.get('id', ''),
'created_at': log.get('created_at', ''),
'category': log.get('category', ''),
'job_id': data.get('job_id', ''),
'name': data.get('name', data.get('swarm_name', '')),
'input_tokens': usage.get('input_tokens', ''),
'output_tokens': usage.get('output_tokens', ''),
'total_tokens': usage.get('total_tokens', ''),
'total_cost': total_cost
}
writer.writerow(row)
print(f"â
Logs exported to {filename}")
return filename
def export_logs_to_json(logs_data, filename=None):
"""Export logs to JSON format"""
if not logs_data:
print("No logs to export")
return
if not filename:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"swarm_logs_{timestamp}.json"
with open(filename, 'w', encoding='utf-8') as jsonfile:
json.dump(logs_data, jsonfile, indent=2, ensure_ascii=False)
print(f"â
Logs exported to {filename}")
return filename
def create_log_backup(logs_data, compress=True):
"""Create a compressed backup of logs"""
import gzip
if not logs_data:
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"swarm_logs_backup_{timestamp}.json"
if compress:
filename += '.gz'
with gzip.open(filename, 'wt', encoding='utf-8') as f:
json.dump(logs_data, f, indent=2, ensure_ascii=False)
else:
with open(filename, 'w', encoding='utf-8') as f:
json.dump(logs_data, f, indent=2, ensure_ascii=False)
print(f"â
Backup created: {filename}")
return filename
# Example usage
logs_data = get_swarm_logs()
if logs_data:
# Export to different formats
export_logs_to_csv(logs_data)
export_logs_to_json(logs_data)
create_log_backup(logs_data, compress=True)
function exportLogsToCSV(logsData, filename = null) {
if (!logsData || !logsData.logs) {
console.log("No logs to export");
return;
}
if (!filename) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
filename = `swarm_logs_${timestamp}.csv`;
}
const logs = logsData.logs;
const headers = ['id', 'created_at', 'category', 'job_id', 'name', 'input_tokens', 'output_tokens', 'total_tokens', 'total_cost'];
let csvContent = headers.join(',') + '\n';
logs.forEach(log => {
const data = log.data || {};
const usage = data.usage || {};
const totalCost = usage.total_cost !== undefined
? usage.total_cost
: (usage.billing_info || {}).total_cost || '';
const row = [
log.id || '',
log.created_at || '',
log.category || '',
data.job_id || '',
data.name || data.swarm_name || '',
usage.input_tokens || '',
usage.output_tokens || '',
usage.total_tokens || '',
totalCost
];
csvContent += row.map(field => `"${field}"`).join(',') + '\n';
});
// Download CSV (browser environment)
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
console.log(`â
Logs exported to ${filename}`);
return filename;
}
function exportLogsToJSON(logsData, filename = null) {
if (!logsData) {
console.log("No logs to export");
return;
}
if (!filename) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
filename = `swarm_logs_${timestamp}.json`;
}
const jsonContent = JSON.stringify(logsData, null, 2);
// Download JSON (browser environment)
const blob = new Blob([jsonContent], { type: 'application/json;charset=utf-8;' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
console.log(`â
Logs exported to ${filename}`);
return filename;
}
// Example usage
getSwarmLogs().then(logsData => {
if (logsData) {
exportLogsToCSV(logsData);
exportLogsToJSON(logsData);
}
});
Log Monitoring Dashboard
- Python
- JavaScript
import time
from datetime import datetime, timedelta, timezone
class LogMonitor:
def __init__(self, check_interval=300): # 5 minutes default
self.check_interval = check_interval
self.last_log_count = 0
self.cost_accumulator = 0
def monitor_logs(self):
"""Monitor logs continuously"""
print("đ Starting log monitoring... (Press Ctrl+C to stop)")
try:
while True:
logs_data = get_swarm_logs()
if logs_data:
self.analyze_recent_activity(logs_data)
self.check_for_anomalies(logs_data)
time.sleep(self.check_interval)
except KeyboardInterrupt:
print("\nâšī¸ Monitoring stopped")
self.generate_monitoring_report()
def analyze_recent_activity(self, logs_data):
"""Analyze recent API activity"""
if not logs_data.get('logs'):
return
current_count = len(logs_data.get('logs', []))
if self.last_log_count > 0:
new_logs = current_count - self.last_log_count
if new_logs > 0:
print(f"đ {new_logs} new requests in the last {self.check_interval}s")
self.last_log_count = current_count
# Analyze recent logs (last hour)
recent_logs = self.get_recent_logs(logs_data, hours=1)
if recent_logs:
# Cost analysis (uses the get_log_cost helper defined above)
recent_cost = sum(get_log_cost(log) for log in recent_logs)
self.cost_accumulator += recent_cost
print(f"đĩ Recent cost: ${recent_cost:.4f}")
print(f"đĩ Total accumulated cost: ${self.cost_accumulator:.4f}")
def check_for_anomalies(self, logs_data):
"""Check for unusual patterns or anomalies"""
if not logs_data.get('logs'):
return
recent_logs = self.get_recent_logs(logs_data, hours=1)
if recent_logs:
# Check for unusual execution times (swarm completion logs)
execution_times = [
log['data'].get('execution_time')
for log in recent_logs
if isinstance(log.get('data'), dict) and log['data'].get('execution_time')
]
if execution_times:
avg_execution_time = sum(execution_times) / len(execution_times)
if avg_execution_time > 60: # More than 60 seconds average
print(f"đĸ Slow swarm runs detected: {avg_execution_time:.2f}s average")
def get_recent_logs(self, logs_data, hours=1):
"""Get logs from the last N hours"""
if not logs_data.get('logs'):
return []
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=hours)
recent_logs = []
for log in logs_data['logs']:
log_time = datetime.fromisoformat(log['created_at'].replace('Z', '+00:00'))
if log_time >= cutoff_time:
recent_logs.append(log)
return recent_logs
def generate_monitoring_report(self):
"""Generate a final monitoring report"""
print("\nđ Monitoring Report")
print("=" * 50)
print(f"Total Accumulated Cost: ${self.cost_accumulator:.4f}")
print(f"Monitoring Duration: {self.check_interval}s intervals")
# Usage
monitor = LogMonitor(check_interval=300) # Check every 5 minutes
monitor.monitor_logs()
class LogMonitor {
constructor(checkInterval = 300000) { // 5 minutes default
this.checkInterval = checkInterval;
this.lastLogCount = 0;
this.costAccumulator = 0;
this.isMonitoring = false;
}
async startMonitoring() {
console.log("đ Starting log monitoring... (Call stopMonitoring() to stop)");
this.isMonitoring = true;
while (this.isMonitoring) {
try {
const logsData = await getSwarmLogs();
if (logsData) {
await this.analyzeRecentActivity(logsData);
this.checkForAnomalies(logsData);
}
} catch (error) {
console.error("Monitoring error:", error);
}
await new Promise(resolve => setTimeout(resolve, this.checkInterval));
}
}
stopMonitoring() {
this.isMonitoring = false;
console.log("âšī¸ Monitoring stopped");
this.generateMonitoringReport();
}
async analyzeRecentActivity(logsData) {
if (!logsData.logs) return;
const currentCount = (logsData.logs || []).length;
if (this.lastLogCount > 0) {
const newLogs = currentCount - this.lastLogCount;
if (newLogs > 0) {
console.log(`đ ${newLogs} new requests in the last ${this.checkInterval/1000}s`);
}
}
this.lastLogCount = currentCount;
// Analyze recent logs (last hour)
const recentLogs = this.getRecentLogs(logsData, 1);
if (recentLogs.length > 0) {
// Cost analysis (uses the getLogCost helper defined above)
const recentCost = recentLogs.reduce((sum, log) => sum + getLogCost(log), 0);
this.costAccumulator += recentCost;
console.log(`đ° Recent Cost (1h): $${recentCost.toFixed(4)}`);
console.log(`đ° Total Accumulated Cost: $${this.costAccumulator.toFixed(4)}`);
}
}
checkForAnomalies(logsData) {
if (!logsData.logs) return;
const recentLogs = this.getRecentLogs(logsData, 1);
if (recentLogs.length === 0) return;
// Check for unusual execution times (swarm completion logs)
const executionTimes = recentLogs
.map(log => (log.data || {}).execution_time)
.filter(t => t);
if (executionTimes.length > 0) {
const avgExecutionTime = executionTimes.reduce((a, b) => a + b, 0) / executionTimes.length;
if (avgExecutionTime > 60) { // More than 60 seconds average
console.log(`đĸ Slow swarm runs detected: ${avgExecutionTime.toFixed(2)}s average`);
}
}
}
getRecentLogs(logsData, hours = 1) {
if (!logsData.logs) return [];
const cutoffTime = new Date(Date.now() - (hours * 60 * 60 * 1000));
return logsData.logs.filter(log => {
const logTime = new Date(log.created_at);
return logTime >= cutoffTime;
});
}
generateMonitoringReport() {
console.log("\nđ Monitoring Report");
console.log("=".repeat(50));
console.log(`Total Accumulated Cost: $${this.costAccumulator.toFixed(4)}`);
}
}
// Usage
const monitor = new LogMonitor(300000); // Check every 5 minutes
monitor.startMonitoring();
// Stop after 30 minutes
setTimeout(() => {
monitor.stopMonitoring();
}, 30 * 60 * 1000);
Privacy and Security
Data Protection
- IP Address Filtering: All client IP addresses are automatically filtered from logs
- PII Protection: Personal identifiable information is not logged
- Secure Storage: Logs are stored securely with encryption at rest
- Access Control: Only accessible via your API key
Compliance
- GDPR Compliant: Adheres to data protection regulations
- Audit Trail: Maintains complete audit trail of API usage
- Data Retention: Logs retained for compliance and debugging purposes
- Access Logging: All log access is itself logged for security
Best Practices
Log Management
- Regular Monitoring: Check logs regularly for unusual patterns
- Error Analysis: Investigate error spikes promptly
- Cost Tracking: Monitor API costs and optimize usage
- Performance Analysis: Track response times and identify bottlenecks
- Security Monitoring: Watch for unauthorized access attempts
Data Analysis
- Trend Analysis: Identify usage patterns and growth trends
- Error Pattern Recognition: Detect recurring issues
- Cost Optimization: Find opportunities to reduce API costs
- Performance Optimization: Identify slow endpoints and optimize
- Capacity Planning: Plan for future usage growth
Automation
- Alert Setup: Set up alerts for high error rates or costs
- Automated Reports: Generate regular usage reports
- Anomaly Detection: Automatically detect unusual patterns
- Cost Controls: Implement automatic cost limiting
- Performance Monitoring: Continuous performance tracking
Troubleshooting
Common Issues
Empty Logs Response# Check if API key is correct
curl -I "https://api.swarms.world/v1/swarm/logs" \
-H "x-api-key: your-api-key"
- Logs are filtered for privacy (no IP addresses)
- Some requests may not be logged due to high volume
- Check your API key permissions
# Analyze execution time patterns (present on swarm completion logs)
logs_data = get_swarm_logs()
if logs_data:
execution_times = [
log['data']['execution_time']
for log in logs_data['logs']
if isinstance(log.get('data'), dict) and log['data'].get('execution_time')
]
if execution_times:
avg_time = sum(execution_times) / len(execution_times)
print(f"Average execution time: {avg_time:.2f}s")
# Calculate cost per log category (uses the get_log_cost helper defined above)
from collections import defaultdict
category_costs = defaultdict(float)
for log in logs_data['logs']:
category_costs[log.get('category', 'unknown')] += get_log_cost(log)
for category, cost in sorted(category_costs.items(), key=lambda x: x[1], reverse=True):
print(f"{category}: ${cost:.4f}")