API Reference

The Praetor API is built on Hono (a lightweight TypeScript web framework) and follows REST conventions. All endpoints return JSON and use Zod for request/response validation.

API Reference

Table of Contents


Overview

The Praetor API is built on Hono (a lightweight TypeScript web framework) and follows REST conventions. All endpoints return JSON and use Zod for request/response validation.

Base URL

Development: http://localhost:4112/api
Production:  https://api.praetor.app/api

Response Format

All responses follow a consistent structure:

interface ApiResponse<T> {
  success: boolean;
  data: T;
  metadata: {
    timestamp: string;       // ISO 8601
    requestId?: string;      // For tracing
  };
  error?: {
    code: string;
    message: string;
    details?: any;
  };
}

Request Headers

HeaderRequiredDescription
AuthorizationYesBearer <session_token>
Content-TypeYesapplication/json
X-Request-IDNoClient-provided request ID for tracing
X-Tenant-IDNoExplicit tenant ID (admin only)

Authentication

Authentication is handled via Stytch. The API expects a valid session token in the Authorization header.

Session Token Flow

1. User logs in via Stytch (/login page)
2. Stytch returns session JWT
3. Frontend stores in cookie (stytch_session_jwt)
4. API requests include: Authorization: Bearer <jwt>
5. Backend validates token with Stytch SDK

E2E Test Mode

For testing, authentication can be bypassed:

# Environment variable
NEXT_PUBLIC_E2E_TEST_MODE=true

# Or header
X-E2E-Test-Mode: true

Project Management

List Projects

GET /api/projects

Returns all projects for the current tenant with progress metrics.

Query Parameters:

ParamTypeDefaultDescription
statusstringallFilter by status (active, completed, archived)
limitnumber50Max results
offsetnumber0Pagination offset

Response:

{
  success: true,
  data: {
    projects: [
      {
        id: "uuid",
        name: "Project Name",
        status: "active",
        phase: "DISCOVERY",
        progress: {
          overall: 0.45,
          discovery: 1.0,
          featureSelection: 0.8,
          planGeneration: 0.2,
          planning: 0,
          visualDiscovery: 0,
          specification: 0
        },
        createdAt: "2024-01-15T10:30:00Z",
        updatedAt: "2024-01-16T14:22:00Z"
      }
    ],
    total: 12,
    limit: 50,
    offset: 0
  }
}

Create Project

POST /api/projects

Creates a new project. Does NOT auto-start the flow.

Request Body:

{
  name: string;              // Required
  description?: string;
  template?: string;         // e.g., "e-commerce", "saas", "marketplace"
  metadata?: Record<string, any>;
}

Response:

{
  success: true,
  data: {
    id: "uuid",
    name: "My Project",
    status: "active",
    phase: "CREATED",        // Not DISCOVERY until flow/start called
    createdAt: "2024-01-15T10:30:00Z"
  }
}

Get Project

GET /api/projects/:projectId

Returns detailed project information including all phase data.

Response:

{
  success: true,
  data: {
    id: "uuid",
    name: "Project Name",
    status: "active",
    phase: "PLAN_GENERATION",

    // Phase timing
    discoveryStartedAt: "2024-01-15T10:30:00Z",
    discoveryCompletedAt: "2024-01-15T11:45:00Z",
    featureSelectionStartedAt: "2024-01-15T11:45:00Z",
    featureSelectionCompletedAt: "2024-01-15T12:00:00Z",
    planGenerationStartedAt: "2024-01-15T12:00:00Z",

    // Progress metrics
    progress: {
      overall: 0.55,
      byPhase: { ... }
    },

    // Discovery data
    discoveryOutput: { ... },

    // Selected features
    selectedFeatures: [ ... ],

    // Ontology coverage
    ontologyCoverage: 0.82
  }
}

Update Project

PATCH /api/projects/:projectId

Updates project metadata. Cannot change phase directly (use flow endpoints).

Request Body:

{
  name?: string;
  description?: string;
  metadata?: Record<string, any>;
  status?: "active" | "archived";
}

Delete Project

DELETE /api/projects/:projectId

Deletes project and all associated data. Uses enhanced deletion with transaction handling.

Response:

{
  success: true,
  data: {
    deletedTables: [
      "graph_nodes",
      "plan_questions",
      "answers",
      "tasks",
      "feature_selections",
      // ... all related tables
    ],
    rowsDeleted: 1247
  }
}

Flow Orchestration

Start Flow

POST /api/flow/start

Starts the discovery flow for a project. This is the critical entry point.

Request Body:

{
  projectId: string;
}

Response:

{
  success: true,
  data: {
    projectId: "uuid",
    phase: "DISCOVERY",
    firstQuestion: {
      id: "uuid",
      text: "What type of application are you building?",
      variants: [
        { type: "original", text: "What type of application..." },
        { type: "simplified", text: "What kind of app do you want?" }
      ],
      answerType: "select",
      options: [
        { value: "web", label: "Web Application" },
        { value: "mobile", label: "Mobile App" },
        { value: "both", label: "Both Web and Mobile" }
      ]
    },
    totalQuestions: 15
  }
}

Get Next Question

POST /api/flow/get-next-question

Retrieves the next question in the flow.

Request Body:

{
  projectId: string;
  sessionId?: string;        // For session continuity
}

