---
title: "Generate execution plan"
method: POST
path: "/api/rigor/plan"
tags: ["Rigor"]
---

# Generate execution plan

`POST /api/rigor/plan`

## Request

- Base URL: `https://plith.ai`
- URL: `https://plith.ai/api/rigor/plan`
- Auth: API key in header `x-api-key`

Classifies the task, resolves rigor level, selects an appropriate framework sequence, and returns a structured execution plan with cost estimates and insertion rules. Costs 5 credits.

## Request body

- object
  - `task_description` string, required: The task to plan.
  - `task_type` string: Optional explicit task type. Bypasses classification when provided.
  - `mode` 'plan' | 'execute', required: Workflow mode. Use 'plan' to receive a plan without executing.
  - `preferences` object: Caller-controlled workflow composition preferences.
    - `independent_of` object: Model creators and model ids that must not receive this workflow's content (for example when it grades output one model family produced). Covers every model call Rigor makes for the workflow: planning (classification, intent extraction, title), every step, research agents, review and quality checks, retrieval over files attached to the workflow, and per-step quality grading after the workflow ends. Not covered: processing when a file is uploaded (text extraction, audio and video transcription, indexing) and POST /api/rigor/enhance. A hard constraint: an excluded model, or one whose creator cannot be confirmed, is skipped; a step with no model left fails the workflow with policy_rule no_independent_model; an optional planning or grading call with no model left is skipped. Not relaxed by any workspace policy enforcement mode. Fixed when the workflow is planned; entry order does not matter.
      - `families` string[]: Model creators: anthropic, deepseek, google, minimax, mistral, moonshot, openai, qwen, xai or zhipu. Case does not matter; any other name is refused with 400.
      - `models` string[]: Model ids. A dated version or -latest alias of a listed id is excluded too.
    - `review_depth` 'quick' | 'standard' | 'full': Depth of review passes included in the plan.
    - `rigor_level` 'quick' | 'standard' | 'thorough': Explicit rigor level override. Determines model tier and framework count.
    - `skip_frameworks` string[]: Framework names to exclude from the recommended sequence.
    - `only_frameworks` string[]: If set, only these frameworks are included in the sequence (mutually exclusive with skip_frameworks).
    - `add_frameworks` object[]: Additional frameworks to inject into the post-filter sequence.
      - `name` string, required: Framework identifier. Must be a recognised framework name.
      - `before_step` integer, required: 0-based index into the post-filter sequence before which to insert this framework.
    - `require_approval` boolean: Insert an APPROVAL-GATE step into the sequence.
    - `approval_before_step` integer[]: Step indices before which to insert APPROVAL-GATE steps. Used in conjunction with require_approval.
    - `insertion_rules` object: Runtime conditional insertion settings.
      - `lav_enabled` boolean: Enable LAV (Literal Assumption Validation) conditional insertion rule.
    - `execution` 'direct': Set to 'direct' to compose the plan's content frameworks into a single LLM call and route cost-first, using a per-task-type model floor that moves when a cheaper model earns the work. Research steps, process steps (classification-verify, review protocol, synthesis) and the quality review each remain separate calls, so this is not a one-call-per-workflow guarantee: for atomic task types, which have a single content framework, the call count matches standard execution and the saving is the model. Supplying output_contract replaces the quality-review call with deterministic validation, which is one fewer call. No intermediate outputs. Available at every tier. Auto-selected for atomic task types when no execution preference is given. The atomic task types cluster, grade_set, rewrite, fill_arguments, synthesise, verify, compare, classify and grounded_edit run in direct mode only: such a request that cannot run in direct mode is refused with 422 direct_mode_unavailable rather than falling back, and until a model qualifies for the type, with 422 task_type_not_qualified. In direct mode cluster runs in 2 steps (propose the groups, then place the items in batches); under coverage partial, items no placement answered are put in ungrouped_ids and listed in the completed workflow's warnings (schema WorkflowWarning, code executor_placed_items). Falls back to standard execution when combined with require_approval or interactive mode, or when the plan exceeds the composition size limit. Attachments and prior_workflow_id chaining are NOT applied — use standard execution for those.
    - `output_contract` object: Only read when execution is 'direct'. Declares the JSON shape you want back, so the answer is generated against your schema (Anthropic forced tool-use, or an OpenAI-compatible json_schema response format) and validated against it before return, instead of returned as prose you have to parse. The schema is closed: a record carrying an undeclared key is rejected exactly like one missing a required key. A conforming run costs one LLM call rather than two, because the contract replaces the separate quality-review call. Persists with the plan, so a later execute against the stored workflow_id inherits it.
      - `task_type` string, required: Your own label for the work. Echoed into telemetry. Not read as a framework name and does not change routing.
      - `shape` 'object' | 'array', required: 'object' for one record, 'array' for one entry per input item.
      - `fields` object[], required: The schema for one record.
        - `name` string, required: The JSON key.
        - `type` 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object', required: The value's type.
        - `required` boolean: Defaults to true. Set false for a field that may be absent.
        - `enum` string[]: Restricts a string field to a fixed set of values.
        - `minimum` number: Lower bound for a numeric field.
        - `maximum` number: Upper bound for a numeric field.
        - `description` string: Passed to the model as the field's description.
      - `count` object: Bounds on the number of entries. Only read when shape is 'array'.
        - `min` number
        - `max` number
      - `selection` object: Use when you want the model to over-generate candidates and Rigor to sort, threshold, and cap them before the count bounds are checked.
        - `scoreField` string
        - `minScore` number
        - `minCount` number
        - `maxCount` number
  - `context` object
    - `additional_context` string: Extra context forwarded to the planner.
  - `webhook_url` string, uri: Optional webhook URL for async plan delivery.
  - `workflow_id` string: Reference an existing workflow plan.
  - `restart_from_step` integer: Step index to restart execution from.

