38 KiB
IGNY8 API Endpoints - Complete Analysis
Date: 2025-01-XX
Purpose: Comprehensive analysis of all existing API endpoints in the Django deployment, including request/response formats, authentication, rate limiting, usage patterns, and third-party integrations.
Executive Summary
Base URL: /api/v1/
Total Endpoints: 100+ endpoints across 5 main modules
Authentication: JWT Bearer tokens (primary), Session authentication (fallback), Basic authentication (fallback)
Rate Limiting: Not currently implemented (planned for future)
Response Format: Standardized JSON with success, data, message, errors fields
Pagination: Custom pagination with page_size parameter (default: 10, max: 100)
Table of Contents
- API Architecture Overview
- Authentication & Authorization
- Response Format Standards
- Pagination Format
- Auth Module Endpoints
- Planner Module Endpoints
- Writer Module Endpoints
- System Module Endpoints
- Billing Module Endpoints
- Frontend API Usage Patterns
- Third-Party Integrations
- Dependencies
- Standardization Recommendations
API Architecture Overview
Base URL Structure
/api/v1/
├── auth/ # Authentication and user management
├── planner/ # Keywords, clusters, content ideas
├── writer/ # Tasks, content, images
├── system/ # Settings, integrations, prompts
└── billing/ # Credits, transactions, usage
Technology Stack
- Framework: Django REST Framework (DRF)
- Router: DefaultRouter (RESTful ViewSets)
- Authentication: Custom JWT + Session + Basic
- Pagination: CustomPageNumberPagination
- Filtering: DjangoFilterBackend, SearchFilter, OrderingFilter
- Serialization: DRF Serializers
Base Classes
AccountModelViewSet:
- Automatic account filtering
- Admin/Developer override (bypasses account filtering)
- System account users bypass account filtering
- Sets account on create operations
SiteSectorModelViewSet:
- Inherits from AccountModelViewSet
- Additional site/sector filtering
- Site access control (based on user role)
- Sector validation (must belong to site)
Authentication & Authorization
Authentication Methods
1. JWT Authentication (Primary)
- Class:
igny8_core.api.authentication.JWTAuthentication - Header:
Authorization: Bearer <token> - Token Type: Access token (type: 'access')
- Expiry: 15 minutes (configurable via
JWT_ACCESS_TOKEN_EXPIRY) - Token Payload: Contains
user_id,account_id,type: 'access' - Account Context: Sets
request.accountfrom token
2. Session Authentication (Fallback)
- Class:
igny8_core.api.authentication.CSRFExemptSessionAuthentication - Method: Session cookies (CSRF exempt for API)
- Use Case: Admin panel, fallback when JWT fails
3. Basic Authentication (Fallback)
- Class:
rest_framework.authentication.BasicAuthentication - Method: HTTP Basic Auth
- Use Case: Fallback authentication
Authentication Configuration
Location: backend/igny8_core/settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'igny8_core.api.authentication.JWTAuthentication', # Primary
'igny8_core.api.authentication.CSRFExemptSessionAuthentication', # Fallback
'rest_framework.authentication.BasicAuthentication', # Fallback
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny', # Default: AllowAny
],
}
Permission Classes
Default: AllowAny (most endpoints)
Custom Permission Classes:
IsAuthenticated: Requires authenticationIsOwnerOrAdmin: Owner or Admin role requiredIsEditorOrAbove: Editor, Admin, or Owner role required- ViewSet-level overrides: Many ViewSets set
permission_classes = [](AllowAny)
Account Context Middleware
Class: igny8_core.auth.middleware.AccountContextMiddleware
Functionality:
- Extracts account ID from JWT token
- Loads Account object
- Sets
request.accountfor all requests - Enables automatic account filtering in ViewSets
Response Format Standards
Success Response
{
"success": true,
"data": { ... },
"message": "Optional success message"
}
Error Response
{
"success": false,
"error": "Error message",
"errors": {
"field_name": ["Error detail"]
}
}
Pagination Response
{
"count": 100,
"next": "http://api.igny8.com/api/v1/endpoint/?page=2",
"previous": null,
"results": [ ... ]
}
Standard Response Fields
- success: Boolean indicating success/failure
- data: Response data (object or array)
- message: Human-readable message (optional)
- error: Error message (on failure)
- errors: Validation errors object (on failure)
Pagination Format
CustomPageNumberPagination
Class: igny8_core.api.pagination.CustomPageNumberPagination
Configuration:
- Default page size: 10
- Max page size: 100
- Query parameter:
page_size(optional) - Page parameter:
page(default: 1)
Example Request:
GET /api/v1/planner/keywords/?page=2&page_size=25
Response:
{
"count": 150,
"next": "http://api.igny8.com/api/v1/planner/keywords/?page=3&page_size=25",
"previous": "http://api.igny8.com/api/v1/planner/keywords/?page=1&page_size=25",
"results": [ ... ]
}
Auth Module Endpoints
Base Path: /api/v1/auth/
Authentication Endpoints
POST /api/v1/auth/register/
Purpose: User registration
Authentication: None (AllowAny)
Request Body:
{
"email": "user@example.com",
"password": "password123",
"password_confirm": "password123"
}
Response:
{
"success": true,
"message": "Registration successful",
"user": {
"id": 1,
"email": "user@example.com",
"role": "owner",
"account": { ... }
}
}
Status Codes: 201 (Created), 400 (Bad Request)
POST /api/v1/auth/login/
Purpose: User login
Authentication: None (AllowAny)
Request Body:
{
"email": "user@example.com",
"password": "password123"
}
Response:
{
"success": true,
"message": "Login successful",
"user": { ... },
"tokens": {
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"access_expires_at": "2025-01-15T12:30:00Z",
"refresh_expires_at": "2025-01-22T12:00:00Z"
}
}
Status Codes: 200 (OK), 401 (Unauthorized), 400 (Bad Request)
POST /api/v1/auth/change-password/
Purpose: Change user password
Authentication: Required (IsAuthenticated)
Request Body:
{
"old_password": "oldpass123",
"new_password": "newpass123",
"new_password_confirm": "newpass123"
}
Response:
{
"success": true,
"message": "Password changed successfully"
}
Status Codes: 200 (OK), 400 (Bad Request)
GET /api/v1/auth/me/
Purpose: Get current user information
Authentication: Required (IsAuthenticated)
Response:
{
"success": true,
"user": {
"id": 1,
"email": "user@example.com",
"role": "owner",
"account": { ... },
"accessible_sites": [ ... ]
}
}
Status Codes: 200 (OK), 401 (Unauthorized)
User Management Endpoints
ViewSet: UsersViewSet
Base Path: /api/v1/auth/users/
Permission: IsOwnerOrAdmin
Standard CRUD:
GET /api/v1/auth/users/- List usersPOST /api/v1/auth/users/- Create userGET /api/v1/auth/users/{id}/- Get userPUT /api/v1/auth/users/{id}/- Update userDELETE /api/v1/auth/users/{id}/- Delete user
Custom Actions:
POST /api/v1/auth/users/invite/- Invite userPOST /api/v1/auth/users/{id}/activate/- Activate user
Account Management Endpoints
ViewSet: AccountsViewSet
Base Path: /api/v1/auth/accounts/
Permission: IsOwnerOrAdmin
Standard CRUD:
GET /api/v1/auth/accounts/- List accountsPOST /api/v1/auth/accounts/- Create accountGET /api/v1/auth/accounts/{id}/- Get accountPUT /api/v1/auth/accounts/{id}/- Update accountDELETE /api/v1/auth/accounts/{id}/- Delete account
Site Management Endpoints
ViewSet: SiteViewSet
Base Path: /api/v1/auth/sites/
Permission: IsEditorOrAbove
Standard CRUD:
GET /api/v1/auth/sites/- List sitesPOST /api/v1/auth/sites/- Create siteGET /api/v1/auth/sites/{id}/- Get sitePUT /api/v1/auth/sites/{id}/- Update siteDELETE /api/v1/auth/sites/{id}/- Delete site
Custom Actions:
GET /api/v1/auth/sites/{id}/sectors/- Get site sectorsPOST /api/v1/auth/sites/{id}/set_active/- Set active sitePOST /api/v1/auth/sites/{id}/select_sectors/- Select sectors
Sector Management Endpoints
ViewSet: SectorViewSet
Base Path: /api/v1/auth/sectors/
Permission: IsEditorOrAbove
Standard CRUD:
GET /api/v1/auth/sectors/- List sectorsPOST /api/v1/auth/sectors/- Create sectorGET /api/v1/auth/sectors/{id}/- Get sectorPUT /api/v1/auth/sectors/{id}/- Update sectorDELETE /api/v1/auth/sectors/{id}/- Delete sector
Plan Management Endpoints
ViewSet: PlanViewSet
Base Path: /api/v1/auth/plans/
Permission: AllowAny (read-only)
Endpoints:
GET /api/v1/auth/plans/- List plansGET /api/v1/auth/plans/{id}/- Get plan
Industry Management Endpoints
ViewSet: IndustryViewSet
Base Path: /api/v1/auth/industries/
Permission: AllowAny (read-only)
Endpoints:
GET /api/v1/auth/industries/- List industriesGET /api/v1/auth/industries/{id}/- Get industry
Seed Keyword Endpoints
ViewSet: SeedKeywordViewSet
Base Path: /api/v1/auth/seed-keywords/
Permission: AllowAny (read-only)
Endpoints:
GET /api/v1/auth/seed-keywords/- List seed keywordsGET /api/v1/auth/seed-keywords/{id}/- Get seed keyword
Site Access Management Endpoints
ViewSet: SiteUserAccessViewSet
Base Path: /api/v1/auth/site-access/
Permission: IsOwnerOrAdmin
Standard CRUD:
GET /api/v1/auth/site-access/- List site access recordsPOST /api/v1/auth/site-access/- Grant site accessGET /api/v1/auth/site-access/{id}/- Get site accessPUT /api/v1/auth/site-access/{id}/- Update site accessDELETE /api/v1/auth/site-access/{id}/- Revoke site access
Subscription Management Endpoints
ViewSet: SubscriptionsViewSet
Base Path: /api/v1/auth/subscriptions/
Permission: IsOwnerOrAdmin
Standard CRUD:
GET /api/v1/auth/subscriptions/- List subscriptionsPOST /api/v1/auth/subscriptions/- Create subscriptionGET /api/v1/auth/subscriptions/{id}/- Get subscriptionPUT /api/v1/auth/subscriptions/{id}/- Update subscriptionDELETE /api/v1/auth/subscriptions/{id}/- Delete subscription
Custom Actions:
GET /api/v1/auth/subscriptions/by-account/{account_id}/- Get subscriptions by account
Planner Module Endpoints
Base Path: /api/v1/planner/
Keyword Management Endpoints
ViewSet: KeywordViewSet
Base Path: /api/v1/planner/keywords/
Permission: AllowAny (default)
Inherits: SiteSectorModelViewSet (automatic account/site/sector filtering)
Standard CRUD:
GET /api/v1/planner/keywords/- List keywords (paginated)POST /api/v1/planner/keywords/- Create keywordGET /api/v1/planner/keywords/{id}/- Get keywordPUT /api/v1/planner/keywords/{id}/- Update keywordDELETE /api/v1/planner/keywords/{id}/- Delete keyword
Filtering:
status: Filter by statuscluster_id: Filter by clusterseed_keyword__intent: Filter by intentseed_keyword_id: Filter by seed keyword IDdifficulty_min: Minimum difficultydifficulty_max: Maximum difficultyvolume_min: Minimum volumevolume_max: Maximum volumesite_id: Filter by site (query param)sector_id: Filter by sector (query param)
Search:
search: Search by keyword text (searchesseed_keyword__keywordfield)
Ordering:
ordering: Order bycreated_at,seed_keyword__volume,seed_keyword__difficulty- Default:
-created_at(newest first)
Custom Actions:
-
POST /api/v1/planner/keywords/bulk_delete/- Bulk delete keywords- Request:
{ "ids": [1, 2, 3] } - Response:
{ "deleted_count": 3 }
- Request:
-
POST /api/v1/planner/keywords/bulk_update_status/- Bulk update status- Request:
{ "ids": [1, 2, 3], "status": "active" } - Response:
{ "updated_count": 3 }
- Request:
-
POST /api/v1/planner/keywords/bulk_add_from_seed/- Add keywords from seed library- Request:
{ "seed_keyword_ids": [1, 2, 3], "site_id": 1, "sector_id": 1 } - Response:
{ "added_count": 3, "keywords": [ ... ] }
- Request:
-
GET /api/v1/planner/keywords/export/- Export keywords to CSV- Query Params: Same filtering as list endpoint
- Response: CSV file download
-
POST /api/v1/planner/keywords/import_keywords/- Import keywords from CSV- Request: Multipart form data with CSV file
- Response:
{ "imported_count": 10, "errors": [] }
-
POST /api/v1/planner/keywords/auto_cluster/- Auto-cluster keywords using AI- Request:
{ "ids": [1, 2, 3, ...], "sector_id": 1 } - Response:
{ "success": true, "task_id": "abc123" } - Max Keywords: 20 per batch
- Returns: Celery task ID for progress tracking
- Request:
Cluster Management Endpoints
ViewSet: ClusterViewSet
Base Path: /api/v1/planner/clusters/
Permission: AllowAny (default)
Inherits: SiteSectorModelViewSet
Standard CRUD:
GET /api/v1/planner/clusters/- List clustersPOST /api/v1/planner/clusters/- Create clusterGET /api/v1/planner/clusters/{id}/- Get clusterPUT /api/v1/planner/clusters/{id}/- Update clusterDELETE /api/v1/planner/clusters/{id}/- Delete cluster
Filtering:
status: Filter by statussite_id: Filter by site (query param)sector_id: Filter by sector (query param)
Search:
search: Search by cluster name
Ordering:
ordering: Order bykeywords_count,volume,created_at
Custom Actions:
-
POST /api/v1/planner/clusters/bulk_delete/- Bulk delete clusters- Request:
{ "ids": [1, 2, 3] } - Response:
{ "deleted_count": 3 }
- Request:
-
POST /api/v1/planner/clusters/auto_generate_ideas/- Auto-generate content ideas- Request:
{ "ids": [1] }(max 1 cluster per batch) - Response:
{ "success": true, "task_id": "abc123" } - Returns: Celery task ID for progress tracking
- Request:
Content Ideas Endpoints
ViewSet: ContentIdeasViewSet
Base Path: /api/v1/planner/ideas/
Permission: AllowAny (default)
Inherits: SiteSectorModelViewSet
Standard CRUD:
GET /api/v1/planner/ideas/- List content ideasPOST /api/v1/planner/ideas/- Create content ideaGET /api/v1/planner/ideas/{id}/- Get content ideaPUT /api/v1/planner/ideas/{id}/- Update content ideaDELETE /api/v1/planner/ideas/{id}/- Delete content idea
Filtering:
status: Filter by statuscluster_id: Filter by clustercontent_type: Filter by content typesite_id: Filter by site (query param)sector_id: Filter by sector (query param)
Search:
search: Search by idea title
Custom Actions:
-
POST /api/v1/planner/ideas/bulk_delete/- Bulk delete ideas- Request:
{ "ids": [1, 2, 3] } - Response:
{ "deleted_count": 3 }
- Request:
-
POST /api/v1/planner/ideas/bulk_queue_to_writer/- Queue ideas to writer (create tasks)- Request:
{ "ids": [1, 2, 3] } - Response:
{ "tasks_created": 3, "tasks": [ ... ] }
- Request:
Writer Module Endpoints
Base Path: /api/v1/writer/
Task Management Endpoints
ViewSet: TasksViewSet
Base Path: /api/v1/writer/tasks/
Permission: AllowAny (default)
Inherits: SiteSectorModelViewSet
Standard CRUD:
GET /api/v1/writer/tasks/- List tasksPOST /api/v1/writer/tasks/- Create taskGET /api/v1/writer/tasks/{id}/- Get taskPUT /api/v1/writer/tasks/{id}/- Update taskDELETE /api/v1/writer/tasks/{id}/- Delete task
Filtering:
status: Filter by status (draft, in_progress, review, completed, archived)cluster_id: Filter by clustercontent_type: Filter by content typecontent_structure: Filter by content structuresite_id: Filter by site (query param)sector_id: Filter by sector (query param)
Search:
search: Search by title or keywords
Ordering:
ordering: Order bytitle,created_at,word_count,status- Default:
-created_at
Custom Actions:
-
POST /api/v1/writer/tasks/bulk_delete/- Bulk delete tasks- Request:
{ "ids": [1, 2, 3] } - Response:
{ "deleted_count": 3 }
- Request:
-
POST /api/v1/writer/tasks/bulk_update/- Bulk update task status- Request:
{ "ids": [1, 2, 3], "status": "review" } - Response:
{ "updated_count": 3 }
- Request:
-
POST /api/v1/writer/tasks/auto_generate_content/- Auto-generate content using AI- Request:
{ "ids": [1, 2, 3, ...] }(max 50 tasks per batch) - Response:
{ "success": true, "task_id": "abc123" } - Returns: Celery task ID for progress tracking
- Request:
Content Management Endpoints
ViewSet: ContentViewSet
Base Path: /api/v1/writer/content/
Permission: AllowAny (default)
Inherits: SiteSectorModelViewSet
Standard CRUD:
GET /api/v1/writer/content/- List contentPOST /api/v1/writer/content/- Create contentGET /api/v1/writer/content/{id}/- Get contentPUT /api/v1/writer/content/{id}/- Update contentDELETE /api/v1/writer/content/{id}/- Delete content
Filtering:
status: Filter by statuscontent_type: Filter by content typesite_id: Filter by site (query param)sector_id: Filter by sector (query param)
Search:
search: Search by title or keywords
Custom Actions:
POST /api/v1/writer/content/generate_image_prompts/- Generate image prompts from content- Request:
{ "ids": [1, 2, 3] } - Response:
{ "success": true, "task_id": "abc123" } - Returns: Celery task ID for progress tracking
- Request:
Image Management Endpoints
ViewSet: ImagesViewSet
Base Path: /api/v1/writer/images/
Permission: AllowAny (default)
Inherits: SiteSectorModelViewSet
Standard CRUD:
GET /api/v1/writer/images/- List imagesPOST /api/v1/writer/images/- Create imageGET /api/v1/writer/images/{id}/- Get imagePUT /api/v1/writer/images/{id}/- Update imageDELETE /api/v1/writer/images/{id}/- Delete image
Filtering:
image_type: Filter by type (featured, in_article, desktop, mobile)status: Filter by statuscontent_id: Filter by contenttask_id: Filter by tasksite_id: Filter by site (query param)sector_id: Filter by sector (query param)
Custom Actions:
-
GET /api/v1/writer/images/{id}/file/- Get image file URL- Response:
{ "image_url": "https://..." }
- Response:
-
GET /api/v1/writer/images/content_images/- Get images for content- Query Params:
content_id(required) - Response:
{ "images": [ ... ] }
- Query Params:
-
POST /api/v1/writer/images/auto_generate/- Auto-generate images (legacy)- Request:
{ "ids": [1, 2, 3] } - Response:
{ "success": true, "images_created": 3 }
- Request:
-
POST /api/v1/writer/images/generate_images/- Generate images using AI- Request:
{ "ids": [1, 2, 3, ...] } - Response:
{ "success": true, "task_id": "abc123" } - Returns: Celery task ID for progress tracking
- Request:
-
POST /api/v1/writer/images/bulk_update/- Bulk update image status- Request:
{ "ids": [1, 2, 3], "status": "completed" }OR{ "content_id": 1, "status": "completed" } - Response:
{ "updated_count": 3 }
- Request:
System Module Endpoints
Base Path: /api/v1/system/
AI Prompt Management Endpoints
ViewSet: AIPromptViewSet
Base Path: /api/v1/system/prompts/
Permission: AllowAny (default)
Inherits: AccountModelViewSet
Standard CRUD:
GET /api/v1/system/prompts/- List promptsPOST /api/v1/system/prompts/- Create promptGET /api/v1/system/prompts/{id}/- Get promptPUT /api/v1/system/prompts/{id}/- Update promptDELETE /api/v1/system/prompts/{id}/- Delete prompt
Custom Actions:
-
GET /api/v1/system/prompts/by_type/{prompt_type}/- Get prompt by type- Response:
{ "prompt_type": "auto_cluster", "prompt_value": "..." }
- Response:
-
POST /api/v1/system/prompts/save/- Save prompt (custom action)- Request:
{ "prompt_type": "auto_cluster", "prompt_value": "..." } - Response:
{ "success": true, "prompt": { ... } }
- Request:
-
POST /api/v1/system/prompts/reset/- Reset prompt to default- Request:
{ "prompt_type": "auto_cluster" } - Response:
{ "success": true, "prompt": { ... } }
- Request:
Author Profile Management Endpoints
ViewSet: AuthorProfileViewSet
Base Path: /api/v1/system/author-profiles/
Permission: AllowAny (default)
Inherits: AccountModelViewSet
Standard CRUD:
GET /api/v1/system/author-profiles/- List author profilesPOST /api/v1/system/author-profiles/- Create author profileGET /api/v1/system/author-profiles/{id}/- Get author profilePUT /api/v1/system/author-profiles/{id}/- Update author profileDELETE /api/v1/system/author-profiles/{id}/- Delete author profile
Strategy Management Endpoints
ViewSet: StrategyViewSet
Base Path: /api/v1/system/strategies/
Permission: AllowAny (default)
Inherits: AccountModelViewSet
Standard CRUD:
GET /api/v1/system/strategies/- List strategiesPOST /api/v1/system/strategies/- Create strategyGET /api/v1/system/strategies/{id}/- Get strategyPUT /api/v1/system/strategies/{id}/- Update strategyDELETE /api/v1/system/strategies/{id}/- Delete strategy
Integration Settings Endpoints
ViewSet: IntegrationSettingsViewSet
Base Path: /api/v1/system/settings/integrations/
Permission: AllowAny (default)
Custom URL Patterns (not standard ViewSet routes):
-
GET /api/v1/system/settings/integrations/{pk}/- Get integration settings- Response:
{ "integration_type": "openai", "config": { ... }, "is_active": true }
- Response:
-
POST /api/v1/system/settings/integrations/{pk}/save/- Save integration settings- Request:
{ "config": { "apiKey": "...", "model": "gpt-4" }, "is_active": true } - Response:
{ "success": true, "integration": { ... } }
- Request:
-
PUT /api/v1/system/settings/integrations/{pk}/- Update integration settings- Request: Same as save
- Response: Same as save
-
POST /api/v1/system/settings/integrations/{pk}/test/- Test connection- Request:
{ "provider": "openai" }or{ "provider": "runware" } - Response:
{ "success": true, "message": "Connection successful" }
- Request:
-
POST /api/v1/system/settings/integrations/{pk}/generate/- Test image generation- Request:
{ "prompt": "...", "provider": "openai", "model": "dall-e-3", ... } - Response:
{ "success": true, "image_url": "https://..." }
- Request:
-
GET /api/v1/system/settings/task_progress/{task_id}/- Get Celery task progress- Response:
{ "state": "PROGRESS", "meta": { "phase": "AI_CALL", "percentage": 50, ... } }
- Response:
-
GET /api/v1/system/integrations/image_generation/- Get image generation settings- Response:
{ "providers": ["openai", "runware"], "models": { ... }, ... }
- Response:
Settings Management Endpoints
ViewSet: SystemSettingsViewSet
Base Path: /api/v1/system/settings/system/
Permission: IsAuthenticated
Standard CRUD:
GET /api/v1/system/settings/system/- List system settingsPOST /api/v1/system/settings/system/- Create system settingGET /api/v1/system/settings/system/{id}/- Get system settingPUT /api/v1/system/settings/system/{id}/- Update system settingDELETE /api/v1/system/settings/system/{id}/- Delete system setting
ViewSet: AccountSettingsViewSet
Base Path: /api/v1/system/settings/account/
Permission: IsAuthenticated
Inherits: AccountModelViewSet
Standard CRUD:
GET /api/v1/system/settings/account/- List account settingsPOST /api/v1/system/settings/account/- Create account settingGET /api/v1/system/settings/account/{id}/- Get account settingPUT /api/v1/system/settings/account/{id}/- Update account settingDELETE /api/v1/system/settings/account/{id}/- Delete account setting
ViewSet: UserSettingsViewSet
Base Path: /api/v1/system/settings/user/
Permission: IsAuthenticated
Standard CRUD:
GET /api/v1/system/settings/user/- List user settingsPOST /api/v1/system/settings/user/- Create user settingGET /api/v1/system/settings/user/{id}/- Get user settingPUT /api/v1/system/settings/user/{id}/- Update user settingDELETE /api/v1/system/settings/user/{id}/- Delete user setting
ViewSet: ModuleSettingsViewSet
Base Path: /api/v1/system/settings/modules/
Permission: IsAuthenticated
Inherits: AccountModelViewSet
Standard CRUD:
GET /api/v1/system/settings/modules/- List module settingsPOST /api/v1/system/settings/modules/- Create module settingGET /api/v1/system/settings/modules/{id}/- Get module settingPUT /api/v1/system/settings/modules/{id}/- Update module settingDELETE /api/v1/system/settings/modules/{id}/- Delete module setting
Custom Actions:
GET /api/v1/system/settings/modules/module/{module_name}/- Get settings by module- Response:
{ "module": "planner", "settings": { ... } }
- Response:
ViewSet: AISettingsViewSet
Base Path: /api/v1/system/settings/ai/
Permission: IsAuthenticated
Inherits: AccountModelViewSet
Standard CRUD:
GET /api/v1/system/settings/ai/- List AI settingsPOST /api/v1/system/settings/ai/- Create AI settingGET /api/v1/system/settings/ai/{id}/- Get AI settingPUT /api/v1/system/settings/ai/{id}/- Update AI settingDELETE /api/v1/system/settings/ai/{id}/- Delete AI setting
System Status Endpoints
GET /api/v1/system/status/
Purpose: System health check
Authentication: AllowAny
Response:
{
"status": "healthy",
"database": "connected",
"redis": "connected",
"celery": "running",
"version": "1.0.0"
}
Status Codes: 200 (OK), 503 (Service Unavailable)
GET /api/v1/system/request-metrics/{request_id}/
Purpose: Get request metrics for debugging
Authentication: Required (typically admin/developer only)
Response:
{
"request_id": "abc123",
"cpu_percent": 25.5,
"memory_mb": 512,
"io_read_mb": 10.2,
"io_write_mb": 5.1
}
POST /api/v1/system/webhook/
Purpose: Gitea webhook endpoint
Authentication: Webhook secret validation
Request: Gitea webhook payload
Response:
{
"success": true,
"message": "Webhook processed"
}
Billing Module Endpoints
Base Path: /api/v1/billing/
Credit Balance Endpoints
ViewSet: CreditBalanceViewSet
Base Path: /api/v1/billing/credits/balance/
Permission: IsAuthenticated
Custom Actions:
GET /api/v1/billing/credits/balance/balance/- Get credit balance- Response:
{ "credits": 1000, "plan_credits_per_month": 500, "credits_used_this_month": 250, "credits_remaining": 750 }
Credit Usage Endpoints
ViewSet: CreditUsageViewSet
Base Path: /api/v1/billing/credits/usage/
Permission: IsAuthenticated
Inherits: ReadOnlyModelViewSet (read-only)
Standard CRUD:
GET /api/v1/billing/credits/usage/- List usage logs (paginated)GET /api/v1/billing/credits/usage/{id}/- Get usage log
Filtering:
operation_type: Filter by operation type (clustering, ideas, content, images, reparse)start_date: Filter by start date (YYYY-MM-DD)end_date: Filter by end date (YYYY-MM-DD)
Custom Actions:
-
GET /api/v1/billing/credits/usage/summary/- Get usage summary- Query Params:
start_date,end_date(optional) - Response:
{ "total_credits_used": 500, "total_cost_usd": 25.50, "by_operation": { "clustering": 100, "ideas": 50, "content": 300, "images": 50 } } - Query Params:
-
GET /api/v1/billing/credits/usage/limits/- Get usage limits- Response:
{ "plan_limits": { "max_keywords": 10000, "max_clusters": 1000, "max_ideas": 5000, "max_ai_requests": 10000 }, "current_usage": { "keywords": 5000, "clusters": 500, "ideas": 2500, "ai_requests": 5000 } }
Credit Transaction Endpoints
ViewSet: CreditTransactionViewSet
Base Path: /api/v1/billing/credits/transactions/
Permission: IsAuthenticated
Inherits: ReadOnlyModelViewSet (read-only)
Standard CRUD:
GET /api/v1/billing/credits/transactions/- List transactions (paginated)GET /api/v1/billing/credits/transactions/{id}/- Get transaction
Filtering:
transaction_type: Filter by type (purchase, subscription, refund, deduction, adjustment)start_date: Filter by start dateend_date: Filter by end date
Ordering:
- Default:
-created_at(newest first)
Frontend API Usage Patterns
API Client Implementation
File: frontend/src/services/api.ts
Base URL Detection:
- Checks
VITE_BACKEND_URLorVITE_API_URLenvironment variable - Auto-detects based on current origin (localhost, IP, subdomain)
- Production default:
https://api.igny8.com/api
Authentication:
- JWT token stored in Zustand auth store
- Token included in
Authorization: Bearer <token>header - Automatic token refresh on 401 responses
- Token stored in localStorage (persisted)
Request Function:
fetchAPI(endpoint: string, options?: RequestInit)
Features:
- Automatic JWT token injection
- 30-second timeout (configurable)
- Automatic token refresh on 401
- Error handling and parsing
- Content-type detection
Common Usage Patterns
List Endpoints:
const response = await fetchAPI('/v1/planner/keywords/?page=1&page_size=25');
const data = await response.json();
// Returns: { count, next, previous, results: [...] }
Create Endpoints:
const response = await fetchAPI('/v1/planner/keywords/', {
method: 'POST',
body: JSON.stringify({ keyword: '...', site_id: 1, sector_id: 1 })
});
Custom Actions:
const response = await fetchAPI('/v1/planner/keywords/auto_cluster/', {
method: 'POST',
body: JSON.stringify({ ids: [1, 2, 3], sector_id: 1 })
});
// Returns: { success: true, task_id: "abc123" }
Progress Tracking:
// Poll progress endpoint
const progress = await fetchAPI(`/v1/system/settings/task_progress/${taskId}/`);
// Returns: { state: "PROGRESS", meta: { phase: "AI_CALL", percentage: 50 } }
State Management Integration
Zustand Stores:
- Auth Store: Manages JWT token and user data
- Site Store: Manages current site selection
- Sector Store: Manages current sector selection
- Module Stores: Cache API responses (Planner, Writer, Billing)
API Calls from Stores:
- Stores use
fetchAPIfor all API calls - Responses cached in store state
- Automatic re-fetch on state changes
Third-Party Integrations
OpenAI Integration
Purpose: Text generation (GPT models) and image generation (DALL-E)
Configuration:
- Stored in
IntegrationSettingsmodel - Integration type:
openai - Config fields:
apiKey,model,max_tokens,temperature
API Usage:
- Called via
AICore.run_ai_request()for text generation - Called via
AICore.generate_image()for image generation - Account-specific API keys
- Cost tracking per request
Endpoints Used:
- OpenAI API:
https://api.openai.com/v1/chat/completions - OpenAI DALL-E:
https://api.openai.com/v1/images/generations
Dependencies:
requestslibrary for HTTP calls- API key stored per account in database
Runware Integration
Purpose: Alternative image generation service
Configuration:
- Stored in
IntegrationSettingsmodel - Integration type:
runware - Config fields:
apiKey,model(e.g.,runware:97@1),image_type
API Usage:
- Called via
AICore.generate_image()for image generation - Account-specific API keys
- Cost tracking per image
Endpoints Used:
- Runware API:
https://api.runware.com/v1/images/generate
Dependencies:
requestslibrary for HTTP calls- API key stored per account in database
WordPress Integration
Purpose: Content publishing to WordPress sites
Configuration:
- Stored in
Sitemodel - Fields:
wp_url,wp_username,wp_app_password - Per-site configuration
API Usage:
- WordPress REST API calls
- Creates posts with content HTML
- Uploads images to media library
- Sets post meta (keywords, etc.)
Endpoints Used:
- WordPress REST API:
{wp_url}/wp-json/wp/v2/posts - WordPress Media API:
{wp_url}/wp-json/wp/v2/media
Dependencies:
requestslibrary for HTTP calls- WordPress REST API (built into WordPress)
Gitea Webhook Integration
Purpose: Receive webhook events from Gitea
Endpoint: POST /api/v1/system/webhook/
Configuration:
- Webhook secret validation
- Processes push events, pull requests, etc.
Dependencies:
- Webhook secret stored in environment variables
Dependencies
Backend Dependencies
Core Framework:
Django 5.2+: Web frameworkdjangorestframework: REST API frameworkdjango-filter: Advanced filteringdjango-cors-headers: CORS handling
Authentication:
PyJWT 2.8.0+: JWT token handling- Custom JWT implementation (not djangorestframework-simplejwt)
Database:
psycopg2-binary: PostgreSQL adapterPostgreSQL 15: Database
Task Queue:
Celery 5.3.0+: Asynchronous task processingRedis 7: Celery broker and cache
HTTP Client:
requests 2.31.0+: External API calls (OpenAI, Runware, WordPress)
Utilities:
python-dotenv: Environment variable managementBeautifulSoup4: HTML parsingpsutil: System utilitiesdocker: Docker API client
Frontend Dependencies
HTTP Client:
- Native
fetchAPI (no external HTTP library) - Custom
fetchAPIwrapper infrontend/src/services/api.ts
State Management:
Zustand 5.0.8: State management- Token stored in Zustand auth store
- API responses cached in module stores
No External API Libraries:
- No Axios, no React Query, no SWR
- Pure fetch API with custom wrapper
Rate Limiting
Current Status
Rate Limiting: ❌ Not Implemented
Status: Planned for future implementation
Configuration: None in current settings
Planned Implementation
Location: docs/02-APPLICATION-ARCHITECTURE.md mentions rate limiting as planned feature
Recommendation: Implement using DRF throttling classes:
rest_framework.throttling.AnonRateThrottle: For anonymous usersrest_framework.throttling.UserRateThrottle: For authenticated users- Custom throttling for AI endpoints (higher limits)
Standardization Recommendations
Current Issues
-
Inconsistent Permission Classes:
- Many ViewSets use
permission_classes = [](AllowAny) - Should standardize to
IsAuthenticatedfor most endpoints - Only public endpoints should use
AllowAny
- Many ViewSets use
-
Inconsistent Response Formats:
- Some endpoints return
{ success: true, data: ... } - Some endpoints return DRF standard format
- Some endpoints return custom formats
- Should standardize to one format
- Some endpoints return
-
Mixed Authentication:
- JWT primary, but session and basic auth also enabled
- Should document which endpoints use which method
- Should standardize authentication requirements
-
No Rate Limiting:
- All endpoints are unlimited
- Should implement rate limiting for production
-
Inconsistent Error Handling:
- Some endpoints return
{ error: "..." } - Some return
{ success: false, message: "..." } - Should standardize error response format
- Some endpoints return
Recommendations
-
Standardize Response Format:
- Use consistent
{ success, data, message, errors }format - Apply to all endpoints
- Create response mixin for ViewSets
- Use consistent
-
Standardize Permissions:
- Default to
IsAuthenticatedfor all endpoints - Only explicitly allow
AllowAnyfor public endpoints - Document permission requirements
- Default to
-
Implement Rate Limiting:
- Add DRF throttling classes
- Different limits for different endpoint types
- Document rate limits
-
Standardize Error Handling:
- Use consistent error response format
- Include error codes for programmatic handling
- Document all error codes
-
API Versioning:
- Current:
/api/v1/ - Plan for future versions
- Document versioning strategy
- Current:
-
API Documentation:
- Consider adding OpenAPI/Swagger documentation
- Document all endpoints with request/response examples
- Include authentication requirements
Summary
Endpoint Statistics
- Total Endpoints: 100+ endpoints
- Auth Module: 15+ endpoints
- Planner Module: 20+ endpoints
- Writer Module: 20+ endpoints
- System Module: 30+ endpoints
- Billing Module: 10+ endpoints
Authentication
- Primary: JWT Bearer tokens
- Fallback: Session authentication
- Fallback: Basic authentication
- Account Context: Set via middleware from JWT
Response Formats
- Success:
{ success: true, data: ..., message: ... } - Error:
{ success: false, error: ..., errors: ... } - Pagination:
{ count, next, previous, results: [...] }
Current Gaps
- ❌ No rate limiting
- ⚠️ Inconsistent permission classes
- ⚠️ Inconsistent response formats
- ⚠️ No API documentation (OpenAPI/Swagger)
- ✅ Good: Consistent pagination
- ✅ Good: Account isolation
- ✅ Good: Site/sector filtering
Third-Party Integrations
- OpenAI: Text and image generation
- Runware: Image generation
- WordPress: Content publishing
- Gitea: Webhook integration
Document Status: Complete analysis of all existing API endpoints
Last Updated: 2025-01-XX