Response:

{
  success: true,
  data: {
    question: {
      id: "uuid",
      text: "Who is your target audience?",
      description: "Understanding your users helps us tailor the specification.",
      variants: [ ... ],
      answerType: "text",
      prefill: {
        value: "Small business owners",
        confidence: 0.72,
        source: "persona",
        explanation: "Based on your e-commerce focus..."
      }
    },
    progress: {
      answered: 5,
      total: 15,
      percent: 33
    },
    isLastQuestion: false
  }
}

Answer Question

POST /api/flow/answer-question

Submits an answer to a question.

Request Body:

{
  projectId: string;
  questionId: string;
  answer: {
    value: string | string[] | boolean | number;
    selectedVariant?: string;    // Which question variant was shown
    confidence?: number;         // User confidence in their answer
    notes?: string;              // Additional context
  };
}

Response:

{
  success: true,
  data: {
    answerId: "uuid",
    processed: true,

    // Post-answer effects
    effects: {
      ontologyUpdates: [
        { type: "user", name: "Small Business Owner", confidence: 0.85 }
      ],
      suggestions: [
        "Consider adding inventory management"
      ],
      prefillCascades: [
        { questionId: "uuid", newConfidence: 0.88 }
      ],
      tasksCreated: []
    },

    // Next question (convenience)
    nextQuestion: { ... }
  }
}

Check Phase Readiness

GET /api/flow/readiness/:projectId

Checks if project is ready for phase transition.

Response:

{
  success: true,
  data: {
    currentPhase: "DISCOVERY",
    readinessScore: 0.93,
    threshold: 0.95,
    isReady: false,

    blockers: [
      {
        type: "unanswered_question",
        questionId: "uuid",
        message: "1 required question unanswered"
      }
    ],

    warnings: [
      {
        type: "low_confidence_prefill",
        count: 3,
        message: "3 prefilled answers have low confidence"
      }
    ]
  }
}

Transition Phase

POST /api/flow/transition

Triggers a phase transition (if ready).

Request Body:

{
  projectId: string;
  targetPhase: "FEATURE_SELECTION" | "PLAN_GENERATION" | "PLANNING" |
               "VISUAL_DISCOVERY" | "SPECIFICATION";
  force?: boolean;           // Admin only: bypass readiness checks
}

Response:

{
  success: true,
  data: {
    previousPhase: "DISCOVERY",
    currentPhase: "FEATURE_SELECTION",
    transitionedAt: "2024-01-15T12:00:00Z",

    // Entry action results
    entryActions: {
      featureCandidatesGenerated: 24,
      patternsMatched: 7,
      questionsSupressed: 12
    }
  }
}

Agent Execution

Execute Multi-Agent Spec Generation

POST /api/agents/generate-spec

Triggers multi-agent specification generation.

Request Body:

{
  projectId: string;
  options?: {
    strategy?: "sequential" | "parallel" | "hierarchical" | "debate";
    agents?: string[];        // Specific agents to use
    budget?: {
      maxTokens?: number;
      maxCostUSD?: number;
    };
  };
}

Response:

{
  success: true,
  data: {
    executionId: "uuid",
    status: "running",
    agents: ["requirements-compiler", "architecture-compiler", ...],
    startedAt: "2024-01-15T14:00:00Z",

    // Polling URL
    statusUrl: "/api/agents/execution/uuid/status"
  }
}

Get Execution Status

GET /api/agents/execution/:executionId/status

Returns current execution status (for polling).

Response:

{
  success: true,
  data: {
    executionId: "uuid",
    status: "running" | "completed" | "failed" | "paused",

    progress: {
      completedSteps: 4,
      totalSteps: 7,
      currentStep: "architecture-compilation"
    },

    budget: {
      tokensUsed: 45000,
      tokensLimit: 100000,
      costIncurred: 2.34,
      costLimit: 5.00
    },

    // If completed
    result?: {
      spec: SpecV1,
      validationPassed: true
    },

    // If failed
    error?: {
      code: "budget_exceeded",
      message: "Token budget exceeded",
      checkpoint: "uuid"        // Resume point
    }
  }
}

Agent Coordination

POST /api/agents/coordinate

Execute custom agent coordination.

Request Body:

{
  projectId: string;
  strategy: "sequential" | "parallel" | "hierarchical" | "debate";
  agents: [
    { name: "requirements-compiler", role: "worker" },
    { name: "architecture-compiler", role: "worker" },
    { name: "completion-audit", role: "supervisor" }
  ];
  input: { ... };
  options?: {
    timeout?: number;
    checkpointInterval?: number;
  };
}

Get Agent Memory

GET /api/agents/memory

Returns agent memory statistics for current session.

Query Parameters:

ParamTypeDescription
sessionIdstringFilter by session
agentNamestringFilter by agent

Response:

{
  success: true,
  data: {
    sessions: [
      {
        sessionId: "uuid",
        agentName: "conversation-agent",
        messageCount: 45,
        tokensUsed: 12500,
        lastActivity: "2024-01-15T14:22:00Z"
      }
    ],
    totals: {
      totalSessions: 5,
      totalMessages: 234,
      totalTokens: 67000
    }
  }
}

Task Management

List Tasks

GET /api/tasks

Returns tasks for a project.

