# IGNY8 API Documentation v1.0 **Base URL**: `https://api.igny8.com/api/v1/` **Version**: 1.0.0 **Last Updated**: 2025-11-16 ## Quick Links - [Interactive API Documentation (Swagger UI)](#swagger-ui) - [Authentication Guide](#authentication) - [Response Format](#response-format) - [Error Handling](#error-handling) - [Rate Limiting](#rate-limiting) - [Pagination](#pagination) - [Endpoint Reference](#endpoint-reference) --- ## Swagger UI Interactive API documentation is available at: - **Swagger UI**: `https://api.igny8.com/api/docs/` - **ReDoc**: `https://api.igny8.com/api/redoc/` - **OpenAPI Schema**: `https://api.igny8.com/api/schema/` The Swagger UI provides: - Interactive endpoint testing - Request/response examples - Authentication testing - Schema definitions - Code samples in multiple languages --- ## Authentication ### JWT Bearer Token All endpoints require JWT Bearer token authentication except: - `POST /api/v1/auth/login/` - User login - `POST /api/v1/auth/register/` - User registration ### 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" }, "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }, "request_id": "uuid" } ``` ### Using the Token Include the token in the `Authorization` header: ```http GET /api/v1/planner/keywords/ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... Content-Type: application/json ``` ### Token Expiration - **Access Token**: 15 minutes - **Refresh Token**: 7 days Use the refresh token to get a new access token: ```http POST /api/v1/auth/refresh/ Content-Type: application/json { "refresh": "your_refresh_token" } ``` --- ## Response Format ### Success Response All successful responses follow this unified format: ```json { "success": true, "data": { "id": 1, "name": "Example", ... }, "message": "Optional success message", "request_id": "550e8400-e29b-41d4-a716-446655440000" } ``` ### Paginated Response List endpoints return paginated data: ```json { "success": true, "count": 100, "next": "https://api.igny8.com/api/v1/planner/keywords/?page=2", "previous": null, "results": [ {"id": 1, "name": "Keyword 1"}, {"id": 2, "name": "Keyword 2"}, ... ], "request_id": "550e8400-e29b-41d4-a716-446655440000" } ``` ### Error Response All error responses follow this unified format: ```json { "success": false, "error": "Validation failed", "errors": { "email": ["This field is required"], "password": ["Password too short"] }, "request_id": "550e8400-e29b-41d4-a716-446655440000" } ``` --- ## 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 | ### Error Response Structure All errors include: - `success`: Always `false` - `error`: Top-level error message - `errors`: Field-specific errors (for validation errors) - `request_id`: Unique request ID for debugging ### Example Error Responses **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" } ``` **Not Found (404):** ```json { "success": false, "error": "Resource not found", "request_id": "550e8400-e29b-41d4-a716-446655440000" } ``` **Rate Limit (429):** ```json { "success": false, "error": "Rate limit exceeded", "request_id": "550e8400-e29b-41d4-a716-446655440000" } ``` --- ## Rate Limiting 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 { "success": false, "error": "Rate limit exceeded", "request_id": "550e8400-e29b-41d4-a716-446655440000" } ``` --- ## Pagination List endpoints support pagination with query parameters: - `page`: Page number (default: 1) - `page_size`: Items per page (default: 10, max: 100) ### Example Request ```http GET /api/v1/planner/keywords/?page=2&page_size=20 ``` ### Paginated Response ```json { "success": true, "count": 100, "next": "https://api.igny8.com/api/v1/planner/keywords/?page=3&page_size=20", "previous": "https://api.igny8.com/api/v1/planner/keywords/?page=1&page_size=20", "results": [ {"id": 21, "name": "Keyword 21"}, {"id": 22, "name": "Keyword 22"}, ... ], "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 --- ## Endpoint Reference ### Authentication Endpoints #### Login ```http POST /api/v1/auth/login/ ``` #### Register ```http POST /api/v1/auth/register/ ``` #### Refresh Token ```http POST /api/v1/auth/refresh/ ``` ### Planner Endpoints #### List Keywords ```http GET /api/v1/planner/keywords/ ``` #### Create Keyword ```http POST /api/v1/planner/keywords/ ``` #### Get Keyword ```http GET /api/v1/planner/keywords/{id}/ ``` #### Update Keyword ```http PUT /api/v1/planner/keywords/{id}/ PATCH /api/v1/planner/keywords/{id}/ ``` #### Delete Keyword ```http DELETE /api/v1/planner/keywords/{id}/ ``` #### Auto Cluster Keywords ```http POST /api/v1/planner/keywords/auto_cluster/ ``` ### Writer Endpoints #### List Tasks ```http GET /api/v1/writer/tasks/ ``` #### Create Task ```http POST /api/v1/writer/tasks/ ``` ### System Endpoints #### System Status ```http GET /api/v1/system/status/ ``` #### List Prompts ```http GET /api/v1/system/prompts/ ``` ### Billing Endpoints #### Credit Balance ```http GET /api/v1/billing/credits/balance/balance/ ``` #### Usage Summary ```http GET /api/v1/billing/credits/usage/summary/ ``` --- ## Code 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/", headers=headers ) keywords_data = response.json() if keywords_data['success']: keywords = keywords_data['results'] print(f"Found {keywords_data['count']} keywords") else: print(f"Error: {keywords_data['error']}") else: print(f"Login failed: {data['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/`, { 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); } } else { console.error('Login failed:', loginData.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" ``` --- ## Request ID 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`) --- ## Support For API support: - Check the [Interactive Documentation](https://api.igny8.com/api/docs/) - Review [Error Codes Reference](ERROR-CODES.md) - Contact support with your `request_id` --- **Last Updated**: 2025-11-16 **API Version**: 1.0.0