Документация для разработчиков

Диалоги

Ответы подписчиков на рассылки: переписка тредами, ответ от имени отправителя рассылки, вложения.

Когда подписчик отвечает на письмо, ответ попадает не в почтовый ящик отправителя, а в диалог — тред, привязанный к рассылке и к подписчику. Дальше в нём можно переписываться: ответ уходит подписчику письмом от того же отправителя, которым была отправлена рассылка.

Что такое диалог

Диалог заводится сам на первый входящий ответ. У него есть ящик и статус, и в фильтре списка они сведены в один параметр:

openОбычный входящий, работа не закончена. Так отдаётся по умолчанию
closedОбычный входящий, помеченный как закрытый
allОбычные входящие целиком, открытые и закрытые
autoreplyАвтоответы вроде «в отпуске» — отдельный ящик, статуса у него нет
spamОтфильтрованное как спам — тоже отдельный ящик

Права субаккаунта

Основной аккаунт видит все диалоги. Субаккаунт — только свои, по тем же правилам, что и рассылки с базами. Доступ к разделу задаётся отдельно: без него запросы отвечают кодом 2, с доступом только на чтение отказываются ответ, закрытие и открытие.

Список диалогов #

GET /dialogs

Треды от новых к старым: по времени последнего сообщения. В каждом — начало последнего сообщения, число непрочитанных и признак вложений, чтобы список можно было показать не запрашивая переписку.

Параметры строки запроса

ПараметрТипОписание
statusstringпо умолчанию: openЯщик и статус диалога.
Допустимые значения: open, closed, all, autoreply, spam
unread_onlyфлагТолько треды с непрочитанными сообщениями.
campaign_idintegerТолько ответы на эту рассылку.
list_idintegerТолько ответы подписчиков этой базы.
qstringПоиск по теме письма, адресу подписчика и названию рассылки. Не длиннее 100 символов.
limitintegerпо умолчанию: 50Размер страницы, не больше 200.
offsetintegerпо умолчанию: 0Смещение.

Возможные ошибки

HTTPcodeКогда возникает
403 65 У субаккаунта нет доступа к разделу
curl -X GET 'https://api.dashamail.com/v2/dialogs?status=open&unread_only=1&limit=2' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs?status=open&unread_only=1&limit=2');
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/dialogs?status=open&unread_only=1&limit=2',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs?status=open&unread_only=1&limit=2', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": [
      {
        "id": 8123,
        "campaign_id": 501233,
        "list_id": 128341,
        "member_id": 90421,
        "subscriber_email": "client@example.com",
        "subject": "Re: Скидки до 40%",
        "status": "open",
        "unread_count": 1,
        "last_message_at": "2026-04-05 12:41:08",
        "last_inbound_at": "2026-04-05 12:41:08",
        "created_at": "2026-04-05 12:41:08",
        "campaign_name": "Весенняя распродажа",
        "last_message_preview": "А до какого числа действует скидка?",
        "has_attachments": false
      }
    ]
  }
}

Один диалог #

GET /dialogs/{dialog_id}

Тред с контекстом: рассылка, на которую пришёл ответ, и карточка подписчика со всеми дополнительными полями базы. Сама переписка — отдельным запросом.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Возможные ошибки

HTTPcodeКогда возникает
404 9 Диалога с таким идентификатором нет либо он не ваш
curl -X GET 'https://api.dashamail.com/v2/dialogs/8123' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123');
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/dialogs/8123',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "id": 8123,
      "campaign_id": 501233,
      "subscriber_email": "client@example.com",
      "subject": "Re: Скидки до 40%",
      "status": "open",
      "unread_count": 1,
      "campaign": {
        "id": 501233,
        "name": "Весенняя распродажа",
        "subject": "Скидки до 40%",
        "from_name": "Ромашка",
        "from_email": "news@example.ru",
        "delivery_time": "2026-04-05 10:00:00",
        "status": "SENT",
        "report_url": "https://lk.dashamail.ru/?page=campaigns&id=501233"
      },
      "member": {
        "id": 90421,
        "email": "client@example.com",
        "state": "active",
        "merge_1": "Иван"
      }
    }
  }
}

Переписка диалога #

GET /dialogs/{dialog_id}/messages

Сообщения треда по возрастанию времени, вперемешку с системными событиями вроде закрытия и открытия: у первых kind: message, у вторых — event.

У сообщения есть и исходное тело, и очищенное: body_text_clean и body_html_clean — без цитат и подписей, их и стоит показывать человеку. Длинные письма и большие вложения обрезаются, на это указывают body_truncated и attachments_truncated.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Параметры строки запроса

ПараметрТипОписание
limitintegerпо умолчанию: 100Сколько сообщений вернуть, не больше 500.
offsetintegerпо умолчанию: 0Смещение.

Что возвращается

direction — in от подписчика, out ваш ответ. Вложения перечислены в attachments, ссылку на файл даёт отдельный запрос.

Возможные ошибки

HTTPcodeКогда возникает
404 9 Диалога с таким идентификатором нет либо он не ваш
curl -X GET 'https://api.dashamail.com/v2/dialogs/8123/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123/messages');
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/dialogs/8123/messages',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123/messages', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": [
      {
        "id": 41201,
        "dialog_id": 8123,
        "kind": "message",
        "direction": "in",
        "from_email": "client@example.com",
        "subject": "Re: Скидки до 40%",
        "body_text_clean": "А до какого числа действует скидка?",
        "is_read": false,
        "is_autoreply": false,
        "is_spam": false,
        "attachments": [],
        "created_at": "2026-04-05 12:41:08"
      }
    ]
  }
}