Query Parameters:

ParamTypeDescription
projectIdstringRequired: Project filter
statusstringFilter by status
assigneeTypestringFilter by user/agent
typestringFilter by task type

Response:

{
  success: true,
  data: {
    tasks: [
      {
        id: "uuid",
        type: "REVIEW",
        title: "Review prefilled answer",
        description: "The system suggested 'PostgreSQL' for database...",
        status: "pending",
        priority: "medium",
        assigneeType: "user",
        actions: [
          {
            id: "uuid",
            type: "APPROVE_REJECT",
            label: "Accept or Modify",
            config: { ... }
          }
        ],
        targets: [
          { type: "question", id: "uuid" }
        ],
        createdAt: "2024-01-15T12:00:00Z"
      }
    ],
    total: 8
  }
}

Create Task

POST /api/tasks

Creates a new task.

Request Body:

{
  projectId: string;
  type: "PROVIDE" | "DECIDE" | "REVIEW" | "CONNECT";
  title: string;
  description: string;
  priority?: "low" | "medium" | "high" | "urgent";
  assigneeType?: "user" | "agent";
  assigneeId?: string;
  actions: [
    {
      type: "FORM_SUBMIT" | "SINGLE_SELECT" | "APPROVE_REJECT" | ...;
      label: string;
      config: { ... };
    }
  ];
  targets?: [
    { type: string; id: string; }
  ];
  dependencies?: string[];     // Task IDs that must complete first
}

Submit Task Action

POST /api/tasks/:taskId/actions/:actionId

Submits an action for a task. Idempotent via idempotency key.

Request Body:

{
  data: any;                   // Action-specific data
  idempotencyKey?: string;     // Auto-generated if not provided
}

Response:

{
  success: true,
  data: {
    submissionId: "uuid",
    taskId: "uuid",
    actionId: "uuid",
    result: { ... },

    // Side effects
    effects: {
      taskCompleted: true,
      outputBindings: [
        { field: "project.database", value: "PostgreSQL" }
      ],
      workflowsTriggered: []
    }
  }
}

Get User Tasks

GET /api/user-tasks

Returns tasks assigned to the current user across all projects.

Response:

{
  success: true,
  data: {
    tasks: [
      {
        id: "uuid",
        projectId: "uuid",
        projectName: "My E-commerce App",
        type: "REVIEW",
        title: "Review database choice",
        status: "pending",
        priority: "high",
        dueDate: "2024-01-16T17:00:00Z"
      }
    ],
    counts: {
      pending: 5,
      inProgress: 2,
      completed: 12
    }
  }
}

Specification Export

Compile Specification

POST /api/specification/compile

Triggers specification compilation.

Request Body:

{
  projectId: string;
  options?: {
    format?: "v1" | "v2";
    includeTestPlan?: boolean;
    includeTaskGraph?: boolean;
    includeRunbook?: boolean;
  };
}

Response:

{
  success: true,
  data: {
    specId: "uuid",
    status: "compiling",
    estimatedTime: 45,          // seconds
    statusUrl: "/api/specification/uuid/status"
  }
}

Get Specification

GET /api/specification/:specId

Retrieves compiled specification.

Response:

{
  success: true,
  data: {
    id: "uuid",
    projectId: "uuid",
    version: "1.0.0",
    compiledAt: "2024-01-15T15:00:00Z",

    spec: {
      metadata: { ... },
      overview: { ... },
      entities: [ ... ],
      endpoints: [ ... ],
      workflows: [ ... ],
      requirements: [ ... ],
      testCases: [ ... ],
      architecture: { ... },
      designSystem: { ... }
    },

    validation: {
      passed: true,
      warnings: []
    }
  }
}

Export Pack

POST /api/exports/download

Generates export pack for external agents.

Request Body:

{
  projectId: string;
  format: "json" | "markdown" | "mcp";
  include: {
    spec: boolean;
    dod: boolean;
    testPlan: boolean;
    taskGraph: boolean;
    runbook: boolean;
    mcpConfig: boolean;
  };
}

Response:

{
  success: true,
  data: {
    downloadUrl: "https://...",
    expiresAt: "2024-01-16T15:00:00Z",
    size: 245678,              // bytes
    contents: [
      "spec.json",
      "dod.md",
      "test-plan.md",
      "task-graph.json",
      "runbook.md",
      "mcp-config.json"
    ]
  }
}

Permissions & Policy API

List Roles

GET /api/permissions/roles

Returns all roles for the current tenant.

Response:

{
  success: true,
  data: {
    roles: [
      {
        id: "uuid",
        name: "Project Admin",
        description: "Full access to project resources",
        capabilities: [
          "project:read",
          "project:write",
          "user:invite",
          "task:assign"
        ],
        isSystemRole: false,
        createdAt: "2024-01-15T10:30:00Z"
      }
    ]
  }
}

Create Role

POST /api/permissions/roles

Creates a new role with capabilities.

Request Body:

{
  name: string;
  description?: string;
  capabilities: string[];
}

Get Role

GET /api/permissions/roles/:roleId

Returns role details including assigned users.


Update Role

PATCH /api/permissions/roles/:roleId

Updates role capabilities or metadata.


Delete Role

DELETE /api/permissions/roles/:roleId

Deletes a role (system roles cannot be deleted).


