Workflow Dispatch

workflow_dispatch is the GitHub Actions trigger that starts a workflow run on demand from the Actions tab, the GitHub CLI, or the REST API, with typed inputs.

workflow_dispatch is the GitHub Actions trigger that lets a person or an API call start a workflow run on demand, instead of the run waiting for a push, a pull request, or a schedule. A workflow that declares the trigger can be started from the repository's Actions tab, from the GitHub CLI, or through the REST API, and it accepts typed inputs that the workflow file declares up front.

The manual path and the programmatic path are the same event. However the run starts, GitHub sets github.event_name to workflow_dispatch and hands the job the input values that were supplied.

Definition

The trigger is declared under the on key, and declaring it on its own is enough to make a workflow dispatchable:

on:
  workflow_dispatch:

Inputs are optional and live under on.workflow_dispatch.inputs. Each input has an id, and under that id you set some combination of description, required, default, and type. The documented types include string, boolean, choice (which also takes an options list), and environment. GitHub caps the block at 25 top-level properties under inputs, with a maximum input payload of 65,535 characters (events that trigger workflows, checked on 2026-08-13).

Three rules decide whether a dispatch works at all.

The workflow file must be on the default branch. GitHub states that "to trigger the workflow_dispatch event, your workflow must be in the default branch" (manually run a workflow, checked on 2026-08-13). A workflow that adds the trigger on a feature branch shows no Run workflow button until the branch merges, which is the usual reason a correct-looking file appears to do nothing.

Every dispatch names a git reference. The REST endpoint takes a ref parameter, described in the API reference as "the git reference for the workflow. The reference can be a branch or tag name" (REST API endpoints for workflows, checked on 2026-08-13). The Actions tab exposes the same choice as a branch picker beside the Run workflow button.

Input values arrive in two contexts with different typing. GitHub documents that "the information in the inputs context and github.event.inputs context is identical except that the inputs context preserves Boolean values as Booleans instead of converting them to strings" (events that trigger workflows, checked on 2026-08-13). A condition written against github.event.inputs therefore compares strings, and the string false is a non-empty string, so it evaluates as true.

The three entry points differ in what they need and in how they carry input values.

Entry pointWhat it needsHow inputs are supplied
Run workflow button in the Actions tabWrite access to the repository in the browserForm fields generated from the inputs block
gh workflow runThe GitHub CLI, authenticated-f key=value flags, or a JSON object on standard input
POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatchesA token with the repo scope for classic tokensAn inputs object in the JSON body, 25 properties maximum

Example

This workflow declares a boolean input and a choice input, then reads both from the inputs context inside the job:

name: Deploy

on:
  workflow_dispatch:
    inputs:
      run_migrations:
        description: Apply pending database migrations before deploying
        type: boolean
        default: false
      target:
        description: Environment to deploy to
        type: choice
        default: staging
        options:
          - staging
          - production

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Apply migrations
        if: ${{ inputs.run_migrations }}
        run: ./scripts/migrate.sh

      - name: Deploy
        run: ./scripts/deploy.sh --target "${{ inputs.target }}"

Once that file is on the default branch, the Actions tab lists the Deploy workflow in the left sidebar with a Run workflow button above the run list. The button opens a small form: a branch picker, a checkbox for run_migrations, and a dropdown holding the two options values for target.

The same run starts from a script with one API call. Every input value crosses the wire as a string, whatever type the workflow declared:

curl -X POST \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $TOKEN" \
  https://api.github.com/repos/octo-org/octo-repo/actions/workflows/deploy.yml/dispatches \
  -d '{"ref":"main","inputs":{"run_migrations":"true","target":"production"}}'

The GitHub CLI wraps the same endpoint and resolves the workflow by file name:

gh workflow run deploy.yml --ref main -f run_migrations=true -f target=production

The typing difference is where dispatched runs usually go wrong. if: ${{ inputs.run_migrations }} reads a real boolean and skips the step when the box is unticked. Writing if: ${{ github.event.inputs.run_migrations }} instead reads the string false, which is not empty and therefore evaluates as true, so the migration step runs on every dispatch. When a workflow has to read github.event.inputs, compare it explicitly with == 'true'.

Two smaller details are worth pinning down before a dispatch goes into an on-call runbook. Inputs are declared per workflow rather than per job, so a matrix that fans a dispatched run across several jobs passes the same values to all of them. And the run is attributed to the account whose credentials made the call, which is what github.actor reports and what shows in the run header, so a dispatch made with a shared token is harder to trace back to a person than one made from the browser.

FAQ

What does workflow_dispatch do?

workflow_dispatch marks a workflow as startable on demand. Once the trigger is declared, a person can start a run from the Actions tab or the GitHub CLI, and a program can start one through the REST API, passing values for the inputs the workflow file declares.

Why is the Run workflow button missing from my workflow?

GitHub's documentation states that to trigger the workflow_dispatch event, your workflow must be in the default branch. A workflow that declares the trigger on a feature branch shows no button until that branch merges, even though the file is syntactically correct.

How many inputs can a workflow_dispatch workflow take?

GitHub documents a maximum of 25 top-level properties under inputs and a maximum input payload of 65,535 characters. The REST endpoint applies the same 25 property maximum to the inputs object in the request body.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.