Пуші
Методи для пуш-сповіщень: завести пуш, змінити тексти й розклад, дізнатися розмір аудиторії, надіслати одразу, наклонувати й прибрати в архів. Як влаштовані пуші, типи, розклад і фільтр, див. розділ «Пуш-сповіщення».
| Метод | Адреса | Що робить |
|---|---|---|
| GET | /pwa_pushes | Список пушів |
| GET | /pwa_pushes/{id} | Один пуш |
| POST | /pwa_pushes | Створити пуш |
| PUT | /pwa_pushes/{id} | Змінити, увімкнути, вимкнути, повернути з архіву |
| GET | /pwa_pushes/{id}/audience | Скільки підписників отримає пуш |
| POST | /pwa_pushes/{id}/send | Надіслати зараз |
| POST | /pwa_pushes/{id}/clone | Клонувати |
| DELETE | /pwa_pushes/{id} | Прибрати в архів |
| POST | /pwa_pushes/preview | Показати, як текст із варіантами прийде підписнику |
| POST | /pwa_pushes/uniqueize | Переписати текст у варіанти за допомогою AI |
Замініть ВАШ_КЛЮЧ і panel.example.com на свої.
Список пушів
GET/pwa_pushes
Пуші ваших команд, нещодавно змінені зверху. Архівні не показуються.
| Параметр | Що фільтрує |
|---|---|
search | Частина назви |
type | manual, scheduled або triggered |
status | active або inactive |
team_id | Команда |
pwa_id | Пуші, які дійдуть до підписників цього PWA |
archived | 1 - разом з архівними |
page, per_page | Сторінка та її розмір (за замовчуванням 100) |
curl "https://panel.example.com/api/pwa_pushes?status=active&pwa_id=WZAX" \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json"<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$response = $api->get('pwa_pushes', ['query' => ['status' => 'active', 'pwa_id' => 'WZAX']]);
$pushes = json_decode($response->getBody(), true)['data']['pwa_pushes'];
foreach ($pushes as $push) {
echo "{$push['name']}: надіслано {$push['sent_count']}, кліків {$push['clicked_count']}\n";
}# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.get(f"{API}/pwa_pushes", headers=HEADERS, params={"status": "active", "pwa_id": "WZAX"}, timeout=30)
pushes = response.json()["data"]["pwa_pushes"]
for push in pushes:
print(push["name"], "надіслано", push["sent_count"], "кліків", push["clicked_count"])// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const params = new URLSearchParams({ status: 'active', pwa_id: 'WZAX' });
const response = await fetch(`${API}/pwa_pushes?${params}`, {
method: 'GET',
headers,
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
for (const push of data.pwa_pushes) {
console.log(push.name, 'надіслано', push.sent_count, 'кліків', push.clicked_count);
}Відповідь
{
"data": {
"meta": { "current_page": 1, "per_page": 100, "last_page": 1, "total": 1 },
"pwa_pushes": [
{
"id": "WZAX",
"name": "Evening reminder",
"type": "scheduled",
"status": "active",
"default_lang": "en",
"config": {
"messages": {
"en": { "title": "{Hey|Hi}, your plan for today is ready", "body": "Just 15 minutes - start now", "url": null, "icon": null }
},
"schedule": { "slots": [ { "days": [1, 2, 3, 4, 5], "time": "19:00" } ] },
"filter": { "pwa_ids": ["WZAX"], "countries": ["US"], "statuses": ["installed"] }
},
"sent_count": 1250,
"failed_count": 14,
"clicked_count": 96,
"archived": false,
"last_run_at": "2026-10-05T19:00:00.000000Z",
"team": { "id": "WQby", "name": "Team A" },
"created_at": "05 Oct 2026 14:23",
"updated_at": "05 Oct 2026 14:23"
}
]
}
}Лічильники за весь час: sent_count - доставлено, failed_count - не доставлено, clicked_count - кліків. last_run_at - коли пуш надсилався востаннє; на відміну від решти дат він приходить у форматі ISO 8601.
Помилки
| Код | message | Коли |
|---|---|---|
422 | The selected type is invalid. | type не з manual, scheduled, triggered |
422 | The selected status is invalid. | status не active і не inactive |
Один пуш
GET/pwa_pushes/{id}
Той самий об'єкт, що в списку, у data.pwa_push.
curl https://panel.example.com/api/pwa_pushes/WZAX \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json"<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$push = json_decode($api->get('pwa_pushes/WZAX')->getBody(), true)['data']['pwa_push'];
echo "{$push['name']}: {$push['type']}, {$push['status']}" . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
push = requests.get(f"{API}/pwa_pushes/WZAX", headers=HEADERS, timeout=30).json()["data"]["pwa_push"]
print(push["name"], push["type"], push["status"])// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/WZAX`, {
method: 'GET',
headers,
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
console.log(data.pwa_push.name, data.pwa_push.type, data.pwa_push.status);Помилки
| Код | message | Коли |
|---|---|---|
404 | Not found | Пуша з таким id немає |
403 | This action is unauthorized. | Пуш чужої команди або створений іншим користувачем (для customer) |
Створення пуша
POST/pwa_pushes
| Поле | Обов'язково | Що це |
|---|---|---|
name | так | Назва пуша в панелі |
team_id | так | Команда пуша |
type | так | manual - лише за send, scheduled - за розкладом, triggered - через час після події підписника |
default_lang | так | Мова, текст якої отримають підписники без власного перекладу |
status | ні | active - працює за розкладом і тригерами. За замовчуванням inactive |
config.messages | ні | Тексти за мовами: ключ - код мови, усередині title (обов'язковий, до 120 символів), body (до 500), url, icon |
config.schedule.slots | ні | Слоти: days - дні тижня від 1 (пн) до 7 (нд), time - час ГГ:ХХ за UTC. Без слотів пуш scheduled збережеться, але не надішлеться жодного разу |
config.schedule.delay_after | ні | Затримки після install, registration, deposit: 30m, 2h, 3d; null - тригер вимкнено. Без затримок пуш triggered не надішлеться жодного разу |
config.filter | ні | Кому надсилати: pwa_ids - PWA, countries - дволітерні коди країн, statuses - installed, registered, deposited |
У customer team_id підставляється сам - його команда.
Порожній фільтр означає «усі підписники всіх PWA команди». У pwa_ids можна вказувати лише PWA команди пуша, до яких у вас є доступ, інакше 422. Підписники вимкнених і архівних PWA до аудиторії не потрапляють: їхні застосунки не відкриваються.
У title і body можна писати варіанти тексту - {Hey|Hi} та інші конструкції з розділу «Пуш-сповіщення»: кожен підписник отримає свою комбінацію.
curl -X POST https://panel.example.com/api/pwa_pushes \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"name": "Evening reminder",
"team_id": "WQby",
"type": "scheduled",
"default_lang": "en",
"status": "active",
"config": {
"messages": { "en": { "title": "{Hey|Hi}, your plan for today is ready", "body": "Just 15 minutes - start now" } },
"schedule": { "slots": [ { "days": [1, 2, 3, 4, 5], "time": "19:00" } ] },
"filter": { "pwa_ids": ["WZAX"], "countries": ["US"], "statuses": ["installed"] }
}
}'<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$response = $api->post('pwa_pushes', ['json' => [
'name' => 'Evening reminder',
'team_id' => 'WQby',
'type' => 'scheduled',
'default_lang' => 'en',
'status' => 'active',
'config' => [
'messages' => ['en' => ['title' => '{Hey|Hi}, your plan for today is ready', 'body' => 'Just 15 minutes - start now']],
'schedule' => ['slots' => [['days' => [1, 2, 3, 4, 5], 'time' => '19:00']]],
'filter' => ['pwa_ids' => ['WZAX'], 'countries' => ['US'], 'statuses' => ['installed']],
],
]]);
$pushId = json_decode($response->getBody(), true)['data']['pwa_push']['id'];
echo "Створено пуш {$pushId}" . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.post(f"{API}/pwa_pushes", headers=HEADERS, json={
"name": "Evening reminder",
"team_id": "WQby",
"type": "scheduled",
"default_lang": "en",
"status": "active",
"config": {
"messages": {"en": {"title": "{Hey|Hi}, your plan for today is ready", "body": "Just 15 minutes - start now"}},
"schedule": {"slots": [{"days": [1, 2, 3, 4, 5], "time": "19:00"}]},
"filter": {"pwa_ids": ["WZAX"], "countries": ["US"], "statuses": ["installed"]},
},
}, timeout=30)
push_id = response.json()["data"]["pwa_push"]["id"]
print("Створено пуш", push_id)// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes`, {
method: 'POST',
headers,
body: JSON.stringify({
name: 'Evening reminder',
team_id: 'WQby',
type: 'scheduled',
default_lang: 'en',
status: 'active',
config: {
messages: { en: { title: '{Hey|Hi}, your plan for today is ready', body: 'Just 15 minutes - start now' } },
schedule: { slots: [{ days: [1, 2, 3, 4, 5], time: '19:00' }] },
filter: { pwa_ids: ['WZAX'], countries: ['US'], statuses: ['installed'] },
},
}),
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
console.log('Створено пуш', data.pwa_push.id);Відповідь - створений пуш у data.pwa_push, у тому ж вигляді, що й GET/pwa_pushes/{id}. Пуш зі статусом active почне надсилатися в найближчий відповідний слот або за тригером - без окремого запуску.
Помилки
| Код | message | Коли |
|---|---|---|
422 | The name field is required. | Не передано обов'язкове поле - так само для team_id, type, default_lang |
422 | You do not have access to this team | team_id команди, у якій вас немає |
422 | The selected type is invalid. | type не з manual, scheduled, triggered |
422 | Every message needs a title. | У тексту якоюсь мовою немає title |
422 | The config.schedule.slots.0.time field must match the format H:i. | Час слота не у форматі ГГ:ХХ |
422 | The config.schedule.slots.0.days.0 field must be between 1 and 7. | День тижня поза 1-7 |
422 | The delay must look like 30m, 2h or 3d. | Затримка тригера в іншому форматі |
422 | The selected PWA does not exist. | У config.filter.pwa_ids неіснуюче PWA |
422 | You do not have access to this resource | У config.filter.pwa_ids PWA, до якого у вас немає доступу |
422 | This resource belongs to another team | У config.filter.pwa_ids PWA іншої команди |
422 | The config.filter.countries.0 field must be 2 characters. | Країна не дволітерним кодом |
Зміна, увімкнення та вимкнення
PUT/pwa_pushes/{id}
Змінює лише передані поля, приймає ті самі поля, що й створення. Зупинити пуш - "status": "inactive", повернути з архіву - "archived": false.
curl -X PUT https://panel.example.com/api/pwa_pushes/WZAX \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"status": "inactive"}'<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$response = $api->put('pwa_pushes/WZAX', ['json' => ['status' => 'inactive']]);
$push = json_decode($response->getBody(), true)['data']['pwa_push'];
echo "{$push['name']}: {$push['status']}" . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.put(f"{API}/pwa_pushes/WZAX", headers=HEADERS, json={"status": "inactive"}, timeout=30)
push = response.json()["data"]["pwa_push"]
print(push["name"], push["status"])// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/WZAX`, {
method: 'PUT',
headers,
body: JSON.stringify({ status: 'inactive' }),
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
console.log(data.pwa_push.name, data.pwa_push.status);Відповідь - пуш після зміни в data.pwa_push.
config замінюється повністю
Якщо в запиті є config, він замінює тексти, розклад і фільтр разом: чого немає в запиті, те зітреться. Спершу отримайте пуш, змініть у його config потрібне й надішліть config повністю.
Помилки
| Код | message | Коли |
|---|---|---|
422 | The selected status is invalid. | status не active і не inactive |
422 | Every message needs a title. | Ті самі перевірки config, що під час створення, включно з PWA в config.filter.pwa_ids |
404 | Not found | Пуша з таким id немає |
403 | This action is unauthorized. | Пуш чужої команди або створений іншим користувачем (для customer) |
Розмір аудиторії
GET/pwa_pushes/{id}/audience
Скільки підписників підходить під фільтр пуша просто зараз, без підписників вимкнених і архівних PWA. Зручно перевірити перед надсиланням.
curl https://panel.example.com/api/pwa_pushes/WZAX/audience \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json"<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$count = json_decode($api->get('pwa_pushes/WZAX/audience')->getBody(), true)['data']['count'];
echo "Отримають пуш: {$count}" . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
count = requests.get(f"{API}/pwa_pushes/WZAX/audience", headers=HEADERS, timeout=30).json()["data"]["count"]
print("Отримають пуш:", count)// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/WZAX/audience`, {
method: 'GET',
headers,
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
console.log('Отримають пуш:', data.count);Відповідь: {"data": {"count": 1250}}.
Помилки
| Код | message | Коли |
|---|---|---|
404 | Not found | Пуша з таким id немає |
403 | This action is unauthorized. | Пуш чужої команди або створений іншим користувачем (для customer) |
Надіслати зараз
POST/pwa_pushes/{id}/send
Одразу ставить пуш на надсилання всій аудиторії з його фільтра.
Це справжня розсилка
Запит надсилає сповіщення реальним підписникам, і скасувати надсилання не можна. Метод спрацьовує за будь-якого статусу й типу пуша, навіть у вимкненого, і не пам'ятає минулих надсилань: кожен виклик шле пуш усім заново, включно з тими, хто вже отримав його за розкладом або тригером. Архівний пуш не надсилається (422). Не більше 10 надсилань на хвилину на користувача. Не викликайте метод у циклі й під час повторів після помилок мережі - спершу перевірте audience і лічильники.
curl -X POST https://panel.example.com/api/pwa_pushes/WZAX/send \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json"<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$queued = json_decode($api->post('pwa_pushes/WZAX/send')->getBody(), true)['data']['queued'];
echo "Поставлено на надсилання: {$queued}" . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
queued = requests.post(f"{API}/pwa_pushes/WZAX/send", headers=HEADERS, timeout=30).json()["data"]["queued"]
print("Поставлено на надсилання:", queued)// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/WZAX/send`, {
method: 'POST',
headers,
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
console.log('Поставлено на надсилання:', data.queued);Відповідь: {"data": {"queued": 1250}} - скільки підписників поставлено на надсилання. Сама доставка йде у фоні, результат з'явиться в sent_count і failed_count.
Помилки
| Код | message | Коли |
|---|---|---|
422 | An archived push cannot be sent | Пуш в архіві |
429 | Too many requests. Try again in a minute. | Більше 10 надсилань за хвилину |
404 | Not found | Пуша з таким id немає |
403 | This action is unauthorized. | Пуш чужої команди або створений іншим користувачем (для customer) |
Клонування
POST/pwa_pushes/{id}/clone
Копії пуша, по одній на кожну назву в names. Копія отримує команду, тип, мову й увесь config оригіналу, а створюється вимкненою та з нульовими лічильниками.
curl -X POST https://panel.example.com/api/pwa_pushes/WZAX/clone \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"names": ["Evening reminder DE"]}'<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$response = $api->post('pwa_pushes/WZAX/clone', ['json' => ['names' => ['Evening reminder DE']]]);
$clones = json_decode($response->getBody(), true)['data']['clones'];
foreach ($clones as $clone) {
echo "{$clone['id']} {$clone['name']}" . PHP_EOL;
}# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.post(f"{API}/pwa_pushes/WZAX/clone", headers=HEADERS, json={"names": ["Evening reminder DE"]}, timeout=30)
clones = response.json()["data"]["clones"]
for clone in clones:
print(clone["id"], clone["name"])// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/WZAX/clone`, {
method: 'POST',
headers,
body: JSON.stringify({ names: ['Evening reminder DE'] }),
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
for (const clone of data.clones) {
console.log(clone.id, clone.name);
}Відповідь
{
"data": {
"clones": [
{ "id": "WQby", "name": "Evening reminder DE", "type": "scheduled", "status": "inactive", "default_lang": "en" }
]
}
}Помилки
| Код | message | Коли |
|---|---|---|
422 | The names field is required. | Не передано names |
404 | Not found | Пуша з таким id немає |
403 | This action is unauthorized. | Пуш чужої команди або створений іншим користувачем (для customer) |
Архівування
DELETE/pwa_pushes/{id}
Прибирає пуш в архів: він більше не надсилається за розкладом і тригерами, історія й лічильники зберігаються. Повернути - PUT з "archived": false.
curl -X DELETE https://panel.example.com/api/pwa_pushes/WZAX \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json"<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$response = $api->delete('pwa_pushes/WZAX');
echo 'Пуш в архіві, HTTP ' . $response->getStatusCode() . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.delete(f"{API}/pwa_pushes/WZAX", headers=HEADERS, timeout=30)
print("Пуш в архіві, HTTP", response.status_code)// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/WZAX`, {
method: 'DELETE',
headers,
signal: AbortSignal.timeout(30000),
});
console.log('Пуш в архіві, HTTP', response.status);Відповідь: {"data": true}.
Помилки
| Код | message | Коли |
|---|---|---|
404 | Not found | Пуша з таким id немає |
403 | This action is unauthorized. | Пуш чужої команди або створений іншим користувачем (для customer) |
Попередній перегляд тексту
POST/pwa_pushes/preview
Збирає з тексту з варіантами одну випадкову комбінацію, як її побачить підписник. Поле text - до 2000 символів. Кожен виклик дає нову комбінацію.
Заголовок і текст пуша можна зібрати одним викликом: замість text передайте title і body (кожне до 2000 символів) - відповідь прийде як {"data": {"title": …, "body": …}}, порожнє поле повернеться порожнім рядком.
curl -X POST https://panel.example.com/api/pwa_pushes/preview \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"text": "{Hey|Hi}, {%RINT=(3,9)} new lessons"}'<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 30,
]);
$response = $api->post('pwa_pushes/preview', ['json' => ['text' => '{Hey|Hi}, {%RINT=(3,9)} new lessons']]);
echo json_decode($response->getBody(), true)['data']['text'] . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.post(f"{API}/pwa_pushes/preview", headers=HEADERS, json={"text": "{Hey|Hi}, {%RINT=(3,9)} new lessons"}, timeout=30)
print(response.json()["data"]["text"])// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
const response = await fetch(`${API}/pwa_pushes/preview`, {
method: 'POST',
headers,
body: JSON.stringify({ text: '{Hey|Hi}, {%RINT=(3,9)} new lessons' }),
signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();
console.log(data.text);Відповідь: {"data": {"text": "Hey, 7 new lessons"}}.
Помилки
| Код | message | Коли |
|---|---|---|
422 | The text field is required when none of title / body are present. | Не передано ні text, ні title / body |
Унікалізація з AI
POST/pwa_pushes/uniqueize
Переписує звичайну фразу в текст із варіантами, як кнопка Uniqueize with AI у формі пуша. Поля: text - фраза до 2000 символів, lang - код мови (необов'язково).
Працює через AI-провайдера
Метод доступний, лише якщо адміністратор підключив AI-провайдера в налаштуваннях панелі, і кожен виклик витрачає його ліміти. Без провайдера прийде 422 з AI uniqueizer is not configured, якщо провайдер не відповів - 422 з AI uniqueizer is unavailable.
curl -X POST https://panel.example.com/api/pwa_pushes/uniqueize \
-H "Authorization: Bearer ВАШ_КЛЮЧ" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"text": "Your plan is ready", "lang": "en"}'<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
$api = new GuzzleHttp\Client([
'base_uri' => 'https://panel.example.com/api/',
'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
'timeout' => 60,
]);
$response = $api->post('pwa_pushes/uniqueize', ['json' => ['text' => 'Your plan is ready', 'lang' => 'en']]);
$template = json_decode($response->getBody(), true)['data']['text'];
echo $template . PHP_EOL;# pip install requests
import requests
API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}
response = requests.post(f"{API}/pwa_pushes/uniqueize", headers=HEADERS, json={"text": "Your plan is ready", "lang": "en"}, timeout=60)
template = response.json()["data"]["text"]
print(template)// Node.js 18+, без залежностей; збережіть як script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };
// AI відповідає довше, ніж зазвичай - тайм-аут 60 секунд
const response = await fetch(`${API}/pwa_pushes/uniqueize`, {
method: 'POST',
headers,
body: JSON.stringify({ text: 'Your plan is ready', lang: 'en' }),
signal: AbortSignal.timeout(60000),
});
const { data } = await response.json();
console.log(data.text);Відповідь: {"data": {"text": "{Your|The} plan {is ready|is waiting} {for you|}"}}.
Помилки
| Код | message | Коли |
|---|---|---|
422 | AI uniqueizer is not configured | У панелі не підключено AI-провайдера |
422 | The text field is required. | Не передано text |