List Policies

GET /api/permissions/policies

Returns ABAC policies for the tenant.

Response:

{
  success: true,
  data: {
    policies: [
      {
        id: "uuid",
        name: "Department Access Policy",
        effect: "allow",
        actions: ["user:read", "user:write"],
        resources: ["user:*"],
        conditions: {
          "user.department": {"$eq": "engineering"}
        },
        priority: 10,
        enabled: true
      }
    ]
  }
}

Create Policy

POST /api/permissions/policies

Creates a new ABAC policy.

Request Body:

{
  name: string;
  description?: string;
  effect: "allow" | "deny";
  actions: string[];
  resources: string[];
  conditions?: {
    [key: string]: {
      $eq?: any;
      $ne?: any;
      $in?: any[];
      $gt?: number;
      $lt?: number;
    };
  };
  priority?: number;
}

Evaluate Permission

POST /api/permissions/evaluate

Evaluates whether a user has permission for an action.

Request Body:

{
  userId: string;
  action: string;         // e.g., "project:delete"
  resourceType: string;   // e.g., "project"
  resourceId?: string;
  context?: Record<string, any>;
}

Response:

{
  success: true,
  data: {
    allowed: boolean;
    matchedPolicies: string[];
    evaluationTimeMs: number;
  }
}

Get Permission Matrix

GET /api/permissions/matrix/:projectId

Returns permission matrix for a project.


Document Templates API

List Templates

GET /api/templates

Returns document templates for a project.

Query Parameters:

ParamTypeDescription
projectIdstringRequired: Project filter
templateTypestringFilter by type (contract, invoice, report)
statusstringFilter by status (draft, active)

Upload Template

POST /api/templates

Uploads a new document template.

Request Body (multipart/form-data):

{
  file: File;              // DOCX, PDF, HTML, or Markdown
  name: string;
  description?: string;
  templateType: string;    // 'contract', 'invoice', 'report', etc.
  projectId: string;
}

Response:

{
  success: true,
  data: {
    templateId: "uuid",
    variablesExtracted: number,
    extractionUrl: "/api/templates/uuid/extract-variables"
  }
}

Extract Variables

POST /api/templates/:templateId/extract-variables

Triggers automatic variable extraction from template.

Response:

{
  success: true,
  data: {
    variables: [
      {
        id: "uuid",
        name: "customer_name",
        type: "text",
        description: "Customer full name",
        isRequired: true
      },
      {
        id: "uuid",
        name: "invoice_date",
        type: "date",
        description: "Invoice generation date",
        isRequired: true
      }
    ]
  }
}

Get Template Variables

GET /api/templates/:templateId/variables

Returns extracted variables for a template.


Create Variable Mapping

POST /api/templates/:templateId/mappings

Maps template variables to data sources.

Request Body:

{
  variableId: string;
  sourceType: "entity_field" | "api_response" | "workflow_output" | "constant" | "computed";
  sourcePath: string;      // JSONPath or dot notation
  transformExpression?: string;
}

Render Template

POST /api/templates/:templateId/render

Renders template with provided data.

Request Body:

{
  outputFormat: "pdf" | "html" | "docx" | "email";
  variables: Record<string, any>;
  projectId: string;
}

Response:

{
  success: true,
  data: {
    renderId: "uuid",
    outputUrl: "https://...",
    format: "pdf"
  }
}

BPMN Workflows API

List Workflows

GET /api/workflows

Returns BPMN workflows for a project.


Upload Workflow

POST /api/workflows

Uploads a BPMN 2.0 XML file.

Request Body (multipart/form-data):

{
  file: File;              // BPMN XML file
  name: string;
  description?: string;
  projectId: string;
}

Response:

{
  success: true,
  data: {
    workflowId: "uuid",
    validationUrl: "/api/workflows/uuid/validate",
    normalizedUrl: "/api/workflows/uuid/normalized"
  }
}

Validate Workflow

POST /api/workflows/:workflowId/validate

Triggers workflow validation (structural, semantic, platform).

Response:

{
  success: true,
  data: {
    validationId: "uuid",
    levels: {
      structural: { passed: true, errors: [], warnings: [] },
      semantic: { passed: true, errors: [], warnings: [] },
      platform: { passed: false, errors: [
        {
          code: "MISSING_BINDING",
          message: "UserTask 'Review_Contract' has no template binding",
          elementId: "UserTask_1",
          severity: "error"
        }
      ]}
    }
  }
}

Get Normalized Model

GET /api/workflows/:workflowId/normalized

Returns normalized JSON workflow model.

Response:

{
  success: true,
  data: {
    model: {
      nodes: [
        { id: "StartEvent_1", type: "StartEvent", name: "Start", properties: {} },
        { id: "UserTask_1", type: "UserTask", name: "Review Contract", properties: {} }
      ],
      edges: [
        { id: "Flow_1", source: "StartEvent_1", target: "UserTask_1" }
      ],
      metadata: {
        totalElements: 15,
        userTasks: 5,
        serviceTasks: 3
      }
    }
  }
}

Get Element Bindings

GET /api/workflows/:workflowId/bindings

Returns element bindings for the workflow.


Update Bindings

POST /api/workflows/:workflowId/bindings

Updates element bindings to templates, integrations, permissions.

