> ## 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.

# Apply Workflow Spec to Existing Workflow

> Apply a declarative YAML spec to an existing workflow draft.

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

Apply a declarative workflow YAML spec to an existing workflow draft.

The `workflow_id` in the URL is the update 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()

  updated = client.workflows.apply(yaml_definition, workflow_id="wf_abc123")

  print(updated.workflow_id)
  print(updated.summary.has_changes)
  ```

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

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

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

  console.log(updated.workflowId);
  console.log(updated.summary.hasChanges);
  ```

  ```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: []
  `

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

  	fmt.Println(result.WorkflowID)
  	fmt.Println(result.Summary)
  }
  ```

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

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

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

  puts updated.workflow_id
  puts updated.summary.has_changes
  ```

  ```rust Rust theme={null}
  use retab::models::DeclarativeWorkflowRequest;
  use retab::resources::workflows::ApplyParams;
  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 result = client
          .workflows()
          .apply(ApplyParams {
              body: DeclarativeWorkflowRequest::new(yaml_definition),
              workflow_id: Some("wf_abc123".to_string()),
          })
          .await?;

      println!("{}", result.workflow_id);
      if let Some(summary) = &result.summary {
          println!("{:?}", summary.has_changes);
      }
      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;

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

  ```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 WorkflowsApplyOptions { YamlDefinition = yamlDefinition };
  options.WorkflowId = "wf_abc123";
  var result = await client.Workflows.ApplyAsync(options);
  Console.WriteLine(result);
  ```

  ```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 result = client.workflows().apply(
          "metadata:\n  id: source_workflow\n",
          null,
          "wf_abc123"
      );
      System.out.println(result);
    }
  }
  ```

  ```curl cURL theme={null}
  curl -X 'POST' \
    'https://api.retab.com/v1/workflows/wf_abc123/spec/apply' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <your-api-key>' \
    -d '{
      "yaml_definition": "apiVersion: workflows.retab.com/v1alpha2\nkind: Workflow\nmetadata:\n  id: source_workflow\n  name: Invoice Workflow\nspec:\n  blocks:\n    start:\n      type: start_json\n      label: Input JSON\n      config:\n        json_schema:\n          type: object\n  edges: []\n"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "workflow_id": "wf_abc123",
    "created": false,
    "block_count": 1,
    "edge_count": 0,
    "diagnostics": {
      "issues": []
    },
    "format_version": "workflows-plan/v1",
    "summary": {
      "add": 0,
      "change": 1,
      "destroy": 0,
      "replace": 0,
      "noop": 0,
      "total": 1,
      "has_changes": true
    },
    "resource_changes": [],
    "rendered_plan": "Updated workflow draft."
  }
  ```
</ResponseExample>


## OpenAPI

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

        The URL workflow id is the update target. Any workflow id in the YAML is
        treated as source context.
      operationId: apply_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/DeclarativeApplyResponse'
        '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.
    DeclarativeApplyResponse:
      properties:
        workflow_id:
          type: string
          title: Workflow Id
        action:
          type: string
          enum:
            - create
            - update
            - noop
          title: Action
        created:
          type: boolean
          title: Created
        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
        - created
        - diagnostics
        - edge_count
        - workflow_id
      title: DeclarativeApplyResponse
      description: >-
        The outcome of applying a workflow YAML definition: whether the workflow
        was `created`, the changes made, and a `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

````