## Response `200`

Execution plan generated

- object
  - `plan` object
    - `workflow_id` string, uuid
    - `classification` object
      - `task_type` string
      - `value_class` 'operational' | 'governance' | 'strategic'
      - `confidence` number
      - `sequence_template` string, nullable
      - `classification_method` 'explicit' | 'keyword' | 'keyword_tiebreak' | 'default' | 'embedding' | 'llm_fallback'
      - `warnings` string[]
    - `recommended_sequence` object[]
      - `step` integer
      - `framework` string
      - `action` string, nullable
      - `model_tier` 'tier_1' | 'tier_2' | 'tier_3'
      - `estimated_credits` integer
      - `estimated_cost_usd` number
      - `required` boolean
      - `tool_scope` string
      - `rationale` string
    - `cost_summary` object
      - `tool_credits` integer
      - `tool_cost_usd` number
      - `orchestration_fee_credits` integer
      - `orchestration_fee_usd` number
      - `total_credits` integer
      - `total_cost_usd` number
      - `quality_review` string
    - `alternatives` object
      - `quick` object
        - `steps` integer
        - `total_credits` integer
        - `total_cost_usd` number
        - `reviews` string
      - `standard` object
        - `steps` integer
        - `total_credits` integer
        - `total_cost_usd` number
        - `reviews` string
      - `thorough` object
        - `steps` integer
        - `total_credits` integer
        - `total_cost_usd` number
        - `reviews` string
    - `budget_warnings` string[]
    - `feasibility_warnings` object[]
      - `intent` string
      - `status` 'degraded' | 'severely_degraded'
      - `reason` string
      - `recommendation` string
      - `estimated_value_at_risk` number, nullable
    - `feasibility_assessed` boolean
    - `rigor_level` 'quick' | 'standard' | 'thorough'
    - `rigor_level_source` 'route_default' | 'explicit' | 'auto_detected' | 'system_default' | 'parent_floor'
    - `insertionRules` object[]: Conditional runtime insertion rules attached to this plan.
      - `id` string
      - `triggerAfterStep` string
      - `condition` object
        - `field` string
        - `operator` 'contains' | 'equals' | 'exists' | 'gt' | 'lt'
        - `value` unknown
      - `insertFramework` string
      - `insertBefore` string
      - `maxInsertions` integer
    - `insertionBudget` object: Budget cap for conditional runtime insertions.
      - `maxTotalInsertions` integer
      - `estimatedCostRange` number[]: [min, max] estimated cost in USD for all possible insertions.
    - `_multi_intent_metadata` object, nullable: Present when multi-intent planning was attempted.
      - `attempted` boolean
      - `intents_detected` string[]
      - `merge_log` unknown[]
        - unknown
    - `execution` 'direct': Present with value 'direct' when direct execution is resolved. Absent for standard multi-call execution.
    - `execution_fallback` boolean: True when the requested execution mode was overridden due to tier, workflow size, or approval gate conflict.
    - `allowed_modes` string[]: Execution approaches available beyond the default. Contains 'direct' when this plan is eligible for direct execution; empty array otherwise. When empty, the plan is not eligible regardless of preferences.execution.
  - `request_id` string
  - `credits_used` integer
  - `credits_remaining` integer
  - `fallback_behavior` string

## Other responses

- `400`: Invalid request — missing required fields or conflicting preferences
- `401`: Invalid or missing API key
- `402`: Insufficient credits
- `500`: Internal server error

---

[API](https://skmtc.dev/plith/apis/plith-api.md) · [All operations](https://skmtc.dev/plith/apis/plith-api/llms.txt) · [OpenAPI document](https://skmtc.dev/plith/apis/plith-api/revisions/4a03164b0d75?raw)
