Files
igny8/docs/API-COMPLETE-REFERENCE.md
alorig 8d096b383a 21
2025-11-29 14:33:07 +05:00

1808 lines
47 KiB
Markdown

# IGNY8 API Complete Reference v1.0
**Base URL**: `https://api.igny8.com/api/v1/`
**Version**: 1.0.0
**Last Updated**: 2025-01-XX (Added 6 missing modules: Linker, Optimizer, Publisher, Site Builder, Automation, Integration)
**Status**: ✅ **100% IMPLEMENTED** - All endpoints use unified format
**Purpose**: Complete, unified reference for IGNY8 API covering authentication, endpoints, response formats, error handling, rate limiting, permissions, and integration examples.
---
## Table of Contents
1. [Quick Start](#quick-start)
2. [Overview & Architecture](#overview--architecture)
3. [Authentication & Authorization](#authentication--authorization)
4. [Response Format Standard](#response-format-standard)
5. [Error Handling](#error-handling)
6. [Rate Limiting](#rate-limiting)
7. [Pagination](#pagination)
8. [Roles & Permissions](#roles--permissions)
9. [Tenant / Site / Sector Scoping](#tenant--site--sector-scoping)
10. [Complete Endpoint Reference](#complete-endpoint-reference)
11. [Integration Examples](#integration-examples)
12. [Testing & Debugging](#testing--debugging)
13. [Change Management](#change-management)
---
## Quick Start
### Interactive Documentation
- **Swagger UI**: `https://api.igny8.com/api/docs/`
- **ReDoc**: `https://api.igny8.com/api/redoc/`
- **OpenAPI Schema**: `https://api.igny8.com/api/schema/`
### Basic Example
```python
import requests
BASE_URL = "https://api.igny8.com/api/v1"
# 1. Login
response = requests.post(
f"{BASE_URL}/auth/login/",
json={"email": "user@example.com", "password": "password"}
)
data = response.json()
if data['success']:
token = data['data']['access']
# 2. Use token for authenticated requests
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
# 3. Get keywords
response = requests.get(
f"{BASE_URL}/planner/keywords/",
headers=headers
)
result = response.json()
if result['success']:
keywords = result['results'] # Paginated results
print(f"Found {result['count']} keywords")
```
---
## Overview & Architecture
### API Standard v1.0 - Key Principles
1. **Unified Response Format**: All endpoints return consistent JSON structure
2. **Layered Authorization**: Authentication → Tenant Access → Role → Site/Sector
3. **Centralized Error Handling**: All errors wrapped in unified format
4. **Scoped Rate Limiting**: Different limits for different operation types
5. **Tenant Isolation**: All resources scoped by account/site/sector
6. **Request Tracking**: Every request has a unique ID for debugging
### Base URL Structure
```
Production: https://api.igny8.com/api/v1/
Development: http://localhost:8000/api/v1/
```
### Module Namespaces
```
/api/v1/
├── auth/ # Authentication and user management
├── planner/ # Keywords, clusters, content ideas
├── writer/ # Tasks, content, images
├── linker/ # Internal linking operations
├── optimizer/ # Content optimization and scoring
├── publisher/ # Publishing records and site deployment
├── site-builder/ # Site blueprint management
├── automation/ # Automation rules and scheduled tasks
├── integration/ # External platform integrations
├── system/ # Settings, prompts, integrations
└── billing/ # Credits, transactions, usage
```
### Technology Stack
- **Framework**: Django REST Framework (DRF)
- **Authentication**: JWT Bearer tokens (primary), Session (fallback), Basic (fallback)
- **Pagination**: CustomPageNumberPagination (default: 10, max: 100)
- **Rate Limiting**: Scoped throttles per module/operation type
- **OpenAPI**: drf-spectacular for schema generation
### Implementation Status
**100% Complete** - All endpoints implemented with:
- Unified response format
- Proper authentication and authorization
- Rate limiting configured
- Error handling standardized
- Request ID tracking
- Complete Swagger/OpenAPI documentation
---
## Authentication & Authorization
### Authentication Methods
#### Primary: JWT Bearer Token
```
Authorization: Bearer <access_token>
```
**Token Characteristics:**
- Contains `user_id` and `account_id`
- Type: `access` (15-minute expiry)
- Automatically sets `request.account` via middleware
- Resolves account → tenant context automatically
**Token Payload:**
```json
{
"user_id": 1,
"account_id": 1,
"type": "access",
"exp": 1234567890
}
```
#### Fallback Methods
1. **Session Authentication** (admin panel)
- Class: `CSRFExemptSessionAuthentication`
- Use case: Django admin panel (`/admin/`)
2. **Basic Authentication** (debug/testing)
- Class: `rest_framework.authentication.BasicAuthentication`
- Use case: API testing tools (Postman, curl)
### Authentication Order
1. JWT Token Authentication (tried first)
2. Session Authentication (fallback)
3. Basic Authentication (last fallback)
4. If all fail: 401 Unauthorized
### Getting an Access Token
**Login Endpoint:**
```http
POST /api/v1/auth/login/
Content-Type: application/json
{
"email": "user@example.com",
"password": "your_password"
}
```
**Response:**
```json
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"username": "user",
"role": "owner",
"account": { ... }
},
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Token Expiration
- **Access Token**: 15 minutes
- **Refresh Token**: 7 days
**Refresh Token:**
```http
POST /api/v1/auth/refresh/
Content-Type: application/json
{
"refresh": "your_refresh_token"
}
```
### Public Endpoints (No Authentication Required)
- `POST /api/v1/auth/register/` - User registration
- `POST /api/v1/auth/login/` - User login
- `GET /api/v1/auth/plans/` - List plans
- `GET /api/v1/auth/industries/` - List industries
- `GET /api/v1/system/status/` - System health check
- `GET /api/v1/system/ping/` - Health check endpoint
- `GET /api/v1/publisher/sites/{site_id}/definition/` - Get site definition for Sites Renderer
**All other endpoints require JWT authentication.**
### Authorization Layers
Every endpoint enforces layered authorization:
1. **User Authentication**: User must be authenticated
2. **Tenant Access**: User must belong to the tenant/account
3. **Role Authorization**: User must have appropriate role
4. **Site/Sector Access**: User must have access to requested site/sector
---
## Response Format Standard
### Mandatory Format
**This is the global standard for all endpoints - no exceptions.**
### Success Response
```json
{
"success": true,
"data": {
"id": 1,
"name": "Example Keyword",
"status": "active"
},
"message": "Optional human-readable success message",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Paginated Response
```json
{
"success": true,
"count": 120,
"next": "http://api.igny8.com/api/v1/planner/keywords/?page=3",
"previous": "http://api.igny8.com/api/v1/planner/keywords/?page=1",
"results": [
{"id": 1, "name": "Keyword 1"},
{"id": 2, "name": "Keyword 2"},
...
],
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Error Response
```json
{
"success": false,
"error": "Readable top-level error message",
"errors": {
"field_name": ["Field-specific error messages"]
},
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Response Helper Functions
**File:** `backend/igny8_core/api/response.py`
```python
from igny8_core.api.response import success_response, error_response, paginated_response
# Success response
return success_response(
data={"id": 1, "name": "Example"},
message="Resource created successfully",
status_code=status.HTTP_201_CREATED
)
# Error response
return error_response(
error="Validation failed",
errors={"email": ["Invalid email format"]},
status_code=status.HTTP_400_BAD_REQUEST
)
# Paginated response
paginator = CustomPageNumberPagination()
page = paginator.paginate_queryset(queryset, request)
serializer = MySerializer(page, many=True)
paginated_data = paginator.get_paginated_response(serializer.data).data
return paginated_response(paginated_data, message="Resources retrieved successfully")
```
---
## Error Handling
### HTTP Status Codes
| Code | Meaning | Description |
|------|---------|-------------|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 204 | No Content | Resource deleted successfully |
| 400 | Bad Request | Validation error or invalid request |
| 401 | Unauthorized | Authentication required |
| 403 | Forbidden | Permission denied |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Resource conflict (e.g., duplicate) |
| 422 | Unprocessable Entity | Validation failed |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
### Centralized Exception Handler
**File:** `backend/igny8_core/api/exception_handlers.py`
All exceptions are handled by a centralized exception handler that:
- Wraps all errors in unified format
- Uses proper HTTP status codes
- Includes sanitized validation errors under `errors`
- Always attaches `request_id` for error tracking
- Logs full exception details
- In DEBUG mode: includes traceback + request context
### Error Response Examples
**Validation Error (400):**
```json
{
"success": false,
"error": "Validation failed",
"errors": {
"email": ["Invalid email format"],
"password": ["Password must be at least 8 characters"]
},
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
**Authentication Error (401):**
```json
{
"success": false,
"error": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
**Permission Error (403):**
```json
{
"success": false,
"error": "Permission denied",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
**Rate Limit (429):**
```json
{
"success": false,
"error": "Rate limit exceeded",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Server-side Logging
- All 4xx errors logged as **warning**
- All 5xx errors logged as **error**
- Structured format with timestamp, request_id, endpoint, user_id, account_id, status_code, error_message
- Rotating log files
- Sentry integration hooks for production
---
## Rate Limiting
### Rate Limiting Configuration
Rate limits are scoped by operation type. Check response headers for limit information:
- `X-Throttle-Limit`: Maximum requests allowed
- `X-Throttle-Remaining`: Remaining requests in current window
- `X-Throttle-Reset`: Time when limit resets (Unix timestamp)
### Rate Limit Scopes
| Scope | Limit | Description |
|-------|-------|-------------|
| `ai_function` | 10/min | AI content generation, clustering |
| `image_gen` | 15/min | Image generation |
| `content_write` | 30/min | Content creation, updates |
| `content_read` | 100/min | Content listing, retrieval |
| `auth` | 20/min | Login, register, password reset |
| `auth_strict` | 5/min | Sensitive auth operations |
| `planner` | 60/min | Keyword, cluster, idea operations |
| `planner_ai` | 10/min | AI-powered planner operations |
| `writer` | 60/min | Task, content management |
| `writer_ai` | 10/min | AI-powered writer operations |
| `system` | 100/min | Settings, prompts, profiles |
| `system_admin` | 30/min | Admin-only system operations |
| `billing` | 30/min | Credit queries, usage logs |
| `billing_admin` | 10/min | Credit management (admin) |
| `default` | 100/min | Default for endpoints without scope |
### Handling Rate Limits
When rate limited (429), the response includes:
- Error message: "Rate limit exceeded"
- Headers with reset time
- Wait until `X-Throttle-Reset` before retrying
**Example:**
```http
HTTP/1.1 429 Too Many Requests
X-Throttle-Limit: 60
X-Throttle-Remaining: 0
X-Throttle-Reset: 1700123456
Retry-After: 60
{
"success": false,
"error": "Rate limit exceeded",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Debug Mode Bypass
Set `IGNY8_DEBUG_THROTTLE=True` or `DEBUG=True` to bypass throttling in development.
---
## Pagination
### Pagination Configuration
**Default Settings:**
- Default page size: **10**
- Maximum page size: **100**
- Query parameter: `page_size` (optional)
- Page parameter: `page` (default: 1)
### Query Parameters
**Pagination:**
```
?page=2&page_size=25
```
**Filtering:**
```
?status=active
?site_id=1
?sector_id=2
?cluster_id=5
```
**Search:**
```
?search=keyword
```
**Ordering:**
```
?ordering=-created_at
?ordering=name,status
```
### Pagination Response Format
```json
{
"success": true,
"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": [
// Array of results
],
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### Pagination Fields
- `count`: Total number of items
- `next`: URL to next page (null if last page)
- `previous`: URL to previous page (null if first page)
- `results`: Array of items for current page
---
## Roles & Permissions
### Role Hierarchy
```
owner > admin > editor > viewer > system_bot
```
### Standard Permission Classes
**File:** `backend/igny8_core/api/permissions.py`
| Permission Class | Description | Use Case |
|-----------------|------------|----------|
| `IsAuthenticatedAndActive` | User authenticated and active | Base permission for most endpoints |
| `HasTenantAccess` | User belongs to tenant/account | Tenant isolation |
| `IsViewerOrAbove` | Viewer, editor, admin, or owner | Read-only operations |
| `IsEditorOrAbove` | Editor, admin, or owner | Content operations |
| `IsAdminOrOwner` | Admin or owner only | Settings, keys, billing |
### Permission Matrix by Endpoint Type
| Endpoint Type | Required Permissions | Roles Allowed |
|--------------|---------------------|---------------|
| Public (register, login) | `AllowAny` | Anyone |
| Read-only (list, retrieve) | `IsAuthenticatedAndActive` + `HasTenantAccess` | All authenticated users |
| Content operations | `IsAuthenticatedAndActive` + `HasTenantAccess` + `IsEditorOrAbove` | Editor, Admin, Owner |
| User management | `IsAuthenticatedAndActive` + `HasTenantAccess` + `IsAdminOrOwner` | Admin, Owner |
| Billing/Transactions | `IsAuthenticatedAndActive` + `HasTenantAccess` + `IsAdminOrOwner` | Admin, Owner |
| Integration settings | `IsAuthenticatedAndActive` + `HasTenantAccess` + `IsAdminOrOwner` | Admin, Owner |
---
## Tenant / Site / Sector Scoping
### Scoping Rules
Every resource created or fetched must be scoped by:
1. **Account/Tenant** - User's account
2. **Site** - Specific site within account
3. **Sector** - Specific sector within site
### Enforcement
**Base Classes:**
- `AccountModelViewSet` - Handles account isolation
- `SiteSectorModelViewSet` - Filters queries by site/sector
**Requirements:**
- All custom actions must use `.get_queryset()` to avoid bypassing filters
- Any ID list must be verified to belong to the authenticated tenant
- Site/sector access validated based on user role
### Scoping Example
```python
class KeywordViewSet(SiteSectorModelViewSet):
# Automatically filters by:
# 1. account (from request.account)
# 2. site_id (from query params or request)
# 3. sector_id (from query params or request)
queryset = Keyword.objects.all()
serializer_class = KeywordSerializer
def get_queryset(self):
# Base class handles account/site/sector filtering
queryset = super().get_queryset()
# Additional filtering can be added here
return queryset
```
---
## Complete Endpoint Reference
### Authentication Endpoints
**Base Path**: `/api/v1/auth/`
#### POST `/api/v1/auth/register/`
**Purpose**: User registration
**Authentication**: None (AllowAny)
**Request:**
```json
{
"email": "user@example.com",
"password": "password123",
"password_confirm": "password123"
}
```
**Response:**
```json
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"role": "owner",
"account": { ... }
}
},
"message": "Registration successful"
}
```
#### POST `/api/v1/auth/login/`
**Purpose**: User login
**Authentication**: None (AllowAny)
**Request:**
```json
{
"email": "user@example.com",
"password": "password123"
}
```
**Response:**
```json
{
"success": true,
"data": {
"user": { ... },
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"access_expires_at": "2025-01-XXT...",
"refresh_expires_at": "2025-01-XXT..."
},
"message": "Login successful",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
#### POST `/api/v1/auth/refresh/`
**Purpose**: Refresh access token
**Authentication**: None (requires refresh token)
**Request:**
```json
{
"refresh": "your_refresh_token"
}
```
#### POST `/api/v1/auth/change-password/`
**Purpose**: Change user password
**Authentication**: Required (IsAuthenticated)
**Request:**
```json
{
"old_password": "oldpass123",
"new_password": "newpass123",
"new_password_confirm": "newpass123"
}
```
#### GET `/api/v1/auth/me/`
**Purpose**: Get current user information
**Authentication**: Required (IsAuthenticated)
**Response:**
```json
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"role": "owner",
"account": { ... },
"accessible_sites": [ ... ]
}
}
}
```
### User Management Endpoints
**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
**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
**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
**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
### Planner Module Endpoints
**Base Path**: `/api/v1/planner/`
#### Keyword Management
**Base Path**: `/api/v1/planner/keywords/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**Inherits**: SiteSectorModelViewSet
**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`, `difficulty_max` - Difficulty range
- `volume_min`, `volume_max` - Volume range
- `site_id` - Filter by site (query param)
- `sector_id` - Filter by sector (query param)
**Search:**
- `search` - Search by keyword text
**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] }`
- `POST /api/v1/planner/keywords/bulk_update_status/` - Bulk update status
- Request: `{ "ids": [1, 2, 3], "status": "active" }`
- `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 }`
- `GET /api/v1/planner/keywords/export/` - Export keywords to CSV
- `POST /api/v1/planner/keywords/import_keywords/` - Import keywords from CSV
- `POST /api/v1/planner/keywords/auto_cluster/` - Auto-cluster keywords using AI
- Request: `{ "ids": [1, 2, 3, ...], "sector_id": 1 }`
- Max Keywords: 20 per batch
- Returns: Celery task ID for progress tracking
#### Cluster Management
**Base Path**: `/api/v1/planner/clusters/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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
**Custom Actions:**
- `POST /api/v1/planner/clusters/bulk_delete/` - Bulk delete clusters
- `POST /api/v1/planner/clusters/auto_generate_ideas/` - Auto-generate content ideas
- Request: `{ "ids": [1] }` (max 1 cluster per batch)
- Returns: Celery task ID for progress tracking
#### Content Ideas Management
**Base Path**: `/api/v1/planner/ideas/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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)
**Custom Actions:**
- `POST /api/v1/planner/ideas/bulk_delete/` - Bulk delete ideas
- `POST /api/v1/planner/ideas/bulk_queue_to_writer/` - Queue ideas to writer (create tasks)
- Request: `{ "ids": [1, 2, 3] }`
### Writer Module Endpoints
**Base Path**: `/api/v1/writer/`
#### Task Management
**Base Path**: `/api/v1/writer/tasks/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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
**Custom Actions:**
- `POST /api/v1/writer/tasks/bulk_delete/` - Bulk delete tasks
- `POST /api/v1/writer/tasks/bulk_update/` - Bulk update task status
- `POST /api/v1/writer/tasks/auto_generate_content/` - Auto-generate content using AI
- Request: `{ "ids": [1, 2, 3, ...] }` (max 50 tasks per batch)
- Returns: Celery task ID for progress tracking
#### Content Management
**Base Path**: `/api/v1/writer/content/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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)
**Custom Actions:**
- `POST /api/v1/writer/content/generate_image_prompts/` - Generate image prompts from content
- Request: `{ "ids": [1, 2, 3] }`
- Returns: Celery task ID for progress tracking
#### Image Management
**Base Path**: `/api/v1/writer/images/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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
- `GET /api/v1/writer/images/content_images/` - Get images for content
- Query Params: `content_id` (required)
- `POST /api/v1/writer/images/generate_images/` - Generate images using AI
- Request: `{ "ids": [1, 2, 3, ...] }`
- Returns: Celery task ID for progress tracking
- `POST /api/v1/writer/images/bulk_update/` - Bulk update image status
### System Module Endpoints
**Base Path**: `/api/v1/system/`
#### AI Prompt Management
**Base Path**: `/api/v1/system/prompts/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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
- `POST /api/v1/system/prompts/save/` - Save prompt (requires editor/admin)
- `POST /api/v1/system/prompts/reset/` - Reset prompt to default
#### Integration Settings
**Base Path**: `/api/v1/system/settings/integrations/`
**Permission**: IsAdminOrOwner
**Custom URL Patterns:**
- `GET /api/v1/system/settings/integrations/{pk}/` - Get integration settings
- `POST /api/v1/system/settings/integrations/{pk}/save/` - Save integration settings
- `PUT /api/v1/system/settings/integrations/{pk}/` - Update integration settings
- `POST /api/v1/system/settings/integrations/{pk}/test/` - Test connection
- Request: `{ "provider": "openai" }` or `{ "provider": "runware" }`
- `POST /api/v1/system/settings/integrations/{pk}/generate/` - Test image generation
- `GET /api/v1/system/settings/task_progress/{task_id}/` - Get Celery task progress
- `GET /api/v1/system/integrations/image_generation/` - Get image generation settings
#### System Status
**Base Path**: `/api/v1/system/`
- `GET /api/v1/system/status/` - System health check (AllowAny)
- `GET /api/v1/system/ping/` - Health check endpoint (AllowAny)
- `GET /api/v1/system/request-metrics/{request_id}/` - Get request metrics for debugging
### Linker Module Endpoints
**Base Path**: `/api/v1/linker/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
#### Process Content for Internal Linking
- `POST /api/v1/linker/process/` - Process single content item for internal linking
**Request:**
```json
{
"content_id": 123
}
```
**Response:**
```json
{
"success": true,
"data": {
"content_id": 123,
"suggested_links": [
{
"target_content_id": 456,
"target_title": "Related Article",
"anchor_text": "relevant keyword",
"confidence": 0.85
}
]
}
}
```
#### Batch Process Content
- `POST /api/v1/linker/batch_process/` - Process multiple content items for linking
**Request:**
```json
{
"content_ids": [123, 456, 789]
}
```
### Optimizer Module Endpoints
**Base Path**: `/api/v1/optimizer/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
#### Optimize Content
- `POST /api/v1/optimizer/optimize/` - Optimize content (auto-detects entry point)
**Request:**
```json
{
"ids": [123, 456],
"entry_point": "seo" // Optional: "seo", "readability", "engagement"
}
```
**Response:**
```json
{
"success": true,
"data": {
"optimized_content": "...",
"seo_score": 85,
"readability_score": 78,
"engagement_score": 82
}
}
```
#### Batch Optimize Content
- `POST /api/v1/optimizer/batch_optimize/` - Batch optimize multiple content items
**Request:**
```json
{
"ids": [123, 456, 789],
"entry_point": "seo" // Optional
}
```
#### Analyze Content
- `POST /api/v1/optimizer/analyze/` - Analyze content without optimization
**Request:**
```json
{
"id": 123
}
```
**Response:**
```json
{
"success": true,
"data": {
"seo_score": 75,
"readability_score": 70,
"engagement_score": 68,
"recommendations": [
"Add more internal links",
"Improve heading structure"
]
}
}
```
### Publisher Module Endpoints
**Base Path**: `/api/v1/publisher/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
#### Publishing Records
**Base Path**: `/api/v1/publisher/publishing-records/`
**Inherits**: SiteSectorModelViewSet
**Standard CRUD:**
- `GET /api/v1/publisher/publishing-records/` - List publishing records (paginated)
- `POST /api/v1/publisher/publishing-records/` - Create publishing record
- `GET /api/v1/publisher/publishing-records/{id}/` - Get publishing record
- `PUT /api/v1/publisher/publishing-records/{id}/` - Update publishing record
- `DELETE /api/v1/publisher/publishing-records/{id}/` - Delete publishing record
**Filtering:**
- `status` - Filter by publishing status
- `destination_type` - Filter by destination (wordpress, sites_renderer, etc.)
- `site_id` - Filter by site
- `sector_id` - Filter by sector
#### Deployment Records
**Base Path**: `/api/v1/publisher/deployments/`
**Inherits**: SiteSectorModelViewSet
**Standard CRUD:**
- `GET /api/v1/publisher/deployments/` - List deployment records (paginated)
- `POST /api/v1/publisher/deployments/` - Create deployment record
- `GET /api/v1/publisher/deployments/{id}/` - Get deployment record
- `PUT /api/v1/publisher/deployments/{id}/` - Update deployment record
- `DELETE /api/v1/publisher/deployments/{id}/` - Delete deployment record
#### Publishing Actions
- `POST /api/v1/publisher/publish/` - Publish content to destination
**Request:**
```json
{
"content_id": 123,
"destination_type": "wordpress",
"destination_id": 1
}
```
- `POST /api/v1/publisher/deploy/` - Deploy site blueprint
**Request:**
```json
{
"blueprint_id": 456,
"environment": "production"
}
```
- `POST /api/v1/publisher/check_readiness/` - Check deployment readiness
**Request:**
```json
{
"blueprint_id": 456
}
```
#### Public Endpoint (No Authentication)
- `GET /api/v1/publisher/sites/{site_id}/definition/` - Get site definition for Sites Renderer
**Response:**
```json
{
"success": true,
"data": {
"site_id": 1,
"slug": "example-site",
"blueprints": [...],
"pages": [...]
}
}
```
### Site Builder Module Endpoints
**Base Path**: `/api/v1/site-builder/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
#### Site Blueprints
**Base Path**: `/api/v1/site-builder/blueprints/`
**Inherits**: SiteSectorModelViewSet
**Standard CRUD:**
- `GET /api/v1/site-builder/blueprints/` - List site blueprints (paginated)
- `POST /api/v1/site-builder/blueprints/` - Create site blueprint
- `GET /api/v1/site-builder/blueprints/{id}/` - Get blueprint details
- `PUT /api/v1/site-builder/blueprints/{id}/` - Update blueprint
- `DELETE /api/v1/site-builder/blueprints/{id}/` - Delete blueprint
**Custom Actions:**
- `POST /api/v1/site-builder/blueprints/{id}/generate_structure/` - Generate site structure using AI
- `POST /api/v1/site-builder/blueprints/{id}/generate_all_pages/` - Generate all pages for blueprint
- `POST /api/v1/site-builder/blueprints/{id}/create_tasks/` - Create Writer tasks for pages
- `GET /api/v1/site-builder/blueprints/{id}/progress/` - Get cluster-level completion status
- `POST /api/v1/site-builder/blueprints/{id}/clusters/attach/` - Attach planner clusters
- `POST /api/v1/site-builder/blueprints/{id}/clusters/detach/` - Detach clusters
- `GET /api/v1/site-builder/blueprints/{id}/taxonomies/` - List taxonomies
- `POST /api/v1/site-builder/blueprints/{id}/taxonomies/` - Create taxonomy
- `POST /api/v1/site-builder/blueprints/{id}/taxonomies/import/` - Import taxonomies
- `POST /api/v1/site-builder/blueprints/bulk_delete/` - Bulk delete blueprints
**Filtering:**
- `status` - Filter by blueprint status
- `site_id` - Filter by site
- `sector_id` - Filter by sector
#### Page Blueprints
**Base Path**: `/api/v1/site-builder/pages/`
**Inherits**: SiteSectorModelViewSet
**Standard CRUD:**
- `GET /api/v1/site-builder/pages/` - List page blueprints (paginated)
- `POST /api/v1/site-builder/pages/` - Create page blueprint
- `GET /api/v1/site-builder/pages/{id}/` - Get page details
- `PUT /api/v1/site-builder/pages/{id}/` - Update page
- `DELETE /api/v1/site-builder/pages/{id}/` - Delete page
**Custom Actions:**
- `POST /api/v1/site-builder/pages/{id}/generate_content/` - Generate content for page
- `POST /api/v1/site-builder/pages/{id}/regenerate/` - Regenerate page content
**Filtering:**
- `site_blueprint_id` - Filter by site blueprint
- `status` - Filter by page status
#### Site Assets
- `GET /api/v1/site-builder/assets/` - List files for site
**Query Parameters:**
- `site_id` - Filter by site
- `file_type` - Filter by file type
- `POST /api/v1/site-builder/assets/` - Upload file
**Request:** Multipart form data
```json
{
"file": "<file>",
"site_id": 1,
"file_type": "image"
}
```
- `DELETE /api/v1/site-builder/assets/` - Delete file
**Request:**
```json
{
"file_path": "path/to/file.jpg",
"site_id": 1
}
```
#### Site Builder Metadata
- `GET /api/v1/site-builder/metadata/` - Get metadata (business types, audience profiles, etc.)
**Response:**
```json
{
"success": true,
"data": {
"business_types": [...],
"audience_profiles": [...],
"brand_personalities": [...],
"hero_imagery_directions": [...]
}
}
```
### Automation Module Endpoints
**Base Path**: `/api/v1/automation/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
#### Automation Rules
**Base Path**: `/api/v1/automation/rules/`
**Inherits**: SiteSectorModelViewSet
**Standard CRUD:**
- `GET /api/v1/automation/rules/` - List automation rules (paginated)
- `POST /api/v1/automation/rules/` - Create automation rule
- `GET /api/v1/automation/rules/{id}/` - Get rule details
- `PUT /api/v1/automation/rules/{id}/` - Update rule
- `DELETE /api/v1/automation/rules/{id}/` - Delete rule
**Custom Actions:**
- `POST /api/v1/automation/rules/{id}/execute/` - Manually execute automation rule
**Filtering:**
- `status` - Filter by rule status (active, inactive)
- `trigger_type` - Filter by trigger type
- `site_id` - Filter by site
- `sector_id` - Filter by sector
#### Scheduled Tasks
**Base Path**: `/api/v1/automation/scheduled-tasks/`
**Inherits**: AccountModelViewSet
**Standard CRUD:**
- `GET /api/v1/automation/scheduled-tasks/` - List scheduled tasks (paginated)
- `POST /api/v1/automation/scheduled-tasks/` - Create scheduled task
- `GET /api/v1/automation/scheduled-tasks/{id}/` - Get task details
- `PUT /api/v1/automation/scheduled-tasks/{id}/` - Update task
- `DELETE /api/v1/automation/scheduled-tasks/{id}/` - Delete task
**Filtering:**
- `status` - Filter by task status
- `task_type` - Filter by task type
- `next_run_date` - Filter by next run date
### Integration Module Endpoints
**Base Path**: `/api/v1/integration/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
#### Site Integrations
**Base Path**: `/api/v1/integration/integrations/`
**Inherits**: SiteSectorModelViewSet
**Standard CRUD:**
- `GET /api/v1/integration/integrations/` - List site integrations (paginated)
- `POST /api/v1/integration/integrations/` - Create integration
- `GET /api/v1/integration/integrations/{id}/` - Get integration details
- `PUT /api/v1/integration/integrations/{id}/` - Update integration
- `DELETE /api/v1/integration/integrations/{id}/` - Delete integration
**Custom Actions:**
- `POST /api/v1/integration/integrations/{id}/test_connection/` - Test connection to integrated platform
**Request:**
```json
{}
```
**Response:**
```json
{
"success": true,
"data": {
"connected": true,
"message": "Connection successful"
}
}
```
- `POST /api/v1/integration/integrations/{id}/sync/` - Sync content with integrated platform
**Request:**
```json
{
"content_ids": [123, 456],
"sync_type": "full" // or "incremental"
}
```
- `GET /api/v1/integration/integrations/{id}/sync_health/` - Get sync health status
**Response:**
```json
{
"success": true,
"data": {
"last_sync": "2025-01-XXT...",
"sync_status": "healthy",
"pending_items": 0,
"failed_items": 0
}
}
```
**Filtering:**
- `platform_type` - Filter by platform (wordpress, shopify, etc.)
- `status` - Filter by integration status
- `site_id` - Filter by site
- `sector_id` - Filter by sector
### Billing Module Endpoints
**Base Path**: `/api/v1/billing/`
#### Credit Balance
**Base Path**: `/api/v1/billing/credits/balance/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
- `GET /api/v1/billing/credits/balance/balance/` - Get credit balance
**Response:**
```json
{
"success": true,
"data": {
"credits": 1000,
"plan_credits_per_month": 500,
"credits_used_this_month": 250,
"credits_remaining": 750
}
}
```
#### Credit Usage
**Base Path**: `/api/v1/billing/credits/usage/`
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
**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
- `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
- `GET /api/v1/billing/credits/usage/limits/` - Get usage limits
#### Credit Transactions
**Base Path**: `/api/v1/billing/credits/transactions/`
**Permission**: IsAdminOrOwner
**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
- `start_date` - Filter by start date
- `end_date` - Filter by end date
---
## Integration Examples
### Python
```python
import requests
BASE_URL = "https://api.igny8.com/api/v1"
# Login
response = requests.post(
f"{BASE_URL}/auth/login/",
json={"email": "user@example.com", "password": "password"}
)
data = response.json()
if data['success']:
token = data['data']['access']
# Use token for authenticated requests
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
# Get keywords
response = requests.get(
f"{BASE_URL}/planner/keywords/?page=1&page_size=25",
headers=headers
)
result = response.json()
if result['success']:
keywords = result['results']
print(f"Found {result['count']} keywords")
else:
print(f"Error: {result['error']}")
```
### JavaScript
```javascript
const BASE_URL = 'https://api.igny8.com/api/v1';
// Login
const loginResponse = await fetch(`${BASE_URL}/auth/login/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'user@example.com',
password: 'password'
})
});
const loginData = await loginResponse.json();
if (loginData.success) {
const token = loginData.data.access;
// Use token for authenticated requests
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
// Get keywords
const keywordsResponse = await fetch(
`${BASE_URL}/planner/keywords/?page=1&page_size=25`,
{ headers }
);
const keywordsData = await keywordsResponse.json();
if (keywordsData.success) {
const keywords = keywordsData.results;
console.log(`Found ${keywordsData.count} keywords`);
} else {
console.error('Error:', keywordsData.error);
}
}
```
### cURL
```bash
# Login
curl -X POST https://api.igny8.com/api/v1/auth/login/ \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password"}'
# Get keywords (with token)
curl -X GET https://api.igny8.com/api/v1/planner/keywords/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"
```
### Frontend Integration (TypeScript)
```typescript
// Using fetchAPI wrapper (automatically extracts data from unified format)
import { fetchAPI } from './services/api';
// List keywords
const response = await fetchAPI('/v1/planner/keywords/?page=1&page_size=25');
// response is already extracted: { count, next, previous, results }
// Create keyword
const newKeyword = await fetchAPI('/v1/planner/keywords/', {
method: 'POST',
body: JSON.stringify({
keyword: 'example keyword',
site_id: 1,
sector_id: 2,
status: 'active'
})
});
// Error handling
try {
const data = await fetchAPI('/v1/planner/keywords/');
} catch (error) {
// Error is already parsed from unified format
console.error(error.message);
if (error.errors) {
// Handle field-specific errors
Object.keys(error.errors).forEach(field => {
console.error(`${field}: ${error.errors[field].join(', ')}`);
});
}
}
```
### WordPress Plugin Integration (PHP)
```php
class Igny8API {
private $base_url = 'https://api.igny8.com/api/v1';
private $token;
public function login($email, $password) {
$response = wp_remote_post($this->base_url . '/auth/login/', [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode(['email' => $email, 'password' => $password])
]);
$data = json_decode(wp_remote_retrieve_body($response), true);
if ($data['success']) {
$this->token = $data['data']['access'];
return true;
}
return false;
}
public function getKeywords($page = 1, $page_size = 25) {
$response = wp_remote_get(
$this->base_url . '/planner/keywords/?page=' . $page . '&page_size=' . $page_size,
[
'headers' => [
'Authorization' => 'Bearer ' . $this->token,
'Content-Type' => 'application/json'
]
]
);
$data = json_decode(wp_remote_retrieve_body($response), true);
if ($data['success']) {
return $data['results'];
}
return [];
}
}
```
---
## Testing & Debugging
### Request ID Tracking
Every API request includes a unique `request_id` in the response. Use this ID for:
- Debugging issues
- Log correlation
- Support requests
The `request_id` is included in:
- All success responses
- All error responses
- Response headers (`X-Request-ID`)
### Progress Tracking (AI Functions)
All AI functions return a Celery task ID for progress tracking:
**Request:**
```json
POST /api/v1/planner/keywords/auto_cluster/
{
"ids": [1, 2, 3, 4, 5],
"sector_id": 1
}
```
**Response:**
```json
{
"success": true,
"data": {
"task_id": "abc123-def456-ghi789"
}
}
```
**Poll Progress:**
```json
GET /api/v1/system/settings/task_progress/abc123-def456-ghi789/
```
**Progress Response:**
```json
{
"state": "PROGRESS",
"meta": {
"phase": "AI_CALL",
"percentage": 50,
"message": "Processing keywords...",
"request_steps": [...],
"response_steps": [...],
"cost": 0.05,
"tokens": 1500
}
}
```
### Error Handling Best Practices
**401 Unauthorized**: Trigger logout → redirect to login
**403 Forbidden**: Show permission alert
**429 Too Many Requests**: Show rate limit warning with retry time
**4xx/5xx**: Display error message from `error` field
### Rate Limit Monitoring
```typescript
const throttleLimit = response.headers.get('X-Throttle-Limit');
const throttleRemaining = response.headers.get('X-Throttle-Remaining');
if (parseInt(throttleRemaining) < 5) {
showNotification('Approaching rate limit', 'warning');
}
```
---
## Change Management
### Versioning Strategy
- **v1** remains stable long-term
- Breaking changes require **v2**
- Deprecations allowed only with explicit timeline
- Non-breaking changes can be added to v1
### Breaking Changes
**Definition:** Changes that require client code updates
**Examples:**
- Removing an endpoint
- Changing response structure
- Changing authentication method
- Removing a field from response
**Process:**
1. Document breaking change
2. Provide migration guide
3. Deprecate in v1 with timeline
4. Implement in v2
5. Maintain v1 for deprecation period
### Non-Breaking Changes
**Definition:** Changes that don't require client code updates
**Examples:**
- Adding new endpoints
- Adding optional fields to response
- Adding new query parameters
- Performance improvements
### Changelog
All API changes are documented in `CHANGELOG.md` with:
- Version number
- Date
- Type (Added, Changed, Fixed, Deprecated, Removed, Security)
- Description
- Affected areas
- Migration notes (if applicable)
---
## Summary
### Implementation Status
**100% Complete** - All endpoints implemented with:
- Unified response format (`{success, data, message, errors, request_id}`)
- Proper authentication and authorization (JWT Bearer tokens)
- Rate limiting configured (scoped by operation type)
- Error handling standardized (centralized exception handler)
- Request ID tracking (every request has unique ID)
- Complete Swagger/OpenAPI documentation
- Tenant/site/sector scoping (automatic filtering)
- Pagination standardized (default: 10, max: 100)
### Key Features
- **100+ endpoints** across 5 modules
- **Unified response format** for all endpoints
- **Scoped rate limiting** (10-100 requests/minute depending on operation)
- **Layered authorization** (Authentication → Tenant → Role → Site/Sector)
- **Complete OpenAPI documentation** (Swagger UI, ReDoc)
- **Request ID tracking** for debugging
- **Progress tracking** for AI functions
- **Comprehensive error handling** with clear messages
### Access Points
- **Interactive Documentation**: `https://api.igny8.com/api/docs/`
- **ReDoc**: `https://api.igny8.com/api/redoc/`
- **OpenAPI Schema**: `https://api.igny8.com/api/schema/`
---
**Last Updated**: 2025-01-XX (Added 6 missing modules: Linker, Optimizer, Publisher, Site Builder, Automation, Integration)
**API Version**: 1.0.0
**Status**: ✅ **100% IMPLEMENTED** - All 10 modules documented with complete endpoint reference