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

# Create a review workflow in Box Automate with Slack notifications

> Build a review workflow with Box Automate that routes files through approval tasks, sends notifications in Box, and posts updates to a Slack channel using HTTPS Request outcomes.

export const RelatedLinks = ({title, items = []}) => {
  const getBadgeClass = badge => {
    if (!badge) return "badge-default";
    const badgeType = badge.toLowerCase().replace(/\s+/g, "-");
    return `badge-${badge === "ガイド" ? "guide" : badgeType}`;
  };
  if (!items || items.length === 0) {
    return null;
  }
  return <div className="my-8">
      {}
      <h3 className="text-sm font-bold uppercase tracking-wider mb-4">{title}</h3>

      {}
      <div className="flex flex-col gap-3">
        {items.map((item, index) => <a key={index} href={item.href} className="py-2 px-3 rounded related_link hover:bg-[#f2f2f2] dark:hover:bg-[#111827] flex items-center gap-3 group no-underline hover:no-underline border-b-0">
            {}
            <span className={`px-2 py-1 rounded-full text-xs font-semibold uppercase tracking-wide flex-shrink-0 ${getBadgeClass(item.badge)}`}>
              {item.badge}
            </span>

            {}
            <span className="text-base">{item.label}</span>
          </a>)}
      </div>
    </div>;
};

export const Link = ({href, children, className, ...props}) => {
  const localizedHref = localizeLink(href);
  return <a href={localizedHref} className={className} {...props}>
      {children}
    </a>;
};

Routing documents through reviewers and approvers usually means juggling email threads, chat messages, and spreadsheets to track who has signed off. Missed notifications stall the process, and there is no single audit trail.

This tutorial builds a review workflow in Box Automate that eliminates that manual coordination. When a file is uploaded, moved, or copied into a folder, the workflow assigns a review task, routes the file through approval, and posts status updates to both Box and Slack.

## What you are building

By the end of this tutorial, you have a working Box Automate workflow that:

* Triggers when a file is uploaded, moved, or copied into a designated folder.
* Assigns a General Task to a reviewer for initial review.
* Routes the file through an Approval Task with separate branches for approved and rejected outcomes.
* Sends HTTPS requests on both branches for downstream system integration.
* Merges the branches and sends a final Box notification summarizing the result.
* Posts updates to a Slack channel using the Slack Web API.

## Prerequisites

Before you start, make sure you have the following:

* A <Link href="https://www.box.com/pricing">Box Enterprise account</Link> with an Advanced plan (required for HTTPS Request outcomes).
* Box Automate enabled in the <Link href="https://support.box.com/hc/en-us/articles/51190675028499-Enabling-Box-Automate"> Admin Console</Link>.
* A Slack workspace where you can <Link href="https://api.slack.com/apps/">install apps</Link> (for the Slack integration section).
* Permission to add connectors in the Box Admin Console.

## Post Slack updates with HTTPS Request

Within the workflow, you can use Box Automate's HTTPS Request outcome to post messages to a Slack channel through Slack's `chat.postMessage` API. This section shows you how to set up the Slack app, allow-list the connector in Box, and configure the request.

<Warning>
  You need workspace admin access in Slack and Admin Console access in Box to complete this setup.
</Warning>

### Create and configure the Slack app

