546 lines
11 KiB
Markdown
546 lines
11 KiB
Markdown
# 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
|
|
|