To create an action that merchants can use in their workflows, you need to add the action to your app. The action needs to contain the following information:

- The fields that the merchant needs to complete when they add the action to their workflows
- The URL that Shopify Flow uses to send (POST) the contents (JSON payload) of the action to your app

You also need to configure your app to process the data from the POST request when it arrives and to send status codes back to Shopify Flow.

To enhance the merchant experience and more closely integrate external systems, you can also [build a custom configuration page](/docs/apps/build/flow/actions/build-config-ui). To improve the reliability of your action, you can add [custom validation](/docs/apps/build/flow/actions/endpoints#custom-validation) for action properties.

## Requirements

- You have the following:
  - A test web server that has access to the Internet, so that it can receive POST requests from Shopify Flow
  - A test app that works with the test web server
  - A development store that has [Shopify Flow](https://apps.shopify.com/flow) and the test app installed

## Step 1: Create a Flow Action

To give your Flow action a meaningful name, use the following guidelines:

- Use a present-tense verb + object acted on format. For example, `Place auction bid`.
- Use sentence case.
- Don't use punctuation.
- Separate words using spaces.

### Using Shopify CLI

Use the Shopify CLI to generate a new extension:

1. Navigate to your app directory.
2. Run the following command:

<p>
<div class="react-code-block" data-preset="terminal">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="bash">
RAW_MD_CONTENT#!/bin/bash
shopify app generate extension
END_RAW_MD_CONTENT</script>

</div>
</p>


3. Select the `Flow Action` as the type of extension.
4. Provide a meaningful name for your extension.
<br>


After you've followed the prompts, Shopify CLI generates the extension’s file representation in your app's `/extensions` directory and gives you a success message. You can then go into your app's `/extensions` directory and start editing your new extension.

The file structure of your extension should look like the following:

```
/place-auction-bid
  shopify.extension.toml
```

To learn more about the extensions file structure, refer to [App structure](/docs/apps/build/cli-for-apps/app-structure) and the documentation for your extension type.

### Using the Partner Dashboard

1. In your Partner Dashboard, click [Apps](https://partners.shopify.com/current/apps).
2. Select the app that you want to add your Shopify Flow action to.
3. Click **Extensions**, then click **Create** or **Create extension**.
4. Under the **Flow** tab, click **Flow/Actions**.
5. In the **Extension name** field, name your action, such as `Place auction bid`. This name is used only for internal purposes.
6. Enter a title and description for the action. In the **Action Preview** area, you can see how the title and action display to merchants when they're choosing actions in Shopify Flow.
7. Enter the URL for the action execution endpoint that you created. Shopify Flow sends the action's JSON payload to this endpoint when it's about to execute your action.

## Step 2: Customize a Flow action configuration file

In this section you'll use the default action template and update it to be a functional extension example. Once you have generated a Flow extension using Shopify CLI, follow the instructions below:

1. Change the description to `Place a bid on an auction`.
2. Update the `extensions.runtime_url` to an endpoint where you can receive the runtime request.
3. On the second `settings.fields` field, update the following values:
  - `type` to `number_decimal`
  - `key` to `amount`
  - `name` to `Bid Amount`
  - Add a `description` property and set it to `The amount of the bid`

<p>
<div class="react-code-block" data-preset="file">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="bash" data-title="toml">
RAW_MD_CONTENT[[extensions]]
name = "Place Auction Bid"
type = "flow_action"
handle = "place-bid"
description = "Place a bid on an auction"
runtime_url = "https://your-server-domain/path/to/action/handler"

[settings]

  [[settings.fields]]
  type = "customer_reference"
  required = true

  [[settings.fields]]
  type = "number_decimal"
  key = "amount"
  name = "Bid Amount"
  description = "The amount of the bid"
  required = true
END_RAW_MD_CONTENT</script>

</div>
</p>


## Step 3: Configure your web server

To build a Shopify Flow action, you need to add a service to your web server to listen for the JSON payload that Shopify Flow sends when the action runs.

Optionally, you can also add the following:

- An endpoint to validate actions
- A [custom configuration page](/docs/apps/build/flow/actions/build-config-ui), and an endpoint that lets merchants preview your custom configuration page

Add the following API endpoints to your server:

| Endpoint | Purpose |
| --- | --- |
| [Flow action execution](/docs/apps/flow/actions/endpoints#flow-action-execution) | The endpoint where the automation tool sends your action's payload. The payload contains data that you can use to execute the action in your app.|
| [Custom configuration page preview](/docs/apps/flow/actions/endpoints#custom-configuration-page-preview) | An endpoint that provides data about your [custom configuration page](/docs/apps/build/flow/actions/build-config-ui) to display in the automation tool. This endpoint is required if you want to use a custom configuration page.|
| [Custom validation](/docs/apps/flow/actions/endpoints#custom-validation) | An endpoint that validates the contents of merchant-configurable properties in an action payload when an action is saved. This endpoint is required if you want to use a custom configuration page.|



To learn more about the endpoint requirements for your server, refer to [Action endpoints](/docs/apps/build/flow/actions/endpoints).

To learn how to create a custom configuration page, refer to [Build a custom configuration page](/docs/apps/build/flow/actions/build-config-ui).

## Step 4: Enable the draft version of your action

Running [`app dev`](/docs/api/shopify-cli/app/app-dev) allows changes made to local files to update the draft version of your Flow task extensions. The draft version is only available in your development store.

> Note:
> When [`app dev`](/docs/api/shopify-cli/app/app-dev) is running and "Development store preview" is enabled, the draft version of a task will appear in your development store _in place_ of the deployed version. Other shops will continue to see the deployed version of your task (if one exists). Draft versions can be identified by the "draft" badge. To see the deployed version of the task in your development store, turn off "Development store preview" in the "Extensions" section of your app in [Shopify Partners](https://partners.shopify.com/).

1. Navigate to your app directory.
2. Run the following command to start using draft versions of your extension(s):

```bash
#!/bin/bash
shopify app dev
```

3. Follow the prompts.


## Step 5: Test the action

After you've created an action in the Partner Dashboard and added support for it in your web server, you can test the action in Shopify Flow on your development store.

1. In your development store, create a [workflow](https://www.shopify.com/admin/apps/flow) that uses the action. For example, add the trigger that you created in the [Triggers guide](/docs/apps/build/flow/triggers/create) and this action to a workflow.

2. If you created a custom configuration page, then ensure that the preview displays and that the custom configuration page is accessible.

3. If you added any custom validation, then ensure that it works as expected.

4. Trigger the workflow. For example, in your web server, run the event that sends the trigger information to Shopify Flow.

When the workflow completes, your web server has sent data to Shopify Flow because of the trigger. Shopify Flow has sent this data to a web server that logged the information to its console because of the action.

## Step 6: Deploy your extension

> Note:
> Deploying extensions using the `app deploy` command also publishes the extensions. We recommend testing changes by using [`app dev`](/docs/api/shopify-cli/app/app-dev) or deploying to a test app before deploying them to a production app.

Use Shopify CLI to deploy your extensions:

1. Navigate to your app directory.
2. Run the following command to start deploying your extension(s):

```bash
#!/bin/bash
shopify app deploy
```

3. Follow the prompts.

When you receive confirmation that the deploy was successful, your extensions have been released.


## Verifying requests

For security reasons, make sure that you verify the following elements in each request:

- The POST request's HMAC header (either `x-shopify-hmac-sha256` or `http-x-shopify-hmac-sha256`). The HMAC header should be verified before you process the payload. For more information, refer to [Verifying requests](/docs/apps/build/flow/actions/endpoints#verifying-requests).
- The payload `handle`. This ID should match the `handle` of the action that you created, and can be retrieved from the payload preview.

## Next steps

- Connect your app to Shopify Flow so that events that occur in your app can [trigger workflows](/docs/apps/build/flow/triggers).
- Learn how to receive [lifecycle events from Shopify Flow](/docs/apps/build/flow/track-lifecycle-events) about the stores that are using your triggers in enabled workflows.
- Learn more about how to [return complex data](/docs/apps/build/flow/configure-complex-data-types) in a Flow action.