Back to blog
blog·June 14, 2026·3 min read

How to Get GitHub Push Notifications on Your iPhone

Get GitHub push notifications on your iPhone when a workflow fails — one curl step in GitHub Actions, no app to install. Setup takes about 5 minutes.

A pull request got merged into main while you were grabbing lunch. CI kicked off, the deploy step failed, and main sat broken for 40 minutes before anyone noticed — because the only signal was an email buried under 200 other GitHub emails.

GitHub's built-in notifications are either too much or too late. The email digest is noise. The mobile app pings you for every comment on every thread you've ever touched. What you actually want is a real push to your phone for the two or three events that matter: a failed build, a deploy that didn't go through, a PR that needs your review.

You can wire that up in about five minutes. One step in your GitHub Actions workflow, one curl call, and your iPhone lights up the moment something breaks — no second GitHub app, no SDK, no webhook server to babysit.

What you'll need

  • A repo that uses GitHub Actions (any workflow file will do)
  • A free TheNotificationApp account and one app key
  • The TheNotificationApp iOS app installed and signed in with Apple

That's the whole shopping list. Let's get the key first.

Step 1 — Grab your API key

Sign in to TheNotificationApp, create an app (call it "GitHub CI" or whatever you like), and copy its app_key. That key is the only credential you need — it maps to your phone, so notifications go straight to you and nobody else.

Before touching any YAML, confirm the key works from your terminal. This is the exact shape every later step reuses (the full curl docs cover the optional link and image fields):

curl -X POST https://thenotification.app/api/sendNotification \
  -H "app_key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Test from GitHub",
    "body": "If you can read this on your phone, you are done."
  }'

Your phone should buzz within a second or two. If it does, the hard part is over.

Step 2 — Store the key as a repo secret

Never paste the key straight into the workflow file. That file gets committed, and now your key lives in git history forever — even after you "delete" it. Instead, go to Settings → Secrets and variables → Actions → New repository secret, name it NOTIFY_KEY, and paste the value there. Actions injects it at runtime and masks it in the logs, so even a curl -v won't leak it.

Step 3 — Add a notify step to your workflow

Here's a minimal CI workflow that runs your tests and pings your phone only when they fail. The whole notification is a single step:

name: CI
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test

      - name: Notify on failure
        if: failure()
        run: |
          curl -X POST https://thenotification.app/api/sendNotification \
            -H "app_key: ${{ secrets.NOTIFY_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{
              "title": "CI failed on ${{ github.repository }}",
              "body": "${{ github.actor }} pushed to ${{ github.ref_name }} and the build went red.",
              "link": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }'

The magic is if: failure(). That step only runs when an earlier step in the job has already failed, so you get pinged on red builds and stay silent on green ones. The link field deep-links straight to the failed run — tap the notification and you're staring at the logs, not hunting through your inbox.

Got more than one repo? Two options. The lazy one: paste those five lines into the bottom of every workflow — it's small enough that copy-paste is fine. The tidy one: move the curl into a reusable workflow or a tiny composite action and call it from each repo, so the body and the API call live in exactly one place. Start lazy, refactor once you're maintaining it in three repos and tired of it.

Step 4 — Ping yourself on the events you actually care about

Failure alerts are the high-value case, but you can fire on anything Actions can see. A few patterns that earn their place:

  • Deploy finished: drop the same curl at the end of your deploy job with if: success() and a "Shipped 🚀" title.
  • Your review was requested: trigger the workflow on pull_request: [review_requested] and send the PR title in the body.
  • A nightly job ran: if you have a scheduled cron workflow, the same one-liner confirms it actually fired — the same idea as getting a phone alert when a cron job fails.

One gotcha worth knowing: GitHub expands those ${{ }} values as plain text directly into your JSON. Fields like github.actor and github.ref_name are safe, but don't drop a raw commit message in there — a stray quote will break the JSON body. Stick to the predictable fields and you'll never hit it.

The honest tradeoff

The free tier caps at 100 notifications total — not per month, total. That's plenty to wire failure alerts onto a repo or two and live with it for a good while. But point this at a busy main with a dozen contributors and notify on every push, and you'll burn through 100 in a couple of days. Keep it to if: failure() plus the handful of deploys you genuinely care about, or move to the Pro tier at $2.99/month for 1,000 notifications a month. Either way, put noisy events behind a condition — a notification that fires constantly is one you'll learn to ignore.

That's it

One secret, one step, and your CI talks to your phone instead of your inbox. Worth a look if you're tired of finding out main is broken from a teammate instead of your own tooling — TheNotificationApp is free to start, no card required.

Stop babysitting your scripts.

Free to download. Free tier available. Swiss-hosted, private by design.

Get the app →