Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

FieldTypeRequiredDescription
category_keystringYesUnique identifier within tenant
category_titlestringYesDisplay title
category_iconstringYesIcon name (e.g., “runner”, “salad”, “sleep”)
pillarstringYesOne of: activity, nutrition, recovery
promptsstring[]YesList of prompt suggestions
display_orderintegerNoSort 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:

FieldTypeDescription
category_titlestringDisplay title
category_iconstringIcon name
pillarstringPillar classification
promptsstring[]Prompt suggestions
display_orderintegerSort order
is_activebooleanVisibility 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:

PillarColorUse For
activityEmerald (#10B981)Training, workouts, performance
nutritionAmber (#F59E0B)Diet, calories, recipes, hydration
recoveryIndigo (#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