Request Body:

{
  bindings: [
    {
      elementId: "UserTask_1",
      elementType: "UserTask",
      bindingType: "template",
      bindingTargetId: "template-uuid",
      config: { ... }
    }
  ]
}

Integrations API

Create Integration

POST /api/integrations

Creates a curated or contract-first integration.

Request Body:

{
  projectId: string;
  integrationType: "curated" | "contract";
  provider: string;        // 'stripe', 'gmail', 'custom', etc.

  // For curated integrations
  config?: {
    apiKey?: string;
    baseUrl?: string;
  };

  // For contract-first integrations
  contractStandardId?: string; // References standards_artifacts
}

Import Contract

POST /api/integrations/import-contract

Imports OpenAPI or AsyncAPI contract.

Request Body (multipart/form-data):

{
  file: File;              // OpenAPI/AsyncAPI JSON or YAML
  projectId: string;
  provider: string;
}

Response:

{
  success: true,
  data: {
    standardId: "uuid",
    integrationId: "uuid",
    operations: [
      { operationId: "createUser", method: "POST", path: "/users" }
    ]
  }
}

Validate Integration

POST /api/integrations/:integrationId/validate

Tests integration connectivity and schema compatibility.


Get Schema Mappings

GET /api/integrations/:integrationId/mappings

Returns schema mappings for an integration.


Create Mapping

POST /api/integrations/:integrationId/mappings

Creates schema mapping for an operation.

Request Body:

{
  operationId: string;
  sourceSchemaId: string;
  targetSchemaId: string;
  mappingRules: [
    {
      sourcePath: "user.email",
      targetPath: "email",
      transform?: "toLowerCase()"
    }
  ];
}

Gaps Analysis API

Trigger Gaps Analysis

POST /api/gaps/run

Triggers gaps analysis run.

Request Body:

{
  projectId: string;
  runType: "full" | "incremental";
  detectors?: string[];    // Optional: specific detectors to run
}

Response:

{
  success: true,
  data: {
    runId: "uuid",
    statusUrl: "/api/gaps/results/uuid",
    estimatedTimeSeconds: 30
  }
}

Get Run Results

GET /api/gaps/results/:runId

Returns gaps analysis results.

Response:

{
  success: true,
  data: {
    runId: "uuid",
    status: "completed",
    findingsCount: 12,
    tasksGenerated: 8,

    findings: [
      {
        id: "uuid",
        findingType: "permission_gap",
        severity: "blocker",
        title: "Missing permission policy for workflow execution",
        description: "Workflow 'Contract Review' requires execute permission",
        resolutionTaskId: "task-uuid"
      }
    ],

    exportReadiness: {
      status: "blocked",
      blockersCount: 3,
      warningsCount: 5
    }
  }
}

Update Task Status

PATCH /api/gaps/tasks/:taskId

Updates task status after gap resolution.


Standards Registry API

List Standards

GET /api/standards

Returns standards artifacts.

Query Parameters:

ParamTypeDescription
kindstringFilter by kind (json-schema, openapi, asyncapi, c4)
namespacestringFilter by namespace (core, domain, project:id)
statusstringFilter by status (draft, active, deprecated)

Import Standard

POST /api/standards/import

Imports a standards artifact.

Request Body:

{
  kind: "json-schema" | "openapi" | "asyncapi" | "c4";
  namespace: string;
  content: object;       // The actual schema/spec
  name: string;
  description?: string;
  version?: string;
}

Get Standard Detail

GET /api/standards/:artifactId

Returns standard with versions and references.


Export API (Enhanced)

Compile Specification

POST /api/exports/compile

Triggers multi-phase export compilation with gating.

Request Body:

{
  projectId: string;
  options?: {
    format?: "v1" | "v2";
    includePermissions?: boolean;
    includeWorkflows?: boolean;
    includeTemplates?: boolean;
    includeIntegrations?: boolean;
    includeStandards?: boolean;
    runGapsAnalysis?: boolean;
  };
}

Response:

{
  success: true,
  data: {
    exportId: "uuid",
    status: "compiling",
    phases: [
      { name: "discover", status: "completed" },
      { name: "validate", status: "running" },
      { name: "resolve", status: "pending" },
      { name: "assemble", status: "pending" },
      { name: "gate", status: "pending" },
      { name: "package", status: "pending" }
    ],
    statusUrl: "/api/exports/uuid"
  }
}

Get Export Status

GET /api/exports/:exportId

Returns enhanced export status with gating results.

Response:

{
  success: true,
  data: {
    exportId: "uuid",
    status: "blocked" | "ready" | "completed",

    gatingResults: {
      blockers: [
        { type: "permission_gap", message: "Missing workflow permissions" }
      ],
      warnings: [
        { type: "template_unmapped", message: "3 template variables unmapped" }
      ]
    },

    bundleMetadata: {
      artifactCount: 47,
      size: 245678,
      checksum: "sha256:abc123..."
    },

    downloadUrl: "/api/exports/uuid/download"
  }
}

Download Bundle

GET /api/exports/:exportId/download

Downloads the export bundle.

Response:

{
  success: true,
  data: {
    downloadUrl: "https://...",
    expiresAt: "2024-01-16T15:00:00Z",
    size: 245678,
    contents: [
      "manifest.json",
      "spec.json",
      "permissions/",
      "workflows/",
      "templates/",
      "integrations/",
      "standards/",
      "README.md"
    ]
  }
}

