# API Examples

This section provides practical examples of using the botserver REST API in various programming languages and scenarios.

## Authentication Examples

### Getting a Session Token

**JavaScript/TypeScript:**
```javascript
// Note: Authentication is handled through Zitadel OAuth flow
// This is a simplified example
async function authenticate() {
  // Redirect to Zitadel login
  window.location.href = '/auth/login';
  
  // After OAuth callback, session token is set
  // Use it for subsequent requests
}
```

**cURL:**
```bash
# Session validation
curl -X GET http://localhost:8080/auth/validate \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"
```

## Group Management Examples

### Creating a Group

**JavaScript:**
```javascript
async function createGroup() {
  const response = await fetch('/api/groups/create', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_TOKEN'
    },
    body: JSON.stringify({
      name: 'Engineering Team',
      description: 'Software developers'
    })
  });
  
  const group = await response.json();
  console.log('Created group:', group);
}
```

**Python:**
```python
import requests

def create_group():
    url = "http://localhost:8080/api/groups/create"
    headers = {
        "Authorization": "Bearer YOUR_TOKEN",
        "Content-Type": "application/json"
    }
    data = {
        "name": "Engineering Team",
        "description": "Software developers"
    }
    
    response = requests.post(url, json=data, headers=headers)
    return response.json()
```

### Adding Group Members

**JavaScript:**
```javascript
async function addMember(groupId, userId) {
  const response = await fetch(`/api/groups/${groupId}/members/add`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_TOKEN'
    },
    body: JSON.stringify({
      user_id: userId,
      role: 'member'
    })
  });
  
  return response.json();
}
```

## Admin API Examples

### Getting System Status

**cURL:**
```bash
curl -X GET http://localhost:8080/api/admin/system/status \
  -H "Authorization: Bearer ADMIN_TOKEN"
```

**Go:**
```go
package main

import (
    "net/http"
    "io/ioutil"
    "fmt"
)

func getSystemStatus(token string) {
    client := &http.Client{}
    req, _ := http.NewRequest("GET", 
        "http://localhost:8080/api/admin/system/status", nil)
    req.Header.Add("Authorization", "Bearer " + token)
    
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
```

### Creating a Backup

**JavaScript:**
```javascript
async function createBackup() {
  const response = await fetch('/api/admin/backup/create', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ADMIN_TOKEN'
    },
    body: JSON.stringify({
      backup_type: 'full',
      include_data: true,
      include_config: true
    })
  });
  
  const backup = await response.json();
  console.log('Backup created:', backup.id);
  console.log('Download URL:', backup.download_url);
}
```

## WebSocket Communication

### Real-Time Chat

**JavaScript:**
```javascript
class BotChat {
  constructor(sessionId) {
    this.sessionId = sessionId;
    this.ws = null;
  }
  
  connect() {
    this.ws = new WebSocket('ws://localhost:8080/ws');
    
    this.ws.onopen = () => {
      console.log('Connected to bot');
    };
    
    this.ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      this.handleMessage(message);
    };
    
    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
  }
  
  sendMessage(content) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({
        type: 'message',
        content: content,
        session_id: this.sessionId
      }));
    }
  }
  
  handleMessage(message) {
    console.log('Bot response:', message.content);
    
    if (message.suggestions) {
      console.log('Suggestions:', message.suggestions);
    }
  }
}

// Usage
const chat = new BotChat('session-123');
chat.connect();
chat.sendMessage('Hello bot!');
```

## Error Handling

### Handling API Errors

**JavaScript:**
```javascript
async function apiCall(url, options = {}) {
  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json',
        ...options.headers
      }
    });
    
    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message || `HTTP ${response.status}`);
    }
    
    return await response.json();
  } catch (error) {
    console.error('API Error:', error);
    
    // Handle specific error codes
    if (error.code === 'RATE_LIMITED') {
      // Wait and retry
      await new Promise(resolve => setTimeout(resolve, 1000));
      return apiCall(url, options);
    }
    
    throw error;
  }
}
```

### Rate Limit Handling

**Python:**
```python
import time
import requests

class APIClient:
    def __init__(self, base_url, token):
        self.base_url = base_url
        self.headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }
    
    def request(self, method, endpoint, **kwargs):
        url = f"{self.base_url}{endpoint}"
        
        response = requests.request(
            method, url, 
            headers=self.headers, 
            **kwargs
        )
        
        # Check rate limit headers
        remaining = response.headers.get('X-RateLimit-Remaining')
        if remaining and int(remaining) < 10:
            reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
            sleep_time = max(reset_time - time.time(), 0)
            print(f"Rate limit approaching, sleeping {sleep_time}s")
            time.sleep(sleep_time)
        
        response.raise_for_status()
        return response.json()
```

## Pagination Examples

### Iterating Through Paginated Results

**JavaScript:**
```javascript
async function* getAllGroups(token) {
  let offset = 0;
  const limit = 20;
  
  while (true) {
    const response = await fetch(
      `/api/groups/list?limit=${limit}&offset=${offset}`,
      {
        headers: { 'Authorization': `Bearer ${token}` }
      }
    );
    
    const data = await response.json();
    
    for (const group of data.groups) {
      yield group;
    }
    
    if (data.groups.length < limit) {
      break;  // No more pages
    }
    
    offset += limit;
  }
}

// Usage
for await (const group of getAllGroups(token)) {
  console.log(group.name);
}
```

## Integration Patterns

### Webhook Handler

**Node.js/Express:**
```javascript
const express = require('express');
const app = express();

app.post('/webhook/botserver', express.json(), (req, res) => {
  const event = req.body;
  
  switch(event.type) {
    case 'user.created':
      handleUserCreated(event.data);
      break;
    case 'conversation.completed':
      handleConversationCompleted(event.data);
      break;
    default:
      console.log('Unknown event type:', event.type);
  }
  
  res.status(200).send('OK');
});

function handleUserCreated(userData) {
  console.log('New user:', userData);
  // Process new user
}

function handleConversationCompleted(conversationData) {
  console.log('Conversation completed:', conversationData);
  // Process completed conversation
}
```

## Best Practices

1. **Always handle errors gracefully** - Network failures happen
2. **Respect rate limits** - Implement exponential backoff
3. **Use environment variables** for API tokens
4. **Log API interactions** for debugging
5. **Cache responses** when appropriate
6. **Use connection pooling** for multiple requests
7. **Implement timeout handling** for long operations

## Testing API Calls

### Using Postman

1. Import the API collection (when available)
2. Set environment variables for:
   - `base_url`: http://localhost:8080
   - `token`: Your session token
3. Run requests individually or as collection

### Unit Testing API Calls

**JavaScript/Jest:**
```javascript
describe('Groups API', () => {
  test('should create a group', async () => {
    const mockFetch = jest.fn(() =>
      Promise.resolve({
        ok: true,
        json: () => Promise.resolve({ 
          id: 'group-123', 
          name: 'Test Group' 
        })
      })
    );
    global.fetch = mockFetch;
    
    const result = await createGroup('Test Group');
    
    expect(mockFetch).toHaveBeenCalledWith(
      '/api/groups/create',
      expect.objectContaining({
        method: 'POST'
      })
    );
    expect(result.id).toBe('group-123');
  });
});
```

## Summary

These examples demonstrate common patterns for interacting with the botserver API. Remember to:
- Handle authentication properly through Zitadel
- Check response status codes
- Parse error responses
- Implement proper error handling
- Use appropriate HTTP methods
- Follow REST conventions

For more specific endpoint documentation, refer to the individual API sections in this chapter.