Перейти к содержанию

REST API Mailexam®

REST API Mailexam® позволяет программно работать с проектами, почтовыми ящиками и письмами — удобно для автотестов, QA и CI/CD. Типичный сценарий: приложение отправляет письмо по SMTP, тест через API проверяет, что оно дошло до sandbox, и сверяет тему, тело или вложения.

Полная спецификация OpenAPI доступна в Swagger UI.

Базовый URL

Параметр Значение
Базовый адрес https://mailexam.ru/api/v1
Формат JSON
Методы GET, POST, PUT, DELETE

Домены

Регион API
Россия mailexam.ru
Китай mailexam.cn
Международный mailexam.io

Пути и формат запросов совпадают; меняется только хост.

Авторизация

Все запросы требуют API-токен — его можно получить в личном кабинете Mailexam®.

Токен передаётся query-параметром token:

curl -s "https://mailexam.ru/api/v1/project?token=ВАШ_API_ТОКЕН"

Секреты в CI/CD

Не храните токен в коде репозитория. Добавьте переменную MAILEXAM_API_TOKEN в секреты GitLab CI, GitHub Actions или другого pipeline.

Код ответа Значение
200 / 201 Успешная операция
403 Недостаточно прав или неверный токен
404 Объект по UUID не найден

Типичный сценарий в CI/CD

  1. Отправить письмо из приложения через SMTP (см. примеры интеграции).
  2. Подождать доставку — обычно 1–5 секунд.
  3. Получить список проектов → почтовых ящиков → писем через API.
  4. Найти письмо по теме или получателю и проверить содержимое.
sequenceDiagram
    participant App as Приложение
    participant SMTP as SMTP Mailexam
    participant API as REST API
    participant Test as Автотест

    App->>SMTP: sendMail()
    Note over SMTP: Письмо в sandbox
    Test->>API: GET /project
    Test->>API: GET /inbox?project=...
    Test->>API: GET /email?inbox=...
    Test->>Test: assert subject, body

Справочник эндпоинтов

Проекты (/project)

Метод Путь Описание
GET /project Список проектов
POST /project/store Создание проекта
GET /project/{uuid} Информация о проекте
PUT /project/{uuid}/update Обновление проекта
DELETE /project/{uuid}/delete Удаление проекта

Тело запроса при создании и обновлении:

{
  "name": "Мой проект",
  "description": null
}

Пример ответа (ProjectResponse):

{
  "uuid": "536a47df-5aad-44d0-8163-a39bb55abe0b",
  "name": "Мой проект",
  "description": null,
  "user": {
    "uuid": "984f1f70-21e1-4244-bbb7-734ac151dcdc",
    "name": "Служба поддержки Mailexam",
    "email": "support@mailexam.ru"
  }
}

Почтовые ящики (/inbox)

Метод Путь Описание
GET /inbox?project={uuid} Список ящиков проекта
POST /inbox/store Создание ящика
GET /inbox/{uuid} Информация о ящике
PUT /inbox/{uuid}/default Ящик «по умолчанию»
PUT /inbox/{uuid}/update Обновление ящика
DELETE /inbox/{uuid}/delete Удаление ящика

Тело запроса при создании (InboxRequest):

{
  "project_uuid": "536a47df-5aad-44d0-8163-a39bb55abe0b",
  "name": "Все письма",
  "has_autorelay": false,
  "relay_host": null,
  "relay_port": null,
  "relay_pass": null
}

Письма (/email)

Метод Путь Описание
GET /email?inbox={uuid} Список писем в ящике
GET /email/{uuid} Полное письмо (тело, заголовки)
GET /email/{uuid}/attachment?cid={id} Вложение
PUT /email/{uuid}/unread Признак «не прочитано»
PUT /email/{uuid}/like Признак «нравится»
PUT /email/{uuid}/dislike Признак «не нравится»
PUT /email/{uuid}/relay Отправка на сервер ретрансляции
DELETE /email/{uuid}/delete Удаление письма

Краткий формат письма (EmailShort):

{
  "uuid": "e2f9a506-d766-4935-be11-c413384de020",
  "from": "\"Mailexam\" <support@mailexam.ru>",
  "to": "Служба поддержки Mailexam <support@mailexam.ru>",
  "cc": null,
  "subject": "Параметры подключения к Mailexam",
  "human_size": "113 Байт",
  "date": "2025-03-01T08:58:49.000000Z",
  "attachments": true,
  "unread": false,
  "like": true,
  "dislike": false
}

Полный формат (EmailDetailed) дополнительно содержит поля body (html, text, raw, attachments), headers и relay.

Пример: проверка письма через curl

Переменные окружения:

export MAILEXAM_API_TOKEN="ваш_токен"
export MAILEXAM_API_BASE="https://mailexam.ru/api/v1"
curl -s "${MAILEXAM_API_BASE}/project?token=${MAILEXAM_API_TOKEN}" | jq .
PROJECT_UUID="536a47df-5aad-44d0-8163-a39bb55abe0b"

curl -s "${MAILEXAM_API_BASE}/inbox?project=${PROJECT_UUID}&token=${MAILEXAM_API_TOKEN}" | jq .
INBOX_UUID="deab7974-a252-4412-9169-b965116b63cf"

curl -s "${MAILEXAM_API_BASE}/email?inbox=${INBOX_UUID}&token=${MAILEXAM_API_TOKEN}" | jq .
EMAIL_UUID="e2f9a506-d766-4935-be11-c413384de020"

