· 4 min · TextMeFlow Team

WhatsApp alerts for CI/CD failures and uptime monitoring

Slack and email are fine for alerts you'll notice eventually. For the ones that need a response in the next five minutes — a failed production deploy, a server that stopped responding — they're not. Nobody has Slack notifications at full volume at 2am, but almost everyone sees a WhatsApp message arrive. Since TextMeFlow is just a REST API behind a phone number, wiring it into a CI pipeline or an uptime monitor is a handful of lines, not a new on-call tool to adopt.

Sending an alert from a GitHub Actions workflow

The simplest case: a step that runs only when a previous job fails, and fires a POST to /v1/messages.

- name: Notify on failure
  if: failure()
  run: |
    curl -sS -X POST https://api.textmeflow.eu/v1/messages \
      -H "Authorization: Bearer ${{ secrets.TEXTMEFLOW_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{
        "to": "+32472932208",
        "text": "Deploy failed: ${{ github.repository }} @ ${{ github.sha }} (run ${{ github.run_id }})",
        "urgent": true
      }'

Store the API key as a repository secret, never in the workflow file itself. The response is 202 with a message_id you can log if you want to confirm delivery later via GET /v1/messages/{id}. Include the commit SHA and run id in the text — a bare "build failed" forces whoever reads it to go open GitHub anyway, which defeats the point of a push alert.

Forwarding uptime-monitor webhooks

Most uptime tools (self-hosted options like Uptime Kuma, or external ones with a generic webhook integration) already call your URL with a JSON body on every up/down transition — they just don't know how to speak TextMeFlow's API directly. The fix is a tiny relay endpoint in whatever stack you already run, that translates their payload into a TextMeFlow send:

// Express relay: receives the monitor's webhook, re-posts to TextMeFlow
app.post('/alerts/uptime', express.json(), async (req, res) => {
  const { monitor, status, msg } = req.body; // shape depends on your monitor
  if (status === 'down') {
    await fetch('https://api.textmeflow.eu/v1/messages', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.TEXTMEFLOW_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        to: process.env.ONCALL_NUMBER,
        text: `${monitor} is DOWN: ${msg}`,
        urgent: true,
      }),
    });
  }
  res.sendStatus(200);
});

Keep this relay dumb on purpose: one job (translate payload shape, forward), no retry logic of its own. If the TextMeFlow call fails, let your monitor's own retry/backoff handle resending the webhook rather than building a second retry layer on top of it.

Bypass quiet hours — but only for real incidents

TextMeFlow defers non-urgent messages sent between 22:00 and 08:00 in the recipient's local time, so a reminder doesn't wake anyone up. For an actual incident, that's exactly the opposite of what you want, which is why the urgent: true field exists — it skips quiet-hours shaping entirely. Use it only for pages that genuinely need a response outside office hours; the anti-spam pipeline nudges your account's risk score up slightly on every forced quiet-hours send, which is fine for a handful of real incidents a month and not meant for routine CI noise. Route your flaky, auto-retried test failures to Slack and reserve urgent sends for the pages that would justify phoning someone.

Don't let an alert storm trip your own rate limit

If ten services go down in the same minute, your monitoring will happily try to send ten WhatsApp messages in that same minute — against the same rate limit and monthly quota as any other traffic on your account. Two things are worth building in from the start: debounce at the source (one summary message per flapping incident, not one per check), and handle 429 responses from the API the same way you'd handle them anywhere else — see handling rate limits and message status for retry/backoff code in Node and Python. If your on-call rotation is more than five people and you're tempted to blast the identical text to all of them at once, vary the message slightly (name, role, or just the recipient's own escalation tier) — sending the exact same body to more than five distinct numbers in ten minutes trips the broadcast-detection check meant for marketing blasts, not pages. Exact per-plan limits are in the rate limits doc.

Getting started

You don't need a paid plan to wire this up: the free tier's 50 messages a month, with no expiry, is enough to test a GitHub Actions step or an uptime-monitor relay end to end before it carries real pages. Check the full request/response shape in the API reference, then start for free and get your first failed-deploy alert landing on your phone today.

Zelf WhatsApp-berichten versturen via API?

Gratis voor altijd tot 50 berichten/maand. QR scannen en binnen 5 minuten verstuur je je eerste bericht.

Gratis voor altijd