Kit System API

The Kit System enables extensible code generation and platform integration through self-contained packages. Each Kit includes templates, knowledge, validation rules, and discovery questions to generate platform-specific configuration and code.

See also: 16-kit-system.md for complete Kit System documentation

Feature Flag

All Kit endpoints require the kits_enabled feature flag to be enabled for the tenant.

Kit Catalog

GET /:orgId/kits

List available kits with optional filtering.

Query Parameters:

  • type - Filter by kit type: file, platform, api, hybrid, composite
  • status - Filter by status: active, deprecated, draft
  • limit - Number of kits to return (default: 50)
  • offset - Pagination offset (default: 0)

Response:

{
  "success": true,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "kitId": "hubspot-crm",
      "displayName": "HubSpot CRM Integration",
      "description": "Generate HubSpot CRM configuration including pipelines, properties, and workflows",
      "version": "1.0.0",
      "kitType": "platform",
      "status": "active",
      "platformName": "HubSpot",
      "platformCategory": "CRM",
      "supportedPhases": ["SPEC", "CHECK", "DISCOVER", "PLAN", "VALIDATE", "APPLY", "VERIFY"],
      "outputCount": 3,
      "createdAt": "2026-02-23T10:00:00Z"
    }
  ],
  "total": 15
}

GET /:orgId/kits/:kitId

Get detailed kit information including full manifest.

Response:

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "kitId": "hubspot-crm",
    "displayName": "HubSpot CRM Integration",
    "manifest": {
      "metadata": {
        "id": "hubspot-crm",
        "displayName": "HubSpot CRM Integration",
        "version": "1.0.0",
        "description": "Generate HubSpot CRM configuration",
        "author": "praetor",
        "kitType": "platform"
      },
      "platform": {
        "name": "HubSpot",
        "category": "CRM"
      },
      "phases": ["SPEC", "CHECK", "DISCOVER", "PLAN", "VALIDATE", "APPLY", "VERIFY"],
      "outputs": [
        {
          "id": "pipeline-config",
          "filename": "hubspot-pipelines.json",
          "template": "prompts/pipeline-config.liquid",
          "outputType": "json",
          "schema": "validation/pipeline.schema.json"
        }
      ],
      "discovery": {
        "pools": ["discovery/crm-questions.yaml"]
      }
    }
  }
}

Kit Execution

POST /:orgId/kits/:kitId/execute

Trigger kit execution for a project. This creates an asynchronous execution tracked via Inngest.

Request Body:

{
  "projectId": "proj_abc123",
  "businessProfile": {
    "company": {
      "name": "Acme Corp",
      "industry": "Technology"
    }
  },
  "discoveryAnswers": {
    "salesPipeline": "Lead → Qualified → Demo → Proposal → Closed",
    "customFields": ["deal_size", "competitor", "close_probability"]
  },
  "options": {
    "dryRun": false,
    "skipApply": false
  }
}

Response:

{
  "success": true,
  "data": {
    "executionId": "exec_xyz789",
    "status": "pending",
    "inngestRunId": "01HFMZ9...",
    "createdAt": "2026-02-23T12:00:00Z"
  }
}

GET /:orgId/kits/executions

List all kit executions for an organization.

Query Parameters:

  • projectId - Filter by project
  • kitId - Filter by kit
  • status - Filter by status: pending, running, completed, failed, partial
  • limit - Number of executions (default: 50)
  • offset - Pagination offset (default: 0)

Response:

{
  "success": true,
  "data": [
    {
      "id": "exec_xyz789",
      "kitId": "hubspot-crm",
      "kitVersion": "1.0.0",
      "projectId": "proj_abc123",
      "status": "completed",
      "startedAt": "2026-02-23T12:00:00Z",
      "completedAt": "2026-02-23T12:02:30Z",
      "executionTimeMs": 150000,
      "outputCount": 3,
      "outputsValid": 3,
      "outputsWarnings": 0,
      "outputsFailed": 0,
      "tokenUsageTotal": 15000,
      "estimatedCostUsd": "0.045"
    }
  ],
  "total": 42
}

GET /:orgId/kits/executions/:executionId

Get detailed execution status and results.

Response:

{
  "success": true,
  "data": {
    "id": "exec_xyz789",
    "kitId": "hubspot-crm",
    "status": "completed",
    "startedAt": "2026-02-23T12:00:00Z",
    "completedAt": "2026-02-23T12:02:30Z",
    "executionTimeMs": 150000,
    "outputs": [
      {
        "id": "out_001",
        "outputId": "pipeline-config",
        "filename": "hubspot-pipelines.json",
        "status": "valid",
        "contentSizeBytes": 4567,
        "validationErrors": 0,
        "validationWarnings": 0
      }
    ],
    "tokenUsage": {
      "prompt": 8000,
      "completion": 7000,
      "total": 15000
    },
    "estimatedCostUsd": "0.045",
    "bundlePath": "/bundles/exec_xyz789.zip",
    "bundleSizeBytes": 12345
  }
}

GET /:orgId/kits/executions/:executionId/outputs/:outputId

Retrieve the content of a specific output file.

Response:

