Sending notifications
Targets, content per language, data, links, buttons, categories and validation.
A send is a POST /v1/notifications with your secret key, or the same thing from New send in the panel. It responds 202 immediately and is delivered in the background.
{
"target": { "type": "external_users", "ids": ["customer-123"] },
"content": {
"en": { "title": "Your order is on its way", "body": "Arriving today" },
"es": { "title": "Tu pedido va en camino", "body": "Llega hoy" }
},
"data": { "orderId": "A-1029" },
"deepLink": "myapp://orders/A-1029"
}
Targets (target.type)
| Type | Fields | Reaches |
|---|---|---|
devices |
ids or tokens |
Specific devices |
external_users |
ids |
All the devices of those users (externalUserId) |
topic |
name |
Those subscribed to the topic |
segment |
segmentId |
Those matching a saved segment |
filters |
rules |
An on-the-fly filter (same format as segments) |
all |
— | All active devices of the app |
test_devices |
— | Only test devices |
With a test key, any target is limited to test devices. platforms: ["ios"] restricts to one platform.
Content
- Per language:
content.en,content.es… withtitle,subtitle(iOS) andbody. Each device receives its language; if it isn't there, the app's default language. - Variables:
{{name}}in the text, with their values invariables. - Templates:
templateIduses a saved template; what you send in the request takes priority. contentType:alert, the visible one (default);data_only, data only: the app builds the notification. The title and text travel indata, in the keys your framework's plugin reads (titleandbody;titleandmessagein Cordova and Expo). See Compatibility;silent, to update the app in the background.
Data, links and buttons
data: up to 50 keys your app receives. Don't use keys starting with_ph: they're Pushtifly's.deepLink: the app receives it when the notification is tapped.actions: up to 3 buttons{ id, title, deepLink }. They require code in the app (or the SDK).sound:defaultor a sound included in the app and registered in the panel.badge(iOS),ttlSeconds(up to 28 days),priority(high/normal).- Per-platform options:
android:channelId,color,tag,collapseKey;ios:interruptionLevel,threadId,relevanceScore.
Category
transactional(default): orders, security, user reminders.marketing: promotions. It goes through a lower-priority queue, so it never delays transactional ones, and it respects the app's limits.
Marketing limits
In each app's settings (Apps → edit → Marketing) you can set two limits. They're applied in each device's local time and only to marketing sends:
- Maximum per device per day: notifications above the limit are skipped. They show up as
skipped(codeFREQUENCY_CAP) and don't count as failed. - Quiet hours (for example, from 22:00 to 08:00): delivery is postponed until the end time. The send stays in
sendinguntil they're delivered, andstats.deferredcounts how many were postponed.
If the device didn't report its time zone, the company's is used. The SDK always sends it.
Validate without sending
"validateOnly": true validates everything, estimates how many devices it would reach and calculates the payload size, without creating the send.
The payload can't exceed 4 KB (2003): media never travels in the payload, only its URL.
Tracking
GET /v1/notifications/{id}: status and statistics (sent, accepted, failed, invalid tokens, opens, clicks).GET /v1/notifications/{id}/deliveries: the result per device.POST /v1/notifications/{id}/cancel: cancels a scheduled or in-progress send.notification.completedandnotification.failedwebhooks when it ends. See Webhooks.