# API Endpoints Reference **Last Verified:** January 20, 2026 **Version:** 1.8.4 **Base URL:** `/api/v1/` **Documentation:** `/api/docs/` (Swagger) | `/api/redoc/` (ReDoc) --- ## Authentication All endpoints require authentication unless noted. **Methods:** - `Authorization: Bearer ` - JWT token - `Authorization: ApiKey ` - API key (WordPress integration) - Session cookie (Django Admin) --- ## Auth Endpoints (`/api/v1/auth/`) | Method | Path | Handler | Auth | Purpose | |--------|------|---------|------|---------| | POST | `/register/` | `RegisterView` | ❌ | Create account | | POST | `/login/` | `LoginView` | ❌ | Get tokens | | POST | `/logout/` | `LogoutView` | ✅ | Invalidate session | | POST | `/token/refresh/` | `RefreshTokenView` | ✅ | Refresh access token | | POST | `/password/change/` | `ChangePasswordView` | ✅ | Change password | | POST | `/password/reset/` | `RequestPasswordResetView` | ❌ | Request reset email | | POST | `/password/reset/confirm/` | `ResetPasswordView` | ❌ | Confirm reset | | GET | `/groups/` | `RoleViewSet.list` | ✅ | List roles | | GET | `/users/` | `UserViewSet.list` | ✅ | List users | | POST | `/users/` | `UserViewSet.create` | ✅ | Create user | | GET | `/account/` | `AccountViewSet.retrieve` | ✅ | Get account | | PUT | `/account/` | `AccountViewSet.update` | ✅ | Update account | | GET | `/sites/` | `SiteViewSet.list` | ✅ | List sites | | POST | `/sites/` | `SiteViewSet.create` | ✅ | Create site | | GET | `/sectors/` | `SectorViewSet.list` | ✅ | List sectors | | POST | `/sectors/` | `SectorViewSet.create` | ✅ | Create sector | | GET | `/industries/` | `IndustryViewSet.list` | ✅ | List industries | | GET | `/keywords-library/` | `SeedKeywordViewSet.list` | ✅ | List keywords library (v1.8.2) | | GET | `/keywords-library/sector_stats/` | `SeedKeywordViewSet.sector_stats` | ✅ | Get sector statistics (v1.8.2) | --- ## Keywords Library Endpoints (v1.8.2) **New Endpoint:** `/api/v1/keywords-library/` **Previous:** `/api/v1/auth/seed-keywords/` (deprecated, no backward compatibility) ### List Keywords ``` GET /api/v1/keywords-library/ ``` **Query Parameters:** - `sector_ids` _(string, comma-separated)_ - Filter by specific sector IDs (e.g., `1,2,3`) - **New in v1.8.2:** Ensures sites only see keywords from their configured sectors - `search` _(string)_ - Search keyword names - `country` _(string)_ - Filter by country code (e.g., `US`, `UK`) - `volume_min` _(number)_ - Minimum search volume - `volume_max` _(number)_ - Maximum search volume - `difficulty` _(string)_ - SEO difficulty level (`easy`, `medium`, `hard`, `very_hard`) - `is_high_opportunity` _(boolean)_ - Filter high-opportunity keywords - `is_paid` _(boolean)_ - Filter paid/premium keywords - `ordering` _(string)_ - Sort field (prefix `-` for descending) - Options: `keyword`, `volume`, `difficulty`, `country` - Default: `-volume` - `page` _(number)_ - Page number for pagination - `page_size` _(number)_ - Results per page (default: 20) **Example Request:** ```bash GET /api/v1/keywords-library/?sector_ids=1,2,3&country=US&difficulty=easy&ordering=-volume&page=1 ``` **Response:** ```json { "count": 150, "next": "http://api.igny8.com/api/v1/keywords-library/?page=2§or_ids=1,2,3", "previous": null, "results": [ { "id": 1, "keyword": "cloud computing services", "volume": 12000, "difficulty": "medium", "country": "US", "industry_sector": 1, "industry_sector_name": "Cloud Infrastructure & Services", "is_high_opportunity": true, "is_paid": false, "credit_cost": 0, "created_at": "2025-01-15T10:00:00Z" } ] } ``` ### Sector Statistics ``` GET /api/v1/keywords-library/sector_stats/ ``` Returns aggregated statistics per sector for the keywords library. **Query Parameters:** - `sector_ids` _(string, comma-separated)_ - Filter by specific sector IDs - **New in v1.8.2:** Returns stats only for specified sectors **Example Request:** ```bash GET /api/v1/keywords-library/sector_stats/?sector_ids=1,2,3 ``` **Response:** ```json [ { "sector_id": 1, "sector_name": "Cloud Infrastructure & Services", "sector_description": "Keywords related to cloud computing, hosting, and infrastructure services", "stats": { "total": 250, "added": 45, "available": 205, "high_opportunity": 80, "paid": 30, "free": 220 } } ] ``` **Stat Definitions:** - `total` - All keywords in sector - `added` - Keywords site has added to their workflow - `available` - Keywords not yet added (total - added) - `high_opportunity` - Premium keywords with high volume and potential - `paid` - Premium keywords requiring credits - `free` - Keywords with no credit cost **Use Cases:** 1. **Sector Metric Cards** - Display stats per sector with clickable filters 2. **Smart Suggestions** - Show available counts for bulk-add operations 3. **Progress Tracking** - Track keyword adoption across sectors 4. **Budget Planning** - Understand credit requirements for paid keywords --- ## Planner Endpoints (`/api/v1/planner/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/keywords/` | `KeywordViewSet.list` | List keywords | | POST | `/keywords/` | `KeywordViewSet.create` | Create keyword | | GET | `/keywords/{id}/` | `KeywordViewSet.retrieve` | Get keyword | | PUT | `/keywords/{id}/` | `KeywordViewSet.update` | Update keyword | | DELETE | `/keywords/{id}/` | `KeywordViewSet.destroy` | Delete keyword | | POST | `/keywords/bulk_delete/` | `KeywordViewSet.bulk_delete` | Hard delete multiple | | POST | `/keywords/bulk_status/` | `KeywordViewSet.bulk_status` | Update status | | POST | `/keywords/add_to_workflow/` | `KeywordViewSet.add_to_workflow` | Add seed keywords | | GET | `/clusters/` | `ClusterViewSet.list` | List clusters | | POST | `/clusters/` | `ClusterViewSet.create` | Create cluster | | POST | `/clusters/auto_cluster/` | `ClusterViewSet.auto_cluster` | AI clustering | | POST | `/clusters/generate_ideas/` | `ClusterViewSet.generate_ideas` | Generate ideas | | GET | `/ideas/` | `ContentIdeaViewSet.list` | List ideas | | POST | `/ideas/` | `ContentIdeaViewSet.create` | Create idea | | POST | `/ideas/create_tasks/` | `ContentIdeaViewSet.create_tasks` | Convert to tasks | **Query Parameters:** - `?site_id=` - Filter by site - `?sector_id=` - Filter by sector - `?status=` - Filter by status - `?cluster_id=` - Filter by cluster - `?difficulty_min=`, `?difficulty_max=` - Difficulty range - `?volume_min=`, `?volume_max=` - Volume range --- ## Writer Endpoints (`/api/v1/writer/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/tasks/` | `TaskViewSet.list` | List tasks | | POST | `/tasks/` | `TaskViewSet.create` | Create task | | POST | `/tasks/bulk_create/` | `TaskViewSet.bulk_create` | Create multiple | | POST | `/tasks/{id}/generate_content/` | `TaskViewSet.generate_content` | AI generation | | GET | `/content/` | `ContentViewSet.list` | List content | | POST | `/content/` | `ContentViewSet.create` | Create content | | GET | `/content/{id}/` | `ContentViewSet.retrieve` | Get content | | PUT | `/content/{id}/` | `ContentViewSet.update` | Update content | | POST | `/content/{id}/update_content/` | `ContentViewSet.update_content` | Update with validation | | POST | `/content/{id}/generate_images/` | `ContentViewSet.generate_images` | Generate images | | POST | `/content/{id}/publish_to_wordpress/` | `ContentViewSet.publish_to_wordpress` | Publish to WP | | POST | `/content/{id}/schedule/` | `ContentViewSet.schedule` | Schedule for publishing (v1.3.2) | | POST | `/content/{id}/unschedule/` | `ContentViewSet.unschedule` | Remove from schedule (v1.3.2) | | GET | `/images/` | `ImageViewSet.list` | List images | | POST | `/images/generate_for_content/` | `ImageViewSet.generate_for_content` | Generate images | | POST | `/images/regenerate/` | `ImageViewSet.regenerate` | Regenerate image | | GET | `/taxonomies/` | `TaxonomyViewSet.list` | List taxonomies | **Content Query Parameters (v1.3.2):** - `?status__in=draft,review,approved` - Filter by multiple workflow statuses - `?site_status=scheduled` - Filter by publishing status - `?site_id=` - Filter by site **Schedule Endpoint Request:** ```json POST /api/v1/writer/content/{id}/schedule/ { "scheduled_publish_at": "2026-01-15T09:00:00Z" } ``` **Schedule Endpoint Response:** ```json { "content_id": 123, "site_status": "scheduled", "scheduled_publish_at": "2026-01-15T09:00:00Z" } ``` --- ## Billing Endpoints (`/api/v1/billing/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/balance/` | `CreditBalanceViewSet.list` | Current balance | | GET | `/usage/` | `CreditUsageViewSet.list` | Usage log | | GET | `/usage/summary/` | `CreditUsageViewSet.summary` | Usage summary | | GET | `/usage/limits/` | `CreditUsageViewSet.limits` | Plan limits | | GET | `/transactions/` | `TransactionViewSet.list` | Transaction history | --- ## Integration Endpoints (`/api/v1/integration/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/` | `SiteIntegrationViewSet.list` | List integrations | | POST | `/` | `SiteIntegrationViewSet.create` | Create integration | | PUT | `/{id}/` | `SiteIntegrationViewSet.update` | Update integration | | DELETE | `/{id}/` | `SiteIntegrationViewSet.destroy` | Delete integration | | POST | `/{id}/test_connection/` | Test connection | Verify credentials | | POST | `/{id}/test_collection_connection/` | Test collection | Test specific type | | POST | `/{id}/sync/` | Trigger sync | Start sync | | GET | `/{id}/sync_status/` | Sync status | Current progress | | POST | `/{id}/update_structure/` | Update structure | Refresh site data | | GET | `/{id}/content_types/` | Content types | Available types | | GET | `/{id}/sync_health/` | Sync health | Statistics | | POST | `/site_sync/` | Site-level sync | Sync by site ID | | POST | `/webhook/wordpress/` | WordPress webhook | Receive WP updates | ### Unified Settings Endpoints (v1.8.0) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/sites/{site_id}/unified-settings/` | `UnifiedSiteSettingsViewSet.retrieve` | Get all site settings (automation, publishing, AI) | | PATCH | `/sites/{site_id}/unified-settings/` | `UnifiedSiteSettingsViewSet.partial_update` | Update settings (partial) | | **GET** | `/settings/defaults/` | **v1.8.1** `DefaultSettingsAPIView` | Get default settings for reset functionality | ### Default Settings Endpoint (v1.8.1) Returns centralized defaults from `DefaultAutomationConfig` singleton: ```json GET /api/v1/integration/settings/defaults/ { "automation": { "enabled": false, "frequency": "daily", "time": "02:00" }, "stages": [ {"number": 1, "enabled": true, "batch_size": 50, "per_run_limit": 0, "use_testing": false, "budget_pct": 15}, {"number": 2, "enabled": true, "batch_size": 1, "per_run_limit": 0, "use_testing": false, "budget_pct": 10}, // ... stages 3-7 ], "delays": { "within_stage": 3, "between_stage": 5 }, "publishing": { "auto_approval_enabled": false, "auto_publish_enabled": false, "daily_publish_limit": 3, "weekly_publish_limit": 15, "monthly_publish_limit": 50, "publish_days": ["mon", "tue", "wed", "thu", "fri"], "time_slots": ["09:00", "14:00", "18:00"] }, "images": { "style": "photorealistic", "max_images": 4 } } ``` **Unified Settings Response:** ```json { "automation_config": { "enabled": true, "frequency": "daily", "scheduled_days": ["mon", "wed", "fri"], "scheduled_time": "09:00:00", "next_run_at": "2026-01-18T09:00:00Z", "stage_1_enabled": true, "stage_1_batch_size": 50, "max_keywords_per_run": 100, "stage_2_enabled": true, "stage_2_batch_size": 10, "max_clusters_per_run": 20, // ... stages 3-7 }, "publishing_settings": { "auto_approval_enabled": true, "auto_publish_enabled": true, "daily_publish_limit": 3, "weekly_publish_limit": 15, "monthly_publish_limit": 50, "publish_days": ["mon", "tue", "wed", "thu", "fri"], "publish_time_slots": [{"start": "09:00", "end": "17:00"}], "total_items_per_run": 500 }, "stage_configs": [ {"stage": 1, "enabled": true, "batch_size": 50, "max_per_run": 100}, // ... stages 2-7 ], "ai_settings": { "testing_model_id": 2, "live_model_id": 1, "image_model_id": 3 } } ``` ### Publishing Settings Endpoints (deprecated v1.8.0) > ⚠️ **Deprecated:** Use `/sites/{site_id}/unified-settings/` instead | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/sites/{site_id}/publishing-settings/` | `PublishingSettingsViewSet.retrieve` | Get publishing settings | | PUT | `/sites/{site_id}/publishing-settings/` | `PublishingSettingsViewSet.update` | Update settings (full) | | PATCH | `/sites/{site_id}/publishing-settings/` | `PublishingSettingsViewSet.partial_update` | Update settings (partial) | **Publishing Settings Response:** ```json { "id": 1, "site": 5, "auto_approval_enabled": true, "auto_publish_enabled": true, "daily_publish_limit": 3, "weekly_publish_limit": 15, "monthly_publish_limit": 50, "publish_days": ["mon", "tue", "wed", "thu", "fri"], "publish_time_slots": ["09:00", "14:00", "18:00"], "created_at": "2026-01-03T10:00:00Z", "updated_at": "2026-01-03T10:00:00Z" } ``` --- ## System Endpoints (`/api/v1/system/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/settings/integrations/openai/` | Get OpenAI settings | Current config | | PUT | `/settings/integrations/openai/` | Save OpenAI settings | Update config | | GET | `/settings/integrations/image_generation/` | Get image settings | Current config | | PUT | `/settings/integrations/image_generation/` | Save image settings | Update config | | POST | `/settings/integrations/test/` | Test connection | Verify API keys | | GET | `/settings/content/{key}/` | `ContentSettingsViewSet.retrieve` | Get content settings | | POST | `/settings/content/{key}/save/` | `ContentSettingsViewSet.save_settings` | Save content settings | | GET | `/prompts/` | List prompts | All prompts | | GET | `/prompts/{type}/` | Get prompt | Specific prompt | | PUT | `/prompts/{type}/` | Save prompt | Update prompt | | POST | `/prompts/{type}/reset/` | Reset prompt | Reset to default | | GET | `/modules/` | Get modules | Module enable state | | PUT | `/modules/` | Save modules | Update enabled | | GET | `/health/` | Health check | System status | **Content Settings Keys:** - `content_generation` - AI writing settings (default_article_length, default_tone, include_faq, enable_internal_linking, etc.) - `publishing` - Publishing defaults (default_publish_status, auto_schedule, schedule_frequency, schedule_times) --- ## Notification Endpoints (`/api/v1/notifications/`) - v1.2.0 | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/` | `NotificationViewSet.list` | List notifications (paginated) | | GET | `/{id}/` | `NotificationViewSet.retrieve` | Get notification detail | | DELETE | `/{id}/` | `NotificationViewSet.destroy` | Delete notification | | POST | `/{id}/read/` | `NotificationViewSet.read` | Mark single notification as read | | POST | `/read-all/` | `NotificationViewSet.read_all` | Mark all notifications as read | | GET | `/unread-count/` | `NotificationViewSet.unread_count` | Get unread notification count | **Query Parameters:** - `?page=` - Page number for pagination - `?page_size=` - Results per page (default 20) - `?is_read=` - Filter by read status (true/false) - `?notification_type=` - Filter by type (ai_task, system, credit, billing, integration, content, info) **Notification Types:** - `ai_cluster_complete`, `ai_cluster_failed` - Clustering operations - `ai_ideas_complete`, `ai_ideas_failed` - Idea generation - `ai_content_complete`, `ai_content_failed` - Content generation - `ai_images_complete`, `ai_images_failed` - Image generation - `ai_prompts_complete`, `ai_prompts_failed` - Image prompt generation - `content_ready_review`, `content_published`, `content_publish_failed` - Workflow - `wordpress_sync_success`, `wordpress_sync_failed` - WordPress sync - `credits_low`, `credits_depleted` - Billing alerts - `site_setup_complete`, `keywords_imported` - Setup - `system_info` - System notifications **Response Format:** ```json { "id": 1, "notification_type": "ai_content_complete", "severity": "success", "title": "Content Generated", "message": "Generated 5 articles successfully", "is_read": false, "created_at": "2025-12-27T12:00:00Z", "read_at": null, "action_label": "View Content", "action_url": "/writer/content", "metadata": {"count": 5, "credits": 250} } ``` --- ## Automation Endpoints (`/api/v1/automation/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/config/` | Get config | Automation config | | PUT | `/update_config/` | Update config | Save settings | | POST | `/run_now/` | Run now | Start manual run | | GET | `/current_run/` | Current run | Run status | | GET | `/pipeline_overview/` | Pipeline | Stage counts | | GET | `/current_processing/` | Processing | Live status | | POST | `/pause/` | Pause | Pause run | | POST | `/resume/` | Resume | Resume run | | POST | `/cancel/` | Cancel | Cancel run | | GET | `/history/` | History | Past runs | | GET | `/logs/` | Logs | Activity log | | GET | `/estimate/` | Estimate | Credit estimate | | **GET** | `/runs/` | **v1.8.0** List runs | All automation runs (paginated) | | **GET** | `/runs/{id}/` | **v1.8.0** Run detail | Single run with stages, logs | **Query Parameters:** All require `?site_id=`, run-specific require `?run_id=` ### Automation Runs Response (v1.8.0) ```json GET /api/v1/automation/runs/?site_id=1 { "count": 25, "results": [ { "id": 1, "site": 1, "status": "completed", "started_at": "2026-01-18T09:00:00Z", "completed_at": "2026-01-18T09:45:00Z", "current_stage": 7, "total_stages": 7, "items_processed": 150, "credits_used": 450, "error_message": null } ] } ``` --- ## Linker Endpoints (`/api/v1/linker/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | POST | `/process/` | `LinkerViewSet.process` | Process single content | | POST | `/batch_process/` | `LinkerViewSet.batch_process` | Process multiple | --- ## Optimizer Endpoints (`/api/v1/optimizer/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | POST | `/optimize/` | `OptimizerViewSet.optimize` | Optimize content | | POST | `/batch_optimize/` | `OptimizerViewSet.batch_optimize` | Batch optimize | | POST | `/analyze/` | `OptimizerViewSet.analyze` | Analyze only | --- ## Publisher Endpoints (`/api/v1/publisher/`) | Method | Path | Handler | Purpose | |--------|------|---------|---------| | GET | `/records/` | `PublishingRecordViewSet.list` | List records | | POST | `/records/` | `PublishingRecordViewSet.create` | Create record | | GET | `/deployments/` | `DeploymentViewSet.list` | List deployments | | POST | `/publish/` | `PublishContentViewSet.publish` | Publish content | | GET | `/publish/status/` | `PublishContentViewSet.status` | Publish status | | GET | `/site-definition/` | `SiteDefinitionViewSet.list` | Public site def | --- ## Response Format ### Success Response ```json { "success": true, "data": { ... }, "message": "Optional message" } ``` ### Error Response ```json { "success": false, "error": "Error message", "code": "ERROR_CODE" } ``` ### Paginated Response ```json { "count": 100, "next": "http://api.igny8.com/api/v1/planner/keywords/?page=2", "previous": null, "results": [ ... ] } ``` --- ## HTTP Status Codes | Code | Meaning | |------|---------| | 200 | Success | | 201 | Created | | 400 | Bad Request | | 401 | Unauthorized | | 402 | Payment Required (insufficient credits) | | 403 | Forbidden | | 404 | Not Found | | 429 | Rate Limited | | 500 | Server Error | --- ## Rate Limiting Rate limits are scoped by operation type: | Scope | Limit | |-------|-------| | AI operations | 60/min | | Content operations | 100/min | | Auth operations | 20/min | | General | 300/min | Rate limit headers included in responses: - `X-RateLimit-Limit` - `X-RateLimit-Remaining` - `X-RateLimit-Reset`