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

> Create a new workflow from a declarative YAML spec.

The workflow id in the YAML is treated as source context, not as the target
workflow id. Use `POST /v1/workflows/{workflow_id}/spec/apply` to modify an
existing workflow draft.

Create a new workflow from a declarative workflow YAML spec.

`apply()` creates a new workflow resource and writes the canonical draft graph represented by the YAML spec. It does not publish. Call the workflow publish method separately when the draft is ready to become the live version.

If the YAML includes `metadata.id`, Retab treats it as source context, not as the target workflow id. To modify an existing workflow, use [Apply Workflow Spec to Existing Workflow](/api-reference/workflows/apply-to).

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

  client = Retab()

  result = client.workflows.apply(yaml_definition)

  print(result.workflow_id)
  print(result.created)
  print(result.summary.has_changes)
  ```

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

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

  const result = await client.workflows.apply(yamlDefinition);

  console.log(result.workflowId);
  console.log(result.created);
  console.log(result.summary.hasChanges);
  ```

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

  import (
  	"context"
  	"fmt"
  	"log"

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

  func ptr[T any](v T) *T { return &v }

  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: wf_invoice_demo
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
            required:
              - value
            properties:
              value:
                type: string
    edges: []
  `
  	result, err := client.Workflows.Apply(ctx, &retab.WorkflowsApplyParams{
  		YamlDefinition: yamlDefinition,
  	})
  	if err != nil {
  		log.Fatal(err)
  	}

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

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

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

  result = client.workflows.apply(yaml_definition: yaml_definition)

  puts result.workflow_id
  puts result.created
  puts result.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: wf_invoice_demo
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
            required:
              - value
            properties:
              value:
                type: string
    edges: []
  "#;
      let result = client
          .workflows()
          .apply(ApplyParams::new(DeclarativeWorkflowRequest::new(
              yaml_definition,
          )))
          .await?;

      println!("{}", result.workflow_id);
      println!("{}", result.created);
      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: wf_invoice_demo
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
            required:
              - value
            properties:
              value:
                type: string
    edges: []
  YAML;

  $result = $client->workflows()->apply(
      yamlDefinition: $yamlDefinition,
  );
  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: wf_invoice_demo
    name: Invoice Workflow
  spec:
    blocks:
      start:
        type: start_json
        label: Input JSON
        config:
          json_schema:
            type: object
            required:
              - value
            properties:
              value:
                type: string
    edges: []
  """;

  var result = await client.Workflows.ApplyAsync(
      new WorkflowsApplyOptions { YamlDefinition = yamlDefinition }
  );
  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: invoice-workflow\n", null, null);
      System.out.println(result);
    }
  }
  ```

  ```curl cURL theme={null}
  curl -X 'POST' \
    'https://api.retab.com/v1/workflows/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: wf_invoice_demo\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          required:\n            - value\n          properties:\n            value:\n              type: string\n  edges: []\n"
    }'
  ```
</RequestExample>

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


## OpenAPI

````yaml POST /v1/workflows/spec/apply
openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
servers:
  - url: https://api.retab.com
security: []
paths:
  /v1/workflows/spec/apply:
    post:
      tags:
        - Workflows
      summary: Apply Workflow Spec
      description: >-
        Create a new workflow from a declarative YAML spec.


        The workflow id in the YAML is treated as source context, not as the
        target

        workflow id. Use `POST /v1/workflows/{workflow_id}/spec/apply` to modify
        an

        existing workflow draft.
      operationId: apply_workflow_spec
      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

````