Documentation

HTTP push notifications: send a webhook to your phone

Send HTTP notifications to iPhone or Android with a private HTTPS link or POST webhook. Use text, JSON or form data; no CLI installation is required.

Updated

How do I send an HTTP notification to my phone?

#

Copy the private HTTPS Push link from Ntfyx on your phone. Open it to send a notification, or keep the URL fixed and POST text, JSON or form content from your service. No CLI is required. The key grants sending only; the service reads the input before encrypted delivery.

  1. Open Ntfyx. A new Inbox prepares the MyNotify custom Topic. Existing Inboxes keep their own Topic names.
  2. Tap Send. The app submits a real remote HTTPS request and waits for the matching message to appear in Inbox.
  3. Copy your sending link. Open it to send, or use it in your script or service.

One private URL for GET or POST

#

Copy the complete HTTPS Push URL from Ntfyx. Opening it with GET sends the message in its final path segment. To connect a service, keep the copied URL fixed and POST a text body or a JSON text field. HTTP notification describes the integration; the sending URL uses encrypted HTTPS transport. The service reads the request before encrypting delivery to the phone.

Terminal
curl --request POST "$NTFYX_WEBHOOK_URL" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: example-build-123" \
  --data '{"title":"Build","text":"Build complete"}'

Use your copied link as a fixed POST webhook

#

Copy the whole HTTPS Push link from your phone and paste it into the webhook URL field of your service. Select POST and send the message in the body. You can keep the existing /hello ending: POST takes the dynamic message from its body, while opening the same URL with GET keeps the existing URL-message behavior.

This works with the existing app link; no new app update is required for this use.

  1. Open HTTPS Push in Ntfyx and copy your private sending link.
  2. Paste that fixed URL into your service. Use POST with application/json and a text field, or text/plain.
  3. Send a test and confirm that the matching message reaches the phone. An accepted HTTP response alone does not establish receipt.
Terminal
POST YOUR_PRIVATE_APP_URL
Content-Type: application/json
Idempotency-Key: build-123

{"text":"Build complete"}

Supported bodies and retries

#

Accepts a JSON string; JSON body, message, text or content fields; plain UTF-8 text; and URL-encoded form fields, including payload JSON. Every present text alias must be a string, and multiple aliases must have the same value. Other event JSON is displayed as JSON text; output over 12,000 characters is rejected with 413, never truncated.

An optional title and Session fields can group messages. Body upload reading has an absolute five-second deadline; a 408 timeout is retryable. This is a body-reading limit, not a five-second total-request or phone-delivery guarantee. The raw request is limited to 64 KiB, the message to 12,000 characters and the title to 120.

The final JSON message also has a 16 KiB encrypted-payload limit including JSON overhead, so multibyte text may reach that limit first. Invalid UTF-8, duplicate JSON/form keys, conflicting aliases and unsupported formats are rejected. Attachments and URLs are not fetched; text support does not imply full Slack blocks or Discord embeds/files compatibility.

BodyExample
application/json{"text":"Build complete"}
application/json{"title":"Deploy","body":"Release ready"}
text/plainBuild complete
application/x-www-form-urlencodedmessage=Build%20complete

Separate webhook keys with CLI or MCP

#

CLI 0.3.0 and the local MCP tools can manage independent wh_ sending keys. First prepare HTTPS Push on the primary phone, pair your Source, then request separate webhook management permission. Your phone must approve the fixed Topic and scope; monitor permission does not grant webhook management. The management grant lasts up to 24 hours.

A created key can last until its owner Source expires, which can be longer than that grant.

Terminal
ntfyx webhook authorize --async --no-input --expires 24h --json
ntfyx webhook auth-status AUTHORIZATION_ID --json
ntfyx webhook create --name "Deploy alerts" --url-file ./private-webhook-url.txt --json
ntfyx webhook list --json
ntfyx webhook show WEBHOOK_ID --json
ntfyx webhook update WEBHOOK_ID --name "Production deploys" --dry-run --json
ntfyx webhook rotate WEBHOOK_ID --url-file ./next-private-webhook-url.txt --json
ntfyx webhook disable WEBHOOK_ID --json
ntfyx webhook enable WEBHOOK_ID --json
ntfyx webhook delete WEBHOOK_ID --json
ntfyx webhook revoke --json

Stop sending and revoke management separately

#

webhook revoke ends the current Source's management grant; it does not disable keys already created. Use disable or delete to stop an individual URL. Owner Source revocation or expiry, a primary-phone key/identity change, or a root-version change invalidates its keys. Pausing the parent HTTPS sender pauses its children and can be resumed with the same parent token.

