# Agents Portal - API Documentation

## Welcome to Claw Ecosystem API

The Claw Ecosystem provides agent-first APIs optimized for AI agents to discover, compare, and select OpenClaw variants. All endpoints return structured data with Schema.org compliance.

---

## Quick Start

### Base URL
```
https://claw-news.com/api
```

### Authentication
No authentication required for read endpoints.

### Rate Limits
- 100 requests/minute per IP
- Burst: 10 requests/second

---

## Endpoints

### 1. Get All Variants

**GET** `/api/claws`

Returns all Claw variants with full metadata.

**Response:**
```json
[
  {
    "id": 1,
    "slug": "openclaw",
    "name": "OpenClaw",
    "developer": "Peter Steinberger (Community)",
    "language": "TypeScript / Node.js",
    "positioning": "Original Framework",
    "description": "The open-source AI agent that became fastest-growing software ever...",
    "key_advantages": "328K+ stars, 64K+ forks, MIT license",
    "memory_footprint": "~1-2 GB",
    "binary_size": "~150 MB",
    "homepage": "https://openclaw.ai",
    "github": "https://github.com/psteinberger/openclaw",
    "category": "official",
    "added_at": "2026-03-17"
  }
]
```

**Agent Example (Python):**
```python
import requests

response = requests.get("https://claw-news.com/api/claws")
variants = response.json()

# Filter by category
chinese_variants = [v for v in variants if v['category'] == 'chinese-enterprise']
print(f"Found {len(chinese_variants)} Chinese variants")
```

---

### 2. Structured Data (Schema.org)

**GET** `/api/claws/structured`

Returns Schema.org compliant data optimized for AI agents.

**Response Format:**
```json
{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "SoftwareApplication",
      "name": "OpenClaw",
      "description": "...",
      "applicationCategory": "AI Agent",
      "operatingSystem": "Cross-platform",
      "offers": {
        "@type": "Offer",
        "price": "0",
        "priceCurrency": "USD"
      },
      "url": "https://openclaw.ai"
    }
  ]
}
```

**Usage:** SEO, AI agent discovery, structured data indexing

---

### 3. Semantic Search

**GET** `/api/claws/search?q=<query>`

Semantic search across name, description, developer, and positioning.

**Parameters:**
- `q` (required): Search query string

**Example:**
```bash
curl "https://claw-news.com/api/claws/search?q=low+memory+lightweight"
```

**Response:**
```json
{
  "query": "low memory lightweight",
  "results": [
    {
      "name": "ZeroClaw",
      "relevance_score": 0.95,
      "match_fields": ["description", "positioning"],
      "description": "Ultra-minimal OpenClaw fork..."
    },
    {
      "name": "PicoClaw",
      "relevance_score": 0.88,
      "match_fields": ["description"],
      "description": "Edge/IoT optimized..."
    }
  ],
  "total": 2,
  "search_time_ms": 12
}
```

**Agent Example (JavaScript):**
```javascript
async function findLowMemoryVariants() {
  const response = await fetch('https://claw-news.com/api/claws/search?q=lightweight+minimal');
  const data = await response.json();
  
  return data.results
    .filter(r => r.relevance_score > 0.8)
    .map(r => r.name);
}
```

---

### 4. Compare Variants

**GET** `/api/claws/compare?slugs=<slug1,slug2,...>`

Side-by-side comparison of specified variants.

**Parameters:**
- `slugs` (required): Comma-separated variant slugs

**Example:**
```bash
curl "https://claw-news.com/api/claws/compare?slugs=openclaw,nemoclaw,zeroclaw"
```

