2021-10-23 03:26:01 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
2021-10-24 20:22:53 +02:00
< meta charset = "UTF-8" >
< title > ntfy.sh | simple HTTP-based pub-sub< / title >
< link rel = "stylesheet" href = "static/css/app.css" type = "text/css" >
<!-- Mobile view -->
< meta name = "viewport" content = "width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" >
< meta name = "HandheldFriendly" content = "true" >
<!-- Mobile browsers, background color -->
2021-10-25 14:54:46 +02:00
< meta name = "theme-color" content = "#39005a" >
< meta name = "msapplication-navbutton-color" content = "#39005a" >
< meta name = "apple-mobile-web-app-status-bar-style" content = "#39005a" >
2021-10-24 20:22:53 +02:00
<!-- Favicon, see favicon.io -->
< link rel = "icon" type = "image/png" href = "static/img/favicon.png" >
<!-- Previews in Google, Slack, WhatsApp, etc. -->
< meta property = "og:type" content = "website" / >
< meta property = "og:locale" content = "en_US" / >
< meta property = "og:site_name" content = "ntfy.sh" / >
< meta property = "og:title" content = "ntfy.sh | simple HTTP-based pub-sub" / >
< meta property = "og:description" content = "ntfy is a simple HTTP-based pub-sub notification service. It allows you to send desktop notifications via scripts from any computer, entirely without signup or cost. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy." / >
2021-10-31 04:46:08 +01:00
< meta property = "og:image" content = "/static/img/ntfy.png" / >
2021-10-24 20:22:53 +02:00
< meta property = "og:url" content = "https://ntfy.sh" / >
2021-10-23 03:26:01 +02:00
< / head >
< body >
2021-10-24 03:29:45 +02:00
< div id = "main" >
2021-10-31 04:46:08 +01:00
< h1 > < img src = "static/img/ntfy.png" alt = "ntfy" / > < br / > ntfy.sh - simple HTTP-based pub-sub< / h1 >
2021-10-24 03:29:45 +02:00
< p >
2021-10-25 04:08:06 +02:00
< b > ntfy< / b > (pronounce: < i > notify< / i > ) is a simple HTTP-based < a href = "https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern" > pub-sub< / a > notification service.
2021-11-04 15:55:34 +01:00
It allows you to send notifications < a href = "https://play.google.com/store/apps/details?id=io.heckel.ntfy" > to your phone< / a > or desktop via scripts from any computer,
entirely < b > without signup or cost< / b > . It's also < a href = "https://github.com/binwiederhier/ntfy" > open source< / a > if you want to run your own.
2021-10-24 03:29:45 +02:00
< / p >
2021-10-23 03:26:01 +02:00
2021-10-29 19:58:14 +02:00
< h2 > Publishing messages< / h2 >
2021-10-24 03:29:45 +02:00
< p >
2021-10-29 19:58:14 +02:00
Publishing messages can be done via PUT or POST using. Topics are created on the fly by subscribing or publishing to them.
Because there is no sign-up, < b > the topic is essentially a password< / b > , so pick something that's not easily guessable.
< / p >
< p class = "smallMarginBottom" >
Here's an example showing how to publish a message using < tt > curl< / tt > :
< / p >
< code >
curl -d "long process is done" ntfy.sh/mytopic
< / code >
< p class = "smallMarginBottom" >
Here's an example in JS with < tt > fetch()< / tt > (see < a href = "https://github.com/binwiederhier/ntfy/tree/main/examples" > full example< / a > ):
2021-10-24 04:49:50 +02:00
< / p >
2021-10-29 19:58:14 +02:00
< code >
fetch('https://ntfy.sh/mytopic', {< br / >
method: 'POST', // PUT works too< br / >
body: 'Hello from the other side.'< br / >
})
< / code >
< h2 > Subscribe to a topic< / h2 >
2021-10-24 04:49:50 +02:00
< p >
2021-10-29 19:58:14 +02:00
You can create and subscribe to a topic either in this web UI, or in your own app by subscribing to an
< a href = "https://developer.mozilla.org/en-US/docs/Web/API/EventSource" > EventSource< / a > , a JSON feed, or raw feed.
2021-10-24 03:29:45 +02:00
< / p >
2021-10-23 03:26:01 +02:00
2021-11-04 15:55:34 +01:00
< div id = "subscribeBox" >
2021-11-05 03:32:17 +01:00
< h3 > Subscribe in this Web UI< / h3 >
< p id = "error" > < / p >
< p >
Subscribe to topics here and receive messages as < b > desktop notification< / b > . Topics are not password-protected,
so choose a name that's not easy to guess. Once subscribed, you can publish messages via PUT/POST.
< / p >
2021-11-04 15:55:34 +01:00
< form id = "subscribeForm" >
< p >
2021-11-05 03:32:17 +01:00
< b > Topic:< / b > < br / >
2021-11-04 15:55:34 +01:00
< input type = "text" id = "topicField" autocomplete = "off" placeholder = "Topic name, e.g. phil_alerts" pattern = "[-_A-Za-z]{1,64}" / >
< button id = "subscribeButton" > Subscribe< / button >
< / p >
2021-11-05 03:32:17 +01:00
< p id = "topicsHeader" > < b > Subscribed topics:< / b > < / p >
< ul id = "topicsList" > < / ul >
2021-11-04 15:55:34 +01:00
< / form >
< audio id = "notifySound" src = "static/sound/mixkit-message-pop-alert-2354.mp3" > < / audio >
< / div >
2021-10-24 03:29:45 +02:00
2021-11-05 03:32:17 +01:00
< h3 > Subscribe via Android App< / h3 >
2021-11-01 21:39:40 +01:00
< p >
2021-11-03 16:33:34 +01:00
You can use the < a href = "https://play.google.com/store/apps/details?id=io.heckel.ntfy" > Ntfy Android App< / a >
to receive notifications directly on your phone. Just like the server, this app is also < a href = "https://github.com/binwiederhier/ntfy-android" > open source< / a > .
2021-11-01 21:39:40 +01:00
< / p >
2021-10-24 04:49:50 +02:00
< h3 > Subscribe via your app, or via the CLI< / h3 >
2021-10-27 20:56:17 +02:00
< p class = "smallMarginBottom" >
2021-10-29 19:58:14 +02:00
Using < a href = "https://developer.mozilla.org/en-US/docs/Web/API/EventSource" > EventSource< / a > in JS, you can consume
2021-10-25 04:08:06 +02:00
notifications like this (see < a href = "https://github.com/binwiederhier/ntfy/tree/main/examples" > full example< / a > ):
< / p >
< code >
2021-10-25 14:54:46 +02:00
const eventSource = new EventSource('https://ntfy.sh/mytopic/sse');< br / >
2021-10-25 04:08:06 +02:00
eventSource.onmessage = (e) => {< br / >
// Do something with e.data< br / >
};
2021-10-24 20:22:53 +02:00
< / code >
2021-10-27 20:56:17 +02:00
< p class = "smallMarginBottom" >
2021-10-29 19:58:14 +02:00
You can also use the same < tt > /sse< / tt > endpoint via < tt > curl< / tt > or any other HTTP library:
2021-10-27 20:56:17 +02:00
< / p >
< code >
$ curl -s ntfy.sh/mytopic/sse< br / >
event: open< br / >
2021-10-29 19:58:14 +02:00
data: {"id":"weSj9RtNkj","time":1635528898,"event":"open","topic":"mytopic"}< br / > < br / >
2021-10-27 20:56:17 +02:00
2021-10-29 19:58:14 +02:00
data: {"id":"p0M5y6gcCY","time":1635528909,"event":"message","topic":"mytopic","message":"Hi!"}< br / > < br / >
2021-10-27 20:56:17 +02:00
event: keepalive< br / >
2021-10-29 19:58:14 +02:00
data: {"id":"VNxNIg5fpt","time":1635528928,"event":"keepalive","topic":"test"}
< / code >
< p class = "smallMarginBottom" >
To consume JSON instead, use the < tt > /json< / tt > endpoint, which prints one message per line:
< / p >
< code >
$ curl -s ntfy.sh/mytopic/json< br / >
{"id":"SLiKI64DOt","time":1635528757,"event":"open","topic":"mytopic"}< br / >
{"id":"hwQ2YpKdmg","time":1635528741,"event":"message","topic":"mytopic","message":"Hi!"}< br / >
{"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}
2021-10-27 20:56:17 +02:00
< / code >
< p class = "smallMarginBottom" >
2021-10-29 19:58:14 +02:00
Or use the < tt > /raw< / tt > endpoint if you need something super simple (empty lines are keepalive messages):
2021-10-27 20:56:17 +02:00
< / p >
< code >
$ curl -s ntfy.sh/mytopic/raw< br / >
< br / >
This is a notification
< / code >
2021-10-24 04:49:50 +02:00
2021-10-29 19:58:14 +02:00
< h3 > Message buffering and polling< / h3 >
2021-10-27 20:56:17 +02:00
< p class = "smallMarginBottom" >
2021-10-29 19:58:14 +02:00
Messages are buffered in memory for a few hours to account for network interruptions of subscribers.
You can read back what you missed by using the < tt > since=...< / tt > query parameter. It takes either a
duration (e.g. < tt > 10m< / tt > or < tt > 30s< / tt > ) or a Unix timestamp (e.g. < tt > 1635528757< / tt > ):
2021-10-24 04:49:50 +02:00
< / p >
2021-10-24 20:22:53 +02:00
< code >
2021-10-29 19:58:14 +02:00
$ curl -s "ntfy.sh/mytopic/json?since=10m"< br / >
# Same output as above, but includes messages from up to 10 minutes ago
2021-10-24 20:22:53 +02:00
< / code >
2021-10-27 20:56:17 +02:00
< p class = "smallMarginBottom" >
2021-10-29 19:58:14 +02:00
You can also just poll for messages if you don't like the long-standing connection using the < tt > poll=1< / tt >
query parameter. The connection will end after all available messages have been read. This parameter has to be
combined with < tt > since=< / tt > .
2021-10-25 04:08:06 +02:00
< / p >
< code >
2021-10-29 19:58:14 +02:00
$ curl -s "ntfy.sh/mytopic/json?poll=1& since=10m"< br / >
# Returns messages from up to 10 minutes ago and ends the connection
2021-10-25 04:08:06 +02:00
< / code >
2021-11-01 21:39:40 +01:00
2021-10-25 04:08:06 +02:00
< h2 > FAQ< / h2 >
< p >
< b > Isn't this like ...?< / b > < br / >
Who knows. I didn't do a lot of research before making this. It was fun making it.
< / p >
< p >
< b > Can I use this in my app? Will it stay free?< / b > < br / >
Yes. As long as you don't abuse it, it'll be available and free of charge. I do not plan on monetizing
the service.
< / p >
< p >
< b > What are the uptime guarantees?< / b > < br / >
Best effort.
< / p >
< p >
< b > Will you know what topics exist, can you spy on me?< / b > < br / >
If you don't trust me or your messages are sensitive, run your own server. It's < a href = "https://github.com/binwiederhier/ntfy" > open source< / a > .
That said, the logs do not contain any topic names or other details about you. Check the code if you don't believe me.
< / p >
2021-11-01 21:39:40 +01:00
< p >
< b > Why is Firebase used?< / b > < br / >
In addition to caching messages locally and delivering them to long-polling subscribers, all messages are also
published to Firebase Cloud Messaging (FCM) (if < tt > FirebaseKeyFile< / tt > is set, which it is on ntfy.sh). This
is to facilitate instant notifications on Android. I tried really, really hard to avoid using FCM, but newer
versions of Android made it impossible to implement < a href = "https://developer.android.com/guide/background" > background services< / a > >.
I'm sorry.
< / p >
< h2 > Privacy policy< / h2 >
< p >
Neither the server nor the app record any personal information, or share any of the messages and topics with
2021-11-03 16:33:34 +01:00
any outside service. All data is exclusively used to make the service function properly. The one exception
2021-11-01 21:39:40 +01:00
is the Firebase Cloud Messaging (FCM) service, which is required to provide instant Android notifications (see
FAQ for details).
< / p >
< p >
The web server does not log or otherwise store request paths, remote IP addresses or even topics or messages,
2021-11-02 19:08:21 +01:00
aside from a short on-disk cache (up to a day) to support service restarts.
2021-11-01 21:39:40 +01:00
< / p >
2021-10-25 04:08:06 +02:00
< center id = "ironicCenterTagDontFreakOut" > < i > Made with ❤️ by < a href = "https://heckel.io" > Philipp C. Heckel< / a > < / i > < / center >
2021-10-24 03:29:45 +02:00
< / div >
2021-10-24 20:22:53 +02:00
< script src = "static/js/app.js" > < / script >
2021-10-23 03:26:01 +02:00
< / body >
< / html >