Documentation
How to send push notifications from your server, script, cron job or database straight to your phone — no account, no sign-up.
Contents
Quick start
Three steps, under two minutes.
- Create your channel on the home page. You immediately get a code, a QR code and the tokens.
- Install the app and tap "Ler QR do canal" to scan the QR code.
- Send your first message with the command below, swapping in your own code and token:
curl -d "first notification" \
-H "Authorization: Bearer YOUR_PUBLISH_TOKEN" \
https://notify.hlgcloud.com.br/v1/publish/hlg-xxxxxxxxYour phone should buzz within a few seconds, even with the app closed.
How it works
Everything revolves around a channel. The channel is the address messages go to, and the device that scanned the QR code is the one that receives them.
- Channel — identified by a code like
hlg-7ad4p7x7. It's public: it's not a secret, whoever publishes to it also needs the token. - Device — every phone that scans the QR code joins the channel. A channel can have several devices, and all of them receive the same messages.
- Message — what you send. It has a body, and optionally a title and priority.
A device can be in several channels at the same time. In the app, switch channels from the list at the top of the screen and use "Adicionar canal" to scan another QR. Each channel has its own notifications: you can mute one without affecting the others.
Send a notification
There's only one address to publish to, and it accepts POST:
POST https://notify.hlgcloud.com.br/v1/publish/YOUR_CODE
Authorization: Bearer YOUR_PUBLISH_TOKENPlain text (the simplest way)
Send the text as the body, no JSON at all. This is the format meant to be pasted straight into a cron job:
curl -d "backup finished" \
-H "Authorization: Bearer YOUR_PUBLISH_TOKEN" \
https://notify.hlgcloud.com.br/v1/publish/hlg-xxxxxxxxJSON (with title and priority)
curl -X POST \
-H "Authorization: Bearer YOUR_PUBLISH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Database backup",
"body": "Finished in 4m12s, 2.3 GB",
"priority": 3
}' \
https://notify.hlgcloud.com.br/v1/publish/hlg-xxxxxxxxAccepted fields
| Field | Type | Description |
|---|---|---|
body | text | Required. The notification's content. |
title | text | Title. Without it, the notification uses the channel code. |
priority | 1 to 5 | Default 3. Determines color, sound and vibration. |
tags | list | Free-form tags, stored alongside the message. |
click_url | text | Link opened when the notification is tapped. |
data | object | Any extra JSON you want to attach. |
The response is 202 with the message id and how many devices it was queued for:
{ "message_id": 42, "devices": 2 }Title
The title is optional. When you don't send one, the notification shows the channel code instead — so it never arrives without any identification:
curl -d "Job completed successfully." \
-H "Authorization: Bearer YOUR_PUBLISH_TOKEN" \
https://notify.hlgcloud.com.br/v1/publish/hlg-7ad4p7x7
→ Title: hlg-7ad4p7x7
Message: Job completed successfully.Formatting
The body accepts its own markup syntax for highlighting parts of the
text. These are paired tags (open/close) that can be freely combined:
| Marker | Effect |
|---|---|
<bold>text</bold> | Bold |
<small>text</small> | Smaller font |
<big>text</big> | Larger font |
<link>https://...</link> |
Clickable link — the content must be only the full URL
(http:// or https://), with no other text |
<red>text</red> | Red text |
<yellow>text</yellow> | Yellow text |
<green>text</green> | Green text |
<blue>text</blue> | Blue text |
Colors automatically adjust to the phone's light/dark theme — the exact shade varies slightly between the two, the color itself doesn't.
This isn't HTML. Despite looking like tags, this is a custom syntax built only
for HLG Notify: only the markers above are recognized, and there's no HTML parser behind it.
Any other tag (e.g. <div>), an unclosed marker, or one closed out of
order shows up as plain text in the message — it never breaks sending or the app.
Markers can be nested in any order, as long as closing follows the reverse order of opening — just like HTML/XML:
<bold><big><red>Backup failed</red></big></bold>
Check the log at <bold><link>https://status.example.com</link></bold>Line breaks and blank lines don't use a marker — they're already literal \n and
\n\n inside the body, and work with no change needed:
curl -X POST \
-H "Authorization: Bearer YOUR_PUBLISH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Deploy",
"body": "<bold>Version 2.1</bold> is live.\n\nFollow along at <link>https://status.example.com</link>"
}' \
https://notify.hlgcloud.com.br/v1/publish/hlg-xxxxxxxxFormatting only applies to the message's body. The title and the system notification (Android's notification bar) always show plain text, without the markers — styled text only shows up inside the app.
Priorities
Priority ranges from 1 to 5 and changes three things: the color in the app, the sound and the vibration. On Android, each HLG Notify channel becomes a notification group with the five levels inside it, so you can tune sound and vibration per channel and per level in the system settings — the shortcut is under "Configurações" in the app. You can also mute a whole channel there: messages still reach the history, without notifications.
| Level | Color | Behavior | When to use it |
|---|---|---|---|
1 | Light green | Silent, no vibration | Logs, routines that succeeded |
2 | Green | Default sound, no vibration | Low-urgency notice |
3 | Yellow | Sound and vibration | Default, when nothing is specified |
4 | Orange | High priority, appears on screen | Needs attention now |
5 | Red | High priority and bypasses Do Not Disturb | Waking someone up in the middle of the night |
Priority 5 rings even with the phone on Do Not Disturb. Use it sparingly — if everything is critical, nothing is.
Examples
Cron
# every day at 3am, alert if the backup fails
0 3 * * * /opt/backup.sh || curl -s -d "BACKUP FAILED" \
-H "Authorization: Bearer $HLG_TOKEN" \
https://notify.hlgcloud.com.br/v1/publish/hlg-xxxxxxxxBash
#!/usr/bin/env bash
notify() {
curl -s -X POST \
-H "Authorization: Bearer $HLG_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"title\":\"$1\",\"body\":\"$2\",\"priority\":${3:-3}}" \
"https://notify.hlgcloud.com.br/v1/publish/$HLG_CANAL" > /dev/null
}
notify "Deploy" "Version 2.1 is live" 3
notify "Disk full" "/ at 96% usage" 5Python
import requests
requests.post(
"https://notify.hlgcloud.com.br/v1/publish/hlg-xxxxxxxx",
headers={"Authorization": "Bearer YOUR_PUBLISH_TOKEN"},
json={"title": "ETL", "body": "12,402 rows processed", "priority": 2},
timeout=10,
)Oracle (PL/SQL)
Once the package is installed (step-by-step in the download package below), publishing is a single call:
BEGIN
hlgnotify_core_pkg.publicar(
p_canal => 'hlg-xxxxxxxx',
p_body => 'Done',
p_title => 'Nightly job',
p_priority => 2
);
END;
/The package looks up the channel's token and wallet from a table — no hardcoded credentials in the call. Requires a configured wallet and a network ACL allowing the host (step-by-step in the download package).
Full package (Oracle 19c or later) — the channel table DDL, the production-ready
hlgnotify_core_pkg package (authentication, UTF-8 payload, timeout, JSON escaping
and error handling), the certificates to build the wallet, and the installation
step-by-step (wallet + ACL + table + package + channel setup).
n8n
Use the HTTP Request node:
- Method:
POST - URL:
https://notify.hlgcloud.com.br/v1/publish/YOUR_CODE - Header:
Authorization: Bearer YOUR_PUBLISH_TOKEN - Body (JSON):
{"title":"...","body":"...","priority":3}
API
| Endpoint | Authentication | What it's for |
|---|---|---|
POST /v1/publish/:code | publish token | Send a notification |
GET /v1/messages/:code | device token | Channel history |
DELETE /v1/messages/:code | publish token | Clear the history |
GET /v1/channels/:code/info | publish or device | Name and device count |
GET /v1/channels/:code/devices | publish token | List devices |
POST /v1/public/channels | none | Create a channel |
A wrong token gets 401 and nothing is recorded. A non-existent channel gets 404.
Tokens
When you create a channel you get two tokens, with very different purposes — and that difference is what lets you invite people to the channel without giving them the power to publish messages:
| Token | Allows | Where it lives |
|---|---|---|
| Publish | Sending messages, viewing subscribed devices, and clearing the channel's history — i.e. it administers the channel | In your scripts and servers, or saved with you. Never share it, never put it in the app. |
| Enroll | Only subscribing a device to the channel, so it starts receiving notifications | Inside the QR code. It's what the app reads when scanning it — it can circulate freely. |
⚠️ BE CAREFUL with the publish token. Whoever has this token can send notifications to the entire channel (and view/erase its history) — treat it like a password. It's shown only once, on the channel creation screen, and isn't stored anywhere on the server — only its hash. If you lose it, there's no way to recover it: create another channel instead.
That's why the home page generates two different files after creating the channel:
- Invite (QR .png or .html) — only has the QR code, i.e. only the embedded enroll token. This is what you distribute: send it to the group, print it, paste it on a page. Whoever scans it joins the channel to receive notifications; no one can publish with it.
- Admin credentials (.html) — has the channel code, the publish token and the curl example. It's yours only: keep it somewhere safe and never send it to anyone who should only receive notifications.
In short: giving someone the QR code/invite doesn't give that person the power to publish to your channel — only the admin credentials file does that, and you don't share that one.
Manage the channel
On the My channel page, with the code and the publish token, you can:
- See subscribed devices — identification, platform, when it joined and when it was last seen.
- Give the channel a nickname — the name every subscriber sees in the app's channel list (up to 60 characters). The app shows the new name on its next refresh.
- Clear the channel's history — erases all messages on the server. Devices stay subscribed and tokens don't change; only the history disappears, on every device.
Clearing the history is irreversible and affects every device on the channel. That's why the page
asks you to type APAGAR to confirm.
For a device to leave the channel, use "Sair deste canal" in the app's settings. That only unsubscribes that device, only from that channel — its other channels keep working — and doesn't erase anyone else's history.
Limits
| Limit | Value |
|---|---|
| Messages kept per channel | the most recent 100 |
| Message size (title + body + link) | 3500 bytes |
| Sends per channel | 60 per minute |
| Channel creation | 5 per minute, per IP |
Anything past 100 messages is discarded on the server, but stays on the phone — the app keeps its own history. Need more than that? Contact support.
FAQ
The notification doesn't arrive. What should I check?
- Open "Sobre" in the app and check whether Notifications shows as "Permitidas".
- Check whether the command returned
202and how manydevices. If it's0, no device is subscribed to that channel. - Check whether the channel code in the command matches the one shown in "Sobre".
- Check under "Configurações" whether the channel is muted — when muted, the message reaches the history without notifying.
- If aggressive battery saving is on, allow the app to run in the background.
I switched phones. Now what?
Just scan the same QR code on the new device. If you no longer have the QR code, the enroll token alone works: you can type it on the app's initial screen along with the channel code. If you were receiving from several channels, repeat for each one using "Adicionar canal".
I lost the publish token.
There's no way to recover it — the server only stores its hash. Create a new channel and scan its QR code in the app.
Can I use the same channel on several phones?
Yes. Every device that scans the QR code receives the same messages.
I want to invite a group of people, but without letting anyone publish. Can I?
Yes, and it already works that way by default — see Tokens. Only distribute the invite file (QR .png or .html) generated on the home page: it carries only the enroll token, which only subscribes the device. The publish token stays in the separate admin credentials file, which you keep to yourself — that's the one that sends messages.
Do I need to create an account?
No. There's no sign-up, email or password. The channel is your identity.
Does deleting a message in the app delete it for everyone?
No. Swiping it away or using the trash icon only removes that device's copy. To delete it for everyone, use "Limpar histórico do canal" on the My channel page.