Push Packs API
Complete REST API documentation for managing Push Packs — sets of automatic push notifications by schedule and events
Authorization
All requests require the Authorization: Bearer <token> header.
To manage system packs you need admin access — using one of these methods:
- JWT token of a user with
is_admin = true - API key with scope
"admin"(headerAuthorization: Bearer psk_live_...)
Check your status: GET /api/v3/profile → field is_admin.
Reading (available to all users)
List Packs
GET /api/v3/push-packsReturns user packs + published system packs.
Note: regular users see only published system packs (
is_published: true). User packs are always considered published. To view all system packs (including drafts) use the admin endpointGET /api/v3/admin/push-packs.
Example request:
curl -X GET "https://api.notify.partners/api/v3/push-packs" \
-H "Authorization: Bearer psk_live_xxxx"Response:
[
{
"id": 1,
"user_id": 5,
"name": "My Pack",
"fallback_language": "en",
"is_system": false,
"is_published": true,
"created_at": "2026-03-18T10:00:00Z",
"updated_at": "2026-03-18T10:00:00Z"
},
{
"id": 2,
"user_id": null,
"name": "System Welcome Pack",
"fallback_language": "en",
"is_system": true,
"is_published": true,
"created_at": "2026-03-18T10:00:00Z",
"updated_at": "2026-03-18T10:00:00Z"
}
]Pack Details
GET /api/v3/push-packs/:pack_idExample request:
curl -X GET "https://api.notify.partners/api/v3/push-packs/1" \
-H "Authorization: Bearer psk_live_xxxx"Pack Languages
GET /api/v3/push-packs/:pack_id/languagesExample request:
curl -X GET "https://api.notify.partners/api/v3/push-packs/2/languages" \
-H "Authorization: Bearer psk_live_xxxx"Response:
[
{"id": 4, "pack_id": 2, "language_code": "ru", "created_at": "2026-03-18T10:00:00Z"},
{"id": 5, "pack_id": 2, "language_code": "en", "created_at": "2026-03-18T10:00:00Z"}
]Scheduled Pushes
GET /api/v3/push-packs/:pack_id/languages/:lang_id/scheduledExample request:
curl -X GET "https://api.notify.partners/api/v3/push-packs/2/languages/4/scheduled" \
-H "Authorization: Bearer psk_live_xxxx"Response (for non-administrators, title and body fields of system packs are masked):
[
{
"id": 3,
"language_id": 4,
"day_of_week": 0,
"send_time": "10:00:00",
"title": "***",
"body": "***",
"click_url": "https://app.com/bonus",
"created_at": "2026-03-18T10:17:01Z",
"updated_at": "2026-03-18T10:17:01Z"
}
]For administrators, the full content is returned: "title": "Monday Bonus".
Event Pushes
GET /api/v3/push-packs/:pack_id/languages/:lang_id/eventsExample request:
curl -X GET "https://api.notify.partners/api/v3/push-packs/2/languages/4/events" \
-H "Authorization: Bearer psk_live_xxxx"Response (same masking for non-administrators):
[
{
"id": 2,
"language_id": 4,
"event_code": "install",
"delay_minutes": 5,
"title": "***",
"body": "***",
"created_at": "2026-03-18T10:17:18Z",
"updated_at": "2026-03-18T10:17:18Z"
}
]Application Packs
GET /api/v3/apps/:app_id/push-packsReturns packs attached to the application.
Example request:
curl -X GET "https://api.notify.partners/api/v3/apps/1/push-packs" \
-H "Authorization: Bearer psk_live_xxxx"Attaching Packs to Applications (available to application owner)
Attach a Pack
POST /api/v3/apps/:app_id/push-packs
Content-Type: application/jsonRequest body:
{"pack_id": 2}Example request:
curl -X POST "https://api.notify.partners/api/v3/apps/1/push-packs" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"pack_id": 2}'Detach a Pack
DELETE /api/v3/apps/:app_id/push-packs/:pack_idExample request:
curl -X DELETE "https://api.notify.partners/api/v3/apps/1/push-packs/2" \
-H "Authorization: Bearer psk_live_xxxx"Managing System Packs (admin only)
Base path: /api/v3/admin/push-packs
Without admin access returns 403 {"error": "admin access required"}.
Create a System Pack
System packs are created as draft (is_published: false). While unpublished, regular users cannot see the pack or attach it to applications. This allows preparing content (languages, pushes) before publishing.
POST /api/v3/admin/push-packs
Content-Type: application/jsonRequest body:
{
"name": "iGaming Welcome RU+EN",
"fallback_language": "en"
}Example request:
curl -X POST "https://api.notify.partners/api/v3/admin/push-packs" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"name": "iGaming Welcome RU+EN", "fallback_language": "en"}'Response (201):
{
"id": 2,
"user_id": null,
"name": "iGaming Welcome RU+EN",
"fallback_language": "en",
"is_system": true,
"is_published": false,
"created_at": "2026-03-18T10:16:24Z",
"updated_at": "2026-03-18T10:16:24Z"
}Update a System Pack
PUT /api/v3/admin/push-packs/:pack_id
Content-Type: application/jsonRequest body:
{
"name": "New Name",
"fallback_language": "ru"
}Example request:
curl -X PUT "https://api.notify.partners/api/v3/admin/push-packs/2" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"name": "New Name", "fallback_language": "ru"}'Delete a System Pack
DELETE /api/v3/admin/push-packs/:pack_idExample request:
curl -X DELETE "https://api.notify.partners/api/v3/admin/push-packs/2" \
-H "Authorization: Bearer psk_live_xxxx"Response: 204 No Content
List All System Packs (including drafts)
GET /api/v3/admin/push-packsReturns all system packs, including unpublished ones (is_published: false). Unlike the user GET /api/v3/push-packs, draft packs are visible here.
Example request:
curl -X GET "https://api.notify.partners/api/v3/admin/push-packs" \
-H "Authorization: Bearer psk_live_xxxx"Response:
[
{
"id": 2,
"user_id": null,
"name": "iGaming Welcome RU+EN",
"fallback_language": "en",
"is_system": true,
"is_published": true,
"created_at": "2026-03-18T10:16:24Z",
"updated_at": "2026-03-18T10:16:24Z"
},
{
"id": 3,
"user_id": null,
"name": "Betting Promo Pack (draft)",
"fallback_language": "en",
"is_system": true,
"is_published": false,
"created_at": "2026-03-18T12:00:00Z",
"updated_at": "2026-03-18T12:00:00Z"
}
]Publish / Unpublish a System Pack
PUT /api/v3/admin/push-packs/:pack_id/publish
Content-Type: application/jsonToggles the publication status of a system pack:
"is_published": true— the pack becomes visible to regular users and available for attaching to applications"is_published": false— the pack is hidden from regular users' list; existing application attachments are preserved but push sending is paused
Request body parameters:
| Field | Type | Required | Description |
|---|---|---|---|
is_published | boolean | yes | true — publish, false — unpublish |
Example request:
curl -X PUT "https://api.notify.partners/api/v3/admin/push-packs/2/publish" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"is_published": true}'Response (200):
{
"id": 2,
"user_id": null,
"name": "iGaming Welcome RU+EN",
"fallback_language": "en",
"is_system": true,
"is_published": true,
"created_at": "2026-03-18T10:16:24Z",
"updated_at": "2026-03-18T14:30:00Z"
}Errors:
| HTTP | Description |
|---|---|
| 400 | Missing or invalid is_published field |
| 403 | No admin access |
| 404 | Pack not found or not a system pack |
Managing Languages (admin only)
Add a Language
POST /api/v3/admin/push-packs/:pack_id/languages
Content-Type: application/jsonRequest body:
{"language_code": "ru"}Example request:
curl -X POST "https://api.notify.partners/api/v3/admin/push-packs/2/languages" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"language_code": "ru"}'Response (201):
{"id": 4, "pack_id": 2, "language_code": "ru", "created_at": "2026-03-18T10:16:31Z"}Delete a Language
DELETE /api/v3/admin/push-packs/:pack_id/languages/:lang_idCascades to delete all pushes of this language (scheduled and event).
Example request:
curl -X DELETE "https://api.notify.partners/api/v3/admin/push-packs/2/languages/4" \
-H "Authorization: Bearer psk_live_xxxx"Managing Scheduled Pushes (admin only)
Create a Scheduled Push
POST /api/v3/admin/push-packs/:pack_id/languages/:lang_id/scheduled
Content-Type: application/jsonRequest body:
{
"day_of_week": 0,
"send_time": "10:00",
"title": "Monday Bonus",
"body": "Claim your bonus!",
"icon_url": "",
"click_url": "https://app.com/bonus",
"image_url": "",
"audience_tag": ""
}Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
day_of_week | int | yes | 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri, 5=Sat, 6=Sun |
send_time | string | yes | Format HH:MM (UTC) |
title | string | yes | Title (max 255) |
body | string | no | Text (max 2000) |
icon_url | string | no | Icon URL |
click_url | string | no | Click URL |
image_url | string | no | Image URL |
audience_tag | string | no | Audience tag (filter) |
Example request:
curl -X POST "https://api.notify.partners/api/v3/admin/push-packs/2/languages/4/scheduled" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{
"day_of_week": 0,
"send_time": "10:00",
"title": "Monday Bonus",
"body": "Claim your bonus!",
"click_url": "https://app.com/bonus"
}'Update a Scheduled Push
PUT /api/v3/admin/push-packs/:pack_id/scheduled/:item_id
Content-Type: application/jsonRequest body — same fields as for creation.
Example request:
curl -X PUT "https://api.notify.partners/api/v3/admin/push-packs/2/scheduled/3" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"day_of_week": 1, "send_time": "12:00", "title": "Tuesday Bonus"}'Delete a Scheduled Push
DELETE /api/v3/admin/push-packs/:pack_id/scheduled/:item_idExample request:
curl -X DELETE "https://api.notify.partners/api/v3/admin/push-packs/2/scheduled/3" \
-H "Authorization: Bearer psk_live_xxxx"Managing Event Pushes (admin only)
Create an Event Push
POST /api/v3/admin/push-packs/:pack_id/languages/:lang_id/events
Content-Type: application/jsonRequest body:
{
"event_code": "install",
"delay_minutes": 5,
"title": "Welcome!",
"body": "Get your install bonus",
"icon_url": "",
"click_url": "",
"image_url": "",
"audience_tag": ""
}Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
event_code | string | yes | Event code: install, reg, dep, purchase, subscribe or custom |
delay_minutes | int | no | Send delay after event (default 0) |
title | string | yes | Title (max 255) |
body | string | no | Text (max 2000) |
icon_url | string | no | Icon URL |
click_url | string | no | Click URL |
image_url | string | no | Image URL |
audience_tag | string | no | Audience tag |
Example request:
curl -X POST "https://api.notify.partners/api/v3/admin/push-packs/2/languages/4/events" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{
"event_code": "install",
"delay_minutes": 5,
"title": "Welcome!",
"body": "Get your install bonus"
}'Update an Event Push
PUT /api/v3/admin/push-packs/:pack_id/events/:item_id
Content-Type: application/jsonRequest body — same fields as for creation.
Example request:
curl -X PUT "https://api.notify.partners/api/v3/admin/push-packs/2/events/2" \
-H "Authorization: Bearer psk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"event_code": "reg", "delay_minutes": 10, "title": "Thanks for registering!"}'Delete an Event Push
DELETE /api/v3/admin/push-packs/:pack_id/events/:item_idExample request:
curl -X DELETE "https://api.notify.partners/api/v3/admin/push-packs/2/events/2" \
-H "Authorization: Bearer psk_live_xxxx"Operators in Pushes
The title and body fields support operators for dynamic content. Operators are processed by the service before sending to each recipient.
Random Selection Operators (per-device — each recipient gets their own result)
| Operator | Description | Example |
|---|---|---|
{a|b|c} | Random selection of one variant | Get {100|200|500} coins! |
{Random=[min,max]} | Random number in range | You earned {Random=[10,100]} bonuses! |
{TimeOfDay} | Time of day by device timezone: morning/afternoon/evening/night (6–11 / 12–17 / 18–22 / 23–5). Supports 10 languages. | Good {TimeOfDay}! Claim your bonus |
Static Operators (same for all recipients of one send)
| Operator | Description | Example |
|---|---|---|
{Date:FORMAT} | Current date. Tokens: DD, MM, YYYY, YY | Sale ends {Date:DD.MM.YYYY} |
{Weekday} | Day of week in device language (10 languages) | Come back on {Weekday}! |
{Weekday:short} | Abbreviated day of week | Sale on {Weekday:short} |
{Push={A|B|C}} | Round-robin content rotation between sends (A→B→C→A). Used for A/B rotation. | {Push={Welcome!|Hey, we missed you!}} |
Post-processing Operators
| Operator | Description | Example |
|---|---|---|
{Upper:text} | Convert to UPPER CASE | {Upper:important}: read this |
{Lower:TEXT} | Convert to lower case | click {Lower:HERE} |
Processing order: first static operators (Date, Weekday), then Push Rotation, then per-device operators (TextRotation, Random, TimeOfDay), then post-processing (Upper, Lower), then
{{macro}}macros.
Validation: curly braces
{}must be balanced.{Push={A|B}}— correct.{A|B— error.
Macros
In addition to operators ({}), the title and body fields support macros — substituted individually for each recipient at send time. Macros use double braces {{macro}}.
| Macro | Description |
|---|---|
{{app_name}} | Application name |
{{app_id}} | Application ID |
{{app_link}} | Application link URL (if configured for the app) |
{{external_id}} | Recipient's external user ID |
{{language}} | Device language code (e.g. en, ru) |
{{country}} | Device country code (e.g. US, UA) |
{{platform}} | Platform type: android, ios, or web |
{{platform_name}} | Platform name (e.g. Chrome, Firefox, Safari) |
{{timezone}} | Device timezone offset in seconds |
{{tag:key}} | Custom device tag value by key (e.g. {{tag:vip_level}}) |
Example:
{
"title": "Special offer from {{app_name}}!",
"body": "Hi {{external_id}}, your country: {{country}}"
}Macros are processed after operators. If a value is not set for the device, the macro is replaced with an empty string.
Error Codes
| HTTP | Description |
|---|---|
| 400 | Invalid data (empty title, invalid send_time format, etc.) |
| 401 | Unauthorized (missing or invalid token) |
| 403 | Access denied (not admin for admin endpoints, or attempt to modify system pack via regular API) |
| 404 | Pack, language or push not found |
| 409 | Conflict (duplicate language_code in pack) |
Send Logic
System packs work automatically after attaching to an application:
-
By schedule — every minute the server checks the current day and time (UTC), finds matching scheduled pushes and sends them to all devices of the attached applications.
-
By events — when a postback or SDK event is received (install, reg, dep, and others), the server finds matching event pushes and sends to the specific device with the specified delay (
delay_minutes). -
Language selection — for each device, the language from the pack is selected by device settings; if the language is not found —
fallback_languageis used.