<Steps>
  <Step title="Create the Slack app">
    1. Go to [Slack API: Your Apps](https://api.slack.com/apps) and sign in.
    2. Select **Create New App** > **From scratch**.
    3. Enter an app name and select your workspace, then select **Create App**.
  </Step>

  <Step title="Add bot token scopes">
    1. In your app, open **OAuth & Permissions**.
    2. Under **Scopes** > **Bot Token Scopes**, add `chat:write`.
    3. Optional: add `chat:write.public` to post in public channels without inviting the bot.

    <Tip>
      Inviting `@YourBot` to each channel is clearer than relying on `chat:write.public`.
    </Tip>
  </Step>

  <Step title="Install the app and copy the token">
    1. Select **Install to Workspace**. Reinstall after any scope change.
    2. Open **Basic Information** > **App-Level Tokens** and generate or open a token.
    3. Copy the **Bot User OAuth Token** (begins with `xoxb-`).
    4. For private channels, run `/invite @YourBotName` in the channel.
  </Step>

  <Step title="Allow-list Slack in the Box Admin Console">
    1. In the Box Admin Console, confirm that Box Automate and HTTPS Request outcomes are enabled for builders.
    2. Go to **Integrations** > **Connectors**.
    3. Add `https://slack.com` as an allowed connector.
    4. Select **Save**.

    <Note>
      If builders cannot add connectors, ask an admin to pre-create a Slack Web API connector for `slack.com`.
    </Note>
  </Step>
</Steps>

## Build the review workflow

Next, build the review workflow. This workflow triggers when a file is uploaded, moved, or copied into a designated folder. It assigns a review task to a reviewer, routes the file through an approval process, and posts status updates to both Box and Slack.

<Steps>
  <Step title="Open the Box Automate builder">
    In the Box end-user view, open the Box Automate builder and select **New +** to start a new workflow. Name the workflow in the header – for example, `Document Review Pipeline`.
  </Step>

  <Step title="Add the trigger">
    From the **Flow Triggers** section in the side panel, drag a **File** trigger onto the canvas. Configure the trigger to start the workflow when a file is:

    * Uploaded
    * Moved
    * Copied
      Then select the folder to trigger the workflow.
  </Step>

  <Step title="Add the General Task outcome">
    Select the **+** helper node after the trigger. From the side panel, add a **General Task** outcome. Assign the task to the appropriate reviewer and set any required instructions or due dates.
  </Step>

  <Step title="Add the Approval Task">
    After the General Task, select the **+** helper node and add an **Approval Task** outcome. Assign the approver(s) and select the file used to trigger the workflow.

    <Tip>
      One common scenario for assignees is the workflow starter and one specified reviewer to approve the file changes.
    </Tip>

    The Approval Task automatically creates two branches: **Approved** and **Rejected**.
  </Step>

  <Step title="Configure the Approved and Rejected branches">
    Select the **+** node after the Approval Task and add a **HTTPS Request** outcome. Configure the endpoint and payload that should run when the file is approved or rejected.

    | Field              | Value                                                                                     |
    | ------------------ | ----------------------------------------------------------------------------------------- |
    | **Connector**      | `slack.com`                                                                               |
    | **Endpoint**       | `/api/chat.postMessage`                                                                   |
    | **HTTPS Method**   | `POST`                                                                                    |
    | **Authentication** | Custom Header                                                                             |
    | **Credentials**    | Key: `Authorization`, Value: `Bearer <your token>` (generated in the Slack app dashboard) |

    Set the request body to:

    ```json theme={null}
    {
      "channel": "box-announcements",
      "markdown_text": "Box Automate: {{workflow.name}} has completed with status {{workflow.status}}. The file {{file.name}} was {{file.status}}."
    }
    ```

    Replace `box-announcements` with your channel name or ID. For production, drive the message text from workflow variables using the Automate variable picker or `/` search.

    <Tip>
      For richer messages, add `blocks` ([Block Kit](https://api.slack.com/block-kit)), `thread_ts` for replies, or `username` and `icon_emoji` overrides where Slack permits.
    </Tip>

    **Test the request**

    Test the HTTPS request directly in the Box Automate builder before publishing the workflow:

    1. In the **HTTPS Request** outcome configuration panel, enter the connector, endpoint, method, headers, and request body.
    2. Select **Test** at the bottom of the panel to send a test request to Slack.
    3. Review the response in the panel:

    * **Success**: Status code `200` with `"ok": true`. The response payload returns message details, including `ts` and `channel`.
    * **Failure**: If `"ok": false`, review the `error` property returned by Slack (such as `invalid_auth`, `channel_not_found`, or `missing_scope`).
  </Step>

  <Step title="Capture the response with JSONPath">
    The results of the `chat.postMessage` from Slack are a JSON payload which are not usable by Box Automate until you pull individual values out of it. JSONPath expressions point at the specific properties you need, so you can store them as workflow variables:

    | Variable   | JSONPath | Meaning                                                                                   |
    | ---------- | -------- | ----------------------------------------------------------------------------------------- |
    | `slack_ts` | `$.ts`   | Message timestamp. Pass as `thread_ts` in a follow-up HTTPS request to reply in a thread. |
    | `slack_ok` | `$.ok`   | Success flag.                                                                             |
  </Step>

  <Step title="Merge the branches">
    Use the **Merge** option to combine the Approved and Rejected branches back into a single path.
  </Step>

  <Step title="Add final outcomes">
    After the merge point, add a **Send Notification** outcome. Customize the recipients, subject line, and message body, using variables to include workflow details such as the file name or initiator.

    Select the **+** node after the notification and add a final **HTTPS Request** outcome to complete any downstream system action.
  </Step>

  <Step title="Save and publish">
    Select **Save** to create a draft of the workflow. Once complete, select **Publish** to validate and activate it.

    <Note>
      Box Automate does not execute workflow actions as the user who created the workflow. Enterprise-level and folder-level restrictions still apply to every step in the workflow.
    </Note>
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Workflow does not trigger when a file is uploaded">
    Confirm the workflow is published, not just saved as a draft. A saved workflow does not execute. Also verify the trigger folder matches the folder you are uploading to – subfolders are not included unless the trigger is configured to monitor them.
  </Accordion>

  <Accordion title="Slack message is not posted (HTTPS Request returns an error)">
    Check the HTTPS Request response in the workflow run details:

    * `invalid_auth` or `not_authed`: the Bot User OAuth Token is missing, expired, or incorrectly formatted. Regenerate the token in the Slack app dashboard and update the `Authorization` header value to `Bearer xoxb-...`.
    * `channel_not_found`: the channel name or ID is incorrect, or the bot has not been invited. Run `/invite @YourBotName` in the target channel.
    * `missing_scope`: the bot token is missing the `chat:write` scope. Add the scope under **OAuth & Permissions** and reinstall the app to your workspace.
  </Accordion>

  <Accordion title="HTTPS Request outcome is not available in the builder">
    HTTPS Request outcomes require a Box Enterprise Advanced plan. Confirm your plan supports this feature and that an admin has enabled HTTPS Request outcomes for builders in the Admin Console.
  </Accordion>

  <Accordion title="Connector blocked or not listed">
    The `slack.com` connector must be allow-listed in the Admin Console under **Integrations** > **Connectors**. If you do not see the option to add connectors, ask a Box admin to pre-create a Slack Web API connector for `slack.com`.
  </Accordion>

  <Accordion title="Task is not assigned or the assignee does not receive it">
    Verify the assignee is a valid, active Box user in the same enterprise. If the user is external, they must be invited as a collaborator on the file or folder before a task can be assigned to them.
  </Accordion>

  <Accordion title="Workflow publishes but actions do not execute">
    Box Automate enforces enterprise-level and folder-level restrictions on every step. If a workflow action targets content the service context does not have access to, that step fails without notification. Verify the target folders and files are accessible and that the required permissions (such as task assignment or notification delivery) are not restricted by Admin Console policies.
  </Accordion>
</AccordionGroup>

## Next steps

Using Box Automate to configure your review processes keeps you on track with notifications in both Box and Slack. While this example covers a single approval flow, you can use it as a template for different iterations – using the HTTPS Request outcome at every action, in just one place, or even combining it with other outcomes such as Box Sign. You can also begin with a File Request trigger to start the workflow.

<CardGroup cols={2}>
  <Card title="Invoice intake automation" href={localizeLink("/tutorials/invoice-intake")} icon="file-invoice" arrow="true">
    Automate accounts payable with Box AI Extract, metadata, and webhooks.
  </Card>

  <Card title="Sales RFP answer bank" href={localizeLink("/tutorials/sales-rfp-answer-bank")} icon="magnifying-glass" arrow="true">
    Build an AI-powered knowledge base for sales teams using Box Hubs and Box AI.
  </Card>
</CardGroup>

<RelatedLinks
  title="RELATED GUIDES"
  items={[
{ label: translate("Box Automate overview"), href: "/guides/box-automate/index", badge: "GUIDE" },
{ label: translate("Get started with Box Automate"), href: "/guides/box-automate/getting-started-box-automate", badge: "GUIDE" },
{ label: translate("Triggers, actions, and logic in Box Automate"), href: "/guides/box-automate/triggers-and-logic", badge: "GUIDE" }
]}
/>
