> ## Documentation Index
> Fetch the complete documentation index at: https://docs.retab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Plan Workflow Spec Against Existing Workflow

> Preview applying a declarative YAML spec to an existing workflow draft.

The URL workflow id is the plan target. Any workflow id in the YAML is
treated as source context.

Compute the reconcile plan for a declarative workflow YAML spec against a specific existing workflow draft. This does not mutate workflow state.

The `workflow_id` in the URL is the plan target. If the YAML includes `metadata.id`, Retab treats it as source context and does not use it to choose a different workflow.

<RequestExample>
  ```python Python theme={null}
  from retab import Retab

  client = Retab()

  plan = client.workflows.plan(yaml_definition, workflow_id="wf_abc123")

  print(plan.workflow_id)
  print(plan.rendered_plan)
  ```

  ```typescript TypeScript theme={null}
  import { Retab } from "@retab/node";

  const client = new Retab({ apiKey: process.env.RETAB_API_KEY });

  const plan = await client.workflows.plan(yamlDefinition, undefined, "wf_abc123");

  console.log(plan.workflowId);
  console.log(plan.renderedPlan);
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"fmt"
  	"log"

  	retab "github.com/retab-dev/retab/clients/go"
  )

  func main() {
  	ctx := context.Background()

  	client, err := retab.NewClient("")
  	if err != nil {
  		log.Fatal(err)
  	}

  	yamlDefinition := `apiVersion: workflows.retab.com/v1alpha2
  kind: Workflow
  metadata:
    id: source_workflow
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
    edges: []
  `

  	plan, err := client.Workflows.Plan(ctx, &retab.WorkflowsPlanParams{
  		YamlDefinition: yamlDefinition,
  		WorkflowID:     retab.Ptr("wf_abc123"),
  	})
  	if err != nil {
  		log.Fatal(err)
  	}

  	fmt.Println(plan.WorkflowID)
  fmt.Println(plan.RenderedPlan)
  }
  ```

  ```ruby Ruby theme={null}
  require 'retab'

  client = Retab::Client.new(api_key: ENV['RETAB_API_KEY'])

  plan = client.workflows.plan(yaml_definition: yaml_definition, workflow_id: 'wf_abc123')

  puts plan.workflow_id
  puts plan.rendered_plan
  ```

  ```rust Rust theme={null}
  use retab::models::DeclarativeWorkflowRequest;
  use retab::resources::workflows::PlanParams;
  use retab::Retab;

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = Retab::new(std::env::var("RETAB_API_KEY")?);

      let yaml_definition = r#"apiVersion: workflows.retab.com/v1alpha2
  kind: Workflow
  metadata:
    id: source_workflow
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
    edges: []
  "#;

      let plan = client
          .workflows()
          .plan(PlanParams {
              body: DeclarativeWorkflowRequest::new(yaml_definition),
              workflow_id: Some("wf_abc123".to_string()),
          })
          .await?;

      println!("{}", plan.workflow_id);
      println!("{}", plan.rendered_plan.as_deref().unwrap_or(""));
      Ok(())
  }
  ```

  ```php PHP theme={null}
  <?php
  require 'vendor/autoload.php';

  use Retab\Client;

  $client = new Client(apiKey: getenv('RETAB_API_KEY'));

  $yamlDefinition = <<<'YAML'
  apiVersion: workflows.retab.com/v1alpha2
  kind: Workflow
  metadata:
    id: source_workflow
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
    edges: []
  YAML;

  $plan = $client->workflows()->plan(yamlDefinition: $yamlDefinition, workflowId: 'wf_abc123');
  print_r($plan);
  ```

  ```csharp C# theme={null}
  using Retab;
  using RetabClient = Retab.Retab;

  var apiKey = Environment.GetEnvironmentVariable("RETAB_API_KEY")!;
  var client = new RetabClient(apiKey);

  var yamlDefinition = """
  apiVersion: workflows.retab.com/v1alpha2
  kind: Workflow
  metadata:
    id: source_workflow
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
    edges: []
  """;

  var options = new WorkflowsPlanOptions { YamlDefinition = yamlDefinition };
  options.WorkflowId = "wf_abc123";
  var plan = await client.Workflows.PlanAsync(options);
  Console.WriteLine(plan);
  ```

  ```java Java theme={null}
  import com.retab.RetabClient;

  public final class Example {
    public static void main(String[] args) throws Exception {
      RetabClient client = new RetabClient(System.getenv("RETAB_API_KEY"));

      var plan = client.workflows().plan(
          "metadata:\n  id: source_workflow\n",
          null,
          "wf_abc123"
      );
      System.out.println(plan);
    }
  }
  ```

  ```bash cURL theme={null}
  curl -X POST 'https://api.retab.com/v1/workflows/wf_abc123/spec/plan' \
    -H "Authorization: Bearer $RETAB_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "yaml_definition": "apiVersion: workflows.retab.com/v1alpha2\nkind: Workflow\nmetadata:\n  name: Invoice Workflow\nspec:\n  blocks: {}\n  edges: []\n"
    }'
  ```
</RequestExample>


## OpenAPI

````yaml POST /v1/workflows/{workflow_id}/spec/plan
openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
servers:
  - url: https://api.retab.com