Ответить подписчику #

POST /dialogs/{dialog_id}/reply

Отправляет ответ подписчику письмом — от того же отправителя, которым была отправлена рассылка. Письмо уходит сразу и не отзывается.

Ответ не уйдёт подписчику, который отписался, пожаловался на спам или числится возвратом: такой запрос получит код 31 с его текущим состоянием.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Параметры тела запроса

ПараметрТипОписание
body_text обязательныйstringТекст ответа.
body_htmlstringHTML-версия ответа. Без неё письмо уйдёт текстом.
quote_originalstringпо умолчанию: 1Цитировать исходное письмо под ответом. 0 — не цитировать.

Что возвращается

Идентификатор созданного сообщения в треде.

Возможные ошибки

HTTPcodeКогда возникает
403 65 У субаккаунта доступ к разделу только на чтение
500 66 Письмо не удалось поставить в очередь отправки; сам ответ при этом сохранён в треде
404 9 Диалога нет; подписчик удалён
404 5 Пустое тело ответа
422 31 Подписчик отписался, пожаловался или числится возвратом
curl -X POST 'https://api.dashamail.com/v2/dialogs/8123/reply' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "body_text": "Скидка действует до 30 апреля включительно."
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123/reply');
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([
            'body_text' => 'Скидка действует до 30 апреля включительно.',
        ], 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/dialogs/8123/reply',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    json={
        'body_text': 'Скидка действует до 30 апреля включительно.',
    },
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123/reply', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "body_text": "Скидка действует до 30 апреля включительно."
}),
});

const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
Ответ HTTP 201
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "message_id": 41202,
      "dialog_id": 8123
    }
  }
}

Пометить прочитанным #

POST /dialogs/{dialog_id}/read

Помечает прочитанным весь тред, а с message_id — одно сообщение.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Параметры тела запроса

ПараметрТипОписание
message_idintegerПометить только это сообщение.

Возможные ошибки

HTTPcodeКогда возникает
404 9 Диалога с таким идентификатором нет либо он не ваш
curl -X POST 'https://api.dashamail.com/v2/dialogs/8123/read' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123/read');
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/dialogs/8123/read',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123/read', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "ok": 1
    }
  }
}

Пометить непрочитанным #

POST /dialogs/{dialog_id}/unread

Возвращает треду признак непрочитанного — чтобы он снова попал в список дел.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Возможные ошибки

HTTPcodeКогда возникает
404 9 Диалога с таким идентификатором нет либо он не ваш
curl -X POST 'https://api.dashamail.com/v2/dialogs/8123/unread' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123/unread');
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/dialogs/8123/unread',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123/unread', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "ok": 1,
      "unread_count": 1
    }
  }
}

Закрыть диалог #

POST /dialogs/{dialog_id}/close

Помечает тред закрытым: работа по нему закончена. Переписка сохраняется, новый ответ подписчика откроет тред снова.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Возможные ошибки

HTTPcodeКогда возникает
403 65 Доступ к разделу только на чтение
404 9 Диалога с таким идентификатором нет либо он не ваш
curl -X POST 'https://api.dashamail.com/v2/dialogs/8123/close' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123/close');
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/dialogs/8123/close',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123/close', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "ok": 1
    }
  }
}

Открыть диалог #

POST /dialogs/{dialog_id}/open

Возвращает закрытый тред в работу.

Параметры пути

ПараметрТипОписание
dialog_id обязательныйintegerИдентификатор диалога.

Возможные ошибки

HTTPcodeКогда возникает
403 65 Доступ к разделу только на чтение
404 9 Диалога с таким идентификатором нет либо он не ваш
curl -X POST 'https://api.dashamail.com/v2/dialogs/8123/open' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/8123/open');
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/dialogs/8123/open',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/8123/open', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "ok": 1
    }
  }
}

Сколько непрочитанного #

GET /dialogs/unread-count

Счётчики непрочитанного одним запросом. total — только обычный входящий: автоответы и спам общий счётчик не раздувают, их числа лежат отдельно в by_box.

Возможные ошибки

HTTPcodeКогда возникает
403 65 У субаккаунта нет доступа к разделу
curl -X GET 'https://api.dashamail.com/v2/dialogs/unread-count' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/unread-count');
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/dialogs/unread-count',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/unread-count', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "total": 4,
      "by_status": {
        "open": 3,
        "closed": 1
      },
      "by_box": {
        "normal": 4,
        "autoreply": 12,
        "spam": 0
      }
    }
  }
}

Ссылка на вложение #

GET /dialogs/attachments/{attachment_id}

Временная ссылка на файл из переписки. Живёт 15 минут, после чего запросите её заново — постоянной ссылки у вложения нет.

Параметры пути

ПараметрТипОписание
attachment_id обязательныйintegerИдентификатор вложения из attachments сообщения.

Возможные ошибки

HTTPcodeКогда возникает
404 9 Вложения с таким идентификатором нет либо оно не ваше
curl -X GET 'https://api.dashamail.com/v2/dialogs/attachments/3391' \
  -H 'Authorization: Bearer YOUR_API_KEY'
<?php
$ch = curl_init('https://api.dashamail.com/v2/dialogs/attachments/3391');
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/dialogs/attachments/3391',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/dialogs/attachments/3391', {
  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);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "url": "https://s3.dashamail.ru/dialogs/3391?X-Amz-Expires=900&…",
      "filename": "счёт.pdf",
      "content_type": "application/pdf",
      "size_bytes": 48211,
      "expires_at": "2026-04-05 13:10:00"
    }
  }
}

DashaMail хранит и защищает ваши данные на территории Российской Федерации

Подробнее...