# 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

1. [API Architecture Overview](#api-architecture-overview)
2. [Authentication & Authorization](#authentication--authorization)
3. [Response Format Standards](#response-format-standards)
4. [Pagination Format](#pagination-format)
5. [Auth Module Endpoints](#auth-module-endpoints)
6. [Planner Module Endpoints](#planner-module-endpoints)
7. [Writer Module Endpoints](#writer-module-endpoints)
8. [System Module Endpoints](#system-module-endpoints)
9. [Billing Module Endpoints](#billing-module-endpoints)
10. [Frontend API Usage Patterns](#frontend-api-usage-patterns)
11. [Third-Party Integrations](#third-party-integrations)
12. [Dependencies](#dependencies)
13. [Standardization Recommendations](#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.account` from 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`

```python
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 authentication
- `IsOwnerOrAdmin`: Owner or Admin role required
- `IsEditorOrAbove`: 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.account` for all requests
- Enables automatic account filtering in ViewSets

---

## Response Format Standards

### Success Response

```json
{
  "success": true,
  "data": { ... },
  "message": "Optional success message"
}
```

### Error Response

```json
{
  "success": false,
  "error": "Error message",
  "errors": {
    "field_name": ["Error detail"]
  }
}
```

### Pagination Response

```json
{
  "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:**
```json
{
  "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:**
```json
{
  "email": "user@example.com",
  "password": "password123",
  "password_confirm": "password123"
}
```

**Response:**
```json
{
  "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:**
```json
{
  "email": "user@example.com",
  "password": "password123"
}
```

**Response:**
```json
{
  "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:**
```json
{
  "old_password": "oldpass123",
  "new_password": "newpass123",
  "new_password_confirm": "newpass123"
}
```

**Response:**
```json
{
  "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:**
```json
{
  "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 users
- `POST /api/v1/auth/users/` - Create user
- `GET /api/v1/auth/users/{id}/` - Get user
- `PUT /api/v1/auth/users/{id}/` - Update user
- `DELETE /api/v1/auth/users/{id}/` - Delete user

**Custom Actions:**
- `POST /api/v1/auth/users/invite/` - Invite user
- `POST /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 accounts
- `POST /api/v1/auth/accounts/` - Create account
- `GET /api/v1/auth/accounts/{id}/` - Get account
- `PUT /api/v1/auth/accounts/{id}/` - Update account
- `DELETE /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 sites
- `POST /api/v1/auth/sites/` - Create site
- `GET /api/v1/auth/sites/{id}/` - Get site
- `PUT /api/v1/auth/sites/{id}/` - Update site
- `DELETE /api/v1/auth/sites/{id}/` - Delete site

**Custom Actions:**
- `GET /api/v1/auth/sites/{id}/sectors/` - Get site sectors
- `POST /api/v1/auth/sites/{id}/set_active/` - Set active site
- `POST /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 sectors
- `POST /api/v1/auth/sectors/` - Create sector
- `GET /api/v1/auth/sectors/{id}/` - Get sector
- `PUT /api/v1/auth/sectors/{id}/` - Update sector
- `DELETE /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 plans
- `GET /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 industries
- `GET /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 keywords
- `GET /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 records
- `POST /api/v1/auth/site-access/` - Grant site access
- `GET /api/v1/auth/site-access/{id}/` - Get site access
- `PUT /api/v1/auth/site-access/{id}/` - Update site access
- `DELETE /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 subscriptions
- `POST /api/v1/auth/subscriptions/` - Create subscription
- `GET /api/v1/auth/subscriptions/{id}/` - Get subscription
- `PUT /api/v1/auth/subscriptions/{id}/` - Update subscription
- `DELETE /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 keyword
- `GET /api/v1/planner/keywords/{id}/` - Get keyword
- `PUT /api/v1/planner/keywords/{id}/` - Update keyword
- `DELETE /api/v1/planner/keywords/{id}/` - Delete keyword

**Filtering:**
- `status`: Filter by status
- `cluster_id`: Filter by cluster
- `seed_keyword__intent`: Filter by intent
- `seed_keyword_id`: Filter by seed keyword ID
- `difficulty_min`: Minimum difficulty
- `difficulty_max`: Maximum difficulty
- `volume_min`: Minimum volume
- `volume_max`: Maximum volume
- `site_id`: Filter by site (query param)
- `sector_id`: Filter by sector (query param)

**Search:**
- `search`: Search by keyword text (searches `seed_keyword__keyword` field)

**Ordering:**
- `ordering`: Order by `created_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 }`

- `POST /api/v1/planner/keywords/bulk_update_status/` - Bulk update status
  - **Request**: `{ "ids": [1, 2, 3], "status": "active" }`
  - **Response**: `{ "updated_count": 3 }`

- `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": [ ... ] }`

- `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

### Cluster Management Endpoints

#### ViewSet: `ClusterViewSet`
**Base Path**: `/api/v1/planner/clusters/`

**Permission**: AllowAny (default)

**Inherits**: SiteSectorModelViewSet

**Standard CRUD:**
- `GET /api/v1/planner/clusters/` - List clusters
- `POST /api/v1/planner/clusters/` - Create cluster
- `GET /api/v1/planner/clusters/{id}/` - Get cluster
- `PUT /api/v1/planner/clusters/{id}/` - Update cluster
- `DELETE /api/v1/planner/clusters/{id}/` - Delete cluster

**Filtering:**
- `status`: Filter by status
- `site_id`: Filter by site (query param)
- `sector_id`: Filter by sector (query param)

**Search:**
- `search`: Search by cluster name

**Ordering:**
- `ordering`: Order by `keywords_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 }`

- `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

### 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 ideas
- `POST /api/v1/planner/ideas/` - Create content idea
- `GET /api/v1/planner/ideas/{id}/` - Get content idea
- `PUT /api/v1/planner/ideas/{id}/` - Update content idea
- `DELETE /api/v1/planner/ideas/{id}/` - Delete content idea

**Filtering:**
- `status`: Filter by status
- `cluster_id`: Filter by cluster
- `content_type`: Filter by content type
- `site_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 }`

- `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": [ ... ] }`

---

## 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 tasks
- `POST /api/v1/writer/tasks/` - Create task
- `GET /api/v1/writer/tasks/{id}/` - Get task
- `PUT /api/v1/writer/tasks/{id}/` - Update task
- `DELETE /api/v1/writer/tasks/{id}/` - Delete task

**Filtering:**
- `status`: Filter by status (draft, in_progress, review, completed, archived)
- `cluster_id`: Filter by cluster
- `content_type`: Filter by content type
- `content_structure`: Filter by content structure
- `site_id`: Filter by site (query param)
- `sector_id`: Filter by sector (query param)

**Search:**
- `search`: Search by title or keywords

**Ordering:**
- `ordering`: Order by `title`, `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 }`

- `POST /api/v1/writer/tasks/bulk_update/` - Bulk update task status
  - **Request**: `{ "ids": [1, 2, 3], "status": "review" }`
  - **Response**: `{ "updated_count": 3 }`

- `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

### Content Management Endpoints

#### ViewSet: `ContentViewSet`
**Base Path**: `/api/v1/writer/content/`

**Permission**: AllowAny (default)

**Inherits**: SiteSectorModelViewSet

**Standard CRUD:**
- `GET /api/v1/writer/content/` - List content
- `POST /api/v1/writer/content/` - Create content
- `GET /api/v1/writer/content/{id}/` - Get content
- `PUT /api/v1/writer/content/{id}/` - Update content
- `DELETE /api/v1/writer/content/{id}/` - Delete content

**Filtering:**
- `status`: Filter by status
- `content_type`: Filter by content type
- `site_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

### Image Management Endpoints

#### ViewSet: `ImagesViewSet`
**Base Path**: `/api/v1/writer/images/`

**Permission**: AllowAny (default)

**Inherits**: SiteSectorModelViewSet

**Standard CRUD:**
- `GET /api/v1/writer/images/` - List images
- `POST /api/v1/writer/images/` - Create image
- `GET /api/v1/writer/images/{id}/` - Get image
- `PUT /api/v1/writer/images/{id}/` - Update image
- `DELETE /api/v1/writer/images/{id}/` - Delete image

**Filtering:**
- `image_type`: Filter by type (featured, in_article, desktop, mobile)
- `status`: Filter by status
- `content_id`: Filter by content
- `task_id`: Filter by task
- `site_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://..." }`

- `GET /api/v1/writer/images/content_images/` - Get images for content
  - **Query Params**: `content_id` (required)
  - **Response**: `{ "images": [ ... ] }`

- `POST /api/v1/writer/images/auto_generate/` - Auto-generate images (legacy)
  - **Request**: `{ "ids": [1, 2, 3] }`
  - **Response**: `{ "success": true, "images_created": 3 }`

- `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

- `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 }`

---

## 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 prompts
- `POST /api/v1/system/prompts/` - Create prompt
- `GET /api/v1/system/prompts/{id}/` - Get prompt
- `PUT /api/v1/system/prompts/{id}/` - Update prompt
- `DELETE /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": "..." }`

- `POST /api/v1/system/prompts/save/` - Save prompt (custom action)
  - **Request**: `{ "prompt_type": "auto_cluster", "prompt_value": "..." }`
  - **Response**: `{ "success": true, "prompt": { ... } }`

- `POST /api/v1/system/prompts/reset/` - Reset prompt to default
  - **Request**: `{ "prompt_type": "auto_cluster" }`
  - **Response**: `{ "success": true, "prompt": { ... } }`

### 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 profiles
- `POST /api/v1/system/author-profiles/` - Create author profile
- `GET /api/v1/system/author-profiles/{id}/` - Get author profile
- `PUT /api/v1/system/author-profiles/{id}/` - Update author profile
- `DELETE /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 strategies
- `POST /api/v1/system/strategies/` - Create strategy
- `GET /api/v1/system/strategies/{id}/` - Get strategy
- `PUT /api/v1/system/strategies/{id}/` - Update strategy
- `DELETE /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 }`

- `POST /api/v1/system/settings/integrations/{pk}/save/` - Save integration settings
  - **Request**: `{ "config": { "apiKey": "...", "model": "gpt-4" }, "is_active": true }`
  - **Response**: `{ "success": true, "integration": { ... } }`

- `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" }`

- `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://..." }`

- `GET /api/v1/system/settings/task_progress/{task_id}/` - Get Celery task progress
  - **Response**: `{ "state": "PROGRESS", "meta": { "phase": "AI_CALL", "percentage": 50, ... } }`

- `GET /api/v1/system/integrations/image_generation/` - Get image generation settings
  - **Response**: `{ "providers": ["openai", "runware"], "models": { ... }, ... }`

### Settings Management Endpoints

#### ViewSet: `SystemSettingsViewSet`
**Base Path**: `/api/v1/system/settings/system/`

**Permission**: IsAuthenticated

**Standard CRUD:**
- `GET /api/v1/system/settings/system/` - List system settings
- `POST /api/v1/system/settings/system/` - Create system setting
- `GET /api/v1/system/settings/system/{id}/` - Get system setting
- `PUT /api/v1/system/settings/system/{id}/` - Update system setting
- `DELETE /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 settings
- `POST /api/v1/system/settings/account/` - Create account setting
- `GET /api/v1/system/settings/account/{id}/` - Get account setting
- `PUT /api/v1/system/settings/account/{id}/` - Update account setting
- `DELETE /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 settings
- `POST /api/v1/system/settings/user/` - Create user setting
- `GET /api/v1/system/settings/user/{id}/` - Get user setting
- `PUT /api/v1/system/settings/user/{id}/` - Update user setting
- `DELETE /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 settings
- `POST /api/v1/system/settings/modules/` - Create module setting
- `GET /api/v1/system/settings/modules/{id}/` - Get module setting
- `PUT /api/v1/system/settings/modules/{id}/` - Update module setting
- `DELETE /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": { ... } }`

#### ViewSet: `AISettingsViewSet`
**Base Path**: `/api/v1/system/settings/ai/`

**Permission**: IsAuthenticated

**Inherits**: AccountModelViewSet

**Standard CRUD:**
- `GET /api/v1/system/settings/ai/` - List AI settings
- `POST /api/v1/system/settings/ai/` - Create AI setting
- `GET /api/v1/system/settings/ai/{id}/` - Get AI setting
- `PUT /api/v1/system/settings/ai/{id}/` - Update AI setting
- `DELETE /api/v1/system/settings/ai/{id}/` - Delete AI setting

### System Status Endpoints

#### GET `/api/v1/system/status/`
**Purpose**: System health check

**Authentication**: AllowAny

**Response:**
```json
{
  "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:**
```json
{
  "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:**
```json
{
  "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**: 
  ```json
  {
    "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**: 
  ```json
  {
    "total_credits_used": 500,
    "total_cost_usd": 25.50,
    "by_operation": {
      "clustering": 100,
      "ideas": 50,
      "content": 300,
      "images": 50
    }
  }
  ```

- `GET /api/v1/billing/credits/usage/limits/` - Get usage limits
  - **Response**: 
  ```json
  {
    "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 date
- `end_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_URL` or `VITE_API_URL` environment 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:**
```typescript
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:**
```typescript
const response = await fetchAPI('/v1/planner/keywords/?page=1&page_size=25');
const data = await response.json();
// Returns: { count, next, previous, results: [...] }
```

**Create Endpoints:**
```typescript
const response = await fetchAPI('/v1/planner/keywords/', {
  method: 'POST',
  body: JSON.stringify({ keyword: '...', site_id: 1, sector_id: 1 })
});
```

**Custom Actions:**
```typescript
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:**
```typescript
// 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 `fetchAPI` for 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 `IntegrationSettings` model
- 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:**
- `requests` library for HTTP calls
- API key stored per account in database

### Runware Integration

**Purpose**: Alternative image generation service

**Configuration:**
- Stored in `IntegrationSettings` model
- 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:**
- `requests` library for HTTP calls
- API key stored per account in database

### WordPress Integration

**Purpose**: Content publishing to WordPress sites

**Configuration:**
- Stored in `Site` model
- 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:**
- `requests` library 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 framework
- `djangorestframework`: REST API framework
- `django-filter`: Advanced filtering
- `django-cors-headers`: CORS handling

**Authentication:**
- `PyJWT 2.8.0+`: JWT token handling
- Custom JWT implementation (not djangorestframework-simplejwt)

**Database:**
- `psycopg2-binary`: PostgreSQL adapter
- `PostgreSQL 15`: Database

**Task Queue:**
- `Celery 5.3.0+`: Asynchronous task processing
- `Redis 7`: Celery broker and cache

**HTTP Client:**
- `requests 2.31.0+`: External API calls (OpenAI, Runware, WordPress)

**Utilities:**
- `python-dotenv`: Environment variable management
- `BeautifulSoup4`: HTML parsing
- `psutil`: System utilities
- `docker`: Docker API client

### Frontend Dependencies

**HTTP Client:**
- Native `fetch` API (no external HTTP library)
- Custom `fetchAPI` wrapper in `frontend/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 users
- `rest_framework.throttling.UserRateThrottle`: For authenticated users
- Custom throttling for AI endpoints (higher limits)

---

## Standardization Recommendations

### Current Issues

1. **Inconsistent Permission Classes:**
   - Many ViewSets use `permission_classes = []` (AllowAny)
   - Should standardize to `IsAuthenticated` for most endpoints
   - Only public endpoints should use `AllowAny`

2. **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

3. **Mixed Authentication:**
   - JWT primary, but session and basic auth also enabled
   - Should document which endpoints use which method
   - Should standardize authentication requirements

4. **No Rate Limiting:**
   - All endpoints are unlimited
   - Should implement rate limiting for production

5. **Inconsistent Error Handling:**
   - Some endpoints return `{ error: "..." }`
   - Some return `{ success: false, message: "..." }`
   - Should standardize error response format

### Recommendations

1. **Standardize Response Format:**
   - Use consistent `{ success, data, message, errors }` format
   - Apply to all endpoints
   - Create response mixin for ViewSets

2. **Standardize Permissions:**
   - Default to `IsAuthenticated` for all endpoints
   - Only explicitly allow `AllowAny` for public endpoints
   - Document permission requirements

3. **Implement Rate Limiting:**
   - Add DRF throttling classes
   - Different limits for different endpoint types
   - Document rate limits

4. **Standardize Error Handling:**
   - Use consistent error response format
   - Include error codes for programmatic handling
   - Document all error codes

5. **API Versioning:**
   - Current: `/api/v1/`
   - Plan for future versions
   - Document versioning strategy

6. **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