{
  "success": true,
  "data": {
    "outputId": "pipeline-config",
    "filename": "hubspot-pipelines.json",
    "contentType": "application/json",
    "content": "{ \"pipelines\": [...] }",
    "contentSizeBytes": 4567,
    "status": "valid",
    "createdAt": "2026-02-23T12:02:00Z"
  }
}

GET /:orgId/kits/executions/:executionId/bundle

Download a ZIP bundle containing all execution outputs.

Response:

{
  "success": true,
  "data": {
    "downloadUrl": "https://storage.../exec_xyz789.zip",
    "expiresAt": "2026-02-23T18:00:00Z",
    "sizeBytes": 12345,
    "contents": [
      "hubspot-pipelines.json",
      "hubspot-properties.json",
      "setup-guide.md",
      "manifest.json"
    ]
  }
}

Credentials Management

POST /:orgId/kits/credentials

Store encrypted credentials for platform integrations.

Request Body:

{
  "projectId": "proj_abc123",
  "kitId": "hubspot-crm",
  "credentialType": "api_key",
  "credentials": {
    "apiKey": "hsk_live_abc123...",
    "accountId": "12345"
  }
}

Response:

{
  "success": true,
  "data": {
    "credentialId": "cred_456",
    "status": "active",
    "createdAt": "2026-02-23T11:00:00Z"
  }
}

GET /:orgId/kits/credentials

List stored credentials (encrypted data not returned).

Query Parameters:

  • projectId - Filter by project
  • kitId - Filter by kit

Response:

{
  "success": true,
  "data": [
    {
      "id": "cred_456",
      "kitId": "hubspot-crm",
      "projectId": "proj_abc123",
      "credentialType": "api_key",
      "status": "active",
      "lastCheckedAt": "2026-02-23T10:00:00Z",
      "lastCheckStatus": "succeeded",
      "createdAt": "2026-02-23T09:00:00Z"
    }
  ]
}

DELETE /:orgId/kits/credentials/:credentialId

Remove stored credentials.

Response:

{
  "success": true,
  "data": {
    "deleted": true
  }
}

Kit Factory

POST /:orgId/kits/factory/generate

Generate a new Kit package using AI based on requirements.

Request Body:

{
  "requirements": {
    "platform": "Salesforce",
    "category": "CRM",
    "capabilities": [
      "Lead management",
      "Opportunity tracking",
      "Custom fields"
    ],
    "integrationStyle": "REST API",
    "outputFormats": ["json", "yaml"]
  },
  "options": {
    "includeTests": true,
    "includeDocumentation": true
  }
}

Response:

{
  "success": true,
  "data": {
    "jobId": "factory_abc",
    "status": "queued",
    "estimatedTimeMinutes": 5
  }
}

Error Handling

Error Response Format

{
  success: false,
  error: {
    code: "VALIDATION_ERROR",
    message: "Request validation failed",
    details: {
      field: "projectId",
      issue: "Invalid UUID format"
    }
  },
  metadata: {
    timestamp: "2024-01-15T15:00:00Z",
    requestId: "req_abc123"
  }
}

Error Codes

CodeHTTP StatusDescription
VALIDATION_ERROR400Request validation failed
UNAUTHORIZED401Missing or invalid auth
FORBIDDEN403Insufficient permissions
NOT_FOUND404Resource not found
CONFLICT409Resource conflict (e.g., duplicate)
RATE_LIMITED429Too many requests
BUDGET_EXCEEDED402Token/cost budget exceeded
PHASE_INVALID400Invalid phase transition
READINESS_FAILED400Phase readiness check failed
AGENT_ERROR500Agent execution error
PERMISSION_DENIED403Permission policy evaluation failed
TEMPLATE_INVALID400Template validation failed
WORKFLOW_INVALID400BPMN workflow validation failed
INTEGRATION_FAILED500Integration connectivity failed
GAPS_BLOCKED402Export blocked by gaps analysis
INTERNAL_ERROR500Unexpected server error

Rate Limiting

  • General endpoints: 100 requests/minute
  • Agent endpoints: 10 requests/minute
  • Compilation endpoints: 5 requests/minute

Headers returned:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705330800

Phase 2 API Endpoints (February 2026)

Organizations

Create Organization

POST /api/organizations

Request Body:

{
  "name": "Acme Digital Agency",
  "slug": "acme-digital",
  "displayName": "Acme Digital",
  "settings": {
    "theme": "dark",
    "branding": { "logo": "https://..." }
  }
}

Response:

{
  "success": true,
  "data": {
    "id": "org-uuid",
    "tenantId": "tenant-uuid",
    "name": "Acme Digital Agency",
    "slug": "acme-digital",
    "ownerId": "user-uuid",
    "createdAt": "2026-02-21T10:00:00Z"
  }
}

List Organizations

GET /api/organizations

Returns all organizations where current user is a member.


Get Organization

GET /api/organizations/:id

Requires organization membership.


Update Organization

PUT /api/organizations/:id

Requires owner or admin role.


Check Slug Availability

GET /api/organizations/slug-check?slug=acme-digital

Response:

{
  "success": true,
  "data": { "available": true }
}

Organization Members

List Members

GET /api/organizations/:id/members

Response:

