Run API Tests on Every PR with GitHub Actions
Run API tests on every pull request with GitHub Actions: the pull_request trigger, fork and secrets limits, required checks, and keeping the suite current.

To run API tests on every pull request, add a GitHub Actions workflow that triggers on the pull_request event and runs your API test command, then mark that job as a required status check on the branch you merge into. The workflow decides when the suite runs. The branch rule decides whether a failure blocks the merge. The rest of this page covers the details that make that setup behave: which activity types start a run, why secrets go missing on forked pull requests, and how to keep a required check from turning into noise.
The short version: one workflow file and one required check
The whole procedure fits in four steps. Write a workflow file that runs on pull_request. Give it a job that starts or reaches your API and runs the suite with a single command. Push it, and open a pull request to see the job report a status. Then turn that job into a required check in your branch protection settings.
The last step is the one teams skip. A workflow that runs but does not block anything is a report, and reports get ignored. Required status checks must have a successful, skipped, or neutral status before collaborators can make changes to a protected branch. That sentence is the whole mechanism: once the job is required, a red result stops the merge button.
Everything below follows that order. First the workflow and its trigger, then what the run can and cannot see, then the branch rule, and last the part that decides whether the check stays useful a month from now.
Create the workflow with the pull_request trigger
Create a new file in the .github/workflows directory of your repository and name it something descriptive, such as api-tests.yml. A minimal version looks like this. The test command is a placeholder: swap in whatever runs your suite, whether that is a collection runner, a test framework or a script.
name: API tests
on:
pull_request:
branches:
- main
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start the API under test
run: ./scripts/start-api.sh
- name: Run the API tests
run: ./scripts/run-api-tests.sh
Three details in that file matter more than they look.
First, the trigger. By default, a workflow only runs when a pull_request event’s activity type is opened, synchronize, or reopened. Those are the moments when an API test usually needs to run. If you want other activity to start a run, list those types explicitly under types.
Second, the branch filter. Limiting the trigger to pull requests that target main keeps the suite from running on every stacked or experimental branch. Drop the filter if your team merges into several long-lived branches, and make sure each one you protect has the workflow attached.
Third, merge conflicts. Workflows will not run on pull_request activity if the pull request has a merge conflict, and the conflict must be resolved first. When a contributor says the check never started, a conflict with the base branch is the first thing to look for, before anything in your YAML.
Keep the start script and the test script separate. When the job fails, the log then shows whether the API never came up or the tests found a real regression, and those two failures need different people to look at them.
What the run can see: secrets and forked pull requests
API tests usually need credentials: a token for a staging service, a database URL, a key for a third-party sandbox. In a workflow triggered from a branch in your own repository, repository secrets are available as usual. Forked pull requests are different, and this is the failure that surprises teams most often.
With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository. The GITHUB_TOKEN also has read-only permissions in pull requests from forked repositories. An API suite that logs in against a real service will fail on every outside contribution, and the failure will look like a bad test when it is really a missing credential.
You have two sensible ways to handle that. The first is to design the suite so the part that needs no secrets runs everywhere: tests against a local instance of the API, a mock of the upstream service, or a seeded test database that the job starts itself. The second is to split the work into two jobs, one that always runs and one that needs credentials and is allowed to be skipped for forks. A required check may have a skipped status and still pass, which is the behavior you want here, but only if you have decided deliberately that fork pull requests will not exercise the credentialed tests until a maintainer reruns them.
Whatever you choose, write it down in the contributing guide. An outside contributor who sees a red check with an authentication error in the log will assume their change broke something.
Make the suite a required check that fails the pull request
Open the branch protection rule for your main branch and turn on the requirement for status checks before merging, then pick the API test job from the list. With the rule on, every required check must pass before changes can reach the protected branch. GitHub’s page on protected branches covers the settings in full.
Two practical points keep this from going wrong.
Job names must be unique. If you use branch protection rules that require specific status checks, make sure that job names are unique across all workflows. Naming a job test in three files is the easy way to end up with a check that means different things on different pull requests. A name like api-tests in one workflow avoids the problem.
Merge queues need an extra trigger. If your repository uses GitHub Actions to perform required checks on pull requests, you need to include the merge_group event as an additional trigger, or status checks will not be triggered when you add a pull request to a merge queue. The workflow then lists both events:
on:
pull_request:
branches:
- main
merge_group:
types:
- checks_requested
With the required check in place, a regression fails the pull request in the same place the author is already looking, next to the diff. That is the point of running API tests per pull request instead of nightly: the person who changed the code sees the failure while the change is still fresh. The GitHub reference on events that trigger workflows lists the remaining activity types and filters if you need finer control.
Keep the suite current so the check does not rot
A required check is only as good as the tests behind it, so decide what the suite must cover before you make it a gate. The definition of API testing is a reasonable place to start. If the suite is a set of hand-written requests that nobody updates, the check starts failing for reasons unrelated to the change, people learn to rerun it, and eventually someone asks to make it optional. The workflow was never the hard part.
The fix is to treat the suite as something that changes in the same pull request as the API. For the practical routes, read why API tests go stale, and for generating tests from a spec, turn an OpenAPI spec into contract tests. If you are still choosing a runner for the job, the comparison of Postman and Step CI in CI covers that.
Stresseur takes a different route to the same problem. It is built around tests that keep up with the code, instead of collections that go stale, and it learns from real usage and not from a hand-written spec alone. It is in early access, with a sign-up on the site and no self-serve pricing.
Conclusion
Run the suite on pull_request, keep the start and test steps separate, plan for forks that carry no secrets, and make the job a required check with a unique name. Add merge_group if you use a merge queue. Then spend your effort on the suite itself, because a gate only helps while the tests behind it are accurate.
Frequently asked questions
How can I run tests using GitHub Actions?
Put a workflow file in the .github/workflows directory of your repository. Trigger it on the pull_request event, and GitHub Actions, a CI/CD tool that automates software workflows such as testing, runs it on each pull request.
How do I run GitHub Actions on a pull request?
Use the pull_request event. By default, a workflow only runs when the activity type is opened, synchronize, or reopened. Add a types list if you also want it to run on other activity.
Why did my pull request workflow not run?
Check for a merge conflict first. Workflows will not run on pull_request activity if the pull request has a merge conflict, and the conflict must be resolved before the run starts.
Is it possible to automate API testing?
Yes. You can configure automated tests to run on every pull request by using GitHub Actions. Stresseur, which is in early access, is built around tests that keep up with the code.