> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withperf.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Logs

# Logs API Reference

The Logs API provides access to call history for debugging and analysis.

> **Note**: Response schemas shown are illustrative. Actual responses may vary.

## Authentication

Requires API key authentication:

```
Authorization: Bearer YOUR_API_KEY
```

## Endpoints

| Endpoint                                 | Description                    |
| ---------------------------------------- | ------------------------------ |
| [GET /v1/logs](#list-logs)               | Retrieve paginated call logs   |
| [GET /v1/logs/summary](#logs-summary)    | Get summary statistics         |
| [GET /v1/logs/:call\_id](#get-log-by-id) | Retrieve specific call details |

***

## List Logs

Retrieve paginated call logs with filtering and sorting options.

### Endpoint

```
GET https://api.withperf.pro/v1/logs
```

### Query Parameters

| Parameter      | Type    | Default     | Description                                          |
| -------------- | ------- | ----------- | ---------------------------------------------------- |
| `limit`        | number  | `50`        | Number of logs to return (1-1000)                    |
| `offset`       | number  | `0`         | Number of logs to skip for pagination                |
| `start_date`   | string  | `-7 days`   | ISO 8601 start date                                  |
| `end_date`     | string  | `now`       | ISO 8601 end date                                    |
| `task_type`    | string  | `null`      | Filter by task type                                  |
| `model`        | string  | `null`      | Filter by model used                                 |
| `min_cost`     | number  | `null`      | Minimum cost in USD                                  |
| `max_cost`     | number  | `null`      | Maximum cost in USD                                  |
| `success_only` | boolean | `false`     | Only show successful calls                           |
| `failed_only`  | boolean | `false`     | Only show failed calls                               |
| `sort_by`      | string  | `timestamp` | Sort field: `timestamp`, `cost`, `latency`, `tokens` |
| `sort_order`   | string  | `desc`      | Sort order: `asc` or `desc`                          |

### Example Request

```bash theme={null}
curl "https://api.withperf.pro/v1/logs?limit=10&task_type=extraction&sort_by=cost&sort_order=desc" \
  -H "Authorization: Bearer pk_live_abc123"
```

### Response

```json theme={null}
{
  "total": 12456,
  "limit": 10,
  "offset": 0,
  "logs": [
    {
      "call_id": "call_abc123xyz",
      "timestamp": "2024-01-30T14:32:15.234Z",
      "prompt": {
        "text": "Extract name, email, phone from: John Doe...",
        "hash": "a1b2c3d4e5f6",
        "length": 147
      },
      "classification": {
        "task_type": "extraction",
        "complexity_score": 0.34,
        "confidence": 0.92
      },
      "routing": {
        "model_selected": "gpt-4o-mini",
        "fallback_model": "claude-haiku-4-5",
        "routing_reason": "Optimal for structured data extraction",
        "provider": "openai"
      },
      "execution": {
        "latency_ms": 567,
        "input_tokens": 47,
        "output_tokens": 28,
        "total_tokens": 75,
        "cost_usd": 0.00023,
        "started_at": "2024-01-30T14:32:15.234Z",
        "completed_at": "2024-01-30T14:32:15.801Z"
      },
      "quality": {
        "validation_passed": true,
        "retry_count": 0,
        "fallback_used": false,
        "cost_warning_triggered": false,
        "output_quality_score": 0.94
      },
      "output": {
        "text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\",\"phone\":\"555-1234\"}",
        "length": 67,
        "format_valid": true
      },
      "metadata": {
        "user_id": "user_789",
        "session_id": "sess_xyz",
        "api_key_hash": "hash_abc",
        "custom": {
          "feature": "contact_extraction",
          "version": "v2"
        }
      }
    }
  ],
  "pagination": {
    "has_more": true,
    "next_offset": 10
  }
}
```

***

## Logs Summary

Get aggregated statistics for your logs.

### Endpoint

```
GET https://api.withperf.pro/v1/logs/summary
```

### Query Parameters

| Parameter    | Type   | Default   | Description         |
| ------------ | ------ | --------- | ------------------- |
| `start_date` | string | `-7 days` | ISO 8601 start date |
| `end_date`   | string | `now`     | ISO 8601 end date   |

### Example Request

```bash theme={null}
curl "https://api.withperf.pro/v1/logs/summary" \
  -H "Authorization: Bearer pk_live_abc123"
```

### Response

```json theme={null}
{
  "period": {
    "start_date": "2024-01-24T00:00:00Z",
    "end_date": "2024-01-30T23:59:59Z",
    "days": 7
  },
  "summary": {
    "total_calls": 8234,
    "successful_calls": 8121,
    "failed_calls": 113,
    "success_rate": 0.986,
    "total_cost_usd": 42.34,
    "avg_cost_per_call": 0.00514,
    "total_tokens": 1234567,
    "avg_latency_ms": 1245
  },
  "by_model": {
    "gpt-4o-mini": {
      "calls": 4234,
      "percentage": 0.514,
      "total_cost_usd": 9.87,
      "avg_latency_ms": 834
    },
    "claude-sonnet-4-5": {
      "calls": 3456,
      "percentage": 0.420,
      "total_cost_usd": 28.93,
      "avg_latency_ms": 1456
    },
    "gpt-4o": {
      "calls": 544,
      "percentage": 0.066,
      "total_cost_usd": 3.54,
      "avg_latency_ms": 1876
    }
  },
  "by_task_type": {
    "extraction": 2801,
    "classification": 1893,
    "summarization": 1483,
    "reasoning": 988,
    "code": 658,
    "writing": 411
  },
  "quality_metrics": {
    "avg_quality_score": 0.92,
    "validation_pass_rate": 0.987,
    "retry_rate": 0.023,
    "fallback_rate": 0.034
  }
}
```

***

## Get Log by ID

Retrieve detailed information for a specific call.

### Endpoint

```
GET https://api.withperf.pro/v1/logs/:call_id
```

### Example Request

```bash theme={null}
curl https://api.withperf.pro/v1/logs/call_abc123xyz \
  -H "Authorization: Bearer pk_live_abc123"
```

### Response

```json theme={null}
{
  "call_id": "call_abc123xyz",
  "timestamp": "2024-01-30T14:32:15.234Z",
  "prompt": {
    "text": "Extract structured data from the following text...",
    "hash": "a1b2c3d4e5f6",
    "embedding": [0.123, -0.456, 0.789, ...],
    "length": 247,
    "message_count": 1
  },
  "classification": {
    "task_type": "extraction",
    "complexity_score": 0.34,
    "confidence": 0.92,
    "detected_format": "json"
  },
  "routing": {
    "model_selected": "gpt-4o-mini",
    "fallback_model": "claude-haiku-4-5",
    "routing_reason": "Optimal cost/quality for structured extraction",
    "provider": "openai",
    "decision_factors": {
      "task_match": 0.92,
      "cost_efficiency": 0.87,
      "historical_performance": 0.89
    }
  },
  "execution": {
    "latency_ms": 567,
    "input_tokens": 47,
    "output_tokens": 28,
    "total_tokens": 75,
    "cost_usd": 0.00023,
    "started_at": "2024-01-30T14:32:15.234Z",
    "completed_at": "2024-01-30T14:32:15.801Z",
    "attempts": [
      {
        "attempt_number": 1,
        "model": "gpt-4o-mini",
        "success": true,
        "latency_ms": 567,
        "cost_usd": 0.00023
      }
    ]
  },
  "quality": {
    "validation_passed": true,
    "retry_count": 0,
    "fallback_used": false,
    "cost_warning_triggered": false,
    "output_quality_score": 0.94,
    "validation_checks": {
      "format_valid": true,
      "no_refusal": true,
      "no_disclaimer": true,
      "completeness": true
    }
  },
  "output": {
    "text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\",\"phone\":\"555-1234\"}",
    "length": 67,
    "format_valid": true,
    "parsed_json": {
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "555-1234"
    }
  },
  "context": {
    "provider_health": {
      "openai": {
        "error_rate": 0.002,
        "avg_latency_ms": 1234,
        "status": "healthy"
      }
    },
    "budget": {
      "max_cost_per_call": 0.01,
      "cost_warning_threshold": 0.008
    }
  },
  "metadata": {
    "user_id": "user_789",
    "session_id": "sess_xyz",
    "api_key_hash": "hash_abc",
    "request_ip": "203.0.113.42",
    "user_agent": "Mozilla/5.0...",
    "custom": {
      "feature": "contact_extraction",
      "version": "v2",
      "experiment_id": "exp_123"
    }
  },
  "shadow_call": {
    "executed": true,
    "shadow_model": "claude-haiku-4-5",
    "shadow_cost_usd": 0.00019,
    "shadow_latency_ms": 423,
    "quality_comparison": {
      "primary_score": 0.94,
      "shadow_score": 0.96,
      "optimal_choice": "shadow"
    }
  }
}
```

***

## Use Cases

### Debugging Failed Calls

```python theme={null}
# Find all failed calls
response = requests.get(
    "https://api.withperf.pro/v1/logs?failed_only=true&limit=100",
    headers={"Authorization": f"Bearer {API_KEY}"}
)

logs = response.json()['logs']

for log in logs:
    print(f"Failed call: {log['call_id']}")
    print(f"  Task: {log['classification']['task_type']}")
    print(f"  Model: {log['routing']['model_selected']}")
    print(f"  Retries: {log['quality']['retry_count']}")
    print(f"  Fallback used: {log['quality']['fallback_used']}")
```

### Cost Analysis

```python theme={null}
# Find expensive calls
response = requests.get(
    "https://api.withperf.pro/v1/logs?min_cost=0.01&sort_by=cost&sort_order=desc&limit=50",
    headers={"Authorization": f"Bearer {API_KEY}"}
)

for log in response.json()['logs']:
    print(f"${log['execution']['cost_usd']:.4f} - {log['prompt']['text'][:50]}...")
```

### Quality Monitoring

```python theme={null}
# Find calls that required retries
response = requests.get(
    "https://api.withperf.pro/v1/logs?limit=1000",
    headers={"Authorization": f"Bearer {API_KEY}"}
)

retry_calls = [
    log for log in response.json()['logs']
    if log['quality']['retry_count'] > 0
]

print(f"Retry rate: {len(retry_calls) / len(response.json()['logs']):.1%}")
```

### Export for Analysis

```python theme={null}
import csv
from datetime import datetime, timedelta

# Export last 30 days to CSV
start_date = (datetime.now() - timedelta(days=30)).isoformat()
all_logs = []
offset = 0
limit = 1000

while True:
    response = requests.get(
        f"https://api.withperf.pro/v1/logs?start_date={start_date}&limit={limit}&offset={offset}",
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()

    all_logs.extend(response['logs'])

    if not response['pagination']['has_more']:
        break

    offset += limit

# Write to CSV
with open('perf_logs.csv', 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=[
        'call_id', 'timestamp', 'task_type', 'model', 'cost_usd', 'latency_ms', 'success'
    ])
    writer.writeheader()

    for log in all_logs:
        writer.writerow({
            'call_id': log['call_id'],
            'timestamp': log['timestamp'],
            'task_type': log['classification']['task_type'],
            'model': log['routing']['model_selected'],
            'cost_usd': log['execution']['cost_usd'],
            'latency_ms': log['execution']['latency_ms'],
            'success': log['quality']['validation_passed']
        })
```

***

## Log Retention

| Tier       | Retention Period       | Export Available   |
| ---------- | ---------------------- | ------------------ |
| Free       | 7 days                 | JSON               |
| Pro        | 90 days                | JSON, CSV          |
| Enterprise | Custom (up to 2 years) | JSON, CSV, Parquet |

***

## Filtering Best Practices

### 1. Use Date Ranges for Performance

```bash theme={null}
# Good - specific date range
curl "https://api.withperf.pro/v1/logs?start_date=2024-01-01&end_date=2024-01-07"

# Avoid - fetching all logs
curl "https://api.withperf.pro/v1/logs?limit=10000"
```

### 2. Paginate Large Results

```python theme={null}
def get_all_logs(start_date, end_date):
    all_logs = []
    offset = 0
    limit = 1000

    while True:
        response = requests.get(
            f"{API_URL}/v1/logs",
            params={
                'start_date': start_date,
                'end_date': end_date,
                'limit': limit,
                'offset': offset
            },
            headers={'Authorization': f'Bearer {API_KEY}'}
        ).json()

        all_logs.extend(response['logs'])

        if not response['pagination']['has_more']:
            break

        offset += limit
        time.sleep(0.1)  # Rate limiting

    return all_logs
```

### 3. Combine Filters Efficiently

```bash theme={null}
# Efficient - multiple filters reduce result set
curl "https://api.withperf.pro/v1/logs?task_type=extraction&model=gpt-4o-mini&success_only=true&limit=100"
```

***

## Rate Limits

| Tier       | Requests/Minute | Max Limit per Request |
| ---------- | --------------- | --------------------- |
| Free       | 30              | 100                   |
| Pro        | 120             | 1000                  |
| Enterprise | 600             | 10000                 |

***

## Privacy & Security

### Data Handling

* **Prompt Storage**: Full prompts stored for retention period
* **Output Storage**: Full outputs stored for retention period
* **PII Detection**: Automatic flagging (Enterprise)
* **Encryption**: AES-256 at rest, TLS 1.3 in transit

### GDPR Compliance

Delete user data on request:

```bash theme={null}
curl -X DELETE https://api.withperf.pro/v1/logs/user/user_12345 \
  -H "Authorization: Bearer pk_live_abc123"
```

### Export User Data

```bash theme={null}
curl "https://api.withperf.pro/v1/logs?user_id=user_12345" \
  -H "Authorization: Bearer pk_live_abc123" \
  > user_data.json
```

***

## Related Resources

* [Metrics API](./metrics) - For aggregated analytics
* [Dashboard](../platform/dashboard) - Visual log exploration
* [Best Practices](../resources/best-practices) - Optimization tips

## Support

* **Email**: [support@withperf.pro](mailto:support@withperf.pro)
* **Documentation**: [docs.withperf.pro](https://docs.withperf.pro)
