# Create workflow

POST https://app.launchdarkly.com/api/v2/projects/{projectKey}/flags/{featureFlagKey}/environments/{environmentKey}/workflows
Content-Type: application/json

> ### Workflows are in maintenance mode
>
> The workflows feature is in maintenance mode, and is planned for future deprecation at a date not yet specified. We will work with existing customers using workflows to migrate to a replacement solution when deprecation occurs.

Create a workflow for a feature flag. You can create a workflow directly, or you can apply a template to create a new workflow.

### Creating a workflow

You can use the create workflow endpoint to create a workflow directly by adding a `stages` array to the request body.

For each stage, define the `name`, `conditions` when the stage should be executed, and `action` that describes the stage. For approval stages, only standard LaunchDarkly approvals are permitted. Workflows of `kind` `integration-approval` cannot be used for custom workflows. 

<details>
<summary>Click to expand example</summary>

_Example request body_
```json
{
  "name": "Progressive rollout starting in two days",
  "description": "Turn flag targeting on and increase feature rollout in 10% increments each day",
  "stages": [
    {
      "name": "10% rollout on day 1",
      "conditions": [
        {
          "kind": "schedule",
          "scheduleKind": "relative", // or "absolute"
              //  If "scheduleKind" is "absolute", set "executionDate";
              // "waitDuration" and "waitDurationUnit" will be ignored
          "waitDuration": 2,
          "waitDurationUnit": "calendarDay"
        },
        {
          "kind": "ld-approval",
          "notifyMemberIds": [ "507f1f77bcf86cd799439011" ],
          "notifyTeamKeys": [ "team-key-123abc" ]
        }
      ],
      "action": {
        "instructions": [
          {
            "kind": "turnFlagOn"
          },
          {
            "kind": "updateFallthroughVariationOrRollout",
            "rolloutWeights": {
              "452f5fb5-7320-4ba3-81a1-8f4324f79d49": 90000,
              "fc15f6a4-05d3-4aa4-a997-446be461345d": 10000
            }
          }
        ]
      }
    }
  ]
}
```
</details>

### Creating a workflow by applying a workflow template

You can also create a workflow by applying a workflow template. If you pass a valid workflow template key as the `templateKey` query parameter with the request, the API will attempt to create a new workflow with the stages defined in the workflow template with the corresponding key.

#### Applicability of stages
Templates are created in the context of a particular flag in a particular environment in a particular project. However, because workflows created from a template can be applied to any project, environment, and flag, some steps of the workflow may need to be updated in order to be applicable for the target resource.

You can pass a `dryRun` query parameter to tell the API to return a report of which steps of the workflow template are applicable in the target project/environment/flag, and which will need to be updated. When the `dryRun` query parameter is present the response body includes a `meta` property that holds a list of parameters that could potentially be inapplicable for the target resource. Each of these parameters will include a `valid` field. You will need to update any invalid parameters in order to create the new workflow. You can do this using the `parameters` property, which overrides the workflow template parameters.

#### Overriding template parameters
You can use the `parameters` property in the request body to tell the API to override the specified workflow template parameters with new values that are specific to your target project/environment/flag.

<details>
<summary>Click to expand example</summary>

_Example request body_
```json
{
	"name": "workflow created from my-template",
	"description": "description of my workflow",
	"parameters": [
		{
			"_id": "62cf2bc4cadbeb7697943f3b",
			"path": "/clauses/0/values",
			"default": {
				"value": ["updated-segment"]
			}
		},
		{
			"_id": "62cf2bc4cadbeb7697943f3d",
			"path": "/variationId",
			"default": {
				"value": "abcd1234-abcd-1234-abcd-1234abcd12"
			}
		}
	]
}
```
</details>

If there are any steps in the template that are not applicable to the target resource, the workflow will not be created, and the `meta` property will be included in the response body detailing which parameters need to be updated.


Reference: https://launchdarkly.com/docs/api/workflows/post-workflow

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: LaunchDarkly REST API
  version: 1.0.0
