# Admin API Reference Admin endpoints for testing and manual operations. ## Overview The admin API allows you to trigger manual operations like crawling news and sending test emails directly through HTTP requests. **How it works**: The backend container has access to the Docker socket, allowing it to execute commands in other containers via `docker exec`. --- ## API Endpoints ### Trigger Crawler Manually trigger the news crawler to fetch new articles. ```http POST /api/admin/trigger-crawl ``` **Request Body** (optional): ```json { "max_articles": 10 } ``` **Parameters**: - `max_articles` (integer, optional): Number of articles to crawl per feed (1-100, default: 10) **Response**: ```json { "success": true, "message": "Crawler executed successfully", "max_articles": 10, "output": "... crawler output (last 1000 chars) ...", "errors": "" } ``` **Example**: ```bash # Crawl 5 articles per feed curl -X POST http://localhost:5001/api/admin/trigger-crawl \ -H "Content-Type: application/json" \ -d '{"max_articles": 5}' # Use default (10 articles) curl -X POST http://localhost:5001/api/admin/trigger-crawl ``` --- ### Send Test Email Send a test newsletter to a specific email address. ```http POST /api/admin/send-test-email ``` **Request Body**: ```json { "email": "test@example.com", "max_articles": 10 } ``` **Parameters**: - `email` (string, required): Email address to send test newsletter to - `max_articles` (integer, optional): Number of articles to include (1-50, default: 10) **Response**: ```json { "success": true, "message": "Test email sent to test@example.com", "email": "test@example.com", "output": "... sender output ...", "errors": "" } ``` **Example**: ```bash # Send test email curl -X POST http://localhost:5001/api/admin/send-test-email \ -H "Content-Type: application/json" \ -d '{"email": "your-email@example.com"}' # Send with custom article count curl -X POST http://localhost:5001/api/admin/send-test-email \ -H "Content-Type: application/json" \ -d '{"email": "your-email@example.com", "max_articles": 5}' ``` --- ### Send Newsletter to All Subscribers Send newsletter to all active subscribers in the database. ```http POST /api/admin/send-newsletter ``` **Request Body** (optional): ```json { "max_articles": 10 } ``` **Parameters**: - `max_articles` (integer, optional): Number of articles to include (1-50, default: 10) **Response**: ```json { "success": true, "message": "Newsletter sent successfully to 45 subscribers", "subscriber_count": 45, "max_articles": 10, "output": "... sender output ...", "errors": "" } ``` **Example**: ```bash # Send newsletter to all subscribers curl -X POST http://localhost:5001/api/admin/send-newsletter \ -H "Content-Type: application/json" # Send with custom article count curl -X POST http://localhost:5001/api/admin/send-newsletter \ -H "Content-Type: application/json" \ -d '{"max_articles": 15}' ``` **Notes**: - Only sends to subscribers with `status: 'active'` - Returns error if no active subscribers found - Includes tracking pixels and click tracking - May take several minutes for large subscriber lists --- ### Get System Statistics Get overview statistics of the system. ```http GET /api/admin/stats ``` **Response**: ```json { "articles": { "total": 150, "with_summary": 120, "today": 15 }, "subscribers": { "total": 50, "active": 45 }, "rss_feeds": { "total": 4, "active": 4 }, "tracking": { "total_sends": 200, "total_opens": 150, "total_clicks": 75 } } ``` **Example**: ```bash curl http://localhost:5001/api/admin/stats ``` --- ## Workflow Examples ### Test Complete System ```bash # 1. Check current stats curl http://localhost:5001/api/admin/stats # 2. Trigger crawler to fetch new articles curl -X POST http://localhost:5001/api/admin/trigger-crawl \ -H "Content-Type: application/json" \ -d '{"max_articles": 5}' # 3. Wait a moment for crawler to finish, then check stats again sleep 30 curl http://localhost:5001/api/admin/stats # 4. Send test email to yourself curl -X POST http://localhost:5001/api/admin/send-test-email \ -H "Content-Type: application/json" \ -d '{"email": "your-email@example.com"}' ``` ### Send Newsletter to All Subscribers ```bash # 1. Check subscriber count curl http://localhost:5001/api/admin/stats | jq '.subscribers' # 2. Crawl fresh articles curl -X POST http://localhost:5001/api/admin/trigger-crawl \ -H "Content-Type: application/json" \ -d '{"max_articles": 10}' # 3. Wait for crawl to complete sleep 60 # 4. Send newsletter to all active subscribers curl -X POST http://localhost:5001/api/admin/send-newsletter \ -H "Content-Type: application/json" \ -d '{"max_articles": 10}' ``` ### Quick Test Newsletter ```bash # Send test email with latest articles curl -X POST http://localhost:5001/api/admin/send-test-email \ -H "Content-Type: application/json" \ -d '{"email": "your-email@example.com", "max_articles": 3}' ``` ### Fetch Fresh Content ```bash # Crawl more articles from each feed curl -X POST http://localhost:5001/api/admin/trigger-crawl \ -H "Content-Type: application/json" \ -d '{"max_articles": 20}' ``` ### Daily Newsletter Workflow ```bash # Complete daily workflow (can be automated with cron) # 1. Crawl today's articles curl -X POST http://localhost:5001/api/admin/trigger-crawl \ -H "Content-Type: application/json" \ -d '{"max_articles": 15}' # 2. Wait for crawl and AI processing sleep 120 # 3. Send to all subscribers curl -X POST http://localhost:5001/api/admin/send-newsletter \ -H "Content-Type: application/json" \ -d '{"max_articles": 10}' # 4. Check results curl http://localhost:5001/api/admin/stats ``` --- ## Error Responses All endpoints return standard error responses: ```json { "success": false, "error": "Error message here" } ``` **Common HTTP Status Codes**: - `200` - Success - `400` - Bad request (invalid parameters) - `500` - Server error --- ## Security Notes ⚠️ **Important**: These are admin endpoints and should be protected in production! Recommendations: 1. Add authentication/authorization 2. Rate limiting 3. IP whitelisting 4. API key requirement 5. Audit logging Example protection (add to routes): ```python from functools import wraps from flask import request def require_api_key(f): @wraps(f) def decorated_function(*args, **kwargs): api_key = request.headers.get('X-API-Key') if api_key != os.getenv('ADMIN_API_KEY'): return jsonify({'error': 'Unauthorized'}), 401 return f(*args, **kwargs) return decorated_function @admin_bp.route('/api/admin/trigger-crawl', methods=['POST']) @require_api_key def trigger_crawl(): # ... endpoint code ``` --- ## Related Endpoints - **[Newsletter Preview](../backend/routes/newsletter_routes.py)**: `/api/newsletter/preview` - Preview newsletter HTML - **[Analytics](API.md)**: `/api/analytics/*` - View engagement metrics - **[RSS Feeds](API.md)**: `/api/rss-feeds` - Manage RSS feeds --- ## Newsletter API Summary ### Available Endpoints | Endpoint | Purpose | Recipient | |----------|---------|-----------| | `/api/admin/send-test-email` | Test newsletter | Single email (specified) | | `/api/admin/send-newsletter` | Production send | All active subscribers | | `/api/admin/trigger-crawl` | Fetch articles | N/A | | `/api/admin/stats` | System stats | N/A | ### Subscriber Status The system uses a `status` field to determine who receives newsletters: - **`active`** - Receives newsletters ✅ - **`inactive`** - Does not receive newsletters ❌ See [SUBSCRIBER_STATUS.md](SUBSCRIBER_STATUS.md) for details. ### Quick Examples **Send to all subscribers:** ```bash curl -X POST http://localhost:5001/api/admin/send-newsletter \ -H "Content-Type: application/json" \ -d '{"max_articles": 10}' ``` **Send test email:** ```bash curl -X POST http://localhost:5001/api/admin/send-test-email \ -H "Content-Type: application/json" \ -d '{"email": "test@example.com"}' ``` **Check stats:** ```bash curl http://localhost:5001/api/admin/stats | jq '.subscribers' ``` ### Testing Use the test script: ```bash ./test-newsletter-api.sh ```