# Publishing
Publishing messages can be done via HTTP PUT/POST or via the [ntfy CLI](install.md). Topics are created on the fly by
subscribing or publishing to them. Because there is no sign-up, **the topic is essentially a password**, so pick
something that's not easily guessable.
Here's an example showing how to publish a simple message using a POST request:
=== "Command line (curl)"
```
curl -d "Backup successful 😀" ntfy.sh/mytopic
```
=== "ntfy CLI"
```
ntfy publish mytopic "Backup successful 😀"
```
=== "HTTP"
``` http
POST /mytopic HTTP/1.1
Host: ntfy.sh
Backup successful 😀
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/mytopic', {
method: 'POST', // PUT works too
body: 'Backup successful 😀'
})
```
=== "Go"
``` go
http.Post("https://ntfy.sh/mytopic", "text/plain",
strings.NewReader("Backup successful 😀"))
```
=== "PowerShell"
``` powershell
Invoke-RestMethod -Method 'Post' -Uri https://ntfy.sh/topic -Body "Backup successful 😀" -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/mytopic",
data="Backup successful 😀".encode(encoding='utf-8'))
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/mytopic', false, stream_context_create([
'http' => [
'method' => 'POST', // PUT also works
'header' => 'Content-Type: text/plain',
'content' => 'Backup successful 😀'
]
]));
```
If you have the [Android app](subscribe/phone.md) installed on your phone, this will create a notification that looks like this:
There are more features related to publishing messages: You can set a [notification priority](#message-priority),
a [title](#message-title), and [tag messages](#tags-emojis) 🥳 🎉. Here's an example that uses some of them at together:
=== "Command line (curl)"
```
curl \
-H "Title: Unauthorized access detected" \
-H "Priority: urgent" \
-H "Tags: warning,skull" \
-d "Remote access to phils-laptop detected. Act right away." \
ntfy.sh/phil_alerts
```
=== "ntfy CLI"
```
ntfy publish \
--title "Unauthorized access detected" \
--tags warning,skull \
--priority urgent \
mytopic \
"Remote access to phils-laptop detected. Act right away."
```
=== "HTTP"
``` http
POST /phil_alerts HTTP/1.1
Host: ntfy.sh
Title: Unauthorized access detected
Priority: urgent
Tags: warning,skull
Remote access to phils-laptop detected. Act right away.
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/phil_alerts', {
method: 'POST', // PUT works too
body: 'Remote access to phils-laptop detected. Act right away.',
headers: {
'Title': 'Unauthorized access detected',
'Priority': 'urgent',
'Tags': 'warning,skull'
}
})
```
=== "Go"
``` go
req, _ := http.NewRequest("POST", "https://ntfy.sh/phil_alerts",
strings.NewReader("Remote access to phils-laptop detected. Act right away."))
req.Header.Set("Title", "Unauthorized access detected")
req.Header.Set("Priority", "urgent")
req.Header.Set("Tags", "warning,skull")
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh/phil_alerts"
$headers = @{ Title="Unauthorized access detected"
Priority="urgent"
Tags="warning,skull" }
$body = "Remote access to phils-laptop detected. Act right away."
Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/phil_alerts",
data="Remote access to phils-laptop detected. Act right away.",
headers={
"Title": "Unauthorized access detected",
"Priority": "urgent",
"Tags": "warning,skull"
})
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/phil_alerts', false, stream_context_create([
'http' => [
'method' => 'POST', // PUT also works
'header' =>
"Content-Type: text/plain\r\n" .
"Title: Unauthorized access detected\r\n" .
"Priority: urgent\r\n" .
"Tags: warning,skull",
'content' => 'Remote access to phils-laptop detected. Act right away.'
]
]));
```
## Message title
The notification title is typically set to the topic short URL (e.g. `ntfy.sh/mytopic`). To override the title,
you can set the `X-Title` header (or any of its aliases: `Title`, `ti`, or `t`).
=== "Command line (curl)"
```
curl -H "X-Title: Dogs are better than cats" -d "Oh my ..." ntfy.sh/controversial
curl -H "Title: Dogs are better than cats" -d "Oh my ..." ntfy.sh/controversial
curl -H "t: Dogs are better than cats" -d "Oh my ..." ntfy.sh/controversial
```
=== "ntfy CLI"
```
ntfy publish \
-t "Dogs are better than cats" \
controversial "Oh my ..."
```
=== "HTTP"
``` http
POST /controversial HTTP/1.1
Host: ntfy.sh
Title: Dogs are better than cats
Oh my ...
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/controversial', {
method: 'POST',
body: 'Oh my ...',
headers: { 'Title': 'Dogs are better than cats' }
})
```
=== "Go"
``` go
req, _ := http.NewRequest("POST", "https://ntfy.sh/controversial", strings.NewReader("Oh my ..."))
req.Header.Set("Title", "Dogs are better than cats")
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh/controversial"
$headers = @{ Title="Dogs are better than cats" }
$body = "Oh my ..."
Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/controversial",
data="Oh my ...",
headers={ "Title": "Dogs are better than cats" })
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/controversial', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
"Title: Dogs are better than cats",
'content' => 'Oh my ...'
]
]));
```
## Message priority
All messages have a priority, which defines how urgently your phone notifies you. You can set custom
notification sounds and vibration patterns on your phone to map to these priorities (see [Android config](subscribe/phone.md)).
The following priorities exist:
| Priority | Icon | ID | Name | Description |
|----------------------|--------------------------------------------|-----|----------------|--------------------------------------------------------------------------------------------------------|
| Max priority | ![min priority](static/img/priority-5.svg) | `5` | `max`/`urgent` | Really long vibration bursts, default notification sound with a pop-over notification. |
| High priority | ![min priority](static/img/priority-4.svg) | `4` | `high` | Long vibration burst, default notification sound with a pop-over notification. |
| **Default priority** | *(none)* | `3` | `default` | Short default vibration and sound. Default notification behavior. |
| Low priority | ![min priority](static/img/priority-2.svg) | `2` | `low` | No vibration or sound. Notification will not visibly show up until notification drawer is pulled down. |
| Min priority | ![min priority](static/img/priority-1.svg) | `1` | `min` | No vibration or sound. The notification will be under the fold in "Other notifications". |
You can set the priority with the header `X-Priority` (or any of its aliases: `Priority`, `prio`, or `p`).
=== "Command line (curl)"
```
curl -H "X-Priority: 5" -d "An urgent message" ntfy.sh/phil_alerts
curl -H "Priority: low" -d "Low priority message" ntfy.sh/phil_alerts
curl -H p:4 -d "A high priority message" ntfy.sh/phil_alerts
```
=== "ntfy CLI"
```
ntfy publish \
-p 5 \
phil_alerts An urgent message
```
=== "HTTP"
``` http
POST /phil_alerts HTTP/1.1
Host: ntfy.sh
Priority: 5
An urgent message
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/phil_alerts', {
method: 'POST',
body: 'An urgent message',
headers: { 'Priority': '5' }
})
```
=== "Go"
``` go
req, _ := http.NewRequest("POST", "https://ntfy.sh/phil_alerts", strings.NewReader("An urgent message"))
req.Header.Set("Priority", "5")
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh/phil_alerts"
$headers = @{ Priority="5" }
$body = "An urgent message"
Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/phil_alerts",
data="An urgent message",
headers={ "Priority": "5" })
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/phil_alerts', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
"Priority: 5",
'content' => 'An urgent message'
]
]));
```
## Tags & emojis 🥳 🎉
You can tag messages with emojis and other relevant strings:
* **Emojis**: If a tag matches an [emoji short code](emojis.md), it'll be converted to an emoji and prepended
to title or message.
* **Other tags:** If a tag doesn't match, it will be listed below the notification.
This feature is useful for things like warnings (⚠️, ️🚨, or 🚩), but also to simply tag messages otherwise (e.g. script
names, hostnames, etc.). Use [the emoji short code list](emojis.md) to figure out what tags can be converted to emojis.
Here's an **excerpt of emojis** I've found very useful in alert messages:
Tag
Emoji
+1
👍
partying_face
🥳
tada
🎉
heavy_check_mark
✔️
loudspeaker
📢
...
...
Tag
Emoji
-1
👎️
warning
⚠️
rotating_light
️🚨
triangular_flag_on_post
🚩
skull
💀
...
...
Tag
Emoji
facepalm
🤦
no_entry
⛔
no_entry_sign
🚫
cd
💿
computer
💻
...
...
You can set tags with the `X-Tags` header (or any of its aliases: `Tags`, `tag`, or `ta`). Specify multiple tags by separating
them with a comma, e.g. `tag1,tag2,tag3`.
=== "Command line (curl)"
```
curl -H "X-Tags: warning,mailsrv13,daily-backup" -d "Backup of mailsrv13 failed" ntfy.sh/backups
curl -H "Tags: horse,unicorn" -d "Unicorns are just horses with unique horns" ntfy.sh/backups
curl -H ta:dog -d "Dogs are awesome" ntfy.sh/backups
```
=== "ntfy CLI"
```
ntfy publish \
--tags=warning,mailsrv13,daily-backup \
backups "Backup of mailsrv13 failed"
```
=== "HTTP"
``` http
POST /backups HTTP/1.1
Host: ntfy.sh
Tags: warning,mailsrv13,daily-backup
Backup of mailsrv13 failed
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/backups', {
method: 'POST',
body: 'Backup of mailsrv13 failed',
headers: { 'Tags': 'warning,mailsrv13,daily-backup' }
})
```
=== "Go"
``` go
req, _ := http.NewRequest("POST", "https://ntfy.sh/backups", strings.NewReader("Backup of mailsrv13 failed"))
req.Header.Set("Tags", "warning,mailsrv13,daily-backup")
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh/backups"
$headers = @{ Tags="warning,mailsrv13,daily-backup" }
$body = "Backup of mailsrv13 failed"
Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/backups",
data="Backup of mailsrv13 failed",
headers={ "Tags": "warning,mailsrv13,daily-backup" })
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/backups', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
"Tags: warning,mailsrv13,daily-backup",
'content' => 'Backup of mailsrv13 failed'
]
]));
```
## Scheduled delivery
You can delay the delivery of messages and let ntfy send them at a later date. This can be used to send yourself
reminders or even to execute commands at a later date (if your subscriber acts on messages).
Usage is pretty straight forward. You can set the delivery time using the `X-Delay` header (or any of its aliases: `Delay`,
`X-At`, `At`, `X-In` or `In`), either by specifying a Unix timestamp (e.g. `1639194738`), a duration (e.g. `30m`,
`3h`, `2 days`), or a natural language time string (e.g. `10am`, `8:30pm`, `tomorrow, 3pm`, `Tuesday, 7am`,
[and more](https://github.com/olebedev/when)).
As of today, the minimum delay you can set is **10 seconds** and the maximum delay is **3 days**. This can currently
not be configured otherwise ([let me know](https://github.com/binwiederhier/ntfy/issues) if you'd like to change
these limits).
For the purposes of [message caching](config.md#message-cache), scheduled messages are kept in the cache until 12 hours
after they were delivered (or whatever the server-side cache duration is set to). For instance, if a message is scheduled
to be delivered in 3 days, it'll remain in the cache for 3 days and 12 hours. Also note that naturally,
[turning off server-side caching](#message-caching) is not possible in combination with this feature.
=== "Command line (curl)"
```
curl -H "At: tomorrow, 10am" -d "Good morning" ntfy.sh/hello
curl -H "In: 30min" -d "It's 30 minutes later now" ntfy.sh/reminder
curl -H "Delay: 1639194738" -d "Unix timestamps are awesome" ntfy.sh/itsaunixsystem
```
=== "ntfy CLI"
```
ntfy publish \
--at="tomorrow, 10am" \
hello "Good morning"
```
=== "HTTP"
``` http
POST /hello HTTP/1.1
Host: ntfy.sh
At: tomorrow, 10am
Good morning
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/hello', {
method: 'POST',
body: 'Good morning',
headers: { 'At': 'tomorrow, 10am' }
})
```
=== "Go"
``` go
req, _ := http.NewRequest("POST", "https://ntfy.sh/hello", strings.NewReader("Good morning"))
req.Header.Set("At", "tomorrow, 10am")
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh/hello"
$headers = @{ At="tomorrow, 10am" }
$body = "Good morning"
Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/hello",
data="Good morning",
headers={ "At": "tomorrow, 10am" })
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/backups', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
"At: tomorrow, 10am",
'content' => 'Good morning'
]
]));
```
Here are a few examples (assuming today's date is **12/10/2021, 9am, Eastern Time Zone**):
Delay/At/In header
Message will be delivered at
Explanation
30m
12/10/2021, 9:30am
30 minutes from now
2 hours
12/10/2021, 11:30am
2 hours from now
1 day
12/11/2021, 9am
24 hours from now
10am
12/10/2021, 10am
Today at 10am (same day, because it's only 9am)
8am
12/11/2021, 8am
Tomorrow at 8am (because it's 9am already)
1639152000
12/10/2021, 11am (EST)
Today at 11am (EST)
## Webhooks (publish via GET)
In addition to using PUT/POST, you can also send to topics via simple HTTP GET requests. This makes it easy to use
a ntfy topic as a [webhook](https://en.wikipedia.org/wiki/Webhook), or if your client has limited HTTP support (e.g.
like the [MacroDroid](https://play.google.com/store/apps/details?id=com.arlosoft.macrodroid) Android app).
To send messages via HTTP GET, simply call the `/publish` endpoint (or its aliases `/send` and `/trigger`). Without
any arguments, this will send the message `triggered` to the topic. However, you can provide all arguments that are
also supported as HTTP headers as URL-encoded arguments. Be sure to check the list of all
[supported parameters and headers](#list-of-all-parameters) for details.
For instance, assuming your topic is `mywebhook`, you can simply call `/mywebhook/trigger` to send a message
(aka trigger the webhook):
=== "Command line (curl)"
```
curl ntfy.sh/mywebhook/trigger
```
=== "ntfy CLI"
```
ntfy trigger mywebhook
```
=== "HTTP"
``` http
GET /mywebhook/trigger HTTP/1.1
Host: ntfy.sh
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/mywebhook/trigger')
```
=== "Go"
``` go
http.Get("https://ntfy.sh/mywebhook/trigger")
```
=== "PowerShell"
``` powershell
Invoke-RestMethod -Method 'Get' -Uri "ntfy.sh/mywebhook/trigger"
```
=== "Python"
``` python
requests.get("https://ntfy.sh/mywebhook/trigger")
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/mywebhook/trigger');
```
To add a custom message, simply append the `message=` URL parameter. And of course you can set the
[message priority](#message-priority), the [message title](#message-title), and [tags](#tags-emojis) as well.
For a full list of possible parameters, check the list of [supported parameters and headers](#list-of-all-parameters).
Here's an example with a custom message, tags and a priority:
=== "Command line (curl)"
```
curl "ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull"
```
=== "ntfy CLI"
```
ntfy publish \
-p 5 --tags=warning,skull \
mywebhook "Webhook triggered"
```
=== "HTTP"
``` http
GET /mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull HTTP/1.1
Host: ntfy.sh
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull')
```
=== "Go"
``` go
http.Get("https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull")
```
=== "PowerShell"
``` powershell
Invoke-RestMethod -Method 'Get' -Uri "ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull"
```
=== "Python"
``` python
requests.get("https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull")
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull');
```
## Publish as JSON
For some integrations with other tools (e.g. [Jellyfin](https://jellyfin.org/), [overseerr](https://overseerr.dev/)),
adding custom headers to HTTP requests may be tricky or impossible, so ntfy also allows publishing the entire message
as JSON in the request body.
To publish as JSON, simple PUT/POST the JSON object directly to the ntfy root URL. The message format is described below
the example.
!!! info
To publish as JSON, you must **PUT/POST to the ntfy root URL**, not to the topic URL. Be sure to check that you're
POST-ing to `https://ntfy.sh/` (correct), and not to `https://ntfy.sh/mytopic` (incorrect).
Here's an example using most supported parameters. Check the table below for a complete list. The `topic` parameter
is the only required one:
=== "Command line (curl)"
```
curl ntfy.sh \
-d '{
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/"
}'
```
=== "HTTP"
``` http
POST / HTTP/1.1
Host: ntfy.sh
{
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/"
}
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh', {
method: 'POST',
body: JSON.stringify({
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/"
})
})
```
=== "Go"
``` go
// You should probably use json.Marshal() instead and make a proper struct,
// or even just use req.Header.Set() like in the other examples, but for the
// sake of the example, this is easier.
body := `{
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/"
}`
req, _ := http.NewRequest("POST", "https://ntfy.sh/", strings.NewReader(body))
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh"
$body = @{
"topic"="powershell"
"title"="Low disk space alert"
"message"="Disk space is low at 5.1 GB"
"priority"=4
"attach"="https://filesrv.lan/space.jpg"
"filename"="diskspace.jpg"
"tags"=@("warning","cd")
"click"= "https://homecamera.lan/xasds1h2xsSsa/"
} | ConvertTo-Json
Invoke-RestMethod -Method 'Post' -Uri $uri -Body $body -ContentType "application/json" -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/",
data=json.dumps({
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/"
})
)
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json",
'content' => json_encode([
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/"
])
]
]));
```
The JSON message format closely mirrors the format of the message you can consume when you [subscribe via the API](subscribe/api.md)
(see [JSON message format](subscribe/api.md#json-message-format) for details), but is not exactly identical. Here's an overview of
all the supported fields:
| Field | Required | Type | Example | Description |
|------------|----------|----------------------------------|-------------------------------------------|-----------------------------------------------------------------------|
| `topic` | ✔️ | *string* | `topic1` | Target topic name |
| `message` | - | *string* | `Some message` | Message body; set to `triggered` if empty or not passed |
| `title` | - | *string* | `Some title` | Message [title](#message-title) |
| `tags` | - | *string array* | `["tag1","tag2"]` | List of [tags](#tags-emojis) that may or not map to emojis |
| `priority` | - | *int (one of: 1, 2, 3, 4, or 5)* | `4` | Message [priority](#message-priority) with 1=min, 3=default and 5=max |
| `actions` | - | *JSON array* | *(see [actiom buttons](#action-buttons))* | Custom [user action buttons](#action-buttons) for notifications |
| `click` | - | *URL* | `https://example.com` | Website opened when notification is [clicked](#click-action) |
| `attach` | - | *URL* | `https://example.com/file.jpg` | URL of an attachment, see [attach via URL](#attach-file-from-url) |
| `filename` | - | *string* | `file.jpg` | File name of the attachment |
| `delay` | - | *string* | `30min`, `9am` | Timestamp or duration for delayed delivery |
| `email` | - | *e-mail address* | `phil@example.com` | E-mail address for e-mail notifications |
## Action buttons
You can add action buttons to notifications to allow yourself to react to a notification directly. This is incredibly
useful and has countless applications.
As of today, the following actions are supported:
* [`view`](#open-websiteapp): Opens a website or app when the action button is tapped
* [`broadcast`](#send-android-broadcast): Sends an [Android broadcast](https://developer.android.com/guide/components/broadcasts) intent
when the action button is tapped
* [`http`](#send-http-request): Sends HTTP POST/GET/PUT request when the action button is tapped
Here's an example of what that a notification with actions can look like:
To define the user actions, you can either pass the `actions` field as part of the JSON body (if you're
[publishing via JSON](#publish-as-json)), or use the `X-Actions` header (or any of its aliases: `Actions`, `Action`).
Using the `X-Actions` header and the **simple format** (details see below), you can create the above notification like
this. This format is much **easier to write, but less powerful**:
=== "Command line (curl)"
```
curl \
-d "You left the house. Turn down the A/C?" \
-H "Actions: view, Open portal, https://home.nest.com/; \
http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65" \
ntfy.sh/myhome
```
=== "ntfy CLI"
```
ntfy publish \
--actions="view, Open portal, https://home.nest.com/; \
http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65" \
myhome \
"You left the house. Turn down the A/C?"
```
=== "HTTP"
``` http
POST /myhome HTTP/1.1
Host: ntfy.sh
Actions: view, Open portal, https://home.nest.com/; http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65
You left the house. Turn down the A/C?
```
=== "JavaScript"
``` javascript
fetch('https://ntfy.sh/myhome', {
method: 'POST',
body: 'You left the house. Turn down the A/C?',
headers: {
'Actions': 'view, Open portal, https://home.nest.com/; http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65'
}
})
```
=== "Go"
``` go
req, _ := http.NewRequest("POST", "https://ntfy.sh/myhome", strings.NewReader("You left the house. Turn down the A/C?"))
req.Header.Set("Actions", "view, Open portal, https://home.nest.com/; http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65")
http.DefaultClient.Do(req)
```
=== "PowerShell"
``` powershell
$uri = "https://ntfy.sh/myhome"
$headers = @{ Actions="view, Open portal, https://home.nest.com/; http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65" }
$body = "You left the house. Turn down the A/C?"
Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body -UseBasicParsing
```
=== "Python"
``` python
requests.post("https://ntfy.sh/myhome",
data="You left the house. Turn down the A/C?",
headers={ "Actions": "view, Open portal, https://home.nest.com/; http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65" })
```
=== "PHP"
``` php-inline
file_get_contents('https://ntfy.sh/reddit_alerts', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
"Actions: view, Open portal, https://home.nest.com/; http, Turn down, https://api.nest.com/device/XZ1D2, body=target_temp_f=65",
'content' => 'You left the house. Turn down the A/C?'
]
]));
```
The `X-Actions` header (including above-mentioned aliases) supports the following formats:
=== "Simple format (long)"
```
X-Actions: action=, label=