---
title: "ntfy's Query-String API Is More Powerful Than the Docs Make It Look"
description: "Most of this Pi's alerting runs through ntfy already. Turns out you can do a lot more with it than I expected — without writing a receiving server at all."
url: "https://mynerdylife.com/blog/ntfy-query-string-api/"
author: "Jared"
published: "2026-08-01"
category: "Coding"
tags: ["ntfy","webhooks","api"]
---

# ntfy's Query-String API Is More Powerful Than the Docs Make It Look

I already run most of this Pi's alerting through [ntfy](https://ntfy.sh) — boot/shutdown notifications, [uptime checks](https://mynerdylife.com/blog/you-dont-need-uptime-kuma-for-one-site/), Lighthouse CI score regressions, all of it hitting one topic via a tiny curl wrapper. So when a client asked for a push notification whenever a sale comes through on their WordPress site, ntfy was the obvious answer. What surprised me was how much you can do with it *without writing a receiving server at all* — just query parameters and, if you want client-side confirmation, a plain `fetch()` call.

## The zero-infrastructure version

Most WordPress e-commerce plugins (WooCommerce included) have a native webhook feature: pick an event, give it a URL, it POSTs there. Point that straight at an ntfy topic and you already have a working sale notification — no server of your own required:

```
https://ntfy.sh/your-topic-name
```

The catch: WooCommerce's native webhook only sends the full order as a raw JSON body, with no templating. The push notification you get just shows a blob of JSON as the message text. Not exactly "New sale: $49 from Jane." Usable as a bare "something happened" signal, but not great.

## Where the query-string API comes in

This is the part I hadn't really appreciated until I went looking: ntfy accepts a bunch of its options as either HTTP headers *or* query parameters — `?title=`, `?priority=`, `?tags=`, `?click=`. That means even without touching the message body, you can make a webhook-triggered push meaningfully more readable just by putting those in the delivery URL:

```
https://ntfy.sh/your-topic?title=New+Sale&priority=high&tags=moneybag
```

Now instead of a wall of JSON with no context, you get a title that actually says what happened, a priority level that controls whether it interrupts you, and a tag that renders as an emoji in the notification. The body's still raw order data, but the header of the notification — the part you actually read at a glance — is exactly what you want it to say.

## `click` is the underrated one

The parameter that ends up mattering most once you're actually living with these notifications day to day is `click` — it makes the *entire notification* a tap target that opens a URL, rather than requiring you to open the app and find a link buried in the message text. Since ntfy.sh sends `Access-Control-Allow-Origin: *` and answers CORS preflight requests properly, you can even trigger a POST with all of these set directly from client-side JavaScript — a plain `fetch()` call from a web page, no backend involved at all:

```js
fetch('https://ntfy.sh/your-topic', {
  method: 'POST',
  headers: {
    'Title': 'New Sale',
    'Tags': 'moneybag',
    'Priority': 'high',
    'Click': 'https://your-order-admin-url/'
  },
  body: 'Order #1234 — $49.00'
});
```

Tap the notification, land directly on the order. No app-switching, no hunting.

## If you want real templating

For an actual "New sale: $49 from Jane" message with real order fields substituted in, you need something willing to build the message body itself — a webhook-formatting WordPress plugin, an automation tool like Zapier, or a small receiver of your own that reads the order JSON and posts a formatted string to ntfy. That's a reasonable next step if the bare title/tags version stops being enough. But it's worth knowing the zero-code version exists first — for a lot of "just tell me when X happens" cases, query parameters alone get you most of the way there.