paths:
  /api/v2/projects/{projectKey}/flags/{featureFlagKey}/environments/{environmentKey}/workflows:
    post:
      operationId: post-workflow
      summary: Create workflow
      description: "> ### Workflows are in maintenance mode\n>\n> The workflows feature is in maintenance mode, and is planned for future deprecation at a date not yet specified. We will work with existing customers using workflows to migrate to a replacement solution when deprecation occurs.\n\nCreate a workflow for a feature flag. You can create a workflow directly, or you can apply a template to create a new workflow.\n\n### Creating a workflow\n\nYou can use the create workflow endpoint to create a workflow directly by adding a `stages` array to the request body.\n\nFor each stage, define the `name`, `conditions` when the stage should be executed, and `action` that describes the stage. For approval stages, only standard LaunchDarkly approvals are permitted. Workflows of `kind` `integration-approval` cannot be used for custom workflows. \n\n<details>\n<summary>Click to expand example</summary>\n\n_Example request body_\n```json\n{\n  \"name\": \"Progressive rollout starting in two days\",\n  \"description\": \"Turn flag targeting on and increase feature rollout in 10% increments each day\",\n  \"stages\": [\n    {\n      \"name\": \"10% rollout on day 1\",\n      \"conditions\": [\n        {\n          \"kind\": \"schedule\",\n          \"scheduleKind\": \"relative\", // or \"absolute\"\n              //  If \"scheduleKind\" is \"absolute\", set \"executionDate\";\n              // \"waitDuration\" and \"waitDurationUnit\" will be ignored\n          \"waitDuration\": 2,\n          \"waitDurationUnit\": \"calendarDay\"\n        },\n        {\n          \"kind\": \"ld-approval\",\n          \"notifyMemberIds\": [ \"507f1f77bcf86cd799439011\" ],\n          \"notifyTeamKeys\": [ \"team-key-123abc\" ]\n        }\n      ],\n      \"action\": {\n        \"instructions\": [\n          {\n            \"kind\": \"turnFlagOn\"\n          },\n          {\n            \"kind\": \"updateFallthroughVariationOrRollout\",\n            \"rolloutWeights\": {\n              \"452f5fb5-7320-4ba3-81a1-8f4324f79d49\": 90000,\n              \"fc15f6a4-05d3-4aa4-a997-446be461345d\": 10000\n            }\n          }\n        ]\n      }\n    }\n  ]\n}\n```\n</details>\n\n### Creating a workflow by applying a workflow template\n\nYou can also create a workflow by applying a workflow template. If you pass a valid workflow template key as the `templateKey` query parameter with the request, the API will attempt to create a new workflow with the stages defined in the workflow template with the corresponding key.\n\n#### Applicability of stages\nTemplates are created in the context of a particular flag in a particular environment in a particular project. However, because workflows created from a template can be applied to any project, environment, and flag, some steps of the workflow may need to be updated in order to be applicable for the target resource.\n\nYou can pass a `dryRun` query parameter to tell the API to return a report of which steps of the workflow template are applicable in the target project/environment/flag, and which will need to be updated. When the `dryRun` query parameter is present the response body includes a `meta` property that holds a list of parameters that could potentially be inapplicable for the target resource. Each of these parameters will include a `valid` field. You will need to update any invalid parameters in order to create the new workflow. You can do this using the `parameters` property, which overrides the workflow template parameters.\n\n#### Overriding template parameters\nYou can use the `parameters` property in the request body to tell the API to override the specified workflow template parameters with new values that are specific to your target project/environment/flag.\n\n<details>\n<summary>Click to expand example</summary>\n\n_Example request body_\n```json\n{\n\t\"name\": \"workflow created from my-template\",\n\t\"description\": \"description of my workflow\",\n\t\"parameters\": [\n\t\t{\n\t\t\t\"_id\": \"62cf2bc4cadbeb7697943f3b\",\n\t\t\t\"path\": \"/clauses/0/values\",\n\t\t\t\"default\": {\n\t\t\t\t\"value\": [\"updated-segment\"]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"_id\": \"62cf2bc4cadbeb7697943f3d\",\n\t\t\t\"path\": \"/variationId\",\n\t\t\t\"default\": {\n\t\t\t\t\"value\": \"abcd1234-abcd-1234-abcd-1234abcd12\"\n\t\t\t}\n\t\t}\n\t]\n}\n```\n</details>\n\nIf there are any steps in the template that are not applicable to the target resource, the workflow will not be created, and the `meta` property will be included in the response body detailing which parameters need to be updated.\n"
      tags:
        - subpackage_workflows
      parameters:
        - name: projectKey
          in: path
          description: The project key
          required: true
          schema:
            type: string
            format: string
        - name: featureFlagKey
          in: path
          description: The feature flag key
          required: true
          schema:
            type: string
            format: string
        - name: environmentKey
          in: path
          description: The environment key
          required: true
          schema:
            type: string
            format: string
        - name: templateKey
          in: query
          description: The template key to apply as a starting point for the new workflow
          required: false
          schema:
            type: string
            format: string
        - name: dryRun
          in: query
          description: Whether to call the endpoint in dry-run mode
          required: false
          schema:
            type: boolean
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
      responses:
        '201':
          description: Workflow response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomWorkflowOutput'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidRequestErrorRep'
        '401':
          description: Invalid access token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorRep'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenErrorRep'
        '404':
          description: Invalid resource identifier
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundErrorRep'
        '429':
          description: Rate limited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitedErrorRep'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomWorkflowInput'
