Сайты и виджеты
Сайты клиента, виджеты на них, заявки, посетители, статистика, A/B-тесты, товарные каталоги и веб-пуш.
Раздел описывает управляющее API: им пользуются интеграторы и наш MCP-сервер. Он не имеет отношения к коду, который стоит на сайте клиента, — про загрузчик, события и товары читайте «Руководство для разработчика».
| Слой | Кто пользуется | Что делает |
|---|---|---|
| SDK на сайте | разработчик сайта | собирает события и показывает виджеты: один тег
<script async src="https://w.dashamail.ru/s/<sk>.js"> |
| Это API | интеграторы, MCP | читает и настраивает сайты, виджеты, заявки и статистику |
Что такое сайт
Сайт — запись в общем реестре: к ней привязаны и виджеты, и трекер событий,
и веб-пуш, и товарный каталог. Что из этого подключено, видно в
modules:
| Модуль | Что значит |
|---|---|
modules.widgets | на сайте есть виджеты: формы, поп-апы, полоски |
modules.track | включено отслеживание событий — просмотры, корзина, заказы |
modules.push | подключён веб-пуш |
modules.feed | подключён товарный каталог YML |
site_key — тот самый sk из тега на странице. Он
считается от адреса один раз и при переименовании сайта не меняется:
менять тег на сайте клиента после правки названия не нужно.
Права ключа
Обычный ключ из личного кабинета делает всё, что разрешено аккаунту. Ключ, выданный через OAuth, несёт список прав — для этого раздела их четыре:
| Право | Что открывает |
|---|---|
sites.read | сайты, виджеты, статистика, тесты, каталоги, веб-пуш, события, вебхуки |
sites.write | подключение сайтов и доменов, включение виджетов, каталоги, вебхуки |
leads.read | заявки и посетители |
leads.write | повтор доставки заявки |
Заявки и посетители вынесены в отдельное право: в них персональные
данные, и токен «посмотреть статистику» не должен заодно читать телефоны.
leads.read не включает sites.read — ключу,
который читает заявки и при этом ищет сайт по списку, нужны оба.
Права субаккаунта проверяются отдельно от прав ключа и раньше них: уровень
«только чтение» закрывает изменяющие запросы (code: 65), полный
запрет — весь раздел. События, веб-пуш и товарные каталоги спрашивают своё
право — то же, что в кабинете отвечает за интеграции.
Лимиты тарифа
Количество сайтов, одновременно включённых виджетов и идущих A/B-тестов
ограничено тарифом «Сайты и виджеты»; текущие потолки и расход отдаёт
тариф и расход. Упёрлись в потолок — отказ
code: 69 с цифрами в теле ответа:
{
"error": {
"code": 69,
"message": "На вашем тарифе можно подключить 1 сайт. Чтобы добавить ещё — тариф «Сайты и виджеты» в разделе «Оплата»",
"details": { "what": "sites", "limit": 1, "current": 1 }
}
}
Лимит просмотров считается за расчётный период подписки. Исчерпали его —
рантайм перестаёт отдавать сайт, и у сайта появляется
status: "blocked"; виджеты и настройки при этом читаются как
обычно.
Отказ по значению поля
Когда запрос не проходит проверку (422, code: 67),
рядом с message приходит разбор по полям — в нём видно, что
именно поправить:
{
"error": {
"code": 67,
"message": "Это должен быть поддомен example.ru",
"details": { "errors": [ { "path": "domain", "message": "Это должен быть поддомен example.ru, например m.example.ru" } ] }
}
}
Страницы и выгрузки
Списки заявок, посетителей и виджетов постраничные: limit и
offset, признак следующей страницы — в
meta.has_more. Остальные списки раздела короткие и отдаются
целиком.
Заявки и посетителей можно забрать таблицей: format=csv отдаёт
text/csv вместо JSON. limit и offset
при этом не действуют — выгружается вся выборка.
У заявок отбор тот же, что у списка. Посетители выгружаются целиком, без отбора: это тот же файл «Вся база в CSV», что отдаёт кабинет.
Разделитель у двух выгрузок разный — так сложилось, и мы это сохраняем, чтобы у клиентов не поменялись уже разобранные файлы. Пишите разбор по таблице ниже, а не по догадке.
| Выгрузка | Разделитель | Байты | Переносы |
|---|---|---|---|
| заявки | ; |
UTF-8 с BOM — чтобы кириллица открывалась в Excel | LF |
| посетители | , |
UTF-8 без BOM | CRLF |
В обеих кавычки удваиваются, и в кавычки берётся значение, внутри которого есть разделитель или перенос строки.
Даты и время
Время — московское, формат ГГГГ-ММ-ДД ЧЧ:ММ:СС. Параметры
отбора по датам (from, to) — ГГГГ-ММ-ДД
включительно.
Статистика
Показы, заявки и просмотры страниц считаются в отдельном хранилище и
обновляются раз в сутки, поэтому сегодняшний день в отчёте неполный.
Хранилище недоступно — методы статистики отвечают 503 и
code: 70, а остальные методы раздела продолжают работать.
Конверсия — заявки на 100 показов, не на посетителей.
- GET Список сайтов
- GET Один сайт
- POST Подключить сайт
- PUT Изменить сайт
- GET Код установки и его состояние
- GET Домены сайта
- POST Добавить домен сайта
- DELETE Удалить домен сайта
- GET Поля посетителя
- GET Тариф и расход
- GET Виджеты сайта
- GET Один виджет
- POST Включить виджет
- POST Выключить виджет
- GET Статистика сайта
- GET Статистика по виджетам
- GET Воронка сайта
- GET A/B-тесты сайта
- GET Итоги A/B-тестов
- GET Заявки сайта
- GET Одна заявка
- POST Повторить доставку заявки
- GET Посетители сайта
- GET Карточка посетителя
- GET Заявки посетителя
- GET Вебхуки на заявку
- POST Поставить вебхук на заявку
- DELETE Снять вебхук
- GET Товарные каталоги
- GET Один каталог
- GET Ассортимент каталога
- POST Подключить каталог
- PUT Изменить каталог
- DELETE Отключить каталог
- GET События сайта
- GET Журнал событий
- GET Веб-пуш сайта
Список сайтов #
GET
/sites
Все сайты аккаунта — и с виджетами, и подключённые только под трекер, веб-пуш или товарный каталог.
Что возвращается
track — счётчики трекера: устройства,
события и время последнего события. У сайта без трекера они
нулевые. Сайты, которыми с аккаунтом поделились через
совместный доступ, в список не попадают: это настройка
кабинета.
curl -X GET 'https://api.dashamail.com/v2/sites' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 100842,
"name": "Магазин «Ромашка»",
"url": "https://example.ru/",
"host": "example.ru",
"protocol": "https",
"status": "enabled",
"site_key": "9f2c4b7e51a8d3604ef1c29b7a5d8e03",
"modules": {
"widgets": true,
"track": true,
"push": false,
"feed": true
},
"script_status": "installed",
"script_seen_at": "2026-10-27 09:14:02",
"loader_version": "v2",
"isolation": "shadow",
"widgets_total": 7,
"widgets_enabled": 3,
"tests_total": 1,
"track": {
"devices": 18420,
"events": 264913,
"last_event": "2026-10-27 11:48:31"
},
"created_at": "2026-03-14 11:02:41",
"updated_at": "2026-10-20 16:31:05"
}
]
}
}
Один сайт #
GET
/sites/{site_id}
Сайт целиком: поля списка, его домены и код установки.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
domains — домены сайта: main —
основной, alt — дополнительные. В
install_code.current лежит тег, который нужно
поставить на сайт сейчас; v1 — старый загрузчик,
он остаётся рабочим на уже установленных сайтах.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100842,
"name": "Магазин «Ромашка»",
"url": "https://example.ru/",
"host": "example.ru",
"protocol": "https",
"status": "enabled",
"site_key": "9f2c4b7e51a8d3604ef1c29b7a5d8e03",
"script_status": "installed",
"script_seen_at": "2026-10-27 09:14:02",
"loader_version": "v2",
"isolation": "shadow",
"widgets_total": 7,
"widgets_enabled": 3,
"tests_total": 1,
"created_at": "2026-03-14 11:02:41",
"updated_at": "2026-10-20 16:31:05",
"modules": {
"widgets": true,
"track": true,
"push": false,
"feed": true
},
"track": {
"devices": 18420,
"events": 264913,
"last_event": "2026-10-27 11:48:31"
},
"domains": [
{
"domain": "example.ru",
"kind": "main"
},
{
"domain": "m.example.ru",
"kind": "alt"
}
],
"install_code": {
"current": "<script async src=\"https://w.dashamail.ru/s/9f2c4b7e51a8d3604ef1c29b7a5d8e03.js\"></script>",
"v2": "<script async src=\"https://w.dashamail.ru/s/9f2c4b7e51a8d3604ef1c29b7a5d8e03.js\"></script>",
"v1": "<script async defer src=\"https://w.dashamail.ru/loader.js?sk=9f2c4b7e51a8d3604ef1c29b7a5d8e03\"></script>"
}
}
}
}
Подключить сайт #
POST
/sites
Заводит сайт по адресу. Код установки возвращается сразу — ставить его на сайт можно до всякой настройки.
Свой сайт, подключённый ранее только под трекер, веб-пуш или каталог, не дублируется: к нему просто подключаются виджеты, и в ответ приходит та же запись. Удалённый сайт восстанавливается.
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
url обязательный | string | Адрес сайта, например https://example.ru. Хост нормализуется: приводится к нижнему регистру, www отбрасывается, кириллица переводится в punycode. |
name | string | Название для кабинета, не длиннее 300 символов. Не задано — берётся хост. |
Что возвращается
Тот же набор полей, что у сайта в
списке, плюс install_code.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
422 |
3 |
Адрес не задан или не разбирается |
409 |
68 |
Сайт уже подключён к этому аккаунту либо занят другим — в этом случае нужна поддержка |
409 |
69 |
Исчерпан лимит сайтов на тарифе |
403 |
65 |
Недостаточно прав |
curl -X POST 'https://api.dashamail.com/v2/sites' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.ru",
"name": "Магазин «Ромашка»"
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.ru',
'name' => 'Магазин «Ромашка»',
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'url': 'https://example.ru',
'name': 'Магазин «Ромашка»',
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"url": "https://example.ru",
"name": "Магазин «Ромашка»"
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100842,
"name": "Магазин «Ромашка»",
"url": "https://example.ru/",
"host": "example.ru",
"protocol": "https",
"status": "enabled",
"site_key": "9f2c4b7e51a8d3604ef1c29b7a5d8e03",
"script_status": "unknown",
"script_seen_at": null,
"loader_version": "v2",
"isolation": "none",
"widgets_total": 0,
"widgets_enabled": 0,
"tests_total": 0,
"created_at": "2026-10-28 16:40:11",
"updated_at": "2026-10-28 16:40:11",
"modules": {
"widgets": true,
"track": false,
"push": false,
"feed": false
},
"track": {
"devices": 0,
"events": 0,
"last_event": ""
},
"install_code": {
"current": "<script async src=\"https://w.dashamail.ru/s/9f2c4b7e51a8d3604ef1c29b7a5d8e03.js\"></script>"
}
}
}
}
Изменить сайт #
PUT
/sites/{site_id}
Меняет настройки сайта. Передавайте только то, что нужно изменить — незаданные поля сохраняют прежние значения.
Адрес сайта (url) не меняется: на нём стоит
site_key, зашитый в тег на страницах клиента.
Переехали на другой домен — добавьте его
доменом сайта.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
name | string | Название сайта. |
isolation | string | Изоляция виджетов от CSS сайта. shadow — рисовать виджеты в Shadow DOM: вёрстка сайта на них не влияет.Допустимые значения: none, shadow |
cookie_domain | string | Домен для куки посетителя. Нужен, когда посетитель должен опознаваться на поддоменах как один человек. |
domains | array | Дополнительные домены сайта списком — заменяет прежний набор целиком. [] убирает все. |
Что возвращается
Сайт целиком — тот же набор полей, что в списке.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
422 |
67 |
Недопустимое значение поля |
409 |
68 |
Один из доменов уже занят другим сайтом |
403 |
65 |
Недостаточно прав |
curl -X PUT 'https://api.dashamail.com/v2/sites/100842' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"name": "Магазин «Ромашка»",
"isolation": "shadow"
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Магазин «Ромашка»',
'isolation' => 'shadow',
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.put(
'https://api.dashamail.com/v2/sites/100842',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'name': 'Магазин «Ромашка»',
'isolation': 'shadow',
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842', {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Магазин «Ромашка»",
"isolation": "shadow"
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100842,
"name": "Магазин «Ромашка»",
"host": "example.ru",
"status": "enabled",
"isolation": "shadow",
"modules": {
"widgets": true,
"track": true,
"push": false,
"feed": true
},
"track": {
"devices": 18420,
"events": 264913,
"last_event": "2026-10-27 11:48:31"
}
}
}
}
Код установки и его состояние #
GET
/sites/{site_id}/install
Тег для вставки на сайт и признак того, видели ли мы его на страницах.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
script_status: installed — код
видели, unknown — ещё нет,
missing — раньше видели, а теперь нет.
script_seen_at — когда код отзывался последний
раз. Признак ставит сам загрузчик, отдельной проверки запускать
не нужно.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/install' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/install');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/install',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/install', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"install_code": {
"current": "<script async src=\"https://w.dashamail.ru/s/9f2c4b7e51a8d3604ef1c29b7a5d8e03.js\"></script>",
"v2": "<script async src=\"https://w.dashamail.ru/s/9f2c4b7e51a8d3604ef1c29b7a5d8e03.js\"></script>",
"v1": "<script async defer src=\"https://w.dashamail.ru/loader.js?sk=9f2c4b7e51a8d3604ef1c29b7a5d8e03\"></script>"
},
"script_status": "installed",
"script_seen_at": "2026-10-27 09:14:02",
"loader_version": "v2"
}
}
}
Домены сайта #
GET
/sites/{site_id}/domains
Домены, на которых работает сайт: основной и дополнительные.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
list_id — адресная база, в которую складывает
подписчиков трекер этого домена; 0 — не задана.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/domains' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/domains');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/domains',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/domains', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"domain": "example.ru",
"kind": "main",
"list_id": 128341
},
{
"domain": "m.example.ru",
"kind": "alt",
"list_id": 0
}
]
}
}
Добавить домен сайта #
POST
/sites/{site_id}/domains
Добавляет домен, на котором тоже стоит код сайта. Виджеты, заявки и статистика у доменов одного сайта общие.
Добавить можно только поддомен основного домена сайта:
посетитель на m.example.ru и
example.ru — один человек, а на чужом домене —
другой сайт.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
domain обязательный | string | Домен, например m.example.ru. |
Что возвращается
В ответе — весь список доменов сайта после добавления, а не один добавленный.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
422 |
3 |
Не передан domain |
422 |
67 |
Домен некорректен, не является поддоменом основного либо их уже 20 |
409 |
68 |
Домен у сайта уже есть |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X POST 'https://api.dashamail.com/v2/sites/100842/domains' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"domain": "m.example.ru"
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/domains');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'domain' => 'm.example.ru',
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites/100842/domains',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'domain': 'm.example.ru',
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/domains', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"domain": "m.example.ru"
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"domain": "example.ru",
"kind": "main",
"list_id": 128341
},
{
"domain": "m.example.ru",
"kind": "alt",
"list_id": 0
}
]
}
}
Удалить домен сайта #
DELETE
/sites/{site_id}/domains/{domain}
Отвязывает дополнительный домен. Основной домен сайта удалить нельзя.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
domain обязательный | string | Домен, который нужно отвязать. |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
У сайта нет такого домена |
409 |
68 |
Это основной домен сайта: он задаёт ключ, по которому сайт находит рантайм |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X DELETE 'https://api.dashamail.com/v2/sites/100842/domains/m.example.ru' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/domains/m.example.ru');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.delete(
'https://api.dashamail.com/v2/sites/100842/domains/m.example.ru',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/domains/m.example.ru', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
(тело ответа пустое)
Поля посетителя #
GET
/sites/{site_id}/fields
Поля, которые сайт собирает о посетителе. По ним заполняются
fields в заявках и
карточке посетителя.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
name — ключ поля в данных,
title — подпись в кабинете.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/fields' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/fields');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/fields',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/fields', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 100233,
"name": "email",
"title": "E-mail",
"weight": 0
},
{
"id": 100234,
"name": "name",
"title": "Имя",
"weight": 1
},
{
"id": 100412,
"name": "city",
"title": "Город",
"weight": 2
}
]
}
}
Тариф и расход #
GET
/sites/plan
Тариф «Сайты и виджеты» аккаунта: лимиты, расход и срок.
Только чтение: тариф оплачивается в личном кабинете.
Что возвращается
0 в любом *_limit означает «без
ограничений». can отвечает на вопрос «можно ли
завести ещё» — по нему удобно гасить кнопки, не считая
лимиты самому. period — расчётный период лимита
просмотров, [from, to).
curl -X GET 'https://api.dashamail.com/v2/sites/plan' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/plan');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/plan',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/plan', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"plan_id": 14,
"plan_code": "sites-pro",
"plan_name": "Сайты и виджеты PRO",
"is_pro": false,
"unlimited": false,
"sites_limit": 10,
"widgets_limit": 50,
"tests_limit": 10,
"pageviews_limit": 500000,
"views_included": false,
"period_months": 1,
"ends_at": "2026-11-18 00:00:00",
"usage": {
"sites": 4,
"widgets": 11,
"tests": 1
},
"can": {
"sites": true,
"widgets": true,
"tests": true
},
"period": {
"from": "2026-10-18",
"to": "2026-11-18"
}
}
}
}
Виджеты сайта #
GET
/sites/{site_id}/widgets
Виджеты сайта, новые сверху: формы, поп-апы, полоски.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
status | string | Только включённые или только выключенные. Допустимые значения: enabled, disabled |
kind | string | Вид виджета. Допустимые значения: popup, horizontal, vertical, inline, none |
search | string | Подстрока в названии. |
limit | integerпо умолчанию: 100 | Сколько виджетов вернуть, не больше 500. |
offset | integerпо умолчанию: 0 | Смещение от начала выборки. |
Что возвращается
kind — как виджет показывается:
popup — всплывающее окно, horizontal
и vertical — полоски у края экрана,
inline — форма внутри страницы.
has_draft — есть несохранённые правки: сайт их
ещё не видит. test_id — A/B-тест, в котором
участвует виджет, 0 — ни в одном.
Вид и настройки виджета правятся только в редакторе кабинета: наружу его модель не отдаётся.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/widgets?status=enabled' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/widgets?status=enabled');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/widgets?status=enabled',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/widgets?status=enabled', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 100931,
"site_id": 100842,
"name": "Скидка 10% за подписку",
"kind": "popup",
"status": "enabled",
"template_id": 42,
"test_id": 0,
"has_draft": false,
"published_at": "2026-10-02 13:20:44",
"created_at": "2026-09-30 10:11:09",
"updated_at": "2026-10-02 13:20:44"
}
]
}
}
Один виджет #
GET
/sites/{site_id}/widgets/{widget_id}
Один виджет — в том же наборе полей, что и в списке.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
widget_id обязательный | integer | Идентификатор виджета. |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Виджета с таким идентификатором на сайте нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/widgets/100931' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/widgets/100931');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/widgets/100931',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/widgets/100931', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100931,
"site_id": 100842,
"name": "Скидка 10% за подписку",
"kind": "popup",
"status": "enabled",
"template_id": 42,
"test_id": 0,
"has_draft": false,
"published_at": "2026-10-02 13:20:44",
"created_at": "2026-09-30 10:11:09",
"updated_at": "2026-10-02 13:20:44"
}
}
}
Включить виджет #
POST
/sites/{site_id}/widgets/{widget_id}/enable
Включает виджет: он начинает показываться на сайте. Слепок сайта пересобирается сразу, ждать крона не нужно.
Лимит тарифа считает именно включённые виджеты — создать можно сколько угодно, держать включёнными ограниченное число.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
widget_id обязательный | integer | Идентификатор виджета. |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Виджета с таким идентификатором на сайте нет |
409 |
68 |
Виджет нечего показывать: он ни разу не публиковался |
409 |
68 |
На сайте не установлен код: выключенный виджет показывать негде |
409 |
68 |
Сайт ещё переносится из кабинета Leadplan — правки пока делаются там |
409 |
69 |
Исчерпан лимит включённых виджетов на тарифе |
403 |
65 |
Недостаточно прав |
curl -X POST 'https://api.dashamail.com/v2/sites/100842/widgets/100931/enable' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/widgets/100931/enable');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites/100842/widgets/100931/enable',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/widgets/100931/enable', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100931,
"status": "enabled"
}
}
}
Выключить виджет #
POST
/sites/{site_id}/widgets/{widget_id}/disable
Выключает виджет: он перестаёт показываться. Настройки и собранные заявки остаются.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
widget_id обязательный | integer | Идентификатор виджета. |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Виджета с таким идентификатором на сайте нет |
403 |
65 |
Недостаточно прав |
curl -X POST 'https://api.dashamail.com/v2/sites/100842/widgets/100931/disable' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/widgets/100931/disable');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites/100842/widgets/100931/disable',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/widgets/100931/disable', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100931,
"status": "disabled"
}
}
}
Статистика сайта #
GET
/sites/{site_id}/stats
Просмотры страниц, показы виджетов и заявки по дням или месяцам, с итогами, разбивкой по виджетам и источниками заявок.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
period | stringпо умолчанию: days | days — последние 30 дней, months — последние 12 месяцев.Допустимые значения: days, months |
widget_id | integer | Считать показы, заявки и источники только по одному виджету. Просмотры страниц виджетом не фильтруются — они относятся к сайту. |
Что возвращается
В series пропущенные дни идут нулями. Если
период задевает время, за которое просмотры не собирались,
pageviews в этих точках приходит
null, а сам промежуток — в
pageviews_gap: это «нет данных», а не «ноль
посетителей». sources — источники заявок, не
больше 15 строк.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
422 |
67 |
Недопустимый период |
503 |
70 |
Хранилище статистики недоступно |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/stats?period=days' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/stats?period=days');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/stats?period=days',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/stats?period=days', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"period": "days",
"from": "2026-09-28",
"to": "2026-10-27",
"pageviews_gap": null,
"series": [
{
"date": "2026-10-26",
"pageviews": 1841,
"displays": 612,
"leads": 14
},
{
"date": "2026-10-27",
"pageviews": 1902,
"displays": 640,
"leads": 19
}
],
"totals": {
"pageviews": 54218,
"displays": 18204,
"leads": 431,
"conversion": 2.37
},
"widgets": [
{
"widget_id": 100931,
"name": "Скидка 10% за подписку",
"archived": false,
"displays": 12043,
"leads": 318,
"visitors": 9120,
"conversion": 2.64
}
],
"sources": [
{
"type": "organic",
"src": "yandex",
"leads": 164
},
{
"type": "direct",
"src": "",
"leads": 98
}
]
}
}
}
Статистика по виджетам #
GET
/sites/{site_id}/stats/widgets
Таблица виджетов за произвольный отрезок: показы, заявки и дата первого показа.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
from | string | Начало отрезка, ГГГГ-ММ-ДД включительно. Не задано — всё время. |
to | string | Конец отрезка, ГГГГ-ММ-ДД включительно. |
search | string | Подстрока в названии виджета. |
Что возвращается
В таблицу попадают и архивные виджеты, если за отрезок у
них были показы: archived: true.
first_display — первый показ за всё время, а не
за отрезок: это дата запуска виджета.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
503 |
70 |
Хранилище статистики недоступно |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/stats/widgets?from=2026-10-01&to=2026-10-27' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/stats/widgets?from=2026-10-01&to=2026-10-27');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/stats/widgets?from=2026-10-01&to=2026-10-27',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/stats/widgets?from=2026-10-01&to=2026-10-27', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"widget_id": 100931,
"name": "Скидка 10% за подписку",
"status": "enabled",
"archived": false,
"first_display": "2026-09-30",
"displays": 12043,
"leads": 318
}
]
}
}
Воронка сайта #
GET
/sites/{site_id}/stats/funnel
Ступени за 30 дней: посетители, опознанные, показы, заявки и заказы — с долями от посетителей.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
Ступень, которую нечем считать, приходит
null, а не нулём: посетителей и заказы считает
трекер, заявки — виджеты. У сайта без трекера
visitors и orders —
null.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
503 |
70 |
Хранилище статистики недоступно |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/stats/funnel' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/stats/funnel');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/stats/funnel',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/stats/funnel', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"days": 30,
"from": "2026-09-27",
"visitors": 18420,
"identified": 2140,
"displays": 18204,
"leads": 431,
"orders": 96,
"rates": {
"identified": 11.62,
"leads": 2.34,
"orders": 0.52
}
}
}
}
A/B-тесты сайта #
GET
/sites/{site_id}/tests
Тесты сайта с их вариантами.
Тесты создаются и останавливаются в кабинете: запись наружу не отдаётся.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
Посетитель попадает в вариант по своему идентификатору —
раз и навсегда, а не по счётчику показов. weight
— доля варианта в сплите. reset_at — отчёт
обнулили с этой даты, сами показы и заявки остались.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/tests' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/tests');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/tests',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/tests', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 100044,
"site_id": 100842,
"name": "Поп-ап: скидка или подарок",
"status": "active",
"started_at": "2026-10-10 12:00:00",
"stopped_at": null,
"reset_at": null,
"created_at": "2026-10-10 11:58:21",
"variants": [
{
"widget_id": 100931,
"name": "Скидка 10%",
"status": "enabled",
"weight": 1
},
{
"widget_id": 100932,
"name": "Подарок к заказу",
"status": "enabled",
"weight": 1
}
]
}
]
}
}
Итоги A/B-тестов #
GET
/sites/{site_id}/tests/stats
Сравнение вариантов по всем тестам сайта.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
visitors — уникальные посетители, видевшие
вариант, sessions — уникальные сессии показов.
Победителя API не называет: решение за человеком. Строки есть
и у виджетов, уже убранных из теста, — сравнивайте со списком
текущих вариантов.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
503 |
70 |
Хранилище статистики недоступно |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/tests/stats' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/tests/stats');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/tests/stats',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/tests/stats', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"test_id": 100044,
"variants": [
{
"widget_id": 100931,
"displays": 6102,
"leads": 171,
"visitors": 4610,
"sessions": 5204,
"conversion": 2.8
},
{
"widget_id": 100932,
"displays": 5941,
"leads": 147,
"visitors": 4510,
"sessions": 5102,
"conversion": 2.47
}
]
}
]
}
}
Заявки сайта #
GET
/sites/{site_id}/leads
Что люди отправили через виджеты сайта, новые сверху.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
widget_id | integer | Только заявки одного виджета. |
from | string | С этого дня, ГГГГ-ММ-ДД включительно. |
to | string | До этого дня, ГГГГ-ММ-ДД включительно. |
search | string | Поиск по почте, имени или телефону. По телефону — от трёх цифр. |
limit | integerпо умолчанию: 50 | Сколько заявок вернуть, не больше 500. |
offset | integerпо умолчанию: 0 | Смещение от начала выборки. |
format | string | Отдать выборку таблицей text/csv вместо JSON. Выгружается вся выборка, limit и offset не действуют.Допустимые значения: csv |
Что возвращается
fields — все значения формы в порядке
отправки, с подписями полей. Почта, телефон и имя продублированы
отдельными полями: по ним идёт поиск.
deliveries — сводка доставок в подключённые
сервисы и вебхуки: сколько ушло, сколько не получилось,
сколько ждёт очереди. Разбор по попыткам — в
карточке заявки.
Телефон хранится цифрами, ведущая 8 заменена
на 7. Почта, не прошедшая проверку, в
email не попадает, но остаётся в
fields как её ввёл человек.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/leads?from=2026-10-20&limit=50' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/leads?from=2026-10-20&limit=50');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/leads?from=2026-10-20&limit=50',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/leads?from=2026-10-20&limit=50', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 1024417,
"site_id": 100842,
"widget_id": 100931,
"widget_name": "Скидка 10% за подписку",
"email": "ivan@example.ru",
"phone": "79160000000",
"name": "Иван",
"fields": [
{
"name": "email",
"title": "E-mail",
"value": "ivan@example.ru"
},
{
"name": "name",
"title": "Имя",
"value": "Иван"
},
{
"name": "city",
"title": "Город",
"value": "Москва"
}
],
"utm_source": "yandex",
"traffic": {
"type": "organic",
"src": "yandex"
},
"created_at": "2026-10-27 10:12:40",
"deliveries": {
"sent": 2,
"failed": 0,
"queued": 0
}
}
]
}
}
Одна заявка #
GET
/sites/{site_id}/leads/{lead_id}
Заявка целиком: все значения формы, откуда человек пришёл, его карточка посетителя и журнал доставок.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
lead_id обязательный | integer | Идентификатор заявки. |
Что возвращается
Заявка собирается ровно так же, как уходит в подключённые сервисы: что видно здесь, то и было отправлено.
delivery_log — строка на попытку:
attempt — её номер, http_status и
response — чем ответил сервис (первый килобайт),
next_try_at — когда будет следующая попытка.
timezone_offset — часовой пояс браузера в
минутах, как его прислал сам браузер.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Заявки с таким идентификатором на сайте нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/leads/1024417' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/leads/1024417');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/leads/1024417',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/leads/1024417', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 1024417,
"site_id": 100842,
"widget_id": 100931,
"widget_name": "Скидка 10% за подписку",
"test_id": 100044,
"email": "ivan@example.ru",
"phone": "79160000000",
"name": "Иван",
"fields": [
{
"name": "email",
"title": "E-mail",
"value": "ivan@example.ru"
}
],
"url": "https://example.ru/catalog/",
"referrer": "https://yandex.ru/search/",
"utm": {
"source": "yandex",
"medium": "organic",
"campaign": "",
"term": "",
"content": ""
},
"traffic": {
"type": "organic",
"src": "yandex"
},
"timezone_offset": 180,
"created_at": "2026-10-27 10:12:40",
"visitor": {
"id": "0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62",
"country": "Россия",
"region": "Москва",
"city": "Москва",
"browser": "Chrome",
"os": "Windows",
"device": "desktop"
},
"delivery_log": [
{
"id": 88104221,
"binding_id": 100277,
"attempt": 1,
"status": "sent",
"http_status": 200,
"response": "{\"ok\":true}",
"next_try_at": null,
"created_at": "2026-10-27 10:12:41",
"updated_at": "2026-10-27 10:12:41"
}
]
}
}
}
Повторить доставку заявки #
POST
/sites/{site_id}/leads/{lead_id}/retry
Ставит заявку в очередь на повторную доставку: неудачные попытки и сервисы, подключённые уже после заявки.
Доставленное и уже стоящее в очереди не трогается, дублей не будет. Сам запрос ничего не отправляет — он только возвращает заявку в очередь, отправкой займётся та же доставка, что и у обычных заявок, с теми же повторами.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
lead_id обязательный | integer | Идентификатор заявки. |
Что возвращается
queued — сколько доставок поставлено в
очередь. 0 — повторять нечего: всё либо уже
доставлено, либо ждёт своей очереди.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Заявки с таким идентификатором на сайте нет |
403 |
65 |
Недостаточно прав |
curl -X POST 'https://api.dashamail.com/v2/sites/100842/leads/1024417/retry' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/leads/1024417/retry');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites/100842/leads/1024417/retry',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/leads/1024417/retry', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"queued": 1,
"delivery_log": [
{
"id": 88104998,
"binding_id": 100277,
"attempt": 1,
"status": "queued",
"http_status": null,
"next_try_at": "2026-10-27 12:40:00"
}
]
}
}
}
Посетители сайта #
GET
/sites/{site_id}/visitors
Люди, которые оставляли заявки на сайте, с их полями и числом обращений.
В список попадают только посетители, о которых что-то известно: тот, кто просто ходил по сайту и ничего не отправлял, строки не заводит.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
search | string | Подстрока в любом значении полей посетителя. |
order | stringпо умолчанию: last_activity | Сортировка: по времени последней заявки, по имени, по числу заявок или по последнему виджету. Можно сортировать по значению поля — field:city.Допустимые значения: last_activity, name, activities, last_tool |
asc | флаг | Сортировать по возрастанию. По умолчанию — по убыванию. |
limit | integerпо умолчанию: 25 | Сколько посетителей вернуть. |
offset | integerпо умолчанию: 0 | Смещение от начала выборки. |
format | string | Отдать выборку таблицей text/csv вместо JSON.Допустимые значения: csv |
Что возвращается
id посетителя — строка, а не число: это
идентификатор из куки его браузера.
activities — сколько заявок он оставил,
last_tool — название виджета, через который
обратился в последний раз. params — все значения
его полей объектом.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/visitors?order=activities&limit=25' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/visitors?order=activities&limit=25');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/visitors?order=activities&limit=25',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/visitors?order=activities&limit=25', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": "0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62",
"name": "Иван Петров",
"email": "ivan@example.ru",
"phone": "79160000000",
"params": {
"email": "ivan@example.ru",
"name": "Иван",
"surname": "Петров",
"city": "Москва"
},
"last_activity": "2026-10-27 10:12:40",
"activities": 3,
"last_tool": "Скидка 10% за подписку"
}
]
}
}
Карточка посетителя #
GET
/sites/{site_id}/visitors/{visitor_id}
Посетитель со всеми полями сайта, устройством и источником первого визита.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
visitor_id обязательный | string | Идентификатор посетителя. |
Что возвращается
fields перечисляет все
поля сайта, в том числе
незаполненные: у них value пустая.
created_at — первый визит,
submitted_at — последняя заявка.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Посетителя с таким идентификатором на сайте нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": "0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62",
"name": "Иван",
"surname": "Петров",
"email": "ivan@example.ru",
"fields": [
{
"name": "email",
"title": "E-mail",
"value": "ivan@example.ru"
},
{
"name": "city",
"title": "Город",
"value": "Москва"
}
],
"created_at": "2026-09-14 18:22:10",
"last_activity": "2026-10-27 10:12:40",
"submitted_at": "2026-10-27 10:12:40",
"ip": "81.200.0.0",
"country": "Россия",
"region": "Москва",
"city": "Москва",
"browser": "Chrome",
"os": "Windows",
"device": "desktop",
"referrer": "https://yandex.ru/search/",
"utm_source": "yandex",
"utm_medium": "organic",
"utm_campaign": "",
"utm_term": "",
"utm_content": ""
}
}
}
Заявки посетителя #
GET
/sites/{site_id}/visitors/{visitor_id}/leads
История обращений одного человека, новые сверху.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
visitor_id обязательный | string | Идентификатор посетителя. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
limit | integerпо умолчанию: 25 | Сколько заявок вернуть. |
offset | integerпо умолчанию: 0 | Смещение от начала выборки. |
Что возвращается
В fields у значений только подпись поля и само
значение: историю посетителя показывают таблицей, и системные
имена полей в ней не нужны. Адрес страницы — отдельным полем
url.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Посетителя с таким идентификатором на сайте нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62/leads' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62/leads');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62/leads',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/visitors/0f3a6c18-4b2d-4f1a-9e77-2c5b8d410e62/leads', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 1024417,
"widget_id": 100931,
"widget_name": "Скидка 10% за подписку",
"created_at": "2026-10-27 10:12:40",
"url": "https://example.ru/catalog/",
"fields": [
{
"title": "E-mail",
"value": "ivan@example.ru"
},
{
"title": "Имя",
"value": "Иван"
}
]
}
]
}
}
Вебхуки на заявку #
GET
/sites/{site_id}/webhooks
Куда уходят заявки виджетов сайта: адрес, виджет и состояние.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
Вебхук ставится на виджет, а не на сайт: у разных виджетов могут быть разные адреса. Кроме вебхуков у сайта бывают подключённые сервисы рассылок — они настраиваются в кабинете и здесь не показываются.
status — состояние приёмника:
active — работает, error — последние
доставки не прошли, disabled — выключен в
кабинете.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/webhooks' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/webhooks');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/webhooks',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/webhooks', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 100277,
"widget_id": 100931,
"widget_name": "Скидка 10% за подписку",
"url": "https://example.ru/hooks/dashamail",
"status": "active",
"updated_at": "2026-10-02 13:21:00"
}
]
}
}
Поставить вебхук на заявку #
POST
/sites/{site_id}/webhooks
Заявки виджета начинают уходить POST-запросом на ваш адрес.
Вебхук ставится на один виджет. Повторный вызов на тот же виджет второй привязки не создаёт — меняет у неё адрес, поэтому метод можно звать повторно без опаски. Нужны все виджеты сайта — пройдите их список и позовите метод на каждый: виджеты, которые появятся позже, вебхука сами не получат.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
url обязательный | string | Адрес приёмника. Должен начинаться с http:// или https:// и быть не длиннее 500 символов. |
widget_id обязательный | integer | Виджет, чьи заявки отправлять. |
Что возвращается
Неудачные доставки повторяются с растущей задержкой; сколько попыток было и чем они кончились, видно в карточке заявки.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта или виджета с таким идентификатором нет |
422 |
3 |
Не передан url или widget_id |
422 |
67 |
Адрес не начинается с http:// либо https:// |
403 |
65 |
Недостаточно прав |
curl -X POST 'https://api.dashamail.com/v2/sites/100842/webhooks' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.ru/hooks/dashamail",
"widget_id": 100931
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/webhooks');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.ru/hooks/dashamail',
'widget_id' => 100931,
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites/100842/webhooks',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'url': 'https://example.ru/hooks/dashamail',
'widget_id': 100931,
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/webhooks', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"url": "https://example.ru/hooks/dashamail",
"widget_id": 100931
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 100277,
"widget_id": 100931,
"url": "https://example.ru/hooks/dashamail",
"status": "active"
}
}
}
Снять вебхук #
DELETE
/sites/{site_id}/webhooks/{webhook_id}
Заявки перестают уходить на этот адрес. Уже собранные заявки остаются.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
webhook_id обязательный | integer | Идентификатор вебхука из списка. |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Вебхука с таким идентификатором на сайте нет |
403 |
65 |
Недостаточно прав |
curl -X DELETE 'https://api.dashamail.com/v2/sites/100842/webhooks/100277' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/webhooks/100277');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.delete(
'https://api.dashamail.com/v2/sites/100842/webhooks/100277',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/webhooks/100277', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
(тело ответа пустое)
Товарные каталоги #
GET
/sites/{site_id}/feeds
Каталоги сайта: ссылка на YML-фид, его настройки и что из него загрузилось.
Каталог нужен письмам о товарах — брошенной корзине, просмотренным товарам, снижению цены: из него берутся название, цена и картинка товара, который смотрел посетитель.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
order | stringпо умолчанию: desc | Порядок: по времени правки или по названию магазина. Допустимые значения: desc, asc, name_asc, name_desc |
Что возвращается
last_update — когда фид читался последний
раз, next_load — когда прочитается снова. Товары
в ответ не попадают: их список отдаёт
ассортимент.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/feeds' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/feeds');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/feeds',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/feeds', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"id": 612,
"site_id": 100842,
"shop_name": "Магазин «Ромашка»",
"yml_file_url": "https://example.ru/feed.yml",
"originDomain": "example.ru",
"currency_code": "rub",
"total_products": 4182,
"categories_num": 36,
"yml_load_period": 24,
"last_update": "2026-10-27 04:12:08",
"next_load": "2026-10-28 04:12:08",
"lastedit_time": "2026-10-20 16:40:11"
}
]
}
}
Один каталог #
GET
/sites/{site_id}/feeds/{feed_id}
Каталог со всеми настройками и доменами, из которых можно
выбрать его originDomain.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
feed_id обязательный | integer | Идентификатор каталога. |
Что возвращается
sales_rate_period — за сколько дней считается
рейтинг продаж, abandoned_period — через сколько
часов корзина считается брошенной
(0 — не считать).
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Каталога с таким идентификатором на сайте нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/feeds/612' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/feeds/612');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/feeds/612',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/feeds/612', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 612,
"shop_name": "Магазин «Ромашка»",
"yml_file_url": "https://example.ru/feed.yml",
"shop_url": "https://example.ru",
"originDomain": "example.ru",
"shop_category_id": 1,
"currency_code": "rub",
"price_number_format": 0,
"sales_rate_period": 30,
"abandoned_period": 24,
"yml_load_period": 24,
"total_products": 4182,
"categories_num": 36,
"last_update": "2026-10-27 04:12:08",
"next_load": "2026-10-28 04:12:08",
"domains": [
"example.ru",
"m.example.ru"
]
}
}
}
Ассортимент каталога #
GET
/sites/{site_id}/feeds/{feed_id}/items
Категории каталога со счётчиками и начало списка товаров — проверить, что фид читается правильно.
Товары не хранятся у нас: они читаются с самого фида при
каждом запросе, с начала файла. Поэтому страница ограничена
200 товарами, а offset тут не поддерживается —
выгружать весь ассортимент этим методом не нужно, он у вас
уже есть.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
feed_id обязательный | integer | Идентификатор каталога. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
limit | integerпо умолчанию: 50 | Сколько товаров вернуть: от 10 до 200. |
Что возвращается
pending: true — фид ещё ни разу не
загружался: категорий нет, и это не ошибка.
columns — какие поля нашлись у товаров этого
фида, products у категории — с учётом
вложенных.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Каталога с таким идентификатором на сайте нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
503 |
70 |
Фид не читается: адрес не отвечает или отдаёт не YML |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/feeds/612/items' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/feeds/612/items');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/feeds/612/items',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/feeds/612/items', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"pending": false,
"last_update": "2026-10-27 04:12:08",
"total_products": 4182,
"categories_num": 36,
"categories": [
{
"id": 14,
"name": "Посуда",
"level": 0,
"products": 1204
},
{
"id": 18,
"name": "Кастрюли",
"level": 1,
"products": 316
}
],
"columns": [
"id",
"name",
"price",
"oldprice",
"url",
"picture",
"available"
],
"limit": 50,
"offers": [
{
"id": "4412",
"name": "Кастрюля 3 л",
"price": "2490",
"url": "https://example.ru/catalog/4412",
"available": "true"
}
]
}
}
}
Подключить каталог #
POST
/sites/{site_id}/feeds
Подключает YML-фид к сайту.
Фид читается сразу, в этом же запросе: у большого каталога ответ придёт не мгновенно. Ставьте таймаут с запасом — минуту и больше.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
url обязательный | string | Адрес YML-фида, например https://example.ru/feed.yml. |
Что возвращается
Название магазина, валюта и домен берутся из самого фида; остальные настройки получают значения по умолчанию и правятся отдельно.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
422 |
67 |
Адрес не задан или по нему не YML-фид |
409 |
68 |
Этот фид уже подключён к сайту |
403 |
65 |
Недостаточно прав; каталоги недоступны на текущем тарифе — о причине говорит текст |
curl -X POST 'https://api.dashamail.com/v2/sites/100842/feeds' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.ru/feed.yml"
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/feeds');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.ru/feed.yml',
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/sites/100842/feeds',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'url': 'https://example.ru/feed.yml',
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/feeds', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"url": "https://example.ru/feed.yml"
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 612,
"shop_name": "Магазин «Ромашка»",
"yml_file_url": "https://example.ru/feed.yml",
"originDomain": "example.ru",
"currency_code": "rub",
"total_products": 4182
}
}
}
Изменить каталог #
PUT
/sites/{site_id}/feeds/{feed_id}
Меняет настройки каталога. Передавайте только то, что нужно изменить.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
feed_id обязательный | integer | Идентификатор каталога. |
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
originDomain | string | Домен, к которому относится каталог. Выбирается из доменов сайта. |
shop_category_id | integer | Отрасль магазина. |
currency_code | string | Валюта цен. Допустимые значения: rub, uah, usd, eur, kzt, byr |
price_number_format | integer | Формат цены в письме: 0 — как в фиде, 1 — с разделителем разрядов.Допустимые значения: 0, 1 |
sales_rate_period | integer | За сколько дней считать рейтинг продаж. Допустимые значения: 1, 3, 7, 14, 30, 60, 90 |
abandoned_period | integer | Через сколько часов корзина считается брошенной; 0 — не считать.Допустимые значения: 0, 12, 24, 72, 168, 336, 720, 1440, 2160 |
yml_load_period | integer | Как часто перечитывать фид, в часах. Допустимые значения: 12, 24, 72 |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Каталога с таким идентификатором на сайте нет |
422 |
67 |
Недопустимое значение поля |
403 |
65 |
Недостаточно прав |
curl -X PUT 'https://api.dashamail.com/v2/sites/100842/feeds/612' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"abandoned_period": 24,
"yml_load_period": 12
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/feeds/612');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'abandoned_period' => 24,
'yml_load_period' => 12,
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.put(
'https://api.dashamail.com/v2/sites/100842/feeds/612',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'abandoned_period': 24,
'yml_load_period': 12,
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/feeds/612', {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"abandoned_period": 24,
"yml_load_period": 12
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"id": 612,
"abandoned_period": 24,
"yml_load_period": 12
}
}
}
Отключить каталог #
DELETE
/sites/{site_id}/feeds/{feed_id}
Отключает каталог от сайта. Письма о товарах по нему перестают собираться.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
feed_id обязательный | integer | Идентификатор каталога. |
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Каталога с таким идентификатором на сайте нет |
403 |
65 |
Недостаточно прав |
curl -X DELETE 'https://api.dashamail.com/v2/sites/100842/feeds/612' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/feeds/612');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.delete(
'https://api.dashamail.com/v2/sites/100842/feeds/612',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/feeds/612', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
(тело ответа пустое)
События сайта #
GET
/sites/{site_id}/events
Какие события сайт передаёт в DashaMail и в какую адресную базу они складываются.
Только чтение: соответствие полей события настраивается в кабинете. Неверное соответствие тихо ломает сбор данных, и менять его вслепую через API опаснее, чем руками.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Что возвращается
События сгруппированы по точкам интеграции: у сайта с
несколькими доменами их может быть больше одной.
builtin: true — встроенное событие
(просмотр, корзина, заказ), false — своё.
last_event — когда событие приходило последний
раз; пусто — не приходило ни разу, и это первое, что стоит
проверить при отладке.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/events' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/events');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/events',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/events', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"point": {
"id": 54218,
"endpointId": "a1b2c3d4e5f6",
"name": "example.ru",
"list_id": 128341,
"domains": [
"example.ru",
"m.example.ru"
]
},
"events": [
{
"id": 0,
"event": "Просмотр товара",
"rel": "viewed",
"builtin": true,
"list_id": 128341,
"list_name": "Клиенты интернет-магазина",
"last_event": "2026-10-27 11:48:31"
},
{
"id": 9214,
"event": "Подписка в подвале",
"rel": "subscribe",
"builtin": false,
"list_id": 128341,
"list_name": "Клиенты интернет-магазина",
"originDomain": "",
"last_event": "2026-10-26 20:04:12"
}
]
}
]
}
}
Журнал событий #
GET
/sites/{site_id}/events/log
Последние события сайта как они пришли — чтобы убедиться, что код на сайте передаёт то, что нужно.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
limit | integerпо умолчанию: 100 | Сколько событий вернуть: от 10 до 200. |
days | integerпо умолчанию: 7 | За сколько последних дней смотреть. Допустимые значения: 7, 30 |
operation | string | Только события одного вида. |
endpointId | string | Только события одной точки интеграции. |
Что возвращается
Если за выбранные дни событий не было, журнал ищет глубже
и показывает последнее, что есть: window
говорит, за какой срок ответ на самом деле собран.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
503 |
70 |
Хранилище событий недоступно |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/events/log?limit=100&days=7' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/events/log?limit=100&days=7');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/events/log?limit=100&days=7',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/events/log?limit=100&days=7', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"limit": 100,
"days": 7,
"window": 7,
"events": [
{
"time": "2026-10-27 11:48:31",
"operation": "viewed",
"originDomain": "example.ru",
"email": "ivan@example.ru",
"data": {
"id": "4412",
"price": "2490"
}
}
]
}
}
}
Веб-пуш сайта #
GET
/sites/{site_id}/push
Подписки на веб-пуш по доменам сайта: сколько их и сколько живых.
Только чтение: подключение веб-пуша и тексты запроса подписки настраиваются в кабинете.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
site_id обязательный | integer | Идентификатор сайта. |
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
period | stringпо умолчанию: week | Период графика подписок и отписок. Допустимые значения: week, month, year |
Что возвращается
Строка на каждый домен сайта: подписка заводится на домен,
поэтому у сайта с двумя доменами и приложений два.
push: null — на этом домене веб-пуш не
подключён.
devices — все подписки, active —
неотозванные, engaged — заходившие за последние
30 дней. Отозванная подписка — это браузер, который отписался
или больше не существует.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
404 |
4 |
Сайта с таким идентификатором у аккаунта нет |
403 |
65 |
У субаккаунта нет права на модули сайта |
curl -X GET 'https://api.dashamail.com/v2/sites/100842/push' \
-H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/sites/100842/push');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.get(
'https://api.dashamail.com/v2/sites/100842/push',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/sites/100842/push', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": [
{
"domain": "example.ru",
"push": {
"id": 1182,
"sdk_version": 2,
"autoprompt": true
},
"devices": 24180,
"active": 19420,
"engaged": 8104,
"audience": {
"period": "week",
"title": "7 дней",
"subscribed": 412,
"unsubscribed": 96,
"growth": 316,
"browsers": {
"Chrome": 14204,
"Safari": 3180,
"Firefox": 1204,
"Edge": 832
}
}
},
{
"domain": "m.example.ru",
"push": null,
"devices": 0,
"active": 0,
"engaged": 0
}
]
}
}