Currently, the GitHub UI doesn’t provide any mechanism to manually trigger a GitHub Actions workflow. The exception being that you can re-run a failed workflow.
Recently at Pixite, we created a new GitHub Actions workflow to help update the contents of our app’s home screen on a daily basis. This setup is easy to do with GitHub Actions, and is serving it’s purpose as expected.
However, re ran into the challenge of wanting to run our workflow outside of its pre-scheduled time.
Since there isn’t any means of triggering a workflow from within the current GitHub UI, we had to explore how to manually trigger a GitHub Actions workflow.
Yes. Using the GitHub api, repository dispatch events, and workflow dispatch events.
There are three event types that will trigger your workflow. Webhook events (things like commit and push), scheduled events, and external events via repository dispatch and workflow dispatch events.
Repository Dispatch Events
The solution to this problem comes in the form of sending a repository dispatch event using the GitHub api. The repository_dispatch event is a webhook event which can be treated as a trigger for a GitHub Actions workflow.
By externally triggering a repository_dispatch event, we can run our desired workflow on command.
Scheduling a GitHub Actions workflow
To illustrate how we can manually trigger a GitHub actions workflow, we can walk through a simple example from my sandbox project: https://github.com/n8ebel/GitHubActionsAutomationSandbox
To start, we can define a trivial workflow which prints a message to the terminal. We’ll schedule this workflow to run every 5 minutes.
name: Do Something That Needs Scheduled on: schedule: - cron: '*/5 * * * *' jobs: build: name: Run Some Scheduled Thing runs-on: ubuntu-latest steps: - name: Do Something run: echo Doing Something...
Now, we can walk through the steps for how we can manually trigger this workflow.
Triggering A repository_dispatch Event Using Curl
To manually trigger the repository_dispatch event, we need to interact with the following GitHub api endpoint:
POST /repos/:owner/:repo/dispatches
Using the repository name (GitHubActionsAutomationSandbox), along with my GitHub username (n8ebel), we can build the full path for the endpoint we’ll be interacting with:
https://api.github.com/repos/n8ebel/GitHubActionsAutomationSandbox/dispatches
To make the POST request to this endpoint, we need to do several things:
- Add a custom media type in the Accept header
- Authenticate the call using an Authorization header and a personal access token with repo permissions for the repository we’re working with
- Specify an event_type in the POST body
Adding the custom media type
The following custom media type is required to make the call to the /repos/:owner/:repo/dispatches endpoint:
application/vnd.github.everest-preview+json
To add this to our curl command, we will add an Accept header as follows:
-H "Accept: application/vnd.github.everest-preview+json"
Authenticating the POST request
To authenticate the request, you’ll need to use, or generate, a new personal access token that has access to the repository you’re working with. That token must have the repo scope provided to it.
To understand how to do that, you can follow the steps outlined in the GitHub documentation.
Once you have your token, we’ll update our curl command by adding an Authorization header as follows:
-H "Authorization: token your-token-here"
Adding an event_type
The last part of building our request is to define the event_type property in the POST body.
event_type | String | Required webhook event name |
In this example, we’ll name our event “do-something”.
To add our POST body in JSON format, we can use the following snippet:
--data '{"event_type": "do-something"}'
Building the final curl command
With all of our command components defined, we can build our final curl command like this:
curl -H "Accept: application/vnd.github.everest-preview+json" \ -H "Authorization: token <your-token-here>" \ --request POST \ --data '{"event_type": "do-something"}' \ https://api.github.com/repos/n8ebel/GitHubActionsAutomationSandbox/dispatches
When we run this command, a webhook event will be received by our repository. To manually trigger a GitHub actions workflow from this webhook event, we can update our action to respond to the repository_dispatch trigger.
Responding to the repository_dispatch event in a GitHub Actions workflow
Responding to the repository_dispatch trigger in our workflow requires a small update as seen in the following snippet:
name: Do Something That Needs Scheduled on: repository_dispatch: types: do-something schedule: - cron: '*/5 * * * *' jobs: ...
In the on: block of our workflow configuration, we’ve added repository_dispatch. Additionally, we’ve passed a type which matches the event_type we specified in our curl command.
At this point, we’ve done it! We can now manually trigger our GitHub actions workflow using curl from the command line.
If we do not specify the types property of the repository_dispatch trigger, our workflow will run in response to any repository_dispatch event. Specifying the type enables us to control which workflows are run when we send the repository_dispatch event.
Sending data to your triggered workflow
At this point, our GitHub actions workflow is only using the event_type property of the repository_dispatch event. However, that event also has a client_payload property we can use to add additional data with which to customize our workflow.
client_payload | Object | A JSON field to pass additional data |
With this client_payload property, we can pass configuration values, text, etc.
Let’s imagine we want to send some simple text with our repository_dispatch event and then print that text out during our workflow.
To start, we can update the body of our POST request to include a client_payload JSON object that includes a text property as in the following example:
{ "event_type": "do-something", "client_payload": { "text": "a title" } }
We can add this updated POST body JSON to our existing curl command to end up with something like the following:
curl -H "Accept: application/vnd.github.everest-preview+json" \ -H "Authorization: token <your-token-here>" \ --request POST \ --data '{"event_type": "do-something", "client_payload": { "text": "a title"}}' \ https://api.github.com/repos/n8ebel/GitHubActionsAutomationSandbox/dispatches
Now, when our workflow receives this event, it will contain this additional data which we can then use within the workflow.
For example, to print out the value of our client_payload.text property, we can add an additional workflow step which accesses that property using the following syntax:
github.event.client_payload.text
The full task to print this value during the execution of our workflow might look something like this:
- name: Do Something Based On Triggered Event Data run: 'echo "Event text: ${{ github.event.client_payload.text }}"'
When the repository_dispatch event is received, and this step is run, we will see the passed text value printed out to the workflow output as in this screenshot:

