Prompts API
Pierre provides REST APIs for managing AI chat prompt suggestions. Prompts are tenant-isolated and organized into three pillars: Activity, Nutrition, and Recovery.
Overview
The prompts system consists of three components:
- Prompt Categories: Grouped suggestions displayed in the chat interface
- Welcome Prompt: Message shown to first-time users
- System Prompt: LLM instructions defining assistant behavior
Authentication
All endpoints require JWT authentication via Bearer token or auth cookie:
Authorization: Bearer <jwt_token>
Admin endpoints additionally require admin or super_admin role.
Public Endpoints
Get Prompt Suggestions
Retrieves active prompt categories and welcome message for the authenticated user’s tenant.
GET /api/prompts/suggestions
Authorization: Bearer <jwt_token>
Response 200 OK:
{
"categories": [
{
"category_key": "training",
"category_title": "Training",
"category_icon": "runner",
"pillar": "activity",
"prompts": [
"Am I ready for a hard workout today?",
"What's my predicted marathon time?"
]
},
{
"category_key": "nutrition",
"category_title": "Nutrition",
"category_icon": "salad",
"pillar": "nutrition",
"prompts": [
"How many calories should I eat today?",
"What should I eat before my morning run?"
]
},
{
"category_key": "recovery",
"category_title": "Recovery",
"category_icon": "sleep",
"pillar": "recovery",
"prompts": [
"Do I need a rest day?",
"Analyze my sleep quality"
]
}
],
"welcome_prompt": "Welcome to Pierre! I'm your fitness AI assistant. Connect your fitness tracker to get personalized insights.",
"metadata": {
"timestamp": "2025-01-07T12:00:00Z",
"api_version": "1.0"
}
}
Admin Endpoints
All admin endpoints are prefixed with /api/admin/prompts and require admin role.
List All Categories
Returns all prompt categories including inactive ones.
GET /api/admin/prompts
Authorization: Bearer <admin_jwt_token>
Response 200 OK:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"category_key": "training",
"category_title": "Training",
"category_icon": "runner",
"pillar": "activity",
"prompts": ["Am I ready for a hard workout today?"],
"display_order": 0,
"is_active": true
}
]
Create Category
Creates a new prompt category.
POST /api/admin/prompts
Authorization: Bearer <admin_jwt_token>
Content-Type: application/json
{
"category_key": "strength",
"category_title": "Strength Training",
"category_icon": "dumbbell",
"pillar": "activity",
"prompts": [
"What's my estimated 1RM for bench press?",
"Create a strength training plan"
],
"display_order": 5
}
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
category_key | string | Yes | Unique identifier within tenant |
category_title | string | Yes | Display title |
category_icon | string | Yes | Icon name (e.g., “runner”, “salad”, “sleep”) |
pillar | string | Yes | One of: activity, nutrition, recovery |
prompts | string[] | Yes | List of prompt suggestions |
display_order | integer | No | Sort order (default: 0) |
Response 201 Created:
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"category_key": "strength",
"category_title": "Strength Training",
"category_icon": "dumbbell",
"pillar": "activity",
"prompts": ["What's my estimated 1RM for bench press?", "Create a strength training plan"],
"display_order": 5,
"is_active": true
}
Get Category
Retrieves a specific category by ID.
GET /api/admin/prompts/:id
Authorization: Bearer <admin_jwt_token>
Response 200 OK: Same format as create response.
Update Category
Updates an existing category. All fields are optional.
PUT /api/admin/prompts/:id
Authorization: Bearer <admin_jwt_token>
Content-Type: application/json
{
"category_title": "Strength & Power",
"prompts": [
"What's my estimated 1RM?",
"Create a power building program",
"How should I periodize my training?"
],
"is_active": true
}
Updatable Fields:
| Field | Type | Description |
|---|---|---|
category_title | string | Display title |
category_icon | string | Icon name |
pillar | string | Pillar classification |
prompts | string[] | Prompt suggestions |
display_order | integer | Sort order |
is_active | boolean | Visibility flag |
Response 200 OK: Updated category object.
Delete Category
Permanently deletes a category.
DELETE /api/admin/prompts/:id
Authorization: Bearer <admin_jwt_token>
Response 204 No Content
Get Welcome Prompt
Retrieves the current welcome prompt.
GET /api/admin/prompts/welcome
Authorization: Bearer <admin_jwt_token>
Response 200 OK:
{
"prompt_text": "Welcome to Pierre! I'm your fitness AI assistant."
}
Update Welcome Prompt
Updates the welcome prompt text.
PUT /api/admin/prompts/welcome
Authorization: Bearer <admin_jwt_token>
Content-Type: application/json
{
"prompt_text": "Hello! I'm Pierre, your personal fitness coach. How can I help you today?"
}
Response 200 OK:
{
"prompt_text": "Hello! I'm Pierre, your personal fitness coach. How can I help you today?"
}
Reset to Defaults
Resets all prompts (categories, welcome, system) to factory defaults.
POST /api/admin/prompts/reset
Authorization: Bearer <admin_jwt_token>
Response 200 OK:
{
"success": true
}
Warning: This operation deletes all custom categories and restores defaults. Prompt data is stored in the database and managed via the PromptManager. The system prompt template is at src/llm/prompts/pierre_system.md.
Pillar Classification
Pillars provide visual organization and theming:
| Pillar | Color | Use For |
|---|---|---|
activity | Emerald (#10B981) | Training, workouts, performance |
nutrition | Amber (#F59E0B) | Diet, calories, recipes, hydration |
recovery | Indigo (#6366F1) | Sleep, rest days, stress, HRV |
Error Responses
400 Bad Request
{
"error": {
"code": "invalid_input",
"message": "Invalid pillar: must be activity, nutrition, or recovery"
}
}
401 Unauthorized
{
"error": {
"code": "auth_required",
"message": "Authentication required"
}
}
403 Forbidden
{
"error": {
"code": "permission_denied",
"message": "Admin privileges required"
}
}
404 Not Found
{
"error": {
"code": "resource_not_found",
"message": "Category not found"
}
}
409 Conflict
{
"error": {
"code": "resource_already_exists",
"message": "Category with key 'training' already exists"
}
}
cURL Examples
Get suggestions (user)
curl -X GET http://localhost:8081/api/prompts/suggestions \
-H "Authorization: Bearer $JWT_TOKEN"
Create category (admin)
curl -X POST http://localhost:8081/api/admin/prompts \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"category_key": "cycling",
"category_title": "Cycling",
"category_icon": "bike",
"pillar": "activity",
"prompts": ["What is my FTP?", "Analyze my last ride"]
}'
Update welcome prompt (admin)
curl -X PUT http://localhost:8081/api/admin/prompts/welcome \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"prompt_text": "Welcome! Ready to crush your fitness goals?"}'
Reset to defaults (admin)
curl -X POST http://localhost:8081/api/admin/prompts/reset \
-H "Authorization: Bearer $ADMIN_TOKEN"
Tenant Isolation
All prompt data is tenant-scoped:
- Each tenant has independent prompt categories
- Category keys must be unique within a tenant (not globally)
- Admins can only modify prompts for their own tenant
- Super admins follow the same tenant isolation rules
Related Documentation
- Authentication - JWT token management
- Configuration - Environment variables
- LLM Providers - System prompt usage