servers:
  - url: https://app.launchdarkly.com
  - url: https://app.launchdarkly.us
components:
  schemas:
    ObjectId:
      type: string
      title: ObjectId
    ScheduleKind:
      type: string
      title: ScheduleKind
    UnixMillis:
      type: integer
      format: int64
      title: UnixMillis
    DurationUnit:
      type: string
      title: DurationUnit
    FormVariableConfig:
      type: object
      additionalProperties:
        description: Any type
      title: FormVariableConfig
    ConditionKind:
      type: string
      title: ConditionKind
    ConditionInput:
      type: object
      properties:
        scheduleKind:
          $ref: '#/components/schemas/ScheduleKind'
          description: >-
            Whether the scheduled execution of the workflow stage is relative or
            absolute. If relative, the <code>waitDuration</code> and
            <code>waitDurationUnit</code> specify when the execution occurs. If
            absolute, the <code>executionDate</code> specifies when the
            execution occurs.
        executionDate:
          $ref: '#/components/schemas/UnixMillis'
          description: >-
            For workflow stages whose scheduled execution is absolute, the time,
            in Unix milliseconds, when the stage should start.
        waitDuration:
          type: integer
          description: >-
            For workflow stages whose scheduled execution is relative, how far
            in the future the stage should start.
        waitDurationUnit:
          $ref: '#/components/schemas/DurationUnit'
          description: >-
            For workflow stages whose scheduled execution is relative, the unit
            of measure for the <code>waitDuration</code>.
        executeNow:
          type: boolean
          description: Whether the workflow stage should be executed immediately
        description:
          type: string
          description: A description of the approval required for this stage
        notifyMemberIds:
          type: array
          items:
            type: string
          description: >-
            A list of member IDs for the members to request approval from for
            this stage
        notifyTeamKeys:
          type: array
          items:
            type: string
          description: >-
            A list of team keys for the teams to request approval from for this
            stage
        integrationConfig:
          $ref: '#/components/schemas/FormVariableConfig'
          description: >-
            Additional approval request fields for third-party integration
            approval systems. If you are using a third-party integration to
            manage approval requests, these additional fields will be described
            in the <code>manifest.json</code> for that integration, at
            https://github.com/launchdarkly/integration-framework.
        kind:
          $ref: '#/components/schemas/ConditionKind'
          description: >-
            The type of condition to meet before executing this stage of the
            workflow. Use <code>schedule</code> to schedule a workflow stage.
            Use <code>ld-approval</code> to add an approval request to a
            workflow stage.
      title: ConditionInput
    ActionInput:
      type: object
      properties:
        instructions:
          description: >-
            An array of instructions for the stage. Each object in the array
            uses the semantic patch format for updating a feature flag.
      title: ActionInput
    StageInput:
      type: object
      properties:
        name:
          type: string
          description: The stage name
        executeConditionsInSequence:
          type: boolean
          description: Whether to execute the conditions in sequence for the given stage
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/ConditionInput'
          description: An array of conditions for the stage
        action:
          $ref: '#/components/schemas/ActionInput'
          description: >-
            An <code>instructions</code> field containing an array of
            instructions for the stage. Each object in the array uses the
            semantic patch format for updating a feature flag.
      title: StageInput
    CustomWorkflowInput:
      type: object
      properties:
        maintainerId:
          $ref: '#/components/schemas/ObjectId'
          description: The ID of the workflow maintainer. Defaults to the workflow creator.
        name:
          type: string
          description: The workflow name
        description:
          type: string
          description: The workflow description
        stages:
          type: array
          items:
            $ref: '#/components/schemas/StageInput'
          description: A list of the workflow stages
        templateKey:
          type: string
          description: The template key
      required:
        - name
      title: CustomWorkflowInput
    ConflictOutput:
      type: object
      properties:
        stageId:
          type: string
          description: The stage ID
        message:
          type: string
          description: Message about the conflict
      required:
        - stageId
        - message
      title: ConflictOutput
    Link:
      type: object
      properties:
        href:
          type: string
          description: The URL of the link
        type:
          type: string
          description: The type of the link
      title: Link
    ExecutionOutput:
      type: object
      properties:
        status:
          type: string
          description: The status of the execution of this workflow stage
        stopDate:
          $ref: '#/components/schemas/UnixMillis'
          description: Timestamp of when the workflow was completed.
      required:
        - status
      title: ExecutionOutput
    ReviewOutput:
      type: object
      properties:
        _id:
          type: string
        kind:
          type: string
        creationDate:
          $ref: '#/components/schemas/UnixMillis'
        comment:
          type: string
        memberId:
          type: string
        serviceTokenId:
          type: string
      required:
        - _id
        - kind
      title: ReviewOutput
    ConditionOutput:
      type: object
      properties:
        _id:
          type: string
        kind:
          type: string
        _execution:
          $ref: '#/components/schemas/ExecutionOutput'
        scheduleKind:
          $ref: '#/components/schemas/ScheduleKind'
        executionDate:
          $ref: '#/components/schemas/UnixMillis'
        waitDuration:
          type: integer
        waitDurationUnit:
          $ref: '#/components/schemas/DurationUnit'
        description:
          type: string
        notifyMemberIds:
          type: array
          items:
            type: string
        allReviews:
          type: array
          items:
            $ref: '#/components/schemas/ReviewOutput'
        reviewStatus:
          type: string
        appliedDate:
          $ref: '#/components/schemas/UnixMillis'
        creationConfig:
          $ref: '#/components/schemas/FormVariableConfig'
      required:
        - _id
        - _execution
        - description
        - notifyMemberIds
        - allReviews
        - reviewStatus
      title: ConditionOutput
    Instruction:
      type: object
      additionalProperties:
        description: Any type
      title: Instruction
    Instructions:
      type: array
      items:
        $ref: '#/components/schemas/Instruction'
      title: Instructions
    ActionOutput:
      type: object
      properties:
        kind:
          type: string
          description: The type of action for this stage
        instructions:
          $ref: '#/components/schemas/Instructions'
          description: >-
            An array of instructions for the stage. Each object in the array
            uses the semantic patch format for updating a feature flag.
      required:
        - kind
        - instructions
      title: ActionOutput
    StageOutput:
      type: object
      properties:
        _id:
          type: string
          description: The ID of this stage
        name:
          type: string
          description: The stage name
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/ConditionOutput'
          description: An array of conditions for the stage
        action:
          $ref: '#/components/schemas/ActionOutput'
          description: >-
            The type of instruction, and an array of instructions for the stage.
            Each object in the array uses the semantic patch format for updating
            a feature flag.
        _execution:
          $ref: '#/components/schemas/ExecutionOutput'
          description: Details on the execution of this stage
      required:
        - _id
        - conditions
        - action
        - _execution
      title: StageOutput
    RuleClauseOp:
      type: string
      enum:
        - in
        - endsWith
        - startsWith
        - matches
        - contains
        - lessThan
        - lessThanOrEqual
        - greaterThan
        - greaterThanOrEqual
        - before
        - after
        - segmentMatch
        - semVerEqual
        - semVerLessThan
        - semVerGreaterThan
      description: The operator to apply to the given attribute
      title: RuleClauseOp
    RuleClause:
      type: object
      properties:
        attribute:
          type: string
          description: >-
            The attribute the rule applies to, for example, last name or email
            address
        op:
          $ref: '#/components/schemas/RuleClauseOp'
          description: The operator to apply to the given attribute
        negate:
          type: boolean
          description: Whether the operator should be negated
      title: RuleClause
    ParameterDefault:
      type: object
      properties:
        value:
          description: The default value for the given parameter
        booleanVariationValue:
          type: boolean
          description: >-
            Variation value for boolean flags. Not applicable for non-boolean
            flags.
        ruleClause:
          $ref: '#/components/schemas/RuleClause'
          description: Metadata related to add rule instructions
      title: ParameterDefault
    WorkflowTemplateParameter:
      type: object
      properties:
        _id:
          $ref: '#/components/schemas/ObjectId'
          description: The ID of the condition or instruction referenced by this parameter
        path:
          type: string
          description: >-
            The path of the property to parameterize, relative to its parent
            condition or instruction
        default:
          $ref: '#/components/schemas/ParameterDefault'
          description: The default value of the parameter and other relevant metadata
        valid:
          type: boolean
          description: >-
            Whether the default value is valid for the target flag and
            environment
      title: WorkflowTemplateParameter
    WorkflowTemplateMetadata:
      type: object
      properties:
        parameters:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowTemplateParameter'
      title: WorkflowTemplateMetadata
    CustomWorkflowOutput:
      type: object
      properties:
        _id:
          type: string
          description: The ID of the workflow
        _version:
          type: integer
          description: The version of the workflow
        _conflicts:
          type: array
          items:
            $ref: '#/components/schemas/ConflictOutput'
          description: Any conflicts that are present in the workflow stages
        _creationDate:
          $ref: '#/components/schemas/UnixMillis'
          description: Timestamp of when the workflow was created
        _maintainerId:
          type: string
          description: >-
            The member ID of the maintainer of the workflow. Defaults to the
            workflow creator.
        _links:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Link'
          description: The location and content type of related resources
        name:
          type: string
          description: The name of the workflow
        description:
          type: string
          description: A brief description of the workflow
        kind:
          type: string
          description: The kind of workflow
        stages:
          type: array
          items:
            $ref: '#/components/schemas/StageOutput'
          description: >-
            The stages that make up the workflow. Each stage contains conditions
            and actions.
        _execution:
          $ref: '#/components/schemas/ExecutionOutput'
          description: The current execution status of the workflow
        meta:
          $ref: '#/components/schemas/WorkflowTemplateMetadata'
          description: >-
            For workflows being created from a workflow template, this value
            holds any parameters that could potentially be incompatible with the
            current project, environment, or flag
        templateKey:
          type: string
          description: >-
            For workflows being created from a workflow template, this value is
            the template's key
      required:
        - _id
        - _version
        - _conflicts
        - _creationDate
        - _maintainerId
        - _links
        - name
        - _execution
      title: CustomWorkflowOutput
    InvalidRequestErrorRep:
      type: object
      properties:
        code:
          type: string
          description: Specific error code encountered
        message:
          type: string
          description: Description of the error
      required:
        - code
        - message
      title: InvalidRequestErrorRep
    UnauthorizedErrorRep:
      type: object
      properties:
        code:
          type: string
          description: Specific error code encountered
        message:
          type: string
          description: Description of the error
      required:
        - code
        - message
      title: UnauthorizedErrorRep
    ForbiddenErrorRep:
      type: object
      properties:
        code:
          type: string
          description: Specific error code encountered
        message:
          type: string
          description: Description of the error
      required:
        - code
        - message
      title: ForbiddenErrorRep
    NotFoundErrorRep:
      type: object
      properties:
        code:
          type: string
          description: Specific error code encountered
        message:
          type: string
          description: Description of the error
      required:
        - code
        - message
      title: NotFoundErrorRep
    RateLimitedErrorRep:
      type: object
      properties:
        code:
          type: string
          description: Specific error code encountered
        message:
          type: string
          description: Description of the error
      required:
        - code
        - message
      title: RateLimitedErrorRep
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: Authorization

