Create Message POST
Send a push notification to your devices.
Endpoint
POST https://api.pocketalert.app/v1/messagesAuthentication
Required
Include one of these headers in your request:
Request
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | ✅ | application/json |
Token | ✅ | Your API key |
Authorization | ✅ | Bearer <jwt-token> |
* One of Token or Authorization is required
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | ✅ | Notification title |
message | string | ✅ | Notification body text |
application_id | string | ❌ | Application TID to categorize the message |
device_id | string | ❌ | Specific device TID, omit for all devices |
level | string | int | ❌ | Priority level controlling how the push is delivered. Accepts a name or an int (-2..2). priority is accepted as a synonym. Defaults to the application's default level, then default. |
actions | array | ❌ | Up to 3 action buttons shown on the notification. See Action buttons. |
send_at | string | int | ❌ | Deliver at a specific time instead of immediately. RFC3339, Unix timestamp, or YYYY-MM-DD HH:MM. See Scheduled delivery. |
delay | string | ❌ | Deliver after a relative delay — 30m, 2h, or bare seconds. Mutually exclusive with send_at. |
Action buttons
Each notification can carry up to 3 action buttons. actions is an array of objects:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | ✅ | view (open a URL), http (fire an HTTP request), or copy (copy text to clipboard) |
label | string | ✅ | Button text. Shown on Android; on iOS a generic label per type is shown (Open / Run / Copy) |
value | string | ✅ | Depends on type — see below |
value by type:
view— the URL to open, e.g."https://pocketalert.app".http— a JSON string describing the request:{"url":"https://…","method":"POST","headers":{…},"body":"…"}. Onlyurlis required;methoddefaults toGET. Fires silently in the background without opening the app.copy— the literal text placed on the clipboard.
Human-in-the-loop
Two http actions (e.g. Approve / Decline) make a one-tap control panel — ideal for approving LLM-agent actions straight from the notification.
See Action buttons for limits, validation and webhook templates.
Priority levels
| Level | Aliases | Behavior |
|---|---|---|
silent | min, -2 | Delivered to the tray only — no sound or vibration |
low | -1 | Quiet, no interruption |
default | normal, 0 (or omitted) | Standard banner + sound |
high | 1 | Time-sensitive — breaks through Focus / scheduled summary |
critical | max, urgent, 2 | Wakes the device through the silent switch and Do Not Disturb |
WARNING
critical is a paid-plan feature. On free plans it is automatically downgraded to high. Invalid values (unknown name or out-of-range int) return 400.
See Priority levels for how each level behaves on iOS and Android.
Scheduled delivery
Add send_at or delay — never both — and the message is stored encrypted until its delivery time instead of being sent immediately.
| Parameter | Accepts | Examples |
|---|---|---|
send_at | RFC3339, Unix timestamp, or YYYY-MM-DD HH:MM | 2026-08-15T09:00:00Z, 1786867200 |
delay | Go-style duration or bare seconds | 30m, 2h, 3600 |
A time without an offset is read in your account timezone. The horizon is 30 days, and a past send_at returns 400 (with 60 seconds of tolerance for clock skew).
Scheduled requests return 201 with "scheduled": true, status, deliver_at and deliver_at_utc instead of a delivered message. List them with GET /v1/messages/scheduled and cancel with DELETE /v1/messages/scheduled/{tid} — see Scheduled delivery.
WARNING
Scheduled delivery is a paid-plan feature. Free-plan requests using send_at or delay return 403.
Example Request
curl -X POST "https://api.pocketalert.app/v1/messages" \
-H "Token: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Server Alert",
"message": "CPU usage exceeded 90%",
"application_id": "qm47b9pzxzxg",
"level": "critical",
"actions": [
{ "type": "view", "label": "Dashboard", "value": "https://status.example.com" },
{ "type": "http", "label": "Restart", "value": "{\"url\":\"https://ops.example.com/restart\",\"method\":\"POST\"}" },
{ "type": "copy", "label": "Copy ID", "value": "incident-4821" }
]
}'const response = await fetch('https://api.pocketalert.app/v1/messages', {
method: 'POST',
headers: {
'Token': 'your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Server Alert',
message: 'CPU usage exceeded 90%',
application_id: 'qm47b9pzxzxg'
})
});
const data = await response.json();
console.log(data);import requests
response = requests.post(
'https://api.pocketalert.app/v1/messages',
headers={
'Token': 'your-api-key',
'Content-Type': 'application/json'
},
json={
'title': 'Server Alert',
'message': 'CPU usage exceeded 90%',
'application_id': 'qm47b9pzxzxg'
}
)
print(response.json())$response = Http::withHeaders([
'Token' => 'your-api-key',
])->post('https://api.pocketalert.app/v1/messages', [
'title' => 'Server Alert',
'message' => 'CPU usage exceeded 90%',
'application_id' => 'qm47b9pzxzxg',
]);
return $response->json();Response
Success Response
201 Created
Message created successfully
| Field | Type | Description |
|---|---|---|
tid | string | Unique message identifier |
title | string | Message title |
message | string | Message body |
application | string | Application name (if specified) |
device | string | Target device name |
actions | array | Action buttons echoed back (only when provided) |
created_at | string | Creation timestamp |
{
"tid": "jb4xw9elz28g",
"title": "Server Alert",
"message": "CPU usage exceeded 90%",
"application": "Monitoring",
"device": "iPhone",
"actions": [
{ "type": "view", "label": "Dashboard", "value": "https://status.example.com" }
],
"created_at": "18.01.2026 15:35:35"
}Error Responses
| Status | Description |
|---|---|
401 | Unauthorized — Invalid or missing token |
422 | Validation Error — Missing required fields |
429 | Rate Limited — Too many requests |
{
"error": "Validation failed",
"details": {
"title": ["The title field is required"]
}
}