curl -s "${MAILEXAM_API_BASE}/email/${EMAIL_UUID}?token=${MAILEXAM_API_TOKEN}" | jq .

Пример: автотест на Python

Сценарий: после SMTP-отправки найти письмо по теме и проверить текст.

import os
import time
import urllib.parse
import urllib.request
import json

API_BASE = os.environ.get("MAILEXAM_API_BASE", "https://mailexam.ru/api/v1")
TOKEN = os.environ["MAILEXAM_API_TOKEN"]
PROJECT_UUID = os.environ["MAILEXAM_PROJECT_UUID"]
EXPECTED_SUBJECT = "Проверка CI"


def api_get(path, params=None):
    params = dict(params or {})
    params["token"] = TOKEN
    url = f"{API_BASE}{path}?{urllib.parse.urlencode(params)}"
    with urllib.request.urlopen(url) as resp:
        return json.loads(resp.read().decode())


def wait_for_email(subject, timeout=30, interval=2):
    inboxes = api_get("/inbox", {"project": PROJECT_UUID})
    inbox_uuid = inboxes[0]["uuid"]
    deadline = time.time() + timeout

    while time.time() < deadline:
        emails = api_get("/email", {"inbox": inbox_uuid})
        for item in emails:
            if item["subject"] == subject:
                return api_get(f"/email/{item['uuid']}")
        time.sleep(interval)

    raise TimeoutError(f"Письмо с темой «{subject}» не найдено за {timeout} с")


if __name__ == "__main__":
    # ... здесь отправка письма через SMTP вашего приложения ...
    time.sleep(3)

    email = wait_for_email(EXPECTED_SUBJECT)
    body_text = (email.get("body") or {}).get("text") or ""
    assert "Привет" in body_text, "Текст письма не совпадает"
    print("OK")

Зависимости не нужны — используется стандартная библиотека Python 3. Для HTTP удобнее requests или httpx, если они уже есть в проекте.

Пример: автотест на Node.js

const TOKEN = process.env.MAILEXAM_API_TOKEN;
const API_BASE = process.env.MAILEXAM_API_BASE || 'https://mailexam.ru/api/v1';
const PROJECT_UUID = process.env.MAILEXAM_PROJECT_UUID;
const EXPECTED_SUBJECT = 'Проверка CI';

async function apiGet(path, params = {}) {
  const query = new URLSearchParams({ ...params, token: TOKEN });
  const res = await fetch(`${API_BASE}${path}?${query}`);
  if (!res.ok) throw new Error(`${res.status} ${path}`);
  return res.json();
}

async function waitForEmail(subject, timeoutMs = 30000, intervalMs = 2000) {
  const inboxes = await apiGet('/inbox', { project: PROJECT_UUID });
  const inboxUuid = inboxes[0].uuid;
  const deadline = Date.now() + timeoutMs;

  while (Date.now() < deadline) {
    const emails = await apiGet('/email', { inbox: inboxUuid });
    const match = emails.find((item) => item.subject === subject);
    if (match) return apiGet(`/email/${match.uuid}`);
    await new Promise((r) => setTimeout(r, intervalMs));
  }

  throw new Error(`Письмо «${subject}» не найдено за ${timeoutMs / 1000} с`);
}

(async () => {
  // ... отправка через SMTP ...
  await new Promise((r) => setTimeout(r, 3000));

  const email = await waitForEmail(EXPECTED_SUBJECT);
  const text = email.body?.text || '';
  if (!text.includes('Привет')) throw new Error('Текст письма не совпадает');
  console.log('OK');
})().catch((err) => {
  console.error(err);
  process.exit(1);
});

Node.js 18+ — встроенный fetch.

GitLab CI

integration_test:
  stage: test
  variables:
    MAILEXAM_API_BASE: "https://mailexam.ru/api/v1"
    MAILEXAM_PROJECT_UUID: "536a47df-5aad-44d0-8163-a39bb55abe0b"
  script:
    - python send_and_verify.py
  # MAILEXAM_API_TOKEN, MAILEXAM_LOGIN, MAILEXAM_PASSWORD — в CI/CD Variables

SMTP-секреты (MAILEXAM_LOGIN, MAILEXAM_PASSWORD) и API-токен — разные значения: первые для отправки, второй для чтения через REST.

Сравнение с Mailtrap API

При миграции с Mailtrap замените вызовы Sandbox API:

Задача Mailtrap Mailexam®
Список писем Sandbox API GET /email?inbox={uuid}
Одно письмо Sandbox API GET /email/{uuid}
Вложение Sandbox API GET /email/{uuid}/attachment?cid={id}
Управление sandbox Sandboxes API GET /project, /inbox

Типичные проблемы

403 Forbidden

  • Проверьте, что токен скопирован полностью и передан как ?token=....
  • Токен привязан к аккаунту — убедитесь, что проект принадлежит этому пользователю.

Пустой список писем

  • Письмо могло попасть в другой проект или ящик — сверьте SMTP-логин с нужным проектом.
  • Увеличьте паузу после SMTP-отправки (2–5 с) или используйте polling с таймаутом.

Письмо есть в кабинете, но тест его не находит

  • Фильтруйте по точной теме или проверяйте последние письма по дате (date в ответе API).
  • Для вложений сначала получите EmailDetailed, затем скачайте файл по cid.

См. также