openapi: 3.0.3
info:
  title: RocketWave Pulse Administrative API
  description: |
    REST API for the RocketWave Pulse Administrative Application.
    Manages organizations, environments, workflows, and related resources.
  version: 2.0.0
  contact:
    name: Rocketwave Labs
    url: https://rocketwave.io

servers:
  - url: /api
    description: Relative to application host

tags:
  - name: Organizations
    description: Top-level tenant management
  - name: Users
    description: Organization user management (Auth0)
  - name: Environments
    description: Environment management within organizations
  - name: Variables
    description: Environment-scoped configuration variables
  - name: Models
    description: Legacy AI/LLM model configurations
  - name: Model Providers
    description: AI provider reference data (OpenAI, Anthropic, Bedrock, Google, xAI)
  - name: Model Credentials
    description: API keys and authentication credentials for AI providers
  - name: Model Configurations
    description: Ready-to-use model configurations combining definition + credential
  - name: Workflows
    description: Workflow definitions and canvas data
  - name: Workflow Entities
    description: Reusable workflow entity definitions
  - name: Workflow Entity Types
    description: Entity type definitions
  - name: Scheduled Events
    description: Scheduled workflow execution triggers
  - name: Processed Queue
    description: Processed message queue (S3-backed)
  - name: AI Assistant
    description: AI-powered entity creation assistant
  - name: Prompt Builder
    description: Prompt template management and testing
  - name: Profile
    description: User profile management
  - name: Billing
    description: Transaction usage, subscription management, and plan configuration
  - name: Plugins
    description: Available script plugins and functions
  - name: Healthcheck
    description: Service health monitoring
  - name: Versioning
    description: Version history for workflows, entities, and prompt templates

