Base code
This commit is contained in:
320
docs-site/docs/api/authentication.md
Normal file
320
docs-site/docs/api/authentication.md
Normal file
@@ -0,0 +1,320 @@
|
||||
# API Authentication
|
||||
|
||||
ALwrity uses API key authentication to secure access to all endpoints. This guide explains how to authenticate your requests and manage your API keys.
|
||||
|
||||
## Authentication Methods
|
||||
|
||||
### API Key Authentication
|
||||
|
||||
ALwrity uses Bearer token authentication with API keys. Include your API key in the `Authorization` header of all requests.
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://your-domain.com/api/blog-writer
|
||||
```
|
||||
|
||||
### Header Format
|
||||
|
||||
```http
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
## Getting Your API Key
|
||||
|
||||
### 1. Access the Dashboard
|
||||
|
||||
1. **Sign in** to your ALwrity account
|
||||
2. **Navigate** to the API section
|
||||
3. **Click** "Generate API Key"
|
||||
|
||||
### 2. Generate New Key
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "My Application",
|
||||
"description": "API key for my content management app",
|
||||
"permissions": ["read", "write"],
|
||||
"expires": "2024-12-31"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Store Securely
|
||||
|
||||
- **Never expose** API keys in client-side code
|
||||
- **Use environment variables** for storage
|
||||
- **Rotate keys** regularly
|
||||
- **Monitor usage** for security
|
||||
|
||||
## API Key Management
|
||||
|
||||
### Key Properties
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "key_123456789",
|
||||
"name": "My Application",
|
||||
"key": "alwrity_sk_...",
|
||||
"permissions": ["read", "write"],
|
||||
"created_at": "2024-01-15T10:30:00Z",
|
||||
"expires_at": "2024-12-31T23:59:59Z",
|
||||
"last_used": "2024-01-20T14:22:00Z",
|
||||
"usage_count": 1250
|
||||
}
|
||||
```
|
||||
|
||||
### Permissions
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `read` | Read access to content and analytics |
|
||||
| `write` | Create and update content |
|
||||
| `admin` | Full administrative access |
|
||||
|
||||
### Key Rotation
|
||||
|
||||
```bash
|
||||
# Create new key
|
||||
curl -X POST "https://your-domain.com/api/keys" \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "New Key",
|
||||
"permissions": ["read", "write"]
|
||||
}'
|
||||
|
||||
# Revoke old key
|
||||
curl -X DELETE "https://your-domain.com/api/keys/old_key_id" \
|
||||
-H "Authorization: Bearer YOUR_API_KEY"
|
||||
```
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
### Rate Limits by Plan
|
||||
|
||||
| Plan | Requests per Minute | Requests per Day |
|
||||
|------|-------------------|------------------|
|
||||
| Free | 10 | 100 |
|
||||
| Basic | 60 | 1,000 |
|
||||
| Pro | 300 | 10,000 |
|
||||
| Enterprise | 1,000 | 100,000 |
|
||||
|
||||
### Rate Limit Headers
|
||||
|
||||
```http
|
||||
X-RateLimit-Limit: 60
|
||||
X-RateLimit-Remaining: 59
|
||||
X-RateLimit-Reset: 1640995200
|
||||
```
|
||||
|
||||
### Handling Rate Limits
|
||||
|
||||
```python
|
||||
import time
|
||||
import requests
|
||||
|
||||
def make_request_with_retry(url, headers, data):
|
||||
max_retries = 3
|
||||
retry_delay = 1
|
||||
|
||||
for attempt in range(max_retries):
|
||||
response = requests.post(url, headers=headers, json=data)
|
||||
|
||||
if response.status_code == 429: # Rate limited
|
||||
retry_after = int(response.headers.get('Retry-After', retry_delay))
|
||||
time.sleep(retry_after)
|
||||
retry_delay *= 2 # Exponential backoff
|
||||
else:
|
||||
return response
|
||||
|
||||
raise Exception("Max retries exceeded")
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Authentication Errors
|
||||
|
||||
#### Invalid API Key
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INVALID_API_KEY",
|
||||
"message": "The provided API key is invalid or expired",
|
||||
"details": {
|
||||
"key_id": "key_123456789"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Missing API Key
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "MISSING_API_KEY",
|
||||
"message": "API key is required for authentication",
|
||||
"details": {
|
||||
"header": "Authorization: Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Insufficient Permissions
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INSUFFICIENT_PERMISSIONS",
|
||||
"message": "API key does not have required permissions",
|
||||
"details": {
|
||||
"required": ["write"],
|
||||
"granted": ["read"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Rate Limit Errors
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "RATE_LIMIT_EXCEEDED",
|
||||
"message": "Rate limit exceeded. Please try again later.",
|
||||
"details": {
|
||||
"limit": 60,
|
||||
"remaining": 0,
|
||||
"reset_time": "2024-01-15T10:31:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### API Key Security
|
||||
|
||||
1. **Environment Variables**
|
||||
```bash
|
||||
export ALWRITY_API_KEY="your_api_key_here"
|
||||
```
|
||||
|
||||
2. **Secure Storage**
|
||||
```python
|
||||
import os
|
||||
api_key = os.getenv('ALWRITY_API_KEY')
|
||||
```
|
||||
|
||||
3. **Key Rotation**
|
||||
- Rotate keys every 90 days
|
||||
- Use different keys for different environments
|
||||
- Monitor key usage regularly
|
||||
|
||||
### Request Security
|
||||
|
||||
1. **HTTPS Only**
|
||||
- Always use HTTPS for API requests
|
||||
- Never send API keys over HTTP
|
||||
|
||||
2. **Request Validation**
|
||||
- Validate all input data
|
||||
- Sanitize user inputs
|
||||
- Use proper content types
|
||||
|
||||
3. **Error Handling**
|
||||
- Don't expose sensitive information in errors
|
||||
- Log security events
|
||||
- Monitor for suspicious activity
|
||||
|
||||
## SDK Authentication
|
||||
|
||||
### Python SDK
|
||||
|
||||
```python
|
||||
from alwrity import AlwrityClient
|
||||
|
||||
# Initialize client with API key
|
||||
client = AlwrityClient(api_key="your_api_key_here")
|
||||
|
||||
# Or use environment variable
|
||||
import os
|
||||
client = AlwrityClient(api_key=os.getenv('ALWRITY_API_KEY'))
|
||||
```
|
||||
|
||||
### JavaScript SDK
|
||||
|
||||
```javascript
|
||||
const AlwrityClient = require('alwrity-js');
|
||||
|
||||
// Initialize client with API key
|
||||
const client = new AlwrityClient('your_api_key_here');
|
||||
|
||||
// Or use environment variable
|
||||
const client = new AlwrityClient(process.env.ALWRITY_API_KEY);
|
||||
```
|
||||
|
||||
### cURL Examples
|
||||
|
||||
```bash
|
||||
# Set API key as environment variable
|
||||
export ALWRITY_API_KEY="your_api_key_here"
|
||||
|
||||
# Use in requests
|
||||
curl -H "Authorization: Bearer $ALWRITY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://your-domain.com/api/blog-writer
|
||||
```
|
||||
|
||||
## Testing Authentication
|
||||
|
||||
### Health Check
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_API_KEY" \
|
||||
https://your-domain.com/api/health
|
||||
```
|
||||
|
||||
### Response
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"authenticated": true,
|
||||
"user_id": "user_123456789",
|
||||
"permissions": ["read", "write"],
|
||||
"rate_limit": {
|
||||
"limit": 60,
|
||||
"remaining": 59,
|
||||
"reset": 1640995200
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 401 Unauthorized
|
||||
- **Check API key**: Verify key is correct and active
|
||||
- **Check format**: Ensure proper "Bearer " prefix
|
||||
- **Check expiration**: Verify key hasn't expired
|
||||
|
||||
#### 403 Forbidden
|
||||
- **Check permissions**: Verify key has required permissions
|
||||
- **Check scope**: Ensure key has access to requested resource
|
||||
|
||||
#### 429 Too Many Requests
|
||||
- **Check rate limits**: Verify you're within rate limits
|
||||
- **Implement backoff**: Use exponential backoff for retries
|
||||
- **Upgrade plan**: Consider upgrading for higher limits
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **API Documentation**: Check endpoint documentation
|
||||
- **Support**: Contact support for authentication issues
|
||||
- **Community**: Join developer community for help
|
||||
- **Status Page**: Check API status for outages
|
||||
|
||||
---
|
||||
|
||||
*Ready to authenticate your requests? [Get your API key](https://dashboard.alwrity.com/api-keys) and [start building](overview.md) with the ALwrity API!*
|
||||
688
docs-site/docs/api/error-codes.md
Normal file
688
docs-site/docs/api/error-codes.md
Normal file
@@ -0,0 +1,688 @@
|
||||
# API Error Codes
|
||||
|
||||
This comprehensive reference covers all error codes returned by the ALwrity API, including descriptions, possible causes, and recommended solutions.
|
||||
|
||||
## Error Response Format
|
||||
|
||||
All API errors follow a consistent format:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "ERROR_CODE",
|
||||
"message": "Human-readable error message",
|
||||
"details": {
|
||||
"field": "Additional error details",
|
||||
"suggestion": "Recommended action"
|
||||
}
|
||||
},
|
||||
"timestamp": "2024-01-15T10:30:00Z",
|
||||
"request_id": "req_123456789"
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP Status Codes
|
||||
|
||||
### 4xx Client Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | Bad Request - Invalid request format |
|
||||
| 401 | Unauthorized - Authentication required |
|
||||
| 403 | Forbidden - Insufficient permissions |
|
||||
| 404 | Not Found - Resource not found |
|
||||
| 409 | Conflict - Resource conflict |
|
||||
| 422 | Unprocessable Entity - Validation error |
|
||||
| 429 | Too Many Requests - Rate limit exceeded |
|
||||
|
||||
### 5xx Server Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 500 | Internal Server Error - Server error |
|
||||
| 502 | Bad Gateway - Upstream service error |
|
||||
| 503 | Service Unavailable - Service temporarily down |
|
||||
| 504 | Gateway Timeout - Request timeout |
|
||||
|
||||
## Authentication Errors
|
||||
|
||||
### INVALID_API_KEY
|
||||
|
||||
**Status**: 401 Unauthorized
|
||||
|
||||
**Description**: The provided API key is invalid, expired, or malformed.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INVALID_API_KEY",
|
||||
"message": "The provided API key is invalid or expired",
|
||||
"details": {
|
||||
"key_id": "key_123456789",
|
||||
"suggestion": "Please check your API key or generate a new one"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- API key is incorrect
|
||||
- API key has expired
|
||||
- API key format is invalid
|
||||
|
||||
**Solutions**:
|
||||
- Verify API key is correct
|
||||
- Generate a new API key
|
||||
- Check API key format
|
||||
|
||||
### MISSING_API_KEY
|
||||
|
||||
**Status**: 401 Unauthorized
|
||||
|
||||
**Description**: No API key provided in the request.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "MISSING_API_KEY",
|
||||
"message": "API key is required for authentication",
|
||||
"details": {
|
||||
"header": "Authorization: Bearer YOUR_API_KEY",
|
||||
"suggestion": "Include your API key in the Authorization header"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Missing Authorization header
|
||||
- Incorrect header format
|
||||
|
||||
**Solutions**:
|
||||
- Add Authorization header
|
||||
- Use correct Bearer token format
|
||||
|
||||
### INSUFFICIENT_PERMISSIONS
|
||||
|
||||
**Status**: 403 Forbidden
|
||||
|
||||
**Description**: API key doesn't have required permissions.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INSUFFICIENT_PERMISSIONS",
|
||||
"message": "API key does not have required permissions",
|
||||
"details": {
|
||||
"required": ["write"],
|
||||
"granted": ["read"],
|
||||
"suggestion": "Upgrade your API key permissions or use a different key"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- API key has read-only permissions
|
||||
- Trying to perform write operation
|
||||
- Key doesn't have specific feature access
|
||||
|
||||
**Solutions**:
|
||||
- Use API key with write permissions
|
||||
- Request permission upgrade
|
||||
- Use appropriate key for operation
|
||||
|
||||
## Rate Limiting Errors
|
||||
|
||||
### RATE_LIMIT_EXCEEDED
|
||||
|
||||
**Status**: 429 Too Many Requests
|
||||
|
||||
**Description**: Request rate limit exceeded.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "RATE_LIMIT_EXCEEDED",
|
||||
"message": "Rate limit exceeded. Please try again later.",
|
||||
"details": {
|
||||
"limit": 60,
|
||||
"remaining": 0,
|
||||
"reset_time": "2024-01-15T10:31:00Z",
|
||||
"retry_after": 60,
|
||||
"suggestion": "Wait 60 seconds before retrying or upgrade your plan"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Too many requests in time window
|
||||
- Exceeded daily quota
|
||||
- High resource usage
|
||||
|
||||
**Solutions**:
|
||||
- Wait for rate limit reset
|
||||
- Implement exponential backoff
|
||||
- Upgrade to higher plan
|
||||
- Optimize request frequency
|
||||
|
||||
### QUOTA_EXCEEDED
|
||||
|
||||
**Status**: 429 Too Many Requests
|
||||
|
||||
**Description**: Daily or monthly quota exceeded.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "QUOTA_EXCEEDED",
|
||||
"message": "Daily quota exceeded",
|
||||
"details": {
|
||||
"quota_type": "daily",
|
||||
"limit": 1000,
|
||||
"used": 1000,
|
||||
"reset_time": "2024-01-16T00:00:00Z",
|
||||
"suggestion": "Wait until quota resets or upgrade your plan"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Daily request limit reached
|
||||
- Monthly quota exceeded
|
||||
- Feature-specific quota exceeded
|
||||
|
||||
**Solutions**:
|
||||
- Wait for quota reset
|
||||
- Upgrade plan for higher limits
|
||||
- Optimize API usage
|
||||
- Use caching to reduce requests
|
||||
|
||||
## Validation Errors
|
||||
|
||||
### VALIDATION_ERROR
|
||||
|
||||
**Status**: 422 Unprocessable Entity
|
||||
|
||||
**Description**: Request validation failed.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "Request validation failed",
|
||||
"details": {
|
||||
"field": "topic",
|
||||
"message": "Topic is required and must be at least 3 characters",
|
||||
"suggestion": "Provide a valid topic with at least 3 characters"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Missing required fields
|
||||
- Invalid field values
|
||||
- Field format errors
|
||||
- Value constraints violated
|
||||
|
||||
**Solutions**:
|
||||
- Check required fields
|
||||
- Validate field formats
|
||||
- Ensure values meet constraints
|
||||
- Review API documentation
|
||||
|
||||
### INVALID_REQUEST_FORMAT
|
||||
|
||||
**Status**: 400 Bad Request
|
||||
|
||||
**Description**: Request format is invalid.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INVALID_REQUEST_FORMAT",
|
||||
"message": "Request body must be valid JSON",
|
||||
"details": {
|
||||
"content_type": "application/json",
|
||||
"suggestion": "Ensure request body is valid JSON with correct Content-Type header"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Invalid JSON format
|
||||
- Missing Content-Type header
|
||||
- Incorrect content type
|
||||
- Malformed request body
|
||||
|
||||
**Solutions**:
|
||||
- Validate JSON format
|
||||
- Set correct Content-Type header
|
||||
- Check request body structure
|
||||
- Use proper encoding
|
||||
|
||||
## Content Generation Errors
|
||||
|
||||
### CONTENT_GENERATION_FAILED
|
||||
|
||||
**Status**: 500 Internal Server Error
|
||||
|
||||
**Description**: Content generation process failed.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "CONTENT_GENERATION_FAILED",
|
||||
"message": "Failed to generate content",
|
||||
"details": {
|
||||
"reason": "AI service timeout",
|
||||
"suggestion": "Try again with a shorter content length or contact support"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- AI service timeout
|
||||
- Content too long
|
||||
- Invalid parameters
|
||||
- Service overload
|
||||
|
||||
**Solutions**:
|
||||
- Reduce content length
|
||||
- Retry request
|
||||
- Check parameters
|
||||
- Contact support
|
||||
|
||||
### CONTENT_TOO_LONG
|
||||
|
||||
**Status**: 422 Unprocessable Entity
|
||||
|
||||
**Description**: Content exceeds maximum length limit.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "CONTENT_TOO_LONG",
|
||||
"message": "Content exceeds maximum length limit",
|
||||
"details": {
|
||||
"max_length": 10000,
|
||||
"provided_length": 15000,
|
||||
"suggestion": "Reduce content length to 10,000 characters or less"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Content exceeds character limit
|
||||
- Word count too high
|
||||
- Input text too long
|
||||
|
||||
**Solutions**:
|
||||
- Reduce content length
|
||||
- Split into multiple requests
|
||||
- Use appropriate limits
|
||||
- Check content size
|
||||
|
||||
### INVALID_CONTENT_TYPE
|
||||
|
||||
**Status**: 422 Unprocessable Entity
|
||||
|
||||
**Description**: Invalid content type specified.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INVALID_CONTENT_TYPE",
|
||||
"message": "Invalid content type specified",
|
||||
"details": {
|
||||
"provided": "invalid_type",
|
||||
"valid_types": ["blog_post", "social_media", "email", "article"],
|
||||
"suggestion": "Use one of the valid content types"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Unsupported content type
|
||||
- Typo in content type
|
||||
- Missing content type
|
||||
|
||||
**Solutions**:
|
||||
- Use valid content type
|
||||
- Check spelling
|
||||
- Review documentation
|
||||
- Use default type
|
||||
|
||||
## Research and SEO Errors
|
||||
|
||||
### RESEARCH_FAILED
|
||||
|
||||
**Status**: 500 Internal Server Error
|
||||
|
||||
**Description**: Research process failed.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "RESEARCH_FAILED",
|
||||
"message": "Failed to perform research",
|
||||
"details": {
|
||||
"reason": "External service unavailable",
|
||||
"suggestion": "Try again later or use cached research data"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- External service down
|
||||
- Network connectivity issues
|
||||
- Research service timeout
|
||||
- Invalid research parameters
|
||||
|
||||
**Solutions**:
|
||||
- Retry request
|
||||
- Check network connection
|
||||
- Use cached data
|
||||
- Contact support
|
||||
|
||||
### SEO_ANALYSIS_FAILED
|
||||
|
||||
**Status**: 500 Internal Server Error
|
||||
|
||||
**Description**: SEO analysis failed.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "SEO_ANALYSIS_FAILED",
|
||||
"message": "Failed to perform SEO analysis",
|
||||
"details": {
|
||||
"reason": "Content parsing error",
|
||||
"suggestion": "Ensure content is properly formatted and try again"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Content parsing issues
|
||||
- Invalid HTML format
|
||||
- Missing content elements
|
||||
- Analysis service error
|
||||
|
||||
**Solutions**:
|
||||
- Check content format
|
||||
- Ensure valid HTML
|
||||
- Retry analysis
|
||||
- Contact support
|
||||
|
||||
## Resource Errors
|
||||
|
||||
### RESOURCE_NOT_FOUND
|
||||
|
||||
**Status**: 404 Not Found
|
||||
|
||||
**Description**: Requested resource not found.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "RESOURCE_NOT_FOUND",
|
||||
"message": "Requested resource not found",
|
||||
"details": {
|
||||
"resource_type": "content",
|
||||
"resource_id": "content_123456789",
|
||||
"suggestion": "Check resource ID or create new resource"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Invalid resource ID
|
||||
- Resource deleted
|
||||
- Resource not accessible
|
||||
- Wrong resource type
|
||||
|
||||
**Solutions**:
|
||||
- Verify resource ID
|
||||
- Check resource exists
|
||||
- Ensure proper permissions
|
||||
- Use correct resource type
|
||||
|
||||
### RESOURCE_CONFLICT
|
||||
|
||||
**Status**: 409 Conflict
|
||||
|
||||
**Description**: Resource conflict detected.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "RESOURCE_CONFLICT",
|
||||
"message": "Resource conflict detected",
|
||||
"details": {
|
||||
"conflict_type": "duplicate_name",
|
||||
"existing_resource": "content_123456789",
|
||||
"suggestion": "Use a different name or update existing resource"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Duplicate resource name
|
||||
- Concurrent modification
|
||||
- Resource already exists
|
||||
- Version conflict
|
||||
|
||||
**Solutions**:
|
||||
- Use unique name
|
||||
- Check for existing resources
|
||||
- Handle concurrency
|
||||
- Resolve version conflicts
|
||||
|
||||
## Service Errors
|
||||
|
||||
### SERVICE_UNAVAILABLE
|
||||
|
||||
**Status**: 503 Service Unavailable
|
||||
|
||||
**Description**: Service temporarily unavailable.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "SERVICE_UNAVAILABLE",
|
||||
"message": "Service temporarily unavailable",
|
||||
"details": {
|
||||
"reason": "Maintenance in progress",
|
||||
"estimated_recovery": "2024-01-15T12:00:00Z",
|
||||
"suggestion": "Try again after the estimated recovery time"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Scheduled maintenance
|
||||
- Service overload
|
||||
- Infrastructure issues
|
||||
- Planned downtime
|
||||
|
||||
**Solutions**:
|
||||
- Wait for service recovery
|
||||
- Check status page
|
||||
- Retry after delay
|
||||
- Contact support
|
||||
|
||||
### INTERNAL_SERVER_ERROR
|
||||
|
||||
**Status**: 500 Internal Server Error
|
||||
|
||||
**Description**: Internal server error occurred.
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INTERNAL_SERVER_ERROR",
|
||||
"message": "An internal server error occurred",
|
||||
"details": {
|
||||
"request_id": "req_123456789",
|
||||
"suggestion": "Retry the request or contact support if the issue persists"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Unexpected server error
|
||||
- Database issues
|
||||
- Third-party service failure
|
||||
- Configuration problems
|
||||
|
||||
**Solutions**:
|
||||
- Retry request
|
||||
- Check status page
|
||||
- Contact support
|
||||
- Provide request ID
|
||||
|
||||
## Error Handling Best Practices
|
||||
|
||||
### Client-Side Handling
|
||||
|
||||
```python
|
||||
import requests
|
||||
import time
|
||||
|
||||
def handle_api_error(response):
|
||||
"""Handle API errors with appropriate actions."""
|
||||
|
||||
if response.status_code == 401:
|
||||
# Authentication error
|
||||
print("Authentication failed. Check your API key.")
|
||||
return None
|
||||
|
||||
elif response.status_code == 429:
|
||||
# Rate limit error
|
||||
retry_after = response.headers.get('Retry-After', 60)
|
||||
print(f"Rate limited. Retrying in {retry_after} seconds...")
|
||||
time.sleep(int(retry_after))
|
||||
return "retry"
|
||||
|
||||
elif response.status_code == 422:
|
||||
# Validation error
|
||||
error_data = response.json()
|
||||
print(f"Validation error: {error_data['error']['message']}")
|
||||
return None
|
||||
|
||||
elif response.status_code >= 500:
|
||||
# Server error
|
||||
print("Server error. Please try again later.")
|
||||
return "retry"
|
||||
|
||||
else:
|
||||
# Other errors
|
||||
print(f"Unexpected error: {response.status_code}")
|
||||
return None
|
||||
```
|
||||
|
||||
### Retry Logic
|
||||
|
||||
```python
|
||||
def make_request_with_retry(url, headers, data, max_retries=3):
|
||||
"""Make API request with retry logic."""
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
response = requests.post(url, headers=headers, json=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
|
||||
# Handle specific errors
|
||||
result = handle_api_error(response)
|
||||
|
||||
if result == "retry" and attempt < max_retries - 1:
|
||||
continue
|
||||
elif result is None:
|
||||
return None
|
||||
else:
|
||||
return response.json()
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Request failed: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(2 ** attempt) # Exponential backoff
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
|
||||
return None
|
||||
```
|
||||
|
||||
### Logging and Monitoring
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
def log_api_error(error_data, request_id=None):
|
||||
"""Log API errors for monitoring and debugging."""
|
||||
|
||||
logger = logging.getLogger('alwrity_api')
|
||||
|
||||
error_info = {
|
||||
'error_code': error_data.get('code'),
|
||||
'error_message': error_data.get('message'),
|
||||
'request_id': request_id,
|
||||
'timestamp': error_data.get('timestamp')
|
||||
}
|
||||
|
||||
logger.error(f"API Error: {error_info}")
|
||||
|
||||
# Send to monitoring service
|
||||
send_to_monitoring(error_info)
|
||||
```
|
||||
|
||||
## Troubleshooting Guide
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Authentication Problems
|
||||
1. **Check API key format**: Ensure proper Bearer token format
|
||||
2. **Verify key validity**: Check if key is active and not expired
|
||||
3. **Check permissions**: Ensure key has required permissions
|
||||
4. **Test with simple request**: Use health check endpoint
|
||||
|
||||
#### Rate Limiting Issues
|
||||
1. **Monitor usage**: Track your API usage patterns
|
||||
2. **Implement backoff**: Use exponential backoff for retries
|
||||
3. **Optimize requests**: Reduce unnecessary API calls
|
||||
4. **Consider upgrading**: Evaluate if you need higher limits
|
||||
|
||||
#### Validation Errors
|
||||
1. **Check required fields**: Ensure all required fields are provided
|
||||
2. **Validate formats**: Check field formats and constraints
|
||||
3. **Review documentation**: Verify parameter requirements
|
||||
4. **Test with minimal data**: Start with simple requests
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **API Documentation**: Check endpoint-specific documentation
|
||||
- **Status Page**: Monitor service status and incidents
|
||||
- **Support**: Contact support for persistent issues
|
||||
- **Community**: Join developer community for help
|
||||
- **GitHub Issues**: Report bugs and request features
|
||||
|
||||
---
|
||||
|
||||
*Need help with API errors? [Contact Support](https://support.alwrity.com) or [Check our Status Page](https://status.alwrity.com) for service updates!*
|
||||
433
docs-site/docs/api/overview.md
Normal file
433
docs-site/docs/api/overview.md
Normal file
@@ -0,0 +1,433 @@
|
||||
# API Reference Overview
|
||||
|
||||
ALwrity provides a comprehensive RESTful API that allows you to integrate AI-powered content creation capabilities into your applications. This API enables you to generate blog posts, optimize SEO, create social media content, and manage your content strategy programmatically.
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
Development: http://localhost:8000
|
||||
Production: https://your-domain.com
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
ALwrity uses API key authentication for secure access to endpoints.
|
||||
|
||||
### API Key Setup
|
||||
|
||||
1. **Get your API key** from the ALwrity dashboard
|
||||
2. **Include in requests** using the `Authorization` header:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://your-domain.com/api/blog-writer
|
||||
```
|
||||
|
||||
## API Architecture
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Client Applications"
|
||||
Web[Web Application]
|
||||
Mobile[Mobile App]
|
||||
CLI[CLI Tools]
|
||||
ThirdParty[Third-party Apps]
|
||||
end
|
||||
|
||||
subgraph "API Gateway"
|
||||
Auth[Authentication]
|
||||
RateLimit[Rate Limiting]
|
||||
Validation[Request Validation]
|
||||
Routing[Request Routing]
|
||||
end
|
||||
|
||||
subgraph "Core Services"
|
||||
Blog[Blog Writer API]
|
||||
SEO[SEO Dashboard API]
|
||||
LinkedIn[LinkedIn Writer API]
|
||||
Strategy[Content Strategy API]
|
||||
end
|
||||
|
||||
subgraph "AI Services"
|
||||
Gemini[Gemini AI]
|
||||
Research[Research Services]
|
||||
Analysis[SEO Analysis]
|
||||
Generation[Content Generation]
|
||||
end
|
||||
|
||||
subgraph "Data Layer"
|
||||
DB[(Database)]
|
||||
Cache[(Redis Cache)]
|
||||
Files[File Storage]
|
||||
end
|
||||
|
||||
Web --> Auth
|
||||
Mobile --> Auth
|
||||
CLI --> Auth
|
||||
ThirdParty --> Auth
|
||||
|
||||
Auth --> RateLimit
|
||||
RateLimit --> Validation
|
||||
Validation --> Routing
|
||||
|
||||
Routing --> Blog
|
||||
Routing --> SEO
|
||||
Routing --> LinkedIn
|
||||
Routing --> Strategy
|
||||
|
||||
Blog --> Gemini
|
||||
Blog --> Research
|
||||
SEO --> Analysis
|
||||
LinkedIn --> Generation
|
||||
Strategy --> Research
|
||||
|
||||
Blog --> DB
|
||||
SEO --> DB
|
||||
LinkedIn --> DB
|
||||
Strategy --> DB
|
||||
|
||||
Blog --> Cache
|
||||
SEO --> Cache
|
||||
|
||||
Generation --> Files
|
||||
|
||||
style Auth fill:#ffebee
|
||||
style Blog fill:#e3f2fd
|
||||
style SEO fill:#e8f5e8
|
||||
style LinkedIn fill:#fff3e0
|
||||
style Strategy fill:#f3e5f5
|
||||
```
|
||||
|
||||
## Core Endpoints
|
||||
|
||||
### Blog Writer API
|
||||
|
||||
#### Generate Blog Content
|
||||
```http
|
||||
POST /api/blog-writer
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"topic": "AI in Digital Marketing",
|
||||
"target_audience": "Marketing professionals",
|
||||
"content_type": "how-to-guide",
|
||||
"word_count": 1500,
|
||||
"tone": "professional"
|
||||
}
|
||||
```
|
||||
|
||||
#### Research Integration
|
||||
```http
|
||||
POST /api/blog-writer/research
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"topic": "Content Strategy",
|
||||
"research_depth": "comprehensive",
|
||||
"sources": ["web", "academic", "industry"]
|
||||
}
|
||||
```
|
||||
|
||||
#### SEO Analysis
|
||||
```http
|
||||
POST /api/blog-writer/seo/analyze
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"content": "Your blog post content here...",
|
||||
"target_keywords": ["content strategy", "digital marketing"],
|
||||
"competitor_urls": ["https://example.com"]
|
||||
}
|
||||
```
|
||||
|
||||
### SEO Dashboard API
|
||||
|
||||
#### Performance Analysis
|
||||
```http
|
||||
GET /api/seo-dashboard/performance
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"domain": "your-website.com",
|
||||
"date_range": "30d",
|
||||
"metrics": ["traffic", "rankings", "conversions"]
|
||||
}
|
||||
```
|
||||
|
||||
#### Keyword Research
|
||||
```http
|
||||
POST /api/seo-dashboard/keywords/research
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"seed_keywords": ["digital marketing", "content creation"],
|
||||
"language": "en",
|
||||
"location": "US",
|
||||
"competition_level": "medium"
|
||||
}
|
||||
```
|
||||
|
||||
#### Content Optimization
|
||||
```http
|
||||
POST /api/seo-dashboard/optimize
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"content": "Your content here...",
|
||||
"target_keyword": "content strategy",
|
||||
"optimization_goals": ["readability", "keyword_density", "structure"]
|
||||
}
|
||||
```
|
||||
|
||||
### LinkedIn Writer API
|
||||
|
||||
#### Generate LinkedIn Content
|
||||
```http
|
||||
POST /api/linkedin-writer
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"content_type": "post",
|
||||
"topic": "Professional networking tips",
|
||||
"tone": "professional",
|
||||
"include_hashtags": true,
|
||||
"target_audience": "LinkedIn professionals"
|
||||
}
|
||||
```
|
||||
|
||||
#### Fact Checking
|
||||
```http
|
||||
POST /api/linkedin-writer/fact-check
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"content": "Your LinkedIn post content...",
|
||||
"verification_level": "comprehensive"
|
||||
}
|
||||
```
|
||||
|
||||
### Content Strategy API
|
||||
|
||||
#### Generate Strategy
|
||||
```http
|
||||
POST /api/content-strategy/generate
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"business_type": "SaaS",
|
||||
"target_audience": "Small business owners",
|
||||
"goals": ["lead_generation", "brand_awareness"],
|
||||
"content_types": ["blog", "social", "email"]
|
||||
}
|
||||
```
|
||||
|
||||
#### Persona Development
|
||||
```http
|
||||
POST /api/content-strategy/personas
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"business_niche": "Digital marketing",
|
||||
"target_demographics": {
|
||||
"age_range": "25-45",
|
||||
"profession": "Marketing professionals",
|
||||
"pain_points": ["time_management", "roi_tracking"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Response Formats
|
||||
|
||||
### Success Response
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"content": "Generated content here...",
|
||||
"metadata": {
|
||||
"word_count": 1500,
|
||||
"readability_score": 85,
|
||||
"seo_score": 92
|
||||
}
|
||||
},
|
||||
"timestamp": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "INVALID_REQUEST",
|
||||
"message": "Missing required parameter: topic",
|
||||
"details": {
|
||||
"parameter": "topic",
|
||||
"expected_type": "string"
|
||||
}
|
||||
},
|
||||
"timestamp": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Rate Limits
|
||||
|
||||
| Plan | Requests per Minute | Requests per Day |
|
||||
|------|-------------------|------------------|
|
||||
| Free | 10 | 100 |
|
||||
| Basic | 60 | 1,000 |
|
||||
| Pro | 300 | 10,000 |
|
||||
| Enterprise | 1,000 | 100,000 |
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| `INVALID_API_KEY` | API key is missing or invalid |
|
||||
| `RATE_LIMIT_EXCEEDED` | Too many requests |
|
||||
| `INVALID_REQUEST` | Request parameters are invalid |
|
||||
| `CONTENT_TOO_LONG` | Content exceeds maximum length |
|
||||
| `QUOTA_EXCEEDED` | Daily quota exceeded |
|
||||
| `SERVICE_UNAVAILABLE` | Service temporarily unavailable |
|
||||
|
||||
## SDKs and Libraries
|
||||
|
||||
### Python
|
||||
```bash
|
||||
pip install alwrity-python
|
||||
```
|
||||
|
||||
```python
|
||||
from alwrity import AlwrityClient
|
||||
|
||||
client = AlwrityClient(api_key="YOUR_API_KEY")
|
||||
|
||||
# Generate blog content
|
||||
response = client.blog_writer.generate(
|
||||
topic="AI in Marketing",
|
||||
word_count=1000,
|
||||
tone="professional"
|
||||
)
|
||||
|
||||
print(response.content)
|
||||
```
|
||||
|
||||
### JavaScript/Node.js
|
||||
```bash
|
||||
npm install alwrity-js
|
||||
```
|
||||
|
||||
```javascript
|
||||
const AlwrityClient = require('alwrity-js');
|
||||
|
||||
const client = new AlwrityClient('YOUR_API_KEY');
|
||||
|
||||
// Generate LinkedIn content
|
||||
client.linkedinWriter.generate({
|
||||
content_type: 'post',
|
||||
topic: 'Professional development',
|
||||
tone: 'inspirational'
|
||||
}).then(response => {
|
||||
console.log(response.content);
|
||||
});
|
||||
```
|
||||
|
||||
### cURL Examples
|
||||
|
||||
#### Generate Blog Post
|
||||
```bash
|
||||
curl -X POST "https://your-domain.com/api/blog-writer" \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"topic": "Content Marketing Trends 2024",
|
||||
"word_count": 1200,
|
||||
"tone": "professional"
|
||||
}'
|
||||
```
|
||||
|
||||
#### SEO Analysis
|
||||
```bash
|
||||
curl -X POST "https://your-domain.com/api/blog-writer/seo/analyze" \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"content": "Your content here...",
|
||||
"target_keywords": ["content marketing", "trends"]
|
||||
}'
|
||||
```
|
||||
|
||||
## Webhooks
|
||||
|
||||
ALwrity supports webhooks for real-time notifications about content generation and processing status.
|
||||
|
||||
### Webhook Events
|
||||
|
||||
- `content.generated` - Content generation completed
|
||||
- `seo.analysis.completed` - SEO analysis finished
|
||||
- `strategy.updated` - Content strategy updated
|
||||
- `quota.warning` - Approaching quota limit
|
||||
|
||||
### Webhook Configuration
|
||||
|
||||
```http
|
||||
POST /api/webhooks
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
{
|
||||
"url": "https://your-app.com/webhooks/alwrity",
|
||||
"events": ["content.generated", "seo.analysis.completed"],
|
||||
"secret": "your_webhook_secret"
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### API Usage
|
||||
|
||||
1. **Use HTTPS**: Always use HTTPS for API requests
|
||||
2. **Handle Errors**: Implement proper error handling
|
||||
3. **Rate Limiting**: Respect rate limits and implement backoff
|
||||
4. **Caching**: Cache responses when appropriate
|
||||
5. **Monitoring**: Monitor API usage and performance
|
||||
|
||||
### Content Generation
|
||||
|
||||
1. **Be Specific**: Provide detailed topic descriptions
|
||||
2. **Set Expectations**: Specify word count and tone
|
||||
3. **Review Output**: Always review generated content
|
||||
4. **Iterate**: Use feedback to improve results
|
||||
|
||||
### Security
|
||||
|
||||
1. **Protect API Keys**: Never expose API keys in client-side code
|
||||
2. **Use Environment Variables**: Store keys securely
|
||||
3. **Rotate Keys**: Regularly rotate API keys
|
||||
4. **Monitor Usage**: Track API usage for anomalies
|
||||
|
||||
## Support
|
||||
|
||||
### Documentation
|
||||
- **[Authentication Guide](authentication.md)** - Detailed authentication setup
|
||||
- **[Rate Limiting](rate-limiting.md)** - Understanding rate limits
|
||||
- **[Error Handling](error-codes.md)** - Complete error reference
|
||||
|
||||
### Getting Help
|
||||
- **GitHub Issues**: [Report bugs and request features](https://github.com/AJaySi/ALwrity/issues)
|
||||
- **API Status**: Check [API status page](https://status.alwrity.com)
|
||||
- **Community**: Join our [developer community](https://discord.gg/alwrity)
|
||||
|
||||
---
|
||||
|
||||
*Ready to integrate ALwrity into your application? [Get your API key](https://dashboard.alwrity.com/api-keys) and start building!*
|
||||
397
docs-site/docs/api/rate-limiting.md
Normal file
397
docs-site/docs/api/rate-limiting.md
Normal file
@@ -0,0 +1,397 @@
|
||||
# API Rate Limiting
|
||||
|
||||
ALwrity implements rate limiting to ensure fair usage and maintain service quality for all users. This guide explains how rate limiting works and how to handle rate limits in your applications.
|
||||
|
||||
## Rate Limiting Overview
|
||||
|
||||
### Purpose
|
||||
|
||||
Rate limiting helps:
|
||||
- **Prevent abuse**: Protect against excessive API usage
|
||||
- **Ensure fairness**: Provide equal access to all users
|
||||
- **Maintain performance**: Keep the service responsive
|
||||
- **Control costs**: Manage infrastructure costs
|
||||
|
||||
### How It Works
|
||||
|
||||
Rate limits are applied per API key and are based on:
|
||||
- **Time windows**: Requests per minute, hour, or day
|
||||
- **User plan**: Different limits for different subscription tiers
|
||||
- **Endpoint type**: Some endpoints have specific limits
|
||||
- **Resource usage**: Limits based on computational resources
|
||||
|
||||
## Rate Limit Types
|
||||
|
||||
### Request Rate Limits
|
||||
|
||||
#### Per Minute Limits
|
||||
- **Free Plan**: 10 requests per minute
|
||||
- **Basic Plan**: 60 requests per minute
|
||||
- **Pro Plan**: 300 requests per minute
|
||||
- **Enterprise Plan**: 1,000 requests per minute
|
||||
|
||||
#### Per Day Limits
|
||||
- **Free Plan**: 100 requests per day
|
||||
- **Basic Plan**: 1,000 requests per day
|
||||
- **Pro Plan**: 10,000 requests per day
|
||||
- **Enterprise Plan**: 100,000 requests per day
|
||||
|
||||
### Resource-Based Limits
|
||||
|
||||
#### Content Generation
|
||||
- **Word Count**: Limits based on content length
|
||||
- **Processing Time**: Limits based on computational complexity
|
||||
- **Concurrent Requests**: Limits on simultaneous processing
|
||||
|
||||
#### Data Usage
|
||||
- **Research Queries**: Limits on research API calls
|
||||
- **Image Generation**: Limits on image processing
|
||||
- **SEO Analysis**: Limits on analysis requests
|
||||
|
||||
## Rate Limit Headers
|
||||
|
||||
### Standard Headers
|
||||
|
||||
Every API response includes rate limit information:
|
||||
|
||||
```http
|
||||
X-RateLimit-Limit: 60
|
||||
X-RateLimit-Remaining: 59
|
||||
X-RateLimit-Reset: 1640995200
|
||||
X-RateLimit-Window: 60
|
||||
```
|
||||
|
||||
### Header Descriptions
|
||||
|
||||
| Header | Description |
|
||||
|--------|-------------|
|
||||
| `X-RateLimit-Limit` | Maximum requests allowed in the window |
|
||||
| `X-RateLimit-Remaining` | Requests remaining in current window |
|
||||
| `X-RateLimit-Reset` | Unix timestamp when limit resets |
|
||||
| `X-RateLimit-Window` | Time window in seconds |
|
||||
|
||||
### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
X-RateLimit-Limit: 60
|
||||
X-RateLimit-Remaining: 58
|
||||
X-RateLimit-Reset: 1640995200
|
||||
X-RateLimit-Window: 60
|
||||
|
||||
```
|
||||
|
||||
## Rate Limit Responses
|
||||
|
||||
### 429 Too Many Requests
|
||||
|
||||
When rate limits are exceeded, the API returns a 429 status code:
|
||||
|
||||
```http
|
||||
HTTP/1.1 429 Too Many Requests
|
||||
Content-Type: application/json
|
||||
X-RateLimit-Limit: 60
|
||||
X-RateLimit-Remaining: 0
|
||||
X-RateLimit-Reset: 1640995200
|
||||
Retry-After: 60
|
||||
|
||||
```
|
||||
|
||||
### Retry-After Header
|
||||
|
||||
The `Retry-After` header indicates when you can retry:
|
||||
|
||||
```http
|
||||
Retry-After: 60 # Seconds until retry
|
||||
```
|
||||
|
||||
## Handling Rate Limits
|
||||
|
||||
### Exponential Backoff
|
||||
|
||||
Implement exponential backoff for retries:
|
||||
|
||||
```python
|
||||
import time
|
||||
import random
|
||||
import requests
|
||||
|
||||
def make_request_with_backoff(url, headers, data, max_retries=3):
|
||||
base_delay = 1
|
||||
max_delay = 60
|
||||
|
||||
for attempt in range(max_retries):
|
||||
response = requests.post(url, headers=headers, json=data)
|
||||
|
||||
if response.status_code == 429:
|
||||
# Get retry delay from header or calculate
|
||||
retry_after = int(response.headers.get('Retry-After', base_delay))
|
||||
|
||||
# Add jitter to prevent thundering herd
|
||||
jitter = random.uniform(0.1, 0.5)
|
||||
delay = min(retry_after + jitter, max_delay)
|
||||
|
||||
print(f"Rate limited. Retrying in {delay:.1f} seconds...")
|
||||
time.sleep(delay)
|
||||
|
||||
# Exponential backoff for next attempt
|
||||
base_delay *= 2
|
||||
else:
|
||||
return response
|
||||
|
||||
raise Exception("Max retries exceeded")
|
||||
```
|
||||
|
||||
### Request Queuing
|
||||
|
||||
Implement request queuing to manage rate limits:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import aiohttp
|
||||
from asyncio import Semaphore
|
||||
|
||||
class RateLimitedClient:
|
||||
def __init__(self, rate_limit=60, time_window=60):
|
||||
self.semaphore = Semaphore(rate_limit)
|
||||
self.time_window = time_window
|
||||
self.requests = []
|
||||
|
||||
async def make_request(self, url, headers, data):
|
||||
async with self.semaphore:
|
||||
# Clean old requests
|
||||
current_time = time.time()
|
||||
self.requests = [req_time for req_time in self.requests
|
||||
if current_time - req_time < self.time_window]
|
||||
|
||||
# Wait if at limit
|
||||
if len(self.requests) >= self.semaphore._value:
|
||||
sleep_time = self.time_window - (current_time - self.requests[0])
|
||||
if sleep_time > 0:
|
||||
await asyncio.sleep(sleep_time)
|
||||
|
||||
# Make request
|
||||
self.requests.append(current_time)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, headers=headers, json=data) as response:
|
||||
return await response.json()
|
||||
```
|
||||
|
||||
### Caching Responses
|
||||
|
||||
Cache responses to reduce API calls:
|
||||
|
||||
```python
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
def cache_with_ttl(ttl_seconds):
|
||||
def decorator(func):
|
||||
cache = {}
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
# Create cache key
|
||||
key = str(args) + str(sorted(kwargs.items()))
|
||||
|
||||
# Check cache
|
||||
if key in cache:
|
||||
data, timestamp = cache[key]
|
||||
if time.time() - timestamp < ttl_seconds:
|
||||
return data
|
||||
|
||||
# Make API call
|
||||
result = func(*args, **kwargs)
|
||||
|
||||
# Cache result
|
||||
cache[key] = (result, time.time())
|
||||
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
# Usage
|
||||
@cache_with_ttl(300) # Cache for 5 minutes
|
||||
def get_blog_content(topic, word_count):
|
||||
# API call here
|
||||
pass
|
||||
```
|
||||
|
||||
## Rate Limit Monitoring
|
||||
|
||||
### Track Usage
|
||||
|
||||
Monitor your rate limit usage:
|
||||
|
||||
```python
|
||||
class RateLimitMonitor:
|
||||
def __init__(self):
|
||||
self.usage_history = []
|
||||
|
||||
def track_request(self, response):
|
||||
headers = response.headers
|
||||
|
||||
usage = {
|
||||
'timestamp': time.time(),
|
||||
'limit': int(headers.get('X-RateLimit-Limit', 0)),
|
||||
'remaining': int(headers.get('X-RateLimit-Remaining', 0)),
|
||||
'reset': int(headers.get('X-RateLimit-Reset', 0))
|
||||
}
|
||||
|
||||
self.usage_history.append(usage)
|
||||
|
||||
# Alert if approaching limit
|
||||
if usage['remaining'] < usage['limit'] * 0.1: # Less than 10% remaining
|
||||
self.send_alert(usage)
|
||||
|
||||
def send_alert(self, usage):
|
||||
print(f"Warning: Only {usage['remaining']} requests remaining!")
|
||||
```
|
||||
|
||||
### Usage Analytics
|
||||
|
||||
Analyze your API usage patterns:
|
||||
|
||||
```python
|
||||
def analyze_usage(usage_history):
|
||||
if not usage_history:
|
||||
return
|
||||
|
||||
# Calculate average usage
|
||||
total_requests = sum(1 for _ in usage_history)
|
||||
avg_remaining = sum(u['remaining'] for u in usage_history) / len(usage_history)
|
||||
|
||||
# Find peak usage times
|
||||
peak_times = [u['timestamp'] for u in usage_history if u['remaining'] < 10]
|
||||
|
||||
# Calculate utilization
|
||||
utilization = (usage_history[0]['limit'] - avg_remaining) / usage_history[0]['limit']
|
||||
|
||||
return {
|
||||
'total_requests': total_requests,
|
||||
'average_remaining': avg_remaining,
|
||||
'peak_times': peak_times,
|
||||
'utilization_percentage': utilization * 100
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Efficient API Usage
|
||||
|
||||
1. **Batch Requests**: Combine multiple operations when possible
|
||||
2. **Cache Responses**: Cache frequently accessed data
|
||||
3. **Optimize Queries**: Use specific parameters to reduce processing
|
||||
4. **Monitor Usage**: Track your rate limit consumption
|
||||
5. **Plan Ahead**: Consider rate limits in your application design
|
||||
|
||||
### Error Handling
|
||||
|
||||
1. **Implement Backoff**: Use exponential backoff for retries
|
||||
2. **Handle 429 Errors**: Properly handle rate limit responses
|
||||
3. **Monitor Headers**: Check rate limit headers in responses
|
||||
4. **Queue Requests**: Implement request queuing for high-volume usage
|
||||
5. **Graceful Degradation**: Provide fallbacks when rate limited
|
||||
|
||||
### Application Design
|
||||
|
||||
1. **Async Processing**: Use asynchronous requests when possible
|
||||
2. **Request Prioritization**: Prioritize important requests
|
||||
3. **Load Balancing**: Distribute requests across time
|
||||
4. **Circuit Breakers**: Implement circuit breakers for failures
|
||||
5. **Monitoring**: Monitor rate limit usage and errors
|
||||
|
||||
## Rate Limit by Endpoint
|
||||
|
||||
### Content Generation Endpoints
|
||||
|
||||
| Endpoint | Free | Basic | Pro | Enterprise |
|
||||
|----------|------|-------|-----|------------|
|
||||
| `/api/blog-writer` | 5/min | 30/min | 150/min | 500/min |
|
||||
| `/api/linkedin-writer` | 5/min | 30/min | 150/min | 500/min |
|
||||
| `/api/seo-dashboard/analyze` | 10/min | 60/min | 300/min | 1000/min |
|
||||
|
||||
### Research Endpoints
|
||||
|
||||
| Endpoint | Free | Basic | Pro | Enterprise |
|
||||
|----------|------|-------|-----|------------|
|
||||
| `/api/research` | 5/min | 20/min | 100/min | 300/min |
|
||||
| `/api/keywords/research` | 10/min | 50/min | 200/min | 500/min |
|
||||
|
||||
### Analytics Endpoints
|
||||
|
||||
| Endpoint | Free | Basic | Pro | Enterprise |
|
||||
|----------|------|-------|-----|------------|
|
||||
| `/api/analytics` | 20/min | 100/min | 500/min | 1000/min |
|
||||
| `/api/performance` | 10/min | 50/min | 200/min | 500/min |
|
||||
|
||||
## Upgrading Plans
|
||||
|
||||
### When to Upgrade
|
||||
|
||||
Consider upgrading if you:
|
||||
- **Hit rate limits frequently**: Consistently exceed your limits
|
||||
- **Need higher throughput**: Require more requests per minute
|
||||
- **Have growing usage**: Usage is increasing over time
|
||||
- **Need priority support**: Require dedicated support
|
||||
|
||||
### Plan Comparison
|
||||
|
||||
| Feature | Free | Basic | Pro | Enterprise |
|
||||
|---------|------|-------|-----|------------|
|
||||
| Requests/min | 10 | 60 | 300 | 1,000 |
|
||||
| Requests/day | 100 | 1,000 | 10,000 | 100,000 |
|
||||
| Priority Support | ❌ | ❌ | ✅ | ✅ |
|
||||
| Custom Limits | ❌ | ❌ | ❌ | ✅ |
|
||||
| SLA | ❌ | ❌ | ✅ | ✅ |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Frequent Rate Limiting
|
||||
- **Check usage patterns**: Analyze when you hit limits
|
||||
- **Optimize requests**: Reduce unnecessary API calls
|
||||
- **Implement caching**: Cache responses to reduce calls
|
||||
- **Consider upgrading**: Evaluate if you need a higher plan
|
||||
|
||||
#### Inconsistent Limits
|
||||
- **Check endpoint limits**: Some endpoints have different limits
|
||||
- **Verify plan**: Ensure you're on the expected plan
|
||||
- **Contact support**: Reach out if limits seem incorrect
|
||||
|
||||
#### Performance Issues
|
||||
- **Monitor response times**: Check if rate limiting affects performance
|
||||
- **Implement queuing**: Use request queuing for better performance
|
||||
- **Optimize code**: Improve request efficiency
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **Documentation**: Check API documentation for specific limits
|
||||
- **Support**: Contact support for rate limit questions
|
||||
- **Community**: Join developer community for best practices
|
||||
- **Status Page**: Check for any service issues
|
||||
|
||||
---
|
||||
|
||||
*Need help with rate limiting? [Contact Support](https://support.alwrity.com) or [Upgrade Your Plan](https://dashboard.alwrity.com/billing) for higher limits!*
|
||||
- **Verify plan**: Ensure you're on the expected plan
|
||||
- **Contact support**: Reach out if limits seem incorrect
|
||||
|
||||
#### Performance Issues
|
||||
- **Monitor response times**: Check if rate limiting affects performance
|
||||
- **Implement queuing**: Use request queuing for better performance
|
||||
- **Optimize code**: Improve request efficiency
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **Documentation**: Check API documentation for specific limits
|
||||
- **Support**: Contact support for rate limit questions
|
||||
- **Community**: Join developer community for best practices
|
||||
- **Status Page**: Check for any service issues
|
||||
|
||||
---
|
||||
|
||||
*Need help with rate limiting? [Contact Support](https://support.alwrity.com) or [Upgrade Your Plan](https://dashboard.alwrity.com/billing) for higher limits!*
|
||||
Reference in New Issue
Block a user