Skip to content
Latchkey

How to Trigger a Workflow From an External Webhook in GitHub Actions

Not every trigger is a push or a tag; sometimes a deploy tool or SaaS event needs to kick off CI from the outside.

Listen for repository_dispatch with a chosen event_type, then have the external system POST to the dispatches endpoint with a PAT.

Steps

  • Add an on: repository_dispatch trigger with the event types you accept.
  • Create a token with repo scope for the caller to authenticate with.
  • POST to /repos/OWNER/REPO/dispatches with an event_type that matches.
  • Read the dispatched data inside the workflow from the event payload.

Workflow

.github/workflows/external-trigger.yml
name: External Trigger
on:
  repository_dispatch:
    types: [deploy-requested]
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - run: echo "triggered by ${{ github.event.action }}"
# Caller:
# curl -XPOST -H "Authorization: token $TOKEN" \
#   https://api.github.com/repos/OWNER/REPO/dispatches \
#   -d '{"event_type":"deploy-requested"}'

Notes

  • repository_dispatch always runs on the default branch, so versioned logic must live there.
  • Latchkey managed runners pick up these externally triggered jobs cheaper and self-heal on runner loss.

Verify it actually works

A workflow that runs is not a workflow that works. Confirm the behaviour on a real event rather than on a manual dispatch, because trigger conditions, permissions, and context values all differ between the two.

Terminal
# 1. validate the file before pushing
docker run --rm -v "$(pwd):/repo" --workdir /repo rhysd/actionlint:latest -color

# 2. trigger the real event, not workflow_dispatch
git commit --allow-empty -m "ci: verify trigger" && git push

# 3. watch it and read the conclusion, not just the colour
gh run watch
gh run view --log-failed

What usually goes wrong first

  • The workflow file must exist on the default branch before scheduled or dispatch triggers appear at all.
  • GITHUB_TOKEN permissions default to read-only in many organisations. Declare a permissions: block listing every scope the job needs.
  • Fork pull requests get a read-only token and no access to secrets, regardless of workflow configuration.
  • actions/checkout gives you depth 1 on a detached HEAD, so anything needing history or a branch name needs fetch-depth: 0.

Frequently asked questions

How do I trigger a Workflow From an External Webhook in GitHub Actions?
Listen for repository_dispatch with a chosen event_type, then have the external system POST to the dispatches endpoint with a PAT.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card