paths:
  /organizations:
    get:
      tags: [Organizations]
      summary: List organizations
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
      responses:
        '200':
          description: Paginated list of organizations
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedOrganizations'
    post:
      tags: [Organizations]
      summary: Create organization
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'

  /organizations/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Organizations]
      summary: Get organization by ID
      responses:
        '200':
          description: Organization details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      tags: [Organizations]
      summary: Update organization
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationUpdate'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
    delete:
      tags: [Organizations]
      summary: Delete organization
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'

  /organizations/{id}/users:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Users]
      summary: List organization members
      description: Returns all users who are members of this Auth0 organization
      responses:
        '200':
          description: List of organization members
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationUser'
        '401':
          description: Unauthorized
        '404':
          description: Organization not found

  /organizations/{id}/invitations:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    post:
      tags: [Users]
      summary: Send organization invitation
      description: Sends an email invitation to join the organization via Auth0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationCreate'
      responses:
        '200':
          description: Invitation sent
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invitation'
        '400':
          description: Invalid email or missing parameters
        '401':
          description: Unauthorized
        '404':
          description: Organization not found

  /environments:
    get:
      tags: [Environments]
      summary: List environments
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/OrganizationIdParam'
      responses:
        '200':
          description: Paginated list of environments
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedEnvironments'
    post:
      tags: [Environments]
      summary: Create environment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnvironmentCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Environment'

  /environments/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Environments]
      summary: Get environment by ID
      responses:
        '200':
          description: Environment details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Environment'
    put:
      tags: [Environments]
      summary: Update environment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnvironmentUpdate'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Environment'
    delete:
      tags: [Environments]
      summary: Delete environment
      responses:
        '200':
          description: Deleted

  /variables:
    get:
      tags: [Variables]
      summary: List variables
      description: Variable values are never returned (write-only)
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/OrganizationIdParam'
        - $ref: '#/components/parameters/EnvironmentIdParam'
      responses:
        '200':
          description: Paginated list of variables
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVariables'
    post:
      tags: [Variables]
      summary: Create variable
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VariableCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Variable'
        '409':
          description: Variable with this name already exists

  /variables/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Variables]
      summary: Get variable by ID
      responses:
        '200':
          description: Variable details (value not included)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Variable'
    put:
      tags: [Variables]
      summary: Update variable
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VariableUpdate'
      responses:
        '200':
          description: Updated
    delete:
      tags: [Variables]
      summary: Delete variable
      responses:
        '200':
          description: Deleted

  /models:
    get:
      tags: [Models]
      summary: List models
      description: Credentials are never returned (hasToken/hasClientKey flags only)
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: organizationId
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Paginated list of models
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedModels'
    post:
      tags: [Models]
      summary: Create model
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Model'

  /models/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Models]
      summary: Get model by ID
      responses:
        '200':
          description: Model details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Model'
    put:
      tags: [Models]
      summary: Update model
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelUpdate'
      responses:
        '200':
          description: Updated
    delete:
      tags: [Models]
      summary: Delete model
      responses:
        '200':
          description: Deleted

  /workflows:
    get:
      tags: [Workflows]
      summary: List workflows
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/OrganizationIdParam'
        - $ref: '#/components/parameters/EnvironmentIdParam'
      responses:
        '200':
          description: Paginated list of workflows
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedWorkflows'
    post:
      tags: [Workflows]
      summary: Create workflow
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'

  /workflows/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Workflows]
      summary: Get workflow by ID
      responses:
        '200':
          description: Workflow details with workflowData
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
    put:
      tags: [Workflows]
      summary: Update workflow
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowUpdate'
      responses:
        '200':
          description: Updated
    delete:
      tags: [Workflows]
      summary: Delete workflow
      responses:
        '200':
          description: Deleted

  /workflow-entities:
    get:
      tags: [Workflow Entities]
      summary: List workflow entities
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/OrganizationIdParam'
        - name: search
          in: query
          schema:
            type: string
          description: Search by name
      responses:
        '200':
          description: Paginated list of entities
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedWorkflowEntities'
    post:
      tags: [Workflow Entities]
      summary: Create workflow entity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowEntityCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowEntity'

  /workflow-entities/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Workflow Entities]
      summary: Get entity by ID
      responses:
        '200':
          description: Entity details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowEntity'
    put:
      tags: [Workflow Entities]
      summary: Update entity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowEntityUpdate'
      responses:
        '200':
          description: Updated
    delete:
      tags: [Workflow Entities]
      summary: Delete entity
      responses:
        '200':
          description: Deleted

  /workflow-entities/{id}/usage-count:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Workflow Entities]
      summary: Get workflow usage count
      parameters:
        - $ref: '#/components/parameters/OrganizationIdParam'
        - $ref: '#/components/parameters/EnvironmentIdParam'
      responses:
        '200':
          description: Usage count
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer

  /workflow-entity-types:
    get:
      tags: [Workflow Entity Types]
      summary: List entity types
      responses:
        '200':
          description: List of entity types
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WorkflowEntityType'
    post:
      tags: [Workflow Entity Types]
      summary: Create entity type
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowEntityTypeCreate'
      responses:
        '201':
          description: Created

  /scheduled-events:
    get:
      tags: [Scheduled Events]
      summary: List scheduled events
      description: List scheduled workflow events with optional filtering
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/OrganizationIdParam'
        - $ref: '#/components/parameters/EnvironmentIdParam'
        - name: workflowId
          in: query
          schema:
            type: string
            format: uuid
          description: Filter by workflow
        - name: workflowEntityId
          in: query
          schema:
            type: string
            format: uuid
          description: Filter by workflow entity
      responses:
        '200':
          description: Paginated list of scheduled events
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedScheduledEvents'
    post:
      tags: [Scheduled Events]
      summary: Create scheduled event
      description: Create a new scheduled event (cron or datetime)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScheduledEventCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledEvent'
        '400':
          description: Invalid request (missing fields or invalid cron expression)

  /scheduled-events/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Scheduled Events]
      summary: Get scheduled event by ID
      responses:
        '200':
          description: Scheduled event details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledEvent'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      tags: [Scheduled Events]
      summary: Update scheduled event
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScheduledEventUpdate'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledEvent'
    delete:
      tags: [Scheduled Events]
      summary: Delete scheduled event
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'

  /workflows/{id}/trigger:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    post:
      tags: [Workflows]
      summary: Trigger workflow execution
      description: Manually trigger a workflow execution
      responses:
        '200':
          description: Workflow triggered
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
        '404':
          $ref: '#/components/responses/NotFound'

  /processed-queue:
    get:
      tags: [Processed Queue]
      summary: List processed messages
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: organizationId
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/EnvironmentIdParam'
        - name: status
          in: query
          required: true
          schema:
            type: string
            enum: [success, fail, ignore]
      responses:
        '200':
          description: Paginated list of messages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedProcessedMessages'
    delete:
      tags: [Processed Queue]
      summary: Delete or purge messages
      parameters:
        - name: keys
          in: query
          schema:
            type: string
          description: Comma-separated S3 keys for bulk delete
        - name: organizationId
          in: query
          schema:
            type: string
            format: uuid
          description: Required for purge operation
        - name: status
          in: query
          schema:
            type: string
            enum: [success, fail, ignore]
          description: Required for purge operation
      responses:
        '200':
          description: Deleted

  /processed-queue/{key}:
    parameters:
      - name: key
        in: path
        required: true
        schema:
          type: string
        description: URL-encoded S3 key
    get:
      tags: [Processed Queue]
      summary: Get message by S3 key
      responses:
        '200':
          description: Message content
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessedMessage'
    delete:
      tags: [Processed Queue]
      summary: Delete message
      responses:
        '200':
          description: Deleted

  /prompt-templates:
    get:
      tags: [Prompt Builder]
      summary: List prompt templates
      description: Returns paginated list of prompt templates for the organization/environment
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/OrganizationIdParam'
        - $ref: '#/components/parameters/EnvironmentIdParam'
        - name: search
          in: query
          schema:
            type: string
          description: Filter by template name (case insensitive)
      responses:
        '200':
          description: Paginated list of prompt templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedPromptTemplates'
    post:
      tags: [Prompt Builder]
      summary: Create prompt template
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PromptTemplateCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PromptTemplate'

  /prompt-templates/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Prompt Builder]
      summary: Get prompt template by ID
      responses:
        '200':
          description: Template details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PromptTemplate'
    put:
      tags: [Prompt Builder]
      summary: Update prompt template
      description: Updates increment the version number automatically
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PromptTemplateUpdate'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PromptTemplate'
    delete:
      tags: [Prompt Builder]
      summary: Delete prompt template
      responses:
        '200':
          description: Deleted

  /prompt-templates/{id}/execute:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    post:
      tags: [Prompt Builder]
      summary: Execute prompt template
      description: |
        Executes the prompt template against the configured model.
        Variables in the template are replaced with provided values.
        Returns the model response and execution metadata.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                variables:
                  type: object
                  additionalProperties:
                    type: string
                  description: Variable name-value pairs for substitution
                variableSetId:
                  type: string
                  description: ID of the variable set to update with results
      responses:
        '200':
          description: Execution result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PromptExecutionResult'
        '400':
          description: No model selected or model has no credentials

  /prompt-templates/{id}/analyze:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    post:
      tags: [Prompt Builder]
      summary: Analyze prompt sentiment
      description: |
        Runs sentiment analysis on the raw prompt and/or execution results.
        Returns detailed metrics including style, emotions, and goal efficacy.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                analyzeRaw:
                  type: boolean
                  default: true
                  description: Analyze the raw prompt template
                analyzeResult:
                  type: boolean
                  default: true
                  description: Analyze the execution result
                variableSetId:
                  type: string
                  description: Variable set containing execution result to analyze
      responses:
        '200':
          description: Sentiment analysis results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SentimentAnalysisResult'

  /assistant/chat:
    post:
      tags: [AI Assistant]
      summary: Chat with AI assistant
      description: |
        Send a message to the AI assistant and receive a response.
        The assistant can create workflow entities using function calling.
        Uses RAG (Retrieval Augmented Generation) to provide context from documentation.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssistantChatRequest'
      responses:
        '200':
          description: Assistant response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssistantChatResponse'
        '400':
          description: Invalid request
        '401':
          description: Unauthorized

  /documentation/search:
    post:
      tags: [AI Assistant]
      summary: Search documentation
      description: Search the documentation database using vector similarity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [embedding]
              properties:
                embedding:
                  type: array
                  items:
                    type: number
                  description: 1536-dimension embedding vector from OpenAI
                limit:
                  type: integer
                  default: 10
                  description: Maximum number of results
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentSearchResult'

  /model-providers:
    get:
      tags: [Model Providers]
      summary: List model providers
      description: List all AI model providers (seeded reference data)
      parameters:
        - name: includeModels
          in: query
          schema:
            type: string
            enum: ['true', 'false']
          description: Include model definitions for each provider
      responses:
        '200':
          description: List of providers
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ModelProvider'
              example:
                data:
                  - id: "provider-uuid"
                    slug: "openai"
                    name: "OpenAI"
                    authType: "api_key"
                    apiFormat: "openai"
                    baseUrl: "https://api.openai.com/v1"

  /model-definitions:
    get:
      tags: [Model Providers]
      summary: List model definitions
      description: List specific models available within providers
      parameters:
        - name: providerId
          in: query
          schema:
            type: string
            format: uuid
          description: Filter by provider ID
        - name: providerSlug
          in: query
          schema:
            type: string
          description: Filter by provider slug (e.g., "openai", "anthropic")
        - name: tier
          in: query
          schema:
            type: string
            enum: [standard, premium, economy]
        - name: category
          in: query
          schema:
            type: string
          description: Filter by category (chat, embedding, image)
        - name: activeOnly
          in: query
          schema:
            type: string
            default: 'true'
          description: Only show active, non-deprecated definitions
      responses:
        '200':
          description: List of model definitions
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ModelDefinition'

  /model-credentials:
    get:
      tags: [Model Credentials]
      summary: List model credentials
      description: List credentials for an organization or system-level credentials
      parameters:
        - $ref: '#/components/parameters/OrganizationIdParam'
        - name: scope
          in: query
          schema:
            type: string
            enum: [system, organization]
          description: Filter by scope
        - name: providerId
          in: query
          schema:
            type: string
            format: uuid
        - name: activeOnly
          in: query
          schema:
            type: string
            default: 'true'
      responses:
        '200':
          description: List of credentials (sensitive fields excluded)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ModelCredential'
    post:
      tags: [Model Credentials]
      summary: Create model credential
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelCredentialCreate'
            example:
              scope: "organization"
              organizationId: "550e8400-e29b-41d4-a716-446655440000"
              providerId: "provider-uuid"
              name: "Production OpenAI Key"
              apiKey: "sk-proj-xxxxxxxxxxxxx"
      responses:
        '201':
          description: Created (sensitive fields excluded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelCredential'

  /model-credentials/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Model Credentials]
      summary: Get credential by ID
      responses:
        '200':
          description: Credential details (sensitive fields excluded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelCredential'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      tags: [Model Credentials]
      summary: Update credential
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelCredentialUpdate'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelCredential'
    delete:
      tags: [Model Credentials]
      summary: Delete credential
      description: Cannot delete if in use by model configurations
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Credential is in use by model configurations

  /model-credentials/{id}/validate:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    post:
      tags: [Model Credentials]
      summary: Validate credential
      description: Test that a credential can authenticate with its provider
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                type: object
                properties:
                  valid:
                    type: boolean
                  error:
                    type: string
                    nullable: true
                  lastValidated:
                    type: string
                    format: date-time
                  provider:
                    type: string
              example:
                valid: true
                error: null
                lastValidated: "2026-03-26T10:00:00Z"
                provider: "openai"

  /model-configurations:
    get:
      tags: [Model Configurations]
      summary: List model configurations
      parameters:
        - $ref: '#/components/parameters/OrganizationIdParam'
        - name: scope
          in: query
          schema:
            type: string
            enum: [system, organization]
        - name: includeSystem
          in: query
          schema:
            type: string
            enum: ['true', 'false']
        - name: visibleOnly
          in: query
          schema:
            type: string
            default: 'true'
        - name: category
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of configurations
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ModelConfiguration'
    post:
      tags: [Model Configurations]
      summary: Create model configuration
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelConfigurationCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelConfiguration'

  /model-configurations/{id}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Model Configurations]
      summary: Get configuration by ID
      responses:
        '200':
          description: Configuration details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelConfiguration'
    put:
      tags: [Model Configurations]
      summary: Update configuration
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelConfigurationUpdate'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelConfiguration'
    delete:
      tags: [Model Configurations]
      summary: Delete configuration
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'

  /profile:
    get:
      tags: [Profile]
      summary: Get current user profile
      description: Returns the authenticated user's profile information
      responses:
        '200':
          description: User profile
          content:
            application/json:
              schema:
                type: object
                properties:
                  profile:
                    $ref: '#/components/schemas/Profile'
                  user:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      email:
                        type: string
                      name:
                        type: string
        '401':
          description: Not authenticated
    put:
      tags: [Profile]
      summary: Update user profile
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                firstName:
                  type: string
                lastName:
                  type: string
                avatar:
                  type: string
      responses:
        '200':
          description: Updated profile
          content:
            application/json:
              schema:
                type: object
                properties:
                  profile:
                    $ref: '#/components/schemas/Profile'

  /roles:
    get:
      tags: [Users]
      summary: List available roles
      responses:
        '200':
          description: List of roles
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        name:
                          type: string
                        description:
                          type: string
              example:
                data:
                  - id: "role-uuid-1"
                    name: "admin"
                    description: "Full access to organization resources"
                  - id: "role-uuid-2"
                    name: "user"
                    description: "Standard access"
                  - id: "role-uuid-3"
                    name: "guest"
                    description: "Read-only access"

  /plugins:
    get:
      tags: [Plugins]
      summary: List available plugins
      description: Returns all registered plugin definitions with function signatures
      responses:
        '200':
          description: List of plugins
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Plugin'

  /validate-script:
    post:
      tags: [Plugins]
      summary: Validate JavaScript syntax
      description: Compile-check a JavaScript script without executing it
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [script]
              properties:
                script:
                  type: string
                  description: JavaScript code to validate
            example:
              script: "const x = 1; print(x);"
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                type: object
                properties:
                  valid:
                    type: boolean
                  message:
                    type: string
                  error:
                    type: string
              example:
                valid: true
                message: "Script is valid JavaScript"

  /usage/transactions:
    get:
      tags: [Billing]
      summary: Get current transaction usage
      description: Returns the organization's transaction count for the current billing period
      responses:
        '200':
          description: Transaction usage data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionUsage'
              example:
                organizationId: "org-uuid"
                currentCount: 73
                limit: 100
                percentUsed: 73
                overagePolicy: "hard_limit"
                isOverLimit: false
                period: "2026-03"

  /usage/transactions/history:
    get:
      tags: [Billing]
      summary: Get transaction usage history
      description: Returns monthly transaction counts for the past N months
      parameters:
        - name: months
          in: query
          schema:
            type: integer
            default: 12
          description: Number of months of history (max 24)
      responses:
        '200':
          description: Usage history
          content:
            application/json:
              schema:
                type: object
                properties:
                  organizationId:
                    type: string
                    format: uuid
                  history:
                    type: array
                    items:
                      type: object
                      properties:
                        period:
                          type: string
                        count:
                          type: integer
              example:
                organizationId: "org-uuid"
                history:
                  - period: "2026-03"
                    count: 73
                  - period: "2026-02"
                    count: 95
                  - period: "2026-01"
                    count: 42

  /subscriptions/{orgId}/transaction-config:
    parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      tags: [Billing]
      summary: Get transaction configuration
      responses:
        '200':
          description: Transaction limit configuration
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionConfig'
    put:
      tags: [Billing]
      summary: Update transaction configuration
      description: |
        Update per-org transaction limit and overage policy. Both fields must be
        non-null when provided. A Redis pub/sub notification is published so the
        Stream Consumer re-evaluates the org's limit immediately.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                transactionLimit:
                  type: integer
                  minimum: 0
                  description: Non-negative integer (null not accepted)
                overagePolicy:
                  type: string
                  enum: [hard_limit, warn]
                  description: Must be one of the allowed values (null not accepted)
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionConfig'

  /plan-configurations:
    get:
      tags: [Billing]
      summary: List plan configurations
      description: System admin only. Returns all plan configuration records.
      responses:
        '200':
          description: Plan configurations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PlanConfiguration'

  /plan-configurations/{planKey}:
    parameters:
      - name: planKey
        in: path
        required: true
        schema:
          type: string
          enum: [free, individual, team]
    put:
      tags: [Billing]
      summary: Update plan configuration
      description: |
        System admin only. Updating a plan configuration broadcasts a Redis pub/sub
        notification to all organizations so the Stream Consumer re-evaluates
        transaction limits immediately.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlanConfigurationUpdate'
      responses:
        '200':
          description: Updated

  /organizations/{id}/members:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Users]
      summary: List organization members
      description: Returns all users who are members of this organization with their roles
      responses:
        '200':
          description: List of members
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationMember'
    delete:
      tags: [Users]
      summary: Remove member from organization
      parameters:
        - name: userId
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Member removed

  /organizations/{id}/members/{userId}/role:
    parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: userId
        in: path
        required: true
        schema:
          type: string
    put:
      tags: [Users]
      summary: Update member role
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [roleId]
              properties:
                roleId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: Role updated

  /workflow-entities/{id}/versions:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Versioning]
      summary: List entity version history
      responses:
        '200':
          description: Version list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/VersionRecord'

  /workflow-entities/{id}/versions/{version}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: version
        in: path
        required: true
        schema:
          type: integer
    get:
      tags: [Versioning]
      summary: Get entity at specific version
      responses:
        '200':
          description: Entity snapshot at the requested version

  /workflow-entities/{id}/prompt-details:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Workflow Entities]
      summary: Get entity prompt details
      description: Returns prompt-specific details including model info
      parameters:
        - $ref: '#/components/parameters/OrganizationIdParam'
      responses:
        '200':
          description: Prompt details

  /workflows/{id}/versions:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Versioning]
      summary: List workflow version history
      responses:
        '200':
          description: Version list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/VersionRecord'

  /workflows/{id}/versions/{version}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: version
        in: path
        required: true
        schema:
          type: integer
    get:
      tags: [Versioning]
      summary: Get workflow at specific version
      responses:
        '200':
          description: Workflow snapshot at the requested version

  /prompt-templates/{id}/versions:
    parameters:
      - $ref: '#/components/parameters/IdParam'
    get:
      tags: [Versioning]
      summary: List prompt template version history
      responses:
        '200':
          description: Version list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/VersionRecord'

  /prompt-templates/{id}/versions/{version}:
    parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: version
        in: path
        required: true
        schema:
          type: integer
    get:
      tags: [Versioning]
      summary: Get prompt template at specific version
      responses:
        '200':
          description: Template snapshot at the requested version

  /healthcheck:
    get:
      tags: [Healthcheck]
      summary: Health check
      description: Returns service health status
      responses:
        '200':
          description: Healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: string
                    format: date-time

  /chat:
    post:
      tags: [AI Assistant]
      summary: Chat with AI assistant (SSE)
      description: |
        Send a message to the AI assistant and receive a streaming response via Server-Sent Events.
        Events: `connected`, `response`, `error`, `[DONE]`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [message, organizationId]
              properties:
                message:
                  type: string
                organizationId:
                  type: string
                  format: uuid
                environmentId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: SSE stream
          content:
            text/event-stream:
              schema:
                type: string

  /stripe/create-checkout-session:
    post:
      tags: [Billing]
      summary: Create Stripe checkout session
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [organizationId, planKey]
              properties:
                organizationId:
                  type: string
                  format: uuid
                planKey:
                  type: string
                  enum: [individual, team]
      responses:
        '200':
          description: Checkout session URL
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    format: uri

  /stripe/create-portal-session:
    post:
      tags: [Billing]
      summary: Create Stripe customer portal session
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [organizationId]
              properties:
                organizationId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: Portal session URL
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    format: uri

  /stripe/subscription:
    get:
      tags: [Billing]
      summary: Get subscription status
      parameters:
        - $ref: '#/components/parameters/OrganizationIdParam'
      responses:
        '200':
          description: Subscription details
          content:
            application/json:
              schema:
                type: object
                properties:
                  hasSubscription:
                    type: boolean
                  isActive:
                    type: boolean
                  subscription:
                    type: object
                    nullable: true
                    properties:
                      id:
                        type: string
                      status:
                        type: string
                      planKey:
                        type: string
                      planName:
                        type: string
                      currentPeriodEnd:
                        type: string
                        format: date-time
                      cancelAtPeriodEnd:
                        type: boolean