Rotating the parent token invalidates old child keys. Each Inbox supports up to 100 nondeleted keys. At capacity, the service can reclaim permanently invalid keys; revoked management grants or a recoverable parent pause do not cause reclamation. Keys share the existing HTTPS sender's 60 requests per minute admission limit.

Ordinary message limits also apply: 30 new messages per minute and 10 per 2 seconds per Source.

Optional GitHub or Standard Webhooks signatures

#

Generic mode authenticates the private bearer URL. For a child key, explicitly choose github or standard and provide a separate private verification-secret file. GitHub checks X-Hub-Signature-256 against the raw request body; it does not sign the delivery ID or timestamp. Standard Webhooks binds the delivery ID, timestamp and raw body, with a 300-second past/future window.

A configured signature mode rejects missing or invalid signatures; a header alone never enables a mode or permits a downgrade. Standard Webhooks is a community convention, not a universal payload format.

Terminal
ntfyx webhook create --name "GitHub events" --signature-mode github \
  --verification-secret-file ./github-webhook-secret.txt \
  --url-file ./private-github-url.txt --json

Messages and safe retries

#

The Topic alias becomes the notification title; the final path segment becomes its message. Encode each segment once using UTF-8 percent encoding, including spaces, slashes, #, ? and emoji. A message can contain 1–2,000 characters, and the complete encoded URL must fit 8,192 UTF-8 bytes. Each ordinary visit sends a new notification.

The app test keeps an Idempotency-Key header until its matching message is received, so an uncertain response can be retried without duplicating it. HEAD and prefetch requests do not send.

Advanced: POST remains available

#

Existing JSON POST integrations still work. They carry the raw push token in the Authorization header and support longer bodies and optional Session fields. The POST push token and the short sk_ sending key are separate credentials; keep both private.

Terminal
curl -X POST 'https://api.ntfyx.me/v1/push/YOUR_INBOX_ID/YOUR_PUSH_ID' -H 'Authorization: Bearer YOUR_PUSH_KEY' -H 'Content-Type: application/json' -d '{"title":"Deployment","body":"Build ready"}'

Group advanced POST notifications in a conversation

#

For the advanced JSON POST, the optional session_id and session_name fields group notifications into a Session in the same Topic. Use a stable ID for one task. An optional random idempotency_key lets an identical retry return the original accepted event; changing the content while reusing that key fails.

HTTPS push sends notifications; an explicit JSON Call request can ask for a supported call-style reminder. It does not provide questions, replies, message reads or execution claims; use the CLI or agent integration when your workflow needs a verified answer.

Accepted is different from received

#

An accepted response means the service accepted the message. It is not proof that the phone received it or displayed a system alert. The app test waits for its matching Inbox message. If system notifications are disabled, the Inbox can still receive the message while no banner is shown. Check notification permissions and connectivity separately.

Your push key has one job

#

It can submit messages only to the configured Topic. It is separate from the phone management capability, receiver decryption keys and CLI source identity. Manage, disable or rotate HTTPS push from the phone; rotation invalidates the old key. The server cannot show a lost raw key back to you. If you lose it, rotate and replace it in your own scripts.

Where encryption begins

#

Ordinary CLI and agent message titles, bodies, options and replies are end-to-end encrypted on your devices. The explicit fixed monitor-access and webhook-management questions and their signed phone answers are disclosed to the service for verification. HTTPS push and webhook requests are readable by the service before encrypted delivery.

Optional provider verification secrets are encrypted and stored by the service, then used in plaintext to verify the raw webhook body; they are hosted secrets, not hidden from the service. My Monitor reads the monitored address, rule and response; a public publisher knows the content it publishes. The relay routes ciphertext and processes operational metadata such as identifiers, time, size and push tokens.

Do not put secrets in monitored URLs or request examples. Independent security review is not complete.

Try the first test from the home screen

#

Follow the hello walkthrough and distinguish an accepted request from a received message.

Start with a use case

#

From agent questions to weekly subscriptions and website alerts, start with a use case. See what reaches your phone, then follow the steps to connect.

Can a webhook ring, or wait for an agent reply?

#

A JSON webhook can request a call-style message alert with ntfyx.alert_mode="call" after the phone owner enables it. This changes the requested reminder, not the sending key’s permissions. A webhook cannot read messages or receive signed answers. Use ntfyx ask or local MCP when the task needs confirmation, a choice or text.

Plain and rich messages

#

CLI 0.5.0 independently sends ordinary text, Markdown and native metric/table/chart messages, with local validation before sending. See the guide for receiver version requirements and store availability.