The full workflow will now look something like the following:
name: Do Something That Needs Scheduled on: repository_dispatch: types: do-something schedule: - cron: '*/5 * * * *' jobs: build: name: Run Some Scheduled Thing runs-on: ubuntu-latest steps: - name: Do Something run: echo Doing Something... - name: Do Something Based On Triggered Event Data run: 'echo "Triggered event text: ${{ github.event.client_payload.text }}"'
Conclusion
In this post, we’ve walked through how to manually trigger a GitHub Actions workflow using curl from the command line.
We saw how we could update an existing workflow, running on a schedule, to respond to repository_dispatch events so they can be triggered manually.
Finally, we explored how to pass additional data to our workflows using the client_payload property of the repository_dispatch event enabling us to dynamically control the output of our workflows based on what data we send when manually triggering the workflow.
In a future post, we’ll explore a more practical example of how the client_payload property could be a helpful tool in our CI pipeline.
To learn more about using GitHub Actions, check out my talk from Øredev 2019.
To learn how to trigger your workflows using Postman, check out the followup post.
I love to meet/talk/discuss and help where I can. If you want to chat or ask a question feel free to reach out via Twitter, YouTube, and LinkedIn.
Thanks for the write up. This only works for the master branch, though right?
That’s a great question. By default, I’m pretty sure it’s received by whatever the repository’s default branch is. I don’t see any direct mention on sending to a different branch in the docs, but there is some indirect language that makes it seem like it might be possible. That’s something I’ll try and look into.
In the docs of @action/checkout it says that we can use ‘ref’ to specify a branch. Do you think this helps?
https://github.com/actions/checkout#Checkout-a-different-branch
Yes! I believe that would be the way to do it. My previous comment I believe was a little off. The repository receives the event, and what happens from there, including what branch to checkout, is up to us. Thanks for sharing.
Check this thread: https://github.community/t/how-to-trigger-repository-dispatch-event-for-non-default-branch/14470/6
There’s the Worflow Dispatch option that works on the Branch that received dispatch: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch
Also some workarounds like this: https://github.com/actions-packages-examples/branch-builds
This doesn’t seem to work. Can you please help?
What seems to be the problem?
Really useful, thank you.
Glad it helped!
Thank you!
Hi all!
I’m hoping posting here won’t be a problem.
I wanted to share a small project that I’ve been working on with a buddy that solves this problem.
https://www.actionspanel.app/
ActionsPanel uses this same `repository_dispatch` API but does so with a GitHub App token so that you don’t need to worry about managing your own PAT. This also makes it much easier to trigger your actions across teams with multiple people. Then you don’t need to share the PAT with each other or each create your own PATs.
Based on user requests and feedback, we’ve built in features to specify which branch to send the `repository_dispatch` to, and we’ve even built in a way to inject parameters when you want to execute the action.
You configure your buttons with a declarative yaml file that you leave in the repo, and ActionsPanel will read that file and dynamically create your UI for you to trigger your actions.
We’d love to get your feedback on this project. It’s very simple still but solves the core problem of triggering your actions.
If you do have feedback or any questions, feel free to post in this thread, or email us directly at support (at) actionspanel (dot) app
Looking forward to your feedback!
First of all – great write up!
I have a problem with the repo… seems like the `/dispatches` endpoint is not available on my repo.
The repo belongs to an organization, not to an individual user, if that makes any difference?
When I call the endpoint, I get the following error:
{
“message”: “Not Found”,
“documentation_url”: “https://developer.github.com/v3/repos/#create-a-repository-dispatch-event”
}
I know this question was from a while back, but for anyone else finding this, I had the same issue and this is how I fixed it.
Unless your workflow is appearing on the Actions tab on Github.com, then it won’t work. I had to set the trigger to push first so that it ran once. It then gets registered as an action and will appear on the tab. I then changed the trigger back to workflow_dispatch. At this point, doing the curl call will work. That is unless something in the command is wrong, like a bad path.