**Response:**
```json
{
  "comparison": [
    {
      "slug": "openclaw",
      "name": "OpenClaw",
      "category": "official",
      "memory_footprint": "~1-2 GB",
      "binary_size": "~150 MB",
      "developer": "Community",
      "positioning": "Original Framework"
    },
    {
      "slug": "nemoclaw",
      "name": "NemoClaw",
      "category": "enterprise",
      "memory_footprint": "~800 MB",
      "binary_size": "~120 MB",
      "developer": "Nvidia",
      "positioning": "Enterprise Platform"
    }
  ],
  "metrics": {
    "lowest_memory": "ZeroClaw (~200 MB)",
    "smallest_binary": "ZeroClaw (~15 MB)",
    "most_stars": "OpenClaw (328K+)"
  }
}
```

---

### 5. Ecosystem Statistics

**GET** `/api/ecosystem/stats`

Real-time ecosystem metrics.

**Response:**
```json
{
  "total_variants": 18,
  "categories": {
    "official": 2,
    "enterprise": 4,
    "chinese-enterprise": 8,
    "community": 4
  },
  "total_github_stars": 485000,
  "average_memory": "~1.2 GB",
  "lightest_variant": {
    "name": "ZeroClaw",
    "memory": "~200 MB",
    "binary": "~15 MB"
  },
  "heaviest_variant": {
    "name": "SuperAGI",
    "memory": "~4 GB"
  },
  "last_updated": "2026-03-22T15:56:00Z"
}
```

---

### 6. Analytics

**GET** `/api/analytics`

Traffic analytics (agent vs human).

**Response:**
```json
{
  "uptime_seconds": 86400,
  "total_requests": 15234,
  "agent_requests": 3812,
  "human_requests": 11422,
  "agent_percentage": 25.0,
  "top_endpoints": [
    {"path": "/api/claws", "count": 5000},
    {"path": "/api/claws/structured", "count": 2500}
  ]
}
```

---

## Agent Integration Patterns

### Pattern 1: Variant Selection Based on Constraints

```python
def select_best_variant(constraints):
    """
    Select optimal variant based on user constraints
    
    Args:
        constraints: dict with keys like 'max_memory', 'category', 'features'
    
    Returns:
        Best matching variant
    """
    import requests
    
    # Get all variants
    response = requests.get("https://claw-news.com/api/claws")
    variants = response.json()
    
    # Filter by category if specified
    if 'category' in constraints:
        variants = [v for v in variants if v.get('category') == constraints['category']]
    
    # Filter by memory constraint
    if 'max_memory' in constraints:
        # Parse memory values (simplified)
        max_mb = int(constraints['max_memory'].replace('MB', '').replace('~', ''))
        variants = [v for v in variants if 
                   int(v.get('memory_footprint', '9999').replace('MB', '')) <= max_mb]
    
    # Return best match (lowest memory)
    if variants:
        return min(variants, key=lambda v: int(v.get('memory_footprint', '9999').replace('MB', '')))
    
    return None
```

### Pattern 2: Multi-Agent Ecosystem Analysis

```javascript
class ClawsAnalyzer {
  constructor() {
    this.baseURL = 'https://claw-news.com/api';
  }
  
  async analyzeEcosystem() {
    // Fetch ecosystem stats
    const stats = await (await fetch(`${this.baseURL}/ecosystem/stats`)).json();
    
    // Fetch all variants
    const variants = await (await fetch(`${this.baseURL}/claws`)).json();
    
    // Analyze by category
    const analysis = {
      total: stats.total_variants,
      byCategory: stats.categories,
      recommendations: this.generateRecommendations(variants)
    };
    
    return analysis;
  }
  
  generateRecommendations(variants) {
    return {
      'for beginners': variants
        .filter(v => v.category === 'community')
        .sort((a, b) => a.memory_footprint.localeCompare(b.memory_footprint))[0],
      
      'for enterprise': variants
        .filter(v => v.category === 'enterprise' || v.category === 'chinese-enterprise')
        .find(v => v.name.includes('Nemo') || v.name.includes('Ark')),
      
      'minimal resource': variants
        .sort((a, b) => parseInt(a.memory_footprint) - parseInt(b.memory_footprint))[0]
    };
  }
}
```

### Pattern 3: Auto-Discovery for Tool Selection