{
  "success": true,
  "data": [
    {
      "id": "member-uuid",
      "userId": "user-uuid",
      "role": "owner",
      "joinedAt": "2026-02-21T10:00:00Z",
      "user": {
        "name": "John Doe",
        "email": "john@acme.com"
      }
    }
  ]
}

Add Member

POST /api/organizations/:id/members

Request:

{
  "userId": "user-uuid",
  "role": "admin"
}

Requires admin or owner role.


Update Member Role

PUT /api/organizations/:id/members/:userId

Request:

{
  "role": "member"
}

Remove Member

DELETE /api/organizations/:id/members/:userId

Customer Invitations

Create Invitation

POST /api/customer-invitations

Request:

{
  "organizationId": "org-uuid",
  "email": "customer@example.com",
  "roleId": "role-uuid",
  "message": "Welcome! Looking forward to working with you."
}

Response:

{
  "success": true,
  "data": {
    "id": "invite-uuid",
    "token": "unique-token-uuid",
    "email": "customer@example.com",
    "status": "pending",
    "expiresAt": "2026-02-28T10:00:00Z"
  }
}

Get Invitation

GET /api/customer-invitations/:token

Public endpoint (no auth required).

Response:

{
  "success": true,
  "data": {
    "id": "invite-uuid",
    "organization": {
      "name": "Acme Digital Agency",
      "displayName": "Acme Digital"
    },
    "invitedBy": {
      "name": "John Agency Owner"
    },
    "message": "Welcome!",
    "status": "pending",
    "expiresAt": "2026-02-28T10:00:00Z"
  }
}

Accept Invitation

POST /api/customer-invitations/:token/accept

Request (new user):

{
  "name": "Jane Customer",
  "password": "secure-password"
}

Request (existing user):

{
  "userId": "existing-user-uuid"
}

Revoke Invitation

POST /api/customer-invitations/:token/revoke

Requires organization admin/owner.


List Invitations

GET /api/customer-invitations?organizationId=org-uuid&status=pending

Query Parameters:

  • organizationId (required) — Filter by organization
  • status (optional) — Filter by status (pending, accepted, expired, revoked)

Agency Projects

List Agency Projects

GET /api/agency-projects?organizationId=org-uuid

Assign Project

POST /api/agency-projects

Request:

{
  "organizationId": "org-uuid",
  "projectId": "project-uuid",
  "customerUserId": "customer-user-uuid"
}

Unassign Project

DELETE /api/agency-projects/:id

Discovery Chat

Send Message

POST /api/discovery-chat

Request:

{
  "sessionId": "session-uuid",
  "contextType": "business_profile",
  "message": "My target market is small businesses",
  "userId": "user-uuid",
  "tenantId": "tenant-uuid"
}

Response (SSE Stream):

data: {"type":"message","content":"I understand your target market..."}

data: {"type":"obligation","key":"target_market","status":"satisfied","confidence":0.9}

data: {"type":"completeness","score":0.75}

data: {"type":"phase","phase":"validation"}

data: {"type":"research","taskId":"task-uuid","taskType":"market_research","status":"pending"}

data: {"type":"done"}

Event Types:

  • message — Agent response message
  • obligation — Obligation status update
  • completeness — Session completeness score
  • phase — Session phase change
  • research — Research task triggered
  • done — Stream complete

Error Handling

(Updated for Phase 2)

Error Response Format

{
  success: false,
  error: {
    code: "VALIDATION_ERROR",
    message: "Request validation failed",
    details: {
      field: "projectId",
      issue: "Invalid UUID format"
    }
  },
  metadata: {
    timestamp: "2024-01-15T15:00:00Z",
    requestId: "req_abc123"
  }
}

Error Codes

CodeHTTP StatusDescription
VALIDATION_ERROR400Request validation failed
UNAUTHORIZED401Missing or invalid auth
FORBIDDEN403Insufficient permissions
NOT_FOUND404Resource not found
CONFLICT409Resource conflict (e.g., duplicate)
RATE_LIMITED429Too many requests
BUDGET_EXCEEDED402Token/cost budget exceeded
PHASE_INVALID400Invalid phase transition
READINESS_FAILED400Phase readiness check failed
AGENT_ERROR500Agent execution error
PERMISSION_DENIED403Permission policy evaluation failed
TEMPLATE_INVALID400Template validation failed
WORKFLOW_INVALID400BPMN workflow validation failed
INTEGRATION_FAILED500Integration connectivity failed
GAPS_BLOCKED402Export blocked by gaps analysis
ORG_NOT_MEMBER403Not a member of organization
INVITE_EXPIRED400Customer invitation expired
SLUG_TAKEN409Organization slug already exists
SESSION_INCOMPLETE400Discovery session not complete
OBLIGATION_UNRESOLVED400Required obligations not satisfied
INTERNAL_ERROR500Unexpected server error

Rate Limiting

  • General endpoints: 100 requests/minute
  • Agent endpoints: 10 requests/minute
  • Compilation endpoints: 5 requests/minute
  • Discovery chat: 30 requests/minute

Headers returned:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705330800

See also: 11-database-schema.md for data structures, 13-multi-tenant-organizations.md for organization architecture, 14-discovery-engine.md for discovery system, 15-realtime-infrastructure.md for realtime events

Last Updated: February 2026

Command Palette

Search for a command to run...