Trigger JourneyGuard from GitHub / Bitbucket
Triggering a JourneyGuard Journey from GitHub or Bitbucket
This guide walks you through triggering a JourneyGuard journey run automatically from GitHub Actions or Bitbucket Pipelines whenever a branch is merged. The mechanism is a single authenticated POST /api/runJourney/{monitorId} call, so once the credentials are configured the CI step is a two-line curl.
The whole process takes about 10 minutes and only needs to be done once per repository.
Prerequisites
- A JourneyGuard journey monitor already configured and passing when you click Run Now from the dashboard.
- A Webtools API key generated from your Profile page. The key is shown once in plain text at creation time — save it somewhere safe.
- A paid-tier plan. The
runJourneyendpoint is gated by the same paid-tier check asrunCrawlandrunSiteTest. - Admin access to the target GitHub or Bitbucket repository (to add secrets and edit workflow files).
1. Collect the Values You Will Need
You will need three pieces of information before touching your CI configuration:
| Value | Where to find it |
|---|---|
| Your account email | The email you sign in to JourneyGuard with. This is the X-Email header value. |
| Your API key | Generated at Profile → Generate New API Key. Save the plain-text value shown once. This is the X-API-Key. |
| Your Journey ID | Open Journeys, click the journey you want to run on merge, and read the number from the URL: /journeys/34/edit → the ID is 34. |
You can smoke-test the values with a single curl before doing any CI work:
curl -X POST "https://webtools.ayalr.com/api/runJourney/34" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"
A successful response looks like:
{
"data": {
"monitor_id": 34,
"monitor_name": "Checkout Flow",
"webhook_url": null
},
"message": "Journey queued successfully.",
"server_time": "2026-07-25T10:00:00+00:00"
}
If this does not work, fix it here before adding CI wiring. See the Troubleshooting section at the bottom for common causes.
2. Set It Up on GitHub Actions
2.1 Store the Credentials as Repository Secrets
- Open your repository on GitHub and go to Settings → Secrets and variables → Actions → New repository secret.
- Add two secrets:
- Name:
AYALR_EMAIL— Value: your JourneyGuard account email. - Name:
AYALR_API_KEY— Value: the plain-text API key from step 1.
- Name:
- If you want to keep the journey ID out of your workflow file too, add a third repository variable (not a secret): Variables tab → New repository variable with name
AYALR_JOURNEY_IDand value34.
2.2 Add a Workflow That Fires on Merge
Create .github/workflows/journey-on-merge.yml in the default branch of your repository:
name: JourneyGuard on merge
on:
pull_request:
types: [closed]
jobs:
run-journey:
# Only fire when the PR was actually merged (not just closed) and the base
# branch is the one you care about. Adjust "main" as needed.
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
runs-on: ubuntu-latest
steps:
- name: Trigger JourneyGuard journey
run: |
curl -sSf -X POST "https://webtools.ayalr.com/api/runJourney/${{ vars.AYALR_JOURNEY_ID }}" \
-H "X-Email: ${{ secrets.AYALR_EMAIL }}" \
-H "X-API-Key: ${{ secrets.AYALR_API_KEY }}"
Notes:
- The
if:guard is important. GitHub firespull_request.closedfor both merged and abandoned PRs.github.event.pull_request.merged == truefilters to merges only. - If you prefer to trigger on any push to a branch (bypassing PRs entirely), swap the
on:block foron: push: branches: [main]. - If you did not create a repository variable in step 2.1, hard-code the journey ID in the URL instead of
${{ vars.AYALR_JOURNEY_ID }}.
2.3 (Optional) Tag the Run with the Commit SHA
Add a JSON body to the curl if you want the merge context surfaced in the results downstream:
- name: Trigger JourneyGuard journey
run: |
curl -sSf -X POST "https://webtools.ayalr.com/api/runJourney/${{ vars.AYALR_JOURNEY_ID }}" \
-H "X-Email: ${{ secrets.AYALR_EMAIL }}" \
-H "X-API-Key: ${{ secrets.AYALR_API_KEY }}" \
-H "Content-Type: application/json" \
-d "{\"webhook_url\":\"https://your-app.example.com/webhooks/journey-done?sha=${{ github.sha }}\"}"
The webhook_url is optional. If provided, JourneyGuard will POST to it when the journey finishes so you can update a PR check status, notify Slack, or reconcile with your deployment record.
3. Set It Up on Bitbucket Pipelines
3.1 Store the Credentials as Repository Variables
- Open your repository on Bitbucket and go to Repository settings → Pipelines → Repository variables.
- Add two secured variables (tick the Secured checkbox for both):
- Name:
AYALR_EMAIL— Value: your JourneyGuard account email. - Name:
AYALR_API_KEY— Value: the plain-text API key from step 1.
- Name:
- Optionally add a third, unsecured variable
AYALR_JOURNEY_IDwith value34so you do not hard-code the ID.
3.2 Add a Pipeline That Fires on Merge
Add or edit bitbucket-pipelines.yml at the root of your repository:
image: atlassian/default-image:3
pipelines:
branches:
main:
- step:
name: JourneyGuard on merge
script:
- >
curl -sSf -X POST "https://webtools.ayalr.com/api/runJourney/${AYALR_JOURNEY_ID}"
-H "X-Email: $AYALR_EMAIL"
-H "X-API-Key: $AYALR_API_KEY"
Notes:
- The
branches: main:block fires on every push to themainbranch, which is what a Bitbucket merge produces. Adjust the branch name to match yours (master,production, etc.). - If you prefer to be strict about "merge only, not direct push", add a
pull-requests:pipeline in addition to (or instead of) the branch trigger. Bitbucket exposes$BITBUCKET_PR_IDto those steps. - If you did not create the
AYALR_JOURNEY_IDvariable in step 3.1, hard-code the ID in the URL.
3.3 (Optional) Tag the Run with the Commit SHA
Bitbucket exposes the commit SHA as $BITBUCKET_COMMIT:
- step:
name: JourneyGuard on merge
script:
- >
curl -sSf -X POST "https://webtools.ayalr.com/api/runJourney/${AYALR_JOURNEY_ID}"
-H "X-Email: $AYALR_EMAIL"
-H "X-API-Key: $AYALR_API_KEY"
-H "Content-Type: application/json"
-d "{\"webhook_url\":\"https://your-app.example.com/webhooks/journey-done?sha=${BITBUCKET_COMMIT}\"}"
4. Verify It Worked
- Merge a trivial PR (or push a whitespace-only commit if you skipped the PR check).
- Watch the CI job in GitHub Actions or Bitbucket Pipelines. The curl step should finish in under a second with HTTP 200.
- Open Journeys → your journey → Results in JourneyGuard within a minute. You should see a new result row with the current timestamp.
- If you configured an alert channel on this journey, a FAIL run will notify the channel as normal.
Every successful call consumes one from your Ad-hoc journeys monthly allowance. The counter is visible on the journey results page next to the Run Test Now button.
Troubleshooting
The curl step in CI will exit non-zero on any HTTP error, so the CI job itself will fail loudly. Match the status code to the fix:
| HTTP status | Response message |
What to check |
|---|---|---|
| 401 | Missing or invalid credentials | X-Email / X-API-Key headers are set, values match your Profile page, and no accidental whitespace. |
| 403 | Not on a paid tier | The runJourney endpoint requires a paid plan. Upgrade from Profile → Manage subscription. |
| 404 | Journey not found or does not belong to your account | Wrong monitorId in the URL, monitor is a different type (not Journey), or belongs to a different user. |
| 422 | This journey is paused. Unpause it before queuing a run. | Open the journey in the dashboard and click Resume. |
| 422 | webhook_url must be a valid fully-qualified HTTP or HTTPS URL. |
Body must contain a well-formed absolute URL. Local localhost:... will not pass the FQDN check. |
| 429 | Ad-hoc journey limit reached for this month. | You have consumed your monthly ad-hoc allowance. Upgrade the plan or wait for the counter to reset. |
If the curl succeeds but no result appears in the JourneyGuard dashboard within a minute:
- Confirm the journey monitor has at least one enabled step and is not marked paused.
- Check the journey runner logs (contact support). A queued job that never executes usually means no runner in the configured region is online.
Related Documentation
- Full API reference including all headers, body params, and response schemas: /api-docs
- Slack integration for alert delivery: /docs/slack-integration-setup