```

## SDK Code Examples

```python
import requests

url = "https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows"

payload = {
    "name": "Progressive rollout starting in two days",
    "description": "Turn flag on for 10% of customers each day",
    "stages": [
        {
            "name": "10% rollout on day 1",
            "conditions": [
                {
                    "scheduleKind": "relative",
                    "waitDuration": 2,
                    "waitDurationUnit": "calendarDay",
                    "kind": "schedule"
                }
            ],
            "action": {}
        }
    ]
}
headers = {
    "Authorization": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows';
const options = {
  method: 'POST',
  headers: {Authorization: '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"name":"Progressive rollout starting in two days","description":"Turn flag on for 10% of customers each day","stages":[{"name":"10% rollout on day 1","conditions":[{"scheduleKind":"relative","waitDuration":2,"waitDurationUnit":"calendarDay","kind":"schedule"}],"action":{}}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows"

	payload := strings.NewReader("{\n  \"name\": \"Progressive rollout starting in two days\",\n  \"description\": \"Turn flag on for 10% of customers each day\",\n  \"stages\": [\n    {\n      \"name\": \"10% rollout on day 1\",\n      \"conditions\": [\n        {\n          \"scheduleKind\": \"relative\",\n          \"waitDuration\": 2,\n          \"waitDurationUnit\": \"calendarDay\",\n          \"kind\": \"schedule\"\n        }\n      ],\n      \"action\": {}\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"Progressive rollout starting in two days\",\n  \"description\": \"Turn flag on for 10% of customers each day\",\n  \"stages\": [\n    {\n      \"name\": \"10% rollout on day 1\",\n      \"conditions\": [\n        {\n          \"scheduleKind\": \"relative\",\n          \"waitDuration\": 2,\n          \"waitDurationUnit\": \"calendarDay\",\n          \"kind\": \"schedule\"\n        }\n      ],\n      \"action\": {}\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows")
  .header("Authorization", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"Progressive rollout starting in two days\",\n  \"description\": \"Turn flag on for 10% of customers each day\",\n  \"stages\": [\n    {\n      \"name\": \"10% rollout on day 1\",\n      \"conditions\": [\n        {\n          \"scheduleKind\": \"relative\",\n          \"waitDuration\": 2,\n          \"waitDurationUnit\": \"calendarDay\",\n          \"kind\": \"schedule\"\n        }\n      ],\n      \"action\": {}\n    }\n  ]\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows', [
  'body' => '{
  "name": "Progressive rollout starting in two days",
  "description": "Turn flag on for 10% of customers each day",
  "stages": [
    {
      "name": "10% rollout on day 1",
      "conditions": [
        {
          "scheduleKind": "relative",
          "waitDuration": 2,
          "waitDurationUnit": "calendarDay",
          "kind": "schedule"
        }
      ],
      "action": {}
    }
  ]
}',
  'headers' => [
    'Authorization' => '<apiKey>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"Progressive rollout starting in two days\",\n  \"description\": \"Turn flag on for 10% of customers each day\",\n  \"stages\": [\n    {\n      \"name\": \"10% rollout on day 1\",\n      \"conditions\": [\n        {\n          \"scheduleKind\": \"relative\",\n          \"waitDuration\": 2,\n          \"waitDurationUnit\": \"calendarDay\",\n          \"kind\": \"schedule\"\n        }\n      ],\n      \"action\": {}\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "name": "Progressive rollout starting in two days",
  "description": "Turn flag on for 10% of customers each day",
  "stages": [
    [
      "name": "10% rollout on day 1",
      "conditions": [
        [
          "scheduleKind": "relative",
          "waitDuration": 2,
          "waitDurationUnit": "calendarDay",
          "kind": "schedule"
        ]
      ],
      "action": []
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://app.launchdarkly.com/api/v2/projects/projectKey/flags/featureFlagKey/environments/environmentKey/workflows")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```