security: []
paths:
  /v1/workflows/{workflow_id}/spec/plan:
    post:
      tags:
        - Workflows
      summary: Plan Existing Workflow Spec
      description: |-
        Preview applying a declarative YAML spec to an existing workflow draft.

        The URL workflow id is the plan target. Any workflow id in the YAML is
        treated as source context.
      operationId: plan_existing_workflow_spec
      parameters:
        - in: path
          name: workflow_id
          required: true
          schema:
            type: string
            title: Workflow Id
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeclarativeWorkflowRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeclarativePlanResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - HTTPBearer: []
components:
  schemas:
    DeclarativeWorkflowRequest:
      properties:
        yaml_definition:
          type: string
          title: Yaml Definition
          description: Workflow YAML definition
        project_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Project Id
          description: >-
            Project that should own a workflow created from this spec. Required
            when applying a spec that creates a new workflow.
      additionalProperties: false
      type: object
      required:
        - yaml_definition
      title: DeclarativeWorkflowRequest
      description: >-
        Body carrying a workflow's full YAML definition for validate, plan,
        apply, or export.
    DeclarativePlanResponse:
      properties:
        workflow_id:
          type: string
          title: Workflow Id
        action:
          type: string
          enum:
            - create
            - update
            - noop
          title: Action
        block_count:
          type: integer
          title: Block Count
        edge_count:
          type: integer
          title: Edge Count
        diagnostics:
          additionalProperties: true
          type: object
          title: Diagnostics
        format_version:
          type: string
          title: Format Version
          default: workflows-plan/v1
        summary:
          $ref: '#/components/schemas/DeclarativePlanSummary'
          default:
            add: 0
            change: 0
            destroy: 0
            replace: 0
            noop: 0
            total: 0
            has_changes: false
        resource_changes:
          items:
            $ref: '#/components/schemas/DeclarativePlanResourceChange'
          type: array
          title: Resource Changes
          default: []
        rendered_plan:
          type: string
          title: Rendered Plan
          default: No changes. Workflow spec is up to date.
      type: object
      required:
        - action
        - block_count
        - diagnostics
        - edge_count
        - workflow_id
      title: DeclarativePlanResponse
      description: >-
        A preview of the changes a workflow YAML definition would make, with a
        per-resource diff and a human-readable `rendered_plan`.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
          default: []
      type: object
      title: HTTPValidationError
    DeclarativePlanSummary:
      properties:
        add:
          type: integer
          title: Add
          default: 0
        change:
          type: integer
          title: Change
          default: 0
        destroy:
          type: integer
          title: Destroy
          default: 0
        replace:
          type: integer
          title: Replace
          default: 0
        noop:
          type: integer
          title: Noop
          default: 0
        total:
          type: integer
          title: Total
          default: 0
        has_changes:
          type: boolean
          title: Has Changes
          default: false
      type: object
      title: DeclarativePlanSummary
    DeclarativePlanResourceChange:
      properties:
        address:
          type: string
          title: Address
        target:
          type: string
          enum:
            - workflow
            - block
            - edge
          title: Target
        target_id:
          type: string
          title: Target Id
        name:
          type: string
          title: Name
        type:
          type: string
          enum:
            - workflow
            - edge
            - start_document
            - start_json
            - note
            - parse
            - edit
            - extract
            - split
            - classifier
            - conditional
            - api_call
            - function
            - while_loop
            - for_each
            - merge_dicts
            - while_loop_sentinel_start
            - while_loop_sentinel_end
            - for_each_sentinel_start
            - for_each_sentinel_end
          title: Type
          description: >-
            Resource kind for this plan entry. `workflow` and `edge` are flat
            singletons; for `target='block'` this carries the block's concrete
            type (e.g. `extract`, `api_call`) so the plan summary can render
            type-specific labels.
        actions:
          items:
            type: string
            enum:
              - create
              - update
              - delete
          type: array
          title: Actions
        summary:
          type: string
          title: Summary
        change:
          $ref: '#/components/schemas/DeclarativePlanChange'
        path:
          anyOf:
            - type: string
            - type: 'null'
          title: Path
      type: object
      required:
        - actions
        - address
        - change
        - name
        - summary
        - target
        - target_id
        - type
      title: DeclarativePlanResourceChange
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
          default: null
        ctx:
          type: object
          title: Context
          default: {}
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    DeclarativePlanChange:
      properties:
        before:
          anyOf:
            - {}
            - type: 'null'
          title: Before
        after:
          anyOf:
            - {}
            - type: 'null'
          title: After
        before_sensitive:
          title: Before Sensitive
          default: null
        after_sensitive:
          title: After Sensitive
          default: null
        field_changes:
          items:
            $ref: '#/components/schemas/DeclarativePlanFieldChange'
          type: array
          title: Field Changes
          default: []
      type: object
      title: DeclarativePlanChange
    DeclarativePlanFieldChange:
      properties:
        path:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Path
        path_display:
          type: string
          title: Path Display
        action:
          type: string
          enum:
            - create
            - update
            - delete
          title: Action
        before:
          anyOf:
            - {}
            - type: 'null'
          title: Before
        after:
          anyOf:
            - {}
            - type: 'null'
          title: After
        before_sensitive:
          type: boolean
          title: Before Sensitive
          default: false
        after_sensitive:
          type: boolean
          title: After Sensitive
          default: false
        unified_diff:
          anyOf:
            - type: string
            - type: 'null'
          title: Unified Diff
      type: object
      required:
        - action
        - path
        - path_display
      title: DeclarativePlanFieldChange
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````