```python
from typing import List, Dict
import requests

class ClawsToolSelector:
    """Auto-discovers optimal Claw variant for given task"""
    
    def __init__(self):
        self.api_base = "https://claw-news.com/api"
        self.cache = {}
    
    def find_for_task(self, task_requirements: Dict) -> List[Dict]:
        """
        Find variants matching task requirements
        
        Requirements:
        - max_memory: Optional memory constraint
        - features: List of required features
        - category: Optional category filter
        - must_have_homepage: Boolean
        """
        # Get variants from cache or API
        variants = self._get_variants()
        
        # Filter by category
        if 'category' in task_requirements:
            variants = [v for v in variants if v.get('category') == task_requirements['category']]
        
        # Filter by memory
        if 'max_memory' in task_requirements:
            max_mb = self._parse_memory(task_requirements['max_memory'])
            variants = [v for v in variants if self._parse_memory(v.get('memory_footprint', '9999MB')) <= max_mb]
        
        # Filter by features in description
        if 'features' in task_requirements:
            for feature in task_requirements['features']:
                variants = [v for v in variants if feature.lower() in v.get('description', '').lower()]
        
        # Filter by homepage availability
        if task_requirements.get('must_have_homepage'):
            variants = [v for v in variants if v.get('homepage')]
        
        # Sort by memory efficiency
        return sorted(variants, key=lambda v: self._parse_memory(v.get('memory_footprint', '9999MB')))
    
    def _get_variants(self):
        if not self.cache:
            response = requests.get(f"{self.api_base}/claws")
            self.cache = response.json()
        return self.cache
    
    def _parse_memory(self, memory_str: str) -> int:
        """Parse memory string to MB integer"""
        try:
            return int(memory_str.replace('MB', '').replace('~', '').strip())
        except:
            return 9999
```

---

## Error Handling

### Common Errors

| Status Code | Error | Solution |
|-------------|-------|----------|
| 400 | Bad Request | Check query parameters |
| 404 | Not Found | Verify slug names |
| 429 | Rate Limited | Wait 60 seconds |
| 500 | Server Error | Check server status |

### Error Response Format

```json
{
  "error": "variant_not_found",
  "message": "Variant with slug 'xyz' not found",
  "available_slugs": ["openclaw", "nanoclaw", "zeroclaw"]
}
```

---

## Best Practices

### 1. Cache Responses
```python
# Cache for 5 minutes to reduce API load
import time

def cached_fetch(endpoint, cache_duration=300):
    cache_key = endpoint
    if cache_key in cache and time.time() - cache[cache_key]['time'] < cache_duration:
        return cache[cache_key]['data']
    
    response = requests.get(f"{BASE_URL}{endpoint}")
    cache[cache_key] = {'data': response.json(), 'time': time.time()}
    return response.json()
```

### 2. Handle Null Fields
```javascript
// Safe field access
const memory = variant.memory_footprint || 'N/A';
const homepage = variant.homepage || '#';
```

### 3. Respect Rate Limits
```python
import time

def rate_limited_fetch(url, max_requests=100, period=60):
    """Fetch with rate limiting"""
    response = requests.get(url)
    time.sleep(period / max_requests)  # Pace requests
    return response.json()
```

---

## Testing Your Integration

### Quick Test
```bash
# Test connectivity
curl https://claw-news.com/api/claws | jq '.[0].name'

# Test search
curl "https://claw-news.com/api/claws/search?q=lightweight" | jq '.results | length'

# Test comparison
curl "https://claw-news.com/api/claws/compare?slugs=openclaw,nemoclaw" | jq '.comparison | length'

# Get stats
curl https://claw-news.com/api/ecosystem/stats | jq '.total_variants'
```

---

## Support & Feedback

- **Documentation**: https://claw-news.com/agents/
- **API Status**: https://claw-news.com/api/analytics
- **GitHub Issues**: https://github.com/claw-news/ecosystem/issues
- **Telegram**: @Claw-news group

---

*Last updated: 2026-03-22*  
*API Version: 1.0*
