HG Content System - API Documentation¶
This document provides comprehensive API documentation for all services in the HG Content System. The system consists of four main modules: Content Production Module (CPM), Instructions Module (IM), Strategy Management Module (SMM), and the Frontend Next.js application.
Table of Contents¶
- Authentication
- Content Production Module (CPM) API
- Instructions Module (IM) API
- Strategy Management Module (SMM) API
- Frontend Next.js API Routes
- Error Handling
- Rate Limiting
Authentication¶
Overview¶
The HG Content System uses different authentication methods depending on the service:
- CPM & IM: API Key authentication using Bearer tokens
- SMM: Header-based user authentication (X-User-ID)
- Frontend: Supabase JWT authentication
API Key Authentication (CPM & IM)¶
Format¶
- Production:
cpm_live_<random_32_chars> - Development:
cpm_test_<random_32_chars>
Headers¶
Permissions¶
read: View job status and resultswrite: Create new content generation jobsadmin: Administrative operations
Content Production Module (CPM) API¶
Base URL: http://localhost:8002 (development)
Endpoints¶
POST /generate¶
Generate content using specified LLM provider with IM integration.
Authentication: Required (Bearer token) Permissions: write
Request Body:
{
"content_type": "blog",
"prompt": "Write about AI in healthcare",
"client_id": "client-uuid",
"llm_provider": "openai",
"keywords": ["AI", "healthcare", "technology"],
"length": "medium",
"model": "gpt-4",
"parameters": {
"temperature": 0.7,
"max_tokens": 2000
}
}
Request Schema: - content_type (string, required): Type of content to generate - prompt (string, required): Content generation prompt - client_id (string, required): Client identifier - llm_provider (string, optional): LLM provider to use (default: "openai") - keywords (array[string], optional): SEO keywords for content - length (string, optional): Content length ("short"/"medium"/"long") - model (string, optional): Specific model to use - parameters (object, optional): Additional parameters
Response:
{
"job_id": "job-uuid",
"status": "pending",
"message": "Content generation job queued successfully"
}
Status Codes: - 200: Job created successfully - 400: Invalid request data - 401: Unauthorized - 403: Insufficient permissions - 500: Internal server error
GET /jobs/{job_id}¶
Get status and result of a content generation job.
Authentication: Required (Bearer token) Permissions: read
Path Parameters: - job_id (string): Unique job identifier
Response:
{
"job_id": "job-uuid",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:35:00Z",
"content_type": "blog",
"client_id": "client-uuid",
"result": {
"content": "Generated content...",
"metadata": {
"word_count": 1500,
"model_used": "gpt-4",
"cost_estimate": 0.12
}
},
"error": null
}
Status Values: - pending: Job queued for processing - in_progress: Currently being processed - completed: Successfully completed - failed: Processing failed - cancelled: Job was cancelled
Status Codes: - 200: Job found and returned - 401: Unauthorized - 403: Insufficient permissions - 404: Job not found - 500: Internal server error
GET /jobs¶
List jobs for the authenticated client.
Authentication: Required (Bearer token) Permissions: read
Query Parameters: - status (string, optional): Filter by job status - limit (integer, optional): Maximum number of jobs (default: 20, max: 100) - offset (integer, optional): Number of jobs to skip (default: 0)
Response:
{
"jobs": [
{
"job_id": "job-uuid-1",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:35:00Z",
"content_type": "blog",
"client_id": "client-uuid",
"result": {...},
"error": null
}
],
"total": 1,
"limit": 20,
"offset": 0
}
Status Codes: - 200: Jobs retrieved successfully - 400: Invalid query parameters - 401: Unauthorized - 403: Insufficient permissions - 500: Internal server error
GET /health¶
Health check endpoint for monitoring.
Authentication: Not required
Response:
Status Codes: - 200: Service healthy - 503: Service unhealthy
GET /¶
Root endpoint with basic service information.
Authentication: Not required
Response:
{
"service": "Content Production Module",
"version": "1.0.0",
"status": "operational",
"docs": "/docs"
}
Instructions Module (IM) API¶
Base URL: http://localhost:8001 (development)
Endpoints¶
POST /generate-prompt¶
Create a new prompt generation job.
Authentication: Required (Bearer token) Permissions: write
Request Body:
{
"client_id": "client-uuid",
"content_type": "blog",
"topic": "AI in healthcare",
"keywords": ["AI", "healthcare", "machine learning"],
"context": {
"target_audience": "healthcare professionals",
"tone": "professional"
}
}
Request Schema: - client_id (uuid, required): Client identifier - content_type (enum, required): Type of content ("blog", "social", "email", etc.) - topic (string, required): Topic for prompt generation - keywords (array[string], optional): Keywords to include - context (object, optional): Additional context information
Response:
Status Codes: - 202: Job created successfully - 400: Invalid request parameters - 401: Unauthorized - 503: Service unavailable
GET /prompt/{job_id}¶
Get prompt generation job status and results.
Authentication: Required (Bearer token) Permissions: read
Path Parameters: - job_id (uuid): Unique job identifier
Response (Completed):
{
"job_id": "job-uuid",
"status": "completed",
"prompt": "Enhanced prompt for content generation...",
"metadata": {
"templates_used": ["blog_template_v1"],
"enhancements_applied": ["seo_optimization", "tone_adjustment"]
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:32:00Z"
}
Response (In Progress):
Response (Failed):
{
"job_id": "job-uuid",
"status": "failed",
"error": "Template not found for content type",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:31:00Z"
}
Status Codes: - 200: Job completed - returns prompt - 202: Job still processing - 404: Job not found - 503: Service unavailable
GET /templates/{client_id}¶
Get templates for a specific client (Debug endpoint).
Authentication: Required (Bearer token) Permissions: read
Path Parameters: - client_id (string): Client identifier
Query Parameters: - content_type (string, optional): Filter by content type - active_only (boolean, optional): Return only active templates (default: true)
Response:
{
"client_id": "client-uuid",
"templates": [
{
"id": "template-uuid",
"name": "Blog Template v1",
"content_type": "blog",
"template": "Write a {length} blog post about {topic}...",
"active": true,
"created_at": "2024-01-15T10:30:00Z"
}
],
"count": 1
}
Status Codes: - 200: Templates retrieved successfully - 404: Client not found - 503: Service unavailable
GET /health¶
Service health check endpoint.
Authentication: Not required
Response:
{
"status": "healthy",
"service": "Instructions Module",
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00Z",
"database_status": "connected",
"openai_status": "enabled",
"task_manager": {
"active_tasks": 3,
"total_tasks": 15,
"total_completed": 12,
"total_failed": 0
}
}
Status Codes: - 200: Service healthy - 503: Service unhealthy
GET /stats¶
Get service statistics and metrics.
Authentication: Required (Bearer token) Permissions: read
Query Parameters: - client_id (string, optional): Filter statistics by client
Response:
{
"service": "Instructions Module",
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00Z",
"filter": {
"client_id": "client-uuid"
},
"job_statistics": {
"total_jobs": 150,
"completed_jobs": 145,
"failed_jobs": 3,
"pending_jobs": 2
},
"task_manager_metrics": {
"task_counts": {
"active": 3,
"total": 15
},
"total_completed": 145,
"total_failed": 3
},
"template_cache": {
"cached_templates": 25,
"cache_max_age_seconds": 3600
}
}
Status Codes: - 200: Statistics retrieved successfully - 503: Service unavailable
Strategy Management Module (SMM) API¶
Base URL: http://localhost:8003 (development)
Authentication¶
Uses header-based authentication with X-User-ID header.
Headers:
Endpoints¶
GET /api/strategies/{client_id}¶
Get consolidated strategy for a client.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier
Response:
{
"id": "strategy-uuid",
"client_id": "client-uuid",
"name": "Main Strategy",
"description": "Primary content strategy",
"config": {
"brand_voice": "Professional and approachable",
"target_audience": "Healthcare professionals",
"content_pillars": "Education, Innovation, Trust",
"tone": {
"formality": "professional",
"voice": "authoritative",
"engagement": "educational"
},
"content_guidelines": {
"min_words": 500,
"max_words": 2000,
"required_sections": ["introduction", "main_content", "conclusion"],
"citation_required": true,
"difficulty_level": "professional"
}
},
"active": true,
"version": 1,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"seo_rules": [
{
"id": "rule-uuid",
"rule_type": "keywords",
"rules": {
"value": "healthcare AI",
"weight": 0.8
},
"priority": 1,
"active": true
}
],
"content_preferences": [
{
"content_type": "blog",
"preferences": {
"style": "informative",
"structure": "problem-solution-benefit"
}
}
]
}
Status Codes: - 200: Strategy retrieved successfully - 403: Access denied - 404: Strategy not found - 503: Service unavailable
PUT /api/strategies/{client_id}¶
Update a client's strategy with versioning.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier
Request Body:
{
"config": {
"brand_voice": "Updated brand voice",
"target_audience": "Updated target audience"
},
"change_summary": "Updated brand voice and target audience"
}
Response: Returns updated consolidated strategy (same format as GET)
Status Codes: - 200: Strategy updated successfully - 403: Access denied - 404: Strategy not found - 503: Service unavailable
GET /api/seo-rules/{client_id}¶
Get all SEO rules for a client.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier
Query Parameters: - rule_type (string, optional): Filter by rule type - active_only (boolean, optional): Return only active rules (default: true)
Response:
{
"client_id": "client-uuid",
"rules": [
{
"id": "rule-uuid",
"client_id": "client-uuid",
"rule_type": "keywords",
"rules": {
"value": "healthcare AI",
"weight": 0.8
},
"priority": 1,
"active": true,
"created_at": "2024-01-15T10:30:00Z"
}
],
"total": 1
}
Status Codes: - 200: SEO rules retrieved successfully - 403: Access denied
POST /api/seo-rules/{client_id}¶
Create a new SEO rule for a client.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier
Request Body:
{
"rule_type": "keywords",
"rules": {
"value": "machine learning healthcare",
"weight": 0.7
},
"priority": 2,
"active": true
}
Response: Returns created SEO rule
Status Codes: - 201: SEO rule created successfully - 403: Access denied - 503: Service unavailable
PUT /api/seo-rules/{client_id}/{rule_id}¶
Update an existing SEO rule.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier - rule_id (uuid): SEO rule identifier
Request Body (partial update):
Response: Returns updated SEO rule
Status Codes: - 200: SEO rule updated successfully - 403: Access denied - 404: SEO rule not found - 503: Service unavailable
DELETE /api/seo-rules/{client_id}/{rule_id}¶
Delete an SEO rule.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier - rule_id (uuid): SEO rule identifier
Response:
Status Codes: - 200: SEO rule deleted successfully - 403: Access denied - 404: SEO rule not found - 503: Service unavailable
PUT /api/content-preferences/{client_id}/{content_type}¶
Update content preferences for a specific content type.
Authentication: Required (X-User-ID header)
Path Parameters: - client_id (uuid): Client identifier - content_type (enum): Content type ("blog", "social", "email", etc.)
Request Body:
{
"preferences": {
"style": "conversational",
"structure": "introduction-body-cta",
"length_preference": "medium"
}
}
Response:
{
"success": true,
"message": "Content preferences for blog updated successfully",
"data": {
"preference_id": "preference-uuid"
}
}
Status Codes: - 200: Content preferences updated successfully - 403: Access denied - 503: Service unavailable
GET /health¶
Service health check endpoint.
Authentication: Not required
Response:
{
"status": "healthy",
"service": "Strategy Management Module",
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00Z"
}
Status Codes: - 200: Service healthy - 503: Service unhealthy
Frontend Next.js API Routes¶
Base URL: http://localhost:3000 (development)
Authentication¶
Uses Supabase JWT authentication with session cookies.
Endpoints¶
GET /api/analytics¶
Get analytics and metrics data.
Authentication: Required (Supabase session)
Query Parameters: - client_id (string, optional): Filter by specific client - start_date (string, optional): Start date for analytics (ISO format) - end_date (string, optional): End date for analytics (ISO format)
Response:
{
"totalSpent": 45.67,
"totalContent": 150,
"avgCostPerContent": 0.30,
"costByProvider": [
{
"provider": "gpt-4",
"cost": 30.50,
"percentage": 66.8
}
],
"dailyCosts": [
{
"date": "2024-01-15",
"cost": 5.20
}
],
"totalJobs": 180,
"completedJobs": 150,
"failedJobs": 5,
"avgProcessingTime": 45,
"successRate": 83.33,
"contentByType": [
{
"type": "blog",
"count": 80,
"percentage": 44.4
}
],
"jobsOverTime": [
{
"date": "2024-01-15",
"count": 12
}
],
"statusDistribution": [
{
"status": "completed",
"count": 150,
"percentage": 83.3
}
],
"clientBreakdown": [
{
"client": "Client A",
"count": 90,
"percentage": 50.0
}
]
}
Status Codes: - 200: Analytics retrieved successfully - 401: Unauthorized - 500: Internal server error
POST /api/content/generate¶
Generate content by forwarding request to CPM service.
Authentication: Required (Supabase session)
Request Body:
{
"client_id": "client-uuid",
"content_type": "blog",
"topic": "AI in healthcare",
"keywords": ["AI", "healthcare", "technology"],
"additional_instructions": "Focus on practical applications",
"length": "medium",
"tone": "professional"
}
Request Schema: - client_id (uuid, required): Client identifier - content_type (enum, required): Content type ("blog", "social", "local", "email", "landing") - topic (string, required): Content topic (1-500 chars) - keywords (array[string], required): Keywords (1-10 items) - additional_instructions (string, optional): Additional instructions (max 1000 chars) - length (enum, optional): Content length ("short", "medium", "long") - tone (enum, optional): Content tone ("professional", "casual", "friendly", "authoritative")
Response: Forwards CPM response
Status Codes: - 201: Content generation job created - 400: Invalid request data - 401: Unauthorized - 403: Access denied to client - 503: CPM service not configured
GET /api/jobs¶
List jobs for accessible clients.
Authentication: Required (Supabase session)
Query Parameters: - client_id (string, optional): Filter by specific client - limit (integer, optional): Maximum number of jobs (default: 20) - offset (integer, optional): Number of jobs to skip (default: 0) - status (string, optional): Filter by job status
Response:
{
"jobs": [
{
"id": "job-uuid",
"client_id": "client-uuid",
"content_type": "blog",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:35:00Z",
"result": {...},
"clients": {
"id": "client-uuid",
"name": "Client Name"
}
}
],
"total": 1,
"limit": 20,
"offset": 0
}
Status Codes: - 200: Jobs retrieved successfully - 401: Unauthorized - 500: Internal server error
GET /api/jobs/[jobId]¶
Get specific job details.
Authentication: Required (Supabase session)
Path Parameters: - jobId (string): Job identifier
Response: Returns job object with client information
Status Codes: - 200: Job retrieved successfully - 401: Unauthorized - 403: Access denied - 404: Job not found - 500: Internal server error
GET /api/v2/strategies¶
List strategies for a client.
Authentication: Required (Supabase session)
Query Parameters: - clientId (string, required): Client identifier
Response:
[
{
"id": "strategy-uuid",
"client_id": "client-uuid",
"name": "Main Strategy",
"description": "Primary content strategy",
"active": true,
"config": {
"brand_voice": "Professional and approachable",
"target_audience": "Healthcare professionals"
},
"seo_rules": [
{
"id": "rule-uuid",
"type": "keyword",
"value": "healthcare AI",
"weight": 0.8
}
],
"created_at": "2024-01-15T10:30:00Z"
}
]
Status Codes: - 200: Strategies retrieved successfully - 400: Client ID required - 401: Unauthorized - 403: Access denied - 500: Internal server error
POST /api/v2/strategies¶
Create a new strategy.
Authentication: Required (Supabase session with admin/manager role)
Request Body:
{
"client_id": "client-uuid",
"name": "New Strategy",
"description": "Strategy description",
"active": true,
"config": {
"brand_voice": "Professional",
"target_audience": "Healthcare professionals",
"tone": {
"formality": "professional",
"voice": "authoritative"
}
},
"seo_rules": [
{
"type": "keyword",
"value": "healthcare AI",
"weight": 0.8
}
]
}
Response: Returns created strategy with transformed SEO rules
Status Codes: - 201: Strategy created successfully - 400: Invalid request data - 401: Unauthorized - 403: Insufficient permissions - 500: Internal server error
PUT /api/v2/strategies¶
Update an existing strategy.
Authentication: Required (Supabase session with admin/manager role)
Query Parameters: - id (string, required): Strategy identifier
Request Body: Same format as POST (partial updates allowed)
Response: Returns updated strategy
Status Codes: - 200: Strategy updated successfully - 400: Strategy ID required - 401: Unauthorized - 403: Insufficient permissions - 404: Strategy not found - 500: Internal server error
DELETE /api/v2/strategies¶
Delete a strategy.
Authentication: Required (Supabase session with admin role)
Query Parameters: - id (string, required): Strategy identifier
Response:
Status Codes: - 200: Strategy deleted successfully - 400: Strategy ID required - 401: Unauthorized - 403: Insufficient permissions - 404: Strategy not found - 500: Internal server error
GET /api/health¶
Frontend service health check.
Authentication: Not required
Response:
Status Codes: - 200: Service healthy
GET /auth/callback¶
Supabase authentication callback handler.
Authentication: Not required (handles auth flow)
Query Parameters: - code (string): Authorization code from Supabase
Response: Redirects to /dashboard
Error Handling¶
Standard Error Response Format¶
All services return errors in a consistent format:
{
"error": "Error message",
"detail": "Detailed error description",
"code": "ERROR_CODE",
"timestamp": "2024-01-15T10:30:00Z"
}
Common HTTP Status Codes¶
- 200: OK - Request successful
- 201: Created - Resource created successfully
- 202: Accepted - Request accepted for processing
- 400: Bad Request - Invalid request data
- 401: Unauthorized - Authentication required or failed
- 403: Forbidden - Insufficient permissions
- 404: Not Found - Resource not found
- 429: Too Many Requests - Rate limit exceeded
- 500: Internal Server Error - Server error
- 503: Service Unavailable - Service temporarily unavailable
Service-Specific Error Codes¶
CPM Errors¶
INVALID_CLIENT_ID: Client ID mismatchWRITE_PERMISSION_REQUIRED: Write permission neededJOB_NOT_FOUND: Job does not existJOB_CREATION_FAILED: Failed to create job
IM Errors¶
INVALID_PARAMETERS: Request validation failedJOB_ERROR: Database job operation failedTEMPLATE_ERROR: Template operation failedOPENAI_ERROR: OpenAI service error
SMM Errors¶
STRATEGY_ERROR: Strategy operation failedSEO_RULE_ERROR: SEO rule operation failedACCESS_DENIED: User lacks client access
Frontend Errors¶
UNAUTHORIZED: Supabase authentication failedACCESS_DENIED: User lacks client permissionsCPM_SERVICE_ERROR: CPM service communication failedVALIDATION_ERROR: Request data validation failed
Rate Limiting¶
CPM & IM Rate Limiting¶
Rate limits are enforced per API key with the following default limits:
- Per Minute: 60 requests
- Per Hour: 1,000 requests
- Per Day: 10,000 requests
Rate Limit Headers¶
Responses include rate limit information:
Rate Limit Exceeded Response¶
{
"error": "Rate limit exceeded: 60 requests per minute",
"code": "RATE_LIMIT_EXCEEDED",
"retry_after": 60
}
Status Code: 429 Too Many Requests
Frontend Rate Limiting¶
The frontend service relies on Supabase's built-in rate limiting and does not implement additional limits.
SMM Rate Limiting¶
SMM does not currently implement rate limiting but relies on authentication and authorization controls.
Usage Examples¶
Complete Content Generation Workflow¶
-
Generate Content (Frontend → CPM):
-
Check Job Status:
-
Get Analytics:
Strategy Management¶
-
Get Client Strategy:
-
Update Strategy:
-
Create SEO Rule:
API Versioning¶
Current Versions¶
- CPM: v1.0.0
- IM: v1.0.0
- SMM: v1.0.0
- Frontend: v1.0.0
Versioning Strategy¶
- CPM/IM/SMM: Version included in service metadata, no URL versioning
- Frontend: URL-based versioning for breaking changes (e.g.,
/api/v2/strategies)
Deprecation Policy¶
- Deprecated endpoints will be marked with
X-Deprecated: trueheader - 6-month notice before removal
- Migration guides provided for breaking changes
Development & Testing¶
Environment Variables¶
CPM¶
DATABASE_URL=postgresql://...
REDIS_URL=redis://localhost:6379
IM_SERVICE_URL=http://localhost:8001
ENVIRONMENT=development
IM¶
SMM¶
Frontend¶
NEXT_PUBLIC_SUPABASE_URL=https://...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
CPM_SERVICE_URL=http://localhost:8002
API Documentation URLs¶
- CPM: http://localhost:8002/docs
- IM: http://localhost:8001/docs
- SMM: http://localhost:8003/docs
- Frontend: Available through this document
Last Updated: January 15, 2024 Version: 1.0.0