components:
  parameters:
    IdParam:
      name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    PageParam:
      name: page
      in: query
      schema:
        type: integer
        default: 1
    LimitParam:
      name: limit
      in: query
      schema:
        type: integer
        default: 10
    OrganizationIdParam:
      name: organizationId
      in: query
      schema:
        type: string
        format: uuid
    EnvironmentIdParam:
      name: environmentId
      in: query
      schema:
        type: string
        format: uuid

  responses:
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
        details:
          type: string

    SuccessResponse:
      type: object
      properties:
        success:
          type: boolean

    Pagination:
      type: object
      properties:
        page:
          type: integer
        limit:
          type: integer
        total:
          type: integer
        totalPages:
          type: integer

    Organization:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    OrganizationCreate:
      type: object
      required: [name]
      properties:
        name:
          type: string
        description:
          type: string

    OrganizationUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string

    PaginatedOrganizations:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Organization'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Environment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    EnvironmentCreate:
      type: object
      required: [name, organizationId]
      properties:
        name:
          type: string
        description:
          type: string
        organizationId:
          type: string
          format: uuid

    EnvironmentUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string

    PaginatedEnvironments:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Environment'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Variable:
      type: object
      description: Value field is write-only and never returned
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        name:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    VariableCreate:
      type: object
      required: [organizationId, environmentId, name, value]
      properties:
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        name:
          type: string
        value:
          type: string

    VariableUpdate:
      type: object
      properties:
        name:
          type: string
        value:
          type: string

    PaginatedVariables:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Variable'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Model:
      type: object
      description: Credentials are write-only
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        modelUrl:
          type: string
        hasToken:
          type: boolean
        hasClientKey:
          type: boolean
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    ModelCreate:
      type: object
      required: [organizationId, name, modelUrl]
      properties:
        organizationId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        modelUrl:
          type: string
        token:
          type: string
          description: Mutually exclusive with clientKey/secretKey
        clientKey:
          type: string
          description: Mutually exclusive with token
        secretKey:
          type: string
          description: Required if clientKey provided

    ModelUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        modelUrl:
          type: string
        token:
          type: string
        clientKey:
          type: string
        secretKey:
          type: string

    PaginatedModels:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Model'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Workflow:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        workflowData:
          $ref: '#/components/schemas/WorkflowData'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    WorkflowData:
      type: object
      properties:
        root:
          $ref: '#/components/schemas/WorkflowNode'
        orphans:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowNode'
        presentation:
          type: object
          properties:
            viewport:
              type: object
              properties:
                x:
                  type: number
                y:
                  type: number
                zoom:
                  type: number

    WorkflowNode:
      type: object
      properties:
        name:
          type: string
        label:
          type: string
        entityId:
          type: string
          format: uuid
        entityType:
          type: string
          enum: [event, prompt, action]
        description:
          type: string
        presentation:
          type: object
          properties:
            type:
              type: string
            position:
              type: object
              properties:
                x:
                  type: number
                y:
                  type: number
        children:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowNode'
        tfCondition:
          type: string
          enum: [Single Path, True/False, Multi]
        logicField:
          type: string
        value:
          type: string

    WorkflowCreate:
      type: object
      required: [organizationId, environmentId, name]
      properties:
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        workflowData:
          $ref: '#/components/schemas/WorkflowData'

    WorkflowUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        workflowData:
          $ref: '#/components/schemas/WorkflowData'

    PaginatedWorkflows:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Workflow'
        pagination:
          $ref: '#/components/schemas/Pagination'

    WorkflowEntity:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        workflowEntityTypeId:
          type: string
          format: uuid
        workflowEntityType:
          $ref: '#/components/schemas/WorkflowEntityType'
        condition:
          type: object
          description: Condition tree structure
        script:
          type: string
          description: JavaScript code for V8 execution
        modelId:
          type: string
          format: uuid
          nullable: true
        tfCondition:
          type: string
          enum: [Single Path, True/False, Multi]
        logicField:
          type: string
          nullable: true
        prompt:
          type: string
          nullable: true
        arguments:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEntityArgument'
        logic:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEntityLogic'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    WorkflowEntityArgument:
      type: object
      properties:
        id:
          type: string
          format: uuid
        argumentName:
          type: string
        argumentValue:
          type: string
        argumentDescription:
          type: string
          nullable: true

    WorkflowEntityLogic:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        value:
          type: string

    WorkflowEntityCreate:
      type: object
      required: [organizationId, name, workflowEntityTypeId]
      properties:
        organizationId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        workflowEntityTypeId:
          type: string
          format: uuid
        condition:
          type: object
        script:
          type: string
        modelId:
          type: string
          format: uuid
        tfCondition:
          type: string
        logicField:
          type: string
        prompt:
          type: string
        arguments:
          type: array
          items:
            type: object
            properties:
              argumentName:
                type: string
              argumentValue:
                type: string
              argumentDescription:
                type: string
        logic:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              value:
                type: string

    WorkflowEntityUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        condition:
          type: object
        script:
          type: string
        modelId:
          type: string
          format: uuid
        tfCondition:
          type: string
        logicField:
          type: string
        prompt:
          type: string
        arguments:
          type: array
          items:
            type: object
            properties:
              argumentName:
                type: string
              argumentValue:
                type: string
              argumentDescription:
                type: string
        logic:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              value:
                type: string

    PaginatedWorkflowEntities:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEntity'
        pagination:
          $ref: '#/components/schemas/Pagination'

    WorkflowEntityType:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        showScript:
          type: boolean
        showConditions:
          type: boolean
        showArguments:
          type: boolean
        showModel:
          type: boolean
        showLogic:
          type: boolean
        showPrompt:
          type: boolean
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    WorkflowEntityTypeCreate:
      type: object
      required: [name]
      properties:
        name:
          type: string
        description:
          type: string
        showScript:
          type: boolean
        showConditions:
          type: boolean
        showArguments:
          type: boolean
        showModel:
          type: boolean
        showLogic:
          type: boolean
        showPrompt:
          type: boolean

    # Scheduled Events Schemas
    ScheduledEvent:
      type: object
      description: |
        Schedule status is determined by nextRunAt:
        - Active/Pending: nextRunAt contains a future timestamp
        - Completed/Inactive: nextRunAt is null
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        workflowId:
          type: string
          format: uuid
        workflowEntityId:
          type: string
          format: uuid
        scheduleType:
          type: string
          enum: [cron, datetime]
          description: Type of schedule
        cronExpression:
          type: string
          nullable: true
          description: Cron expression (for cron type)
        scheduledAt:
          type: string
          format: date-time
          nullable: true
          description: One-time execution datetime (for datetime type)
        timezone:
          type: string
          description: IANA timezone identifier (default UTC)
        lastRunAt:
          type: string
          format: date-time
          nullable: true
          description: When the schedule was last executed
        nextRunAt:
          type: string
          format: date-time
          nullable: true
          description: Next scheduled execution time (null = completed/inactive)
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    ScheduledEventCreate:
      type: object
      required: [workflowEntityId, workflowId, organizationId, environmentId, scheduleType]
      properties:
        workflowEntityId:
          type: string
          format: uuid
          description: The event entity to trigger
        workflowId:
          type: string
          format: uuid
          description: The workflow containing the entity
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        scheduleType:
          type: string
          enum: [cron, datetime]
        cronExpression:
          type: string
          description: Cron expression (required if scheduleType is cron)
        scheduledAt:
          type: string
          format: date-time
          description: ISO datetime (required if scheduleType is datetime)
        timezone:
          type: string
          default: UTC
          description: IANA timezone identifier

    ScheduledEventUpdate:
      type: object
      properties:
        scheduleType:
          type: string
          enum: [cron, datetime]
        cronExpression:
          type: string
        scheduledAt:
          type: string
          format: date-time
          description: Setting a future datetime reactivates a completed schedule
        timezone:
          type: string

    PaginatedScheduledEvents:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ScheduledEvent'
        pagination:
          $ref: '#/components/schemas/Pagination'

    ProcessedMessage:
      type: object
      properties:
        fileName:
          type: string
          description: S3 key/identifier
        status:
          type: string
          enum: [success, fail, ignore]
        receivedAt:
          type: string
          format: date-time
        message:
          type: object
          description: Original message payload
        context:
          type: object
          description: Execution context with variables

    PaginatedProcessedMessages:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ProcessedMessage'
        pagination:
          $ref: '#/components/schemas/Pagination'

    OrganizationUser:
      type: object
      description: A user who is a member of an Auth0 organization
      properties:
        id:
          type: string
          description: Auth0 user ID
        email:
          type: string
          format: email
        name:
          type: string
        picture:
          type: string
          format: uri
          nullable: true
        createdAt:
          type: string
          format: date-time
          nullable: true

    InvitationCreate:
      type: object
      required: [email]
      properties:
        email:
          type: string
          format: email
          description: Email address to invite

    Invitation:
      type: object
      properties:
        id:
          type: string
          description: Auth0 invitation ID
        invitee:
          type: object
          properties:
            email:
              type: string
        createdAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time

    AssistantChatRequest:
      type: object
      required: [message, organizationId, environmentId]
      properties:
        message:
          type: string
          description: User's message to the assistant
        history:
          type: array
          items:
            type: object
            properties:
              role:
                type: string
                enum: [user, assistant]
              content:
                type: string
          description: Previous messages in the conversation
        organizationId:
          type: string
          format: uuid
          description: Organization to create entities in
        environmentId:
          type: string
          format: uuid
          description: Environment context

    AssistantChatResponse:
      type: object
      properties:
        message:
          type: string
          description: Assistant's response message (markdown)
        context:
          type: array
          items:
            $ref: '#/components/schemas/DocumentContext'
          description: Documentation sources used for context
        createdEntities:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowEntity'
          description: Entities created by the assistant

    DocumentContext:
      type: object
      properties:
        title:
          type: string
          description: Document title
        content:
          type: string
          description: Relevant excerpt from the document
        similarity:
          type: number
          format: float
          description: Cosine similarity score (0-1)

    DocumentSearchResult:
      type: object
      properties:
        documents:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              title:
                type: string
              content:
                type: string
              similarity:
                type: number
              metadata:
                type: object
        query:
          type: object
          properties:
            limit:
              type: integer

    # Prompt Builder Schemas
    PromptTemplate:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        name:
          type: string
          description: Template name
        description:
          type: string
          nullable: true
        promptText:
          type: string
          description: Prompt template text with {{variable}} placeholders
        modelId:
          type: string
          format: uuid
          nullable: true
          description: Selected model for execution
        version:
          type: integer
          description: Auto-incremented version number
        variableSets:
          type: array
          items:
            $ref: '#/components/schemas/VariableSet'
          description: Test scenarios with variable values and results
        rawSentimentAnalysis:
          $ref: '#/components/schemas/SentimentAnalysisResult'
          nullable: true
          description: Sentiment analysis of the raw prompt
        sentimentVersion:
          type: integer
          nullable: true
          description: Template version when sentiment was last analyzed
        lastEditedBy:
          type: string
          nullable: true
          description: User ID who last edited
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    PromptTemplateCreate:
      type: object
      required: [organizationId, environmentId, name, promptText]
      properties:
        organizationId:
          type: string
          format: uuid
        environmentId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        promptText:
          type: string
          description: Prompt template text with {{variable}} placeholders
        modelId:
          type: string
          format: uuid
        variableSets:
          type: array
          items:
            $ref: '#/components/schemas/VariableSetInput'
      example:
        organizationId: "123e4567-e89b-12d3-a456-426614174000"
        environmentId: "987e6543-e89b-12d3-a456-426614174000"
        name: "Customer Support Response"
        description: "Generate helpful support responses"
        promptText: |
          You are a helpful customer support agent for {{company_name}}.
          
          Customer message: {{customer_message}}
          
          Respond professionally and helpfully.

    PromptTemplateUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        promptText:
          type: string
        modelId:
          type: string
          format: uuid
        variableSets:
          type: array
          items:
            $ref: '#/components/schemas/VariableSetInput'

    PaginatedPromptTemplates:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PromptTemplate'
        pagination:
          $ref: '#/components/schemas/Pagination'

    VariableSet:
      type: object
      description: A test scenario with variable values and execution results
      properties:
        id:
          type: string
          description: Unique identifier for the variable set
        name:
          type: string
          description: Display name (e.g., "Happy Path", "Error Case")
        variables:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/VariableValue'
          description: Map of variable names to their values
        lastExecutionResult:
          type: string
          nullable: true
          description: The model's response from the last execution
        resultSentimentAnalysis:
          $ref: '#/components/schemas/SentimentAnalysisResult'
          nullable: true
        executedAt:
          type: string
          format: date-time
          nullable: true
        executionDuration:
          type: integer
          nullable: true
          description: Execution time in milliseconds

    VariableSetInput:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        variables:
          type: object
          additionalProperties:
            type: object
            properties:
              value:
                type: string
              type:
                type: string
                enum: [text, json]
                default: text

    VariableValue:
      type: object
      properties:
        value:
          type: string
          description: The variable's value
        type:
          type: string
          enum: [text, json]
          description: How to interpret the value
        format:
          type: string
          nullable: true
          description: Optional format specification

    PromptExecutionResult:
      type: object
      properties:
        result:
          type: string
          description: The model's response text
        executionTime:
          type: integer
          description: Execution duration in milliseconds
        model:
          type: object
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
        variableSetId:
          type: string
          description: ID of the variable set that was updated
        assembledPrompt:
          type: string
          description: The prompt after variable substitution

    SentimentAnalysisResult:
      type: object
      description: Comprehensive sentiment and style analysis
      properties:
        sentiment:
          type: string
          enum: [aggressive, assertive, neutral, friendly, negative, positive]
          description: Overall detected sentiment
        confidence:
          type: number
          format: float
          description: Confidence score (0-100)
        goal:
          type: object
          properties:
            identified:
              type: string
              description: AI-identified goal of the prompt
            efficacy:
              type: number
              description: How well the prompt achieves its goal (0-10)
            clarity:
              type: number
              description: How clear the goal is (0-10)
            audienceFit:
              type: number
              description: How appropriate for target audience (0-10)
        style:
          type: object
          properties:
            formality:
              type: number
              description: Formal vs casual (0-10)
            directness:
              type: number
              description: Direct vs indirect (0-10)
            politeness:
              type: number
              description: Politeness level (0-10)
            assertiveness:
              type: number
              description: Assertiveness level (0-10)
            aggressiveness:
              type: number
              description: Aggressiveness level (0-10)
        psychological:
          type: object
          properties:
            emotionality:
              type: number
            confidence:
              type: number
            dominance:
              type: number
            hostility:
              type: number
        emotions:
          type: object
          additionalProperties:
            type: number
          description: Map of emotion names to intensity scores (0-10)
          example:
            interest: 8.0
            excitement: 7.5
            tension: 6.0
            anticipation: 5.0
        suggestions:
          type: array
          items:
            type: string
          description: Improvement suggestions for the prompt

    ModelProvider:
      type: object
      properties:
        id:
          type: string
          format: uuid
        slug:
          type: string
          description: URL-safe identifier (openai, anthropic, bedrock, google, xai)
        name:
          type: string
        authType:
          type: string
          enum: [api_key, iam, service_account]
        apiFormat:
          type: string
          enum: [openai, anthropic, bedrock, google]
        baseUrl:
          type: string
          nullable: true
        modelDefinitions:
          type: array
          items:
            $ref: '#/components/schemas/ModelDefinition'

    ModelDefinition:
      type: object
      properties:
        id:
          type: string
          format: uuid
        providerId:
          type: string
          format: uuid
        slug:
          type: string
        displayName:
          type: string
        modelId:
          type: string
          description: Provider-specific model identifier (e.g., gpt-4o)
        category:
          type: string
          enum: [chat, embedding, image, code, multimodal]
        tier:
          type: string
          enum: [standard, premium, economy]
        contextWindow:
          type: integer
          nullable: true
        maxOutputTokens:
          type: integer
          nullable: true
        inputPricePerMillion:
          type: number
          nullable: true
        outputPricePerMillion:
          type: number
          nullable: true
        supportsVision:
          type: boolean
        supportsFunctionCalling:
          type: boolean
        supportsStreaming:
          type: boolean
        isActive:
          type: boolean
        isDeprecated:
          type: boolean
        provider:
          type: object
          properties:
            id:
              type: string
              format: uuid
            slug:
              type: string
            name:
              type: string
            authType:
              type: string
            apiFormat:
              type: string

    ModelCredential:
      type: object
      description: Sensitive fields (apiKey, serviceAccountJson) are never returned
      properties:
        id:
          type: string
          format: uuid
        scope:
          type: string
          enum: [system, organization]
        organizationId:
          type: string
          format: uuid
          nullable: true
        providerId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        authType:
          type: string
        hasApiKey:
          type: boolean
        hasServiceAccount:
          type: boolean
        hasCustomHeaders:
          type: boolean
        awsRegion:
          type: string
          nullable: true
        requestsPerMinute:
          type: integer
          nullable: true
        tokensPerMinute:
          type: integer
          nullable: true
        tokensPerDay:
          type: integer
          nullable: true
        isActive:
          type: boolean
        lastValidated:
          type: string
          format: date-time
          nullable: true
        validationError:
          type: string
          nullable: true
        provider:
          type: object
          properties:
            id:
              type: string
            slug:
              type: string
            name:
              type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    ModelCredentialCreate:
      type: object
      required: [scope, providerId, name]
      properties:
        scope:
          type: string
          enum: [system, organization]
        organizationId:
          type: string
          format: uuid
          description: Required if scope is organization
        providerId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        apiKey:
          type: string
        awsRoleArn:
          type: string
        awsRegion:
          type: string
        serviceAccountJson:
          type: string
        customHeaders:
          type: object
        requestsPerMinute:
          type: integer
        tokensPerMinute:
          type: integer
        tokensPerDay:
          type: integer

    ModelCredentialUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        apiKey:
          type: string
        awsRoleArn:
          type: string
        awsRegion:
          type: string
        serviceAccountJson:
          type: string
        customHeaders:
          type: object
        requestsPerMinute:
          type: integer
        tokensPerMinute:
          type: integer
        tokensPerDay:
          type: integer
        isActive:
          type: boolean

    ModelConfiguration:
      type: object
      properties:
        id:
          type: string
          format: uuid
        scope:
          type: string
          enum: [system, organization]
        organizationId:
          type: string
          format: uuid
          nullable: true
        modelDefinitionId:
          type: string
          format: uuid
        credentialId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        baseUrlOverride:
          type: string
          nullable: true
        defaultTemperature:
          type: number
          nullable: true
        defaultMaxTokens:
          type: integer
          nullable: true
        defaultTimeout:
          type: integer
          nullable: true
        isVisible:
          type: boolean
        isDefault:
          type: boolean
        priority:
          type: integer
        modelDefinition:
          $ref: '#/components/schemas/ModelDefinition'
        credential:
          $ref: '#/components/schemas/ModelCredential'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    ModelConfigurationCreate:
      type: object
      required: [scope, modelDefinitionId, credentialId, name]
      properties:
        scope:
          type: string
          enum: [system, organization]
        organizationId:
          type: string
          format: uuid
        modelDefinitionId:
          type: string
          format: uuid
        credentialId:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        baseUrlOverride:
          type: string
        defaultTemperature:
          type: number
        defaultMaxTokens:
          type: integer
        defaultTimeout:
          type: integer
        isVisible:
          type: boolean
        isDefault:
          type: boolean
        priority:
          type: integer
        fallbackConfigId:
          type: string
          format: uuid

    ModelConfigurationUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        credentialId:
          type: string
          format: uuid
        baseUrlOverride:
          type: string
        defaultTemperature:
          type: number
        defaultMaxTokens:
          type: integer
        defaultTimeout:
          type: integer
        isVisible:
          type: boolean
        isDefault:
          type: boolean
        priority:
          type: integer
        isActive:
          type: boolean

    Profile:
      type: object
      properties:
        id:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        firstName:
          type: string
          nullable: true
        lastName:
          type: string
          nullable: true
        avatar:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Plugin:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        category:
          type: string
          nullable: true
        definitions:
          type: string
          description: Function signatures documentation

    TransactionUsage:
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
        currentCount:
          type: integer
        limit:
          type: integer
        percentUsed:
          type: number
        overagePolicy:
          type: string
          enum: [hard_limit, warn]
        isOverLimit:
          type: boolean
        period:
          type: string

    TransactionConfig:
      type: object
      required:
        - organizationId
        - transactionLimit
        - overagePolicy
      properties:
        organizationId:
          type: string
          format: uuid
        transactionLimit:
          type: integer
          minimum: 0
          description: Per-org transaction limit (always non-null, default 1000)
        overagePolicy:
          type: string
          enum: [hard_limit, warn]
          description: Per-org overage policy (always non-null, default hard_limit)
        planKey:
          type: string

    PlanConfiguration:
      type: object
      properties:
        id:
          type: string
          format: uuid
        planKey:
          type: string
          enum: [free, individual, team]
        displayName:
          type: string
        transactionLimit:
          type: integer
        overagePolicy:
          type: string
        features:
          type: object

    PlanConfigurationUpdate:
      type: object
      properties:
        displayName:
          type: string
        transactionLimit:
          type: integer
        overagePolicy:
          type: string
        features:
          type: object

    OrganizationMember:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
        name:
          type: string
        picture:
          type: string
          nullable: true
        role:
          type: object
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
        joinedAt:
          type: string
          format: date-time

    VersionRecord:
      type: object
      properties:
        id:
          type: string
          format: uuid
        version:
          type: integer
        changeReason:
          type: string
          nullable: true
        changedBy:
          type: string
          nullable: true
        data:
          type: object
          description: Snapshot of the entity at this version
        createdAt:
          type: string
          format: date-time