Добро пожаловать в TrainAPI
Полнофункциональный REST API для управления электронной почтой от Trainmail - абсолютно бесплатно и навсегда.
100% Бесплатный сервис
TrainAPI является полностью бесплатным проектом без каких-либо скрытых платежей. Мы верим в открытый доступ к инструментам электронной почты для всех разработчиков.
Что такое TrainAPI?
TrainAPI - это мощный RESTful API, который позволяет разработчикам интегрировать полнофункциональные возможности электронной почты в свои приложения. Отправляйте, получайте и управляйте электронными письмами программно с помощью простых HTTP-запросов.
Отправляйте письма за миллисекунды с нашей высокооптимизированной инфраструктурой.
Шифрование на уровне предприятия и соответствие современным стандартам безопасности.
Подробная аналитика доставки, открытий и кликов в реальном времени.
99.99% времени безотказной работы с автоматическим резервным копированием.
Основные возможности
- Отправка транзакционных и маркетинговых писем
- Управление шаблонами писем с динамическими переменными
- Поддержка вложений любого размера
- Webhooks для событий в реальном времени
- Отслеживание открытий и кликов
- Входящая обработка электронной почты
- Валидация email-адресов
- Планирование отправки писем
Начало работы
Начать работу с TrainAPI невероятно просто. Вам нужен только API-ключ, который можно получить бесплатно на сайте Trainmail.
curl -X POST https://api.trainmail.online/v1/emails/send \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@example.com",
"to": "recipient@example.com",
"subject": "Hello from TrainAPI",
"html": "Welcome!
This is your first email.
"
}'
Базовый URL
https://api.trainmail.online/v1
Все запросы к API должны использовать HTTPS и содержать префикс версии API.
Статус сервиса
Все системы работают нормально
API TrainAPI работает на распределенной облачной инфраструктуре для обеспечения максимальной доступности и производительности.
Быстрый старт
Отправьте свое первое письмо за 5 минут
Шаг 1: Получение API-ключа
Зарегистрируйтесь на платформе Trainmail и получите бесплатный API-ключ из панели управления.
- Перейдите на trainmail.online
- Войдите в ваш аккаунт
- Перейдите в раздел "API Keys"
- Создайте новый ключ и скопируйте его
Безопасность
Храните ваш API-ключ в секрете. Не публикуйте его в публичных репозиториях или клиентском коде.
Шаг 2: Отправка первого письма
Используйте endpoint /v1/emails/send для отправки электронного письма:
curl -X POST https://api.trainmail.online/v1/emails/send \
-H "Authorization: Bearer train_sk_1234567890abcdef" \
-H "Content-Type: application/json" \
-d '{
"from": {
"email": "noreply@yourdomain.com",
"name": "Your Company"
},
"to": [
{
"email": "customer@example.com",
"name": "John Doe"
}
],
"subject": "Welcome to our service!",
"html": "Welcome!
Thank you for signing up.
",
"text": "Welcome! Thank you for signing up."
}'
import requests
api_key = "train_sk_1234567890abcdef"
url = "https://api.trainmail.online/v1/emails/send"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"from": {
"email": "noreply@yourdomain.com",
"name": "Your Company"
},
"to": [
{
"email": "customer@example.com",
"name": "John Doe"
}
],
"subject": "Welcome to our service!",
"html": "Welcome!
Thank you for signing up.
",
"text": "Welcome! Thank you for signing up."
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const axios = require('axios');
const apiKey = 'train_sk_1234567890abcdef';
const url = 'https://api.trainmail.online/v1/emails/send';
const payload = {
from: {
email: 'noreply@yourdomain.com',
name: 'Your Company'
},
to: [
{
email: 'customer@example.com',
name: 'John Doe'
}
],
subject: 'Welcome to our service!',
html: 'Welcome!
Thank you for signing up.
',
text: 'Welcome! Thank you for signing up.'
};
axios.post(url, payload, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
[
'email' => 'noreply@yourdomain.com',
'name' => 'Your Company'
],
'to' => [
[
'email' => 'customer@example.com',
'name' => 'John Doe'
]
],
'subject' => 'Welcome to our service!',
'html' => 'Welcome!
Thank you for signing up.
',
'text' => 'Welcome! Thank you for signing up.'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $api_key,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
Шаг 3: Проверка ответа
При успешной отправке вы получите ответ с идентификатором письма:
{
"success": true,
"data": {
"id": "msg_abc123def456",
"status": "queued",
"created_at": "2025-12-01T03:46:00Z",
"from": "noreply@yourdomain.com",
"to": ["customer@example.com"],
"subject": "Welcome to our service!"
}
}
Следующие шаги
Теперь, когда вы отправили свое первое письмо, изучите дополнительные возможности:
- Используйте шаблоны для динамического контента
- Добавьте вложения к вашим письмам
- Настройте webhooks для получения событий
- Отслеживайте открытия и клики
- Используйте расписание для отложенной отправки
Аутентификация
TrainAPI использует API-ключи для аутентификации запросов
Обзор
Все запросы к TrainAPI должны включать действующий API-ключ в заголовке Authorization. API-ключи можно создать и управлять ими через панель управления Trainmail.
Authorization: Bearer train_sk_1234567890abcdef
Типы API-ключей
Секретные ключи (Secret Keys)
Секретные ключи начинаются с префикса train_sk_ и должны использоваться только на серверной стороне. Они имеют полный доступ к вашему аккаунту.
Важно!
Никогда не используйте секретные ключи в клиентском коде (браузер, мобильные приложения). Они дают полный доступ к вашему аккаунту.
Публичные ключи (Public Keys)
Публичные ключи начинаются с префикса train_pk_ и могут безопасно использоваться в клиентском коде. Они имеют ограниченные права доступа.
Создание API-ключей
- Войдите в панель управления Trainmail
- Перейдите в раздел Settings → API Keys
- Нажмите "Create New Key"
- Выберите тип ключа и установите права доступа
- Скопируйте ключ (он больше не будет показан)
Права доступа
Вы можете ограничить права доступа каждого API-ключа следующими разрешениями:
| Разрешение | Описание |
|---|---|
| emails.send | Отправка электронных писем |
| emails.read | Чтение информации о письмах |
| templates.manage | Управление шаблонами |
| webhooks.manage | Управление вебхуками |
| analytics.read | Чтение аналитики |
| admin | Полный административный доступ |
Лучшие практики безопасности
- Используйте отдельные ключи для разных сред (dev, staging, production)
- Регулярно ротируйте API-ключи
- Предоставляйте только необходимые разрешения
- Храните ключи в переменных окружения, а не в коде
- Немедленно отзывайте скомпрометированные ключи
- Мониторьте использование ключей через dashboard
Ошибки аутентификации
Если аутентификация не удалась, API вернет одну из следующих ошибок:
API-ключ отсутствует или недействителен.
{
"error": {
"code": "unauthorized",
"message": "Invalid API key provided"
}
}
У API-ключа недостаточно прав для выполнения операции.
{
"error": {
"code": "forbidden",
"message": "This API key does not have permission to perform this action"
}
}
Электронная почта
API для отправки, получения и управления электронными письмами
Отправка письма
Отправляет электронное письмо одному или нескольким получателям.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| from | object/string | Да | Адрес отправителя |
| to | array | Да | Массив получателей |
| cc | array | Нет | Копия письма |
| bcc | array | Нет | Скрытая копия |
| subject | string | Да | Тема письма |
| html | string | Нет | HTML-содержимое |
| text | string | Нет | Текстовое содержимое |
| attachments | array | Нет | Массив вложений |
| headers | object | Нет | Дополнительные заголовки |
| tags | array | Нет | Теги для категоризации |
| schedule_at | string | Нет | Время отложенной отправки (ISO 8601) |
| track_opens | boolean | Нет | Отслеживать открытия (по умолчанию: true) |
| track_clicks | boolean | Нет | Отслеживать клики (по умолчанию: true) |
Пример запроса
{
"from": {
"email": "sender@yourdomain.com",
"name": "John Sender"
},
"to": [
{
"email": "recipient@example.com",
"name": "Jane Recipient"
},
{
"email": "another@example.com"
}
],
"cc": [
{
"email": "cc@example.com",
"name": "CC Person"
}
],
"subject": "Your order #12345 has been shipped",
"html": "Order Shipped!
Your order is on its way.
",
"text": "Order Shipped! Your order is on its way.",
"tags": ["order", "shipping"],
"track_opens": true,
"track_clicks": true
}
Получение информации о письме
Получает подробную информацию о конкретном письме.
Пример ответа
{
"success": true,
"data": {
"id": "msg_abc123def456",
"status": "delivered",
"from": {
"email": "sender@yourdomain.com",
"name": "John Sender"
},
"to": [
{
"email": "recipient@example.com",
"name": "Jane Recipient"
}
],
"subject": "Your order #12345 has been shipped",
"created_at": "2025-12-01T03:46:00Z",
"sent_at": "2025-12-01T03:46:05Z",
"delivered_at": "2025-12-01T03:46:12Z",
"opened_at": "2025-12-01T04:15:30Z",
"opens_count": 3,
"clicks_count": 1,
"tags": ["order", "shipping"],
"events": [
{
"type": "sent",
"timestamp": "2025-12-01T03:46:05Z"
},
{
"type": "delivered",
"timestamp": "2025-12-01T03:46:12Z"
},
{
"type": "opened",
"timestamp": "2025-12-01T04:15:30Z"
}
]
}
}
Список писем
Получает список всех отправленных писем с возможностью фильтрации.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
| limit | integer | Количество результатов (по умолчанию: 50, макс: 100) |
| offset | integer | Смещение для пагинации |
| status | string | Фильтр по статусу (sent, delivered, bounced, failed) |
| tag | string | Фильтр по тегу |
| from | string | Фильтр по адресу отправителя |
| to | string | Фильтр по адресу получателя |
| created_after | string | Письма после указанной даты (ISO 8601) |
| created_before | string | Письма до указанной даты (ISO 8601) |
Отмена отправки
Отменяет отправку запланированного письма. Работает только для писем со статусом "scheduled".
Статусы писем
- queued - Письмо в очереди на отправку
- scheduled - Письмо запланировано к отправке
- sent - Письмо отправлено
- delivered - Письмо доставлено
- opened - Письмо открыто получателем
- clicked - Получатель кликнул по ссылке
- bounced - Письмо не доставлено (отскок)
- failed - Ошибка при отправке
- spam - Помечено как спам
- unsubscribed - Получатель отписался
Почтовые ящики
Управление почтовыми ящиками и доменами
Обзор
API почтовых ящиков позволяет создавать и управлять виртуальными почтовыми ящиками, настраивать домены и получать входящие письма.
Создание почтового ящика
Создает новый почтовый ящик.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| string | Да | Email-адрес почтового ящика | |
| name | string | Нет | Отображаемое имя |
| forward_to | array | Нет | Адреса для пересылки |
| auto_reply | object | Нет | Настройки автоответчика |
{
"email": "support@yourdomain.com",
"name": "Customer Support",
"forward_to": ["team@internal.com"],
"auto_reply": {
"enabled": true,
"subject": "We received your message",
"body": "Thank you for contacting us. We'll respond within 24 hours."
}
}
Список почтовых ящиков
Получает список всех почтовых ящиков.
Получение почтового ящика
Получает информацию о конкретном почтовом ящике.
Обновление почтового ящика
Обновляет настройки почтового ящика.
Удаление почтового ящика
Удаляет почтовый ящик и все связанные с ним письма.
Получение входящих писем
Получает список входящих писем для указанного почтового ящика.
{
"success": true,
"data": {
"messages": [
{
"id": "msg_xyz789abc123",
"from": {
"email": "customer@example.com",
"name": "Customer Name"
},
"to": "support@yourdomain.com",
"subject": "Question about pricing",
"received_at": "2025-12-01T03:46:00Z",
"size": 15420,
"has_attachments": false,
"is_read": false
}
],
"total": 42,
"limit": 50,
"offset": 0
}
}
Управление доменами
Прежде чем отправлять письма с вашего домена, необходимо его верифицировать.
Добавление домена
Добавляет новый домен для верификации.
{
"domain": "yourdomain.com",
"region": "eu"
}
Верификация домена
После добавления домена вам нужно будет добавить DNS-записи для верификации:
| Тип | Хост | Значение |
|---|---|---|
| TXT | @ | trainmail-verify=abc123def456 |
| MX | @ | 10 mx.trainmail.online |
| TXT | @ | v=spf1 include:spf.trainmail.online ~all |
| TXT | train._domainkey | k=rsa; p=MIGfMA0GCSqGSIb3... |
Распространение DNS
DNS-записи могут обновляться до 48 часов. Верификация домена будет автоматически проверяться каждый час.
Шаблоны
Создание и управление шаблонами писем
Обзор
Шаблоны позволяют создавать переиспользуемые макеты писем с динамическими переменными. Это идеально подходит для транзакционных писем, уведомлений и маркетинговых кампаний.
Создание шаблона
Создает новый шаблон письма.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| name | string | Да | Уникальное имя шаблона |
| subject | string | Да | Тема письма (может содержать переменные) |
| html | string | Нет | HTML-содержимое шаблона |
| text | string | Нет | Текстовое содержимое шаблона |
| description | string | Нет | Описание шаблона |
Пример создания шаблона
{
"name": "welcome-email",
"subject": "Welcome to {{company_name}}, {{user_name}}!",
"html": "
Переменные шаблона
Используйте синтаксис {{variable_name}} для вставки динамических значений. Переменные заменяются при отправке письма.
Поддерживаемые функции
- {{variable}} - Простая переменная
- {{variable|default:"value"}} - Значение по умолчанию
- {{variable|upper}} - Преобразование в верхний регистр
- {{variable|lower}} - Преобразование в нижний регистр
- {{variable|capitalize}} - Первая буква заглавная
- {{date|date:"Y-m-d"}} - Форматирование даты
Отправка с использованием шаблона
Отправляет письмо, используя существующий шаблон.
{
"from": "noreply@yourdomain.com",
"to": "newuser@example.com",
"template": "welcome-email",
"variables": {
"company_name": "Acme Corp",
"user_name": "John Doe",
"user_email": "newuser@example.com",
"activation_link": "https://yourdomain.com/activate/abc123"
}
}
Список шаблонов
Получает список всех шаблонов.
Получение шаблона
Получает информацию о конкретном шаблоне.
Обновление шаблона
Обновляет существующий шаблон.
Удаление шаблона
Удаляет шаблон.
Лучшие практики
- Используйте описательные имена для шаблонов
- Всегда предоставляйте текстовую версию вместе с HTML
- Тестируйте шаблоны с различными значениями переменных
- Используйте значения по умолчанию для необязательных переменных
- Версионируйте ваши шаблоны для отслеживания изменений
Вложения
Добавление файлов к электронным письмам
Обзор
TrainAPI поддерживает отправку файлов в качестве вложений к электронным письмам. Вы можете прикрепить файлы используя base64-кодирование или URL.
Inline вложения
Для добавления вложений непосредственно в запрос, используйте base64-кодирование:
{
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Invoice attached",
"html": "Please find your invoice attached.
",
"attachments": [
{
"filename": "invoice-2025-12.pdf",
"content": "JVBERi0xLjQKJeLjz9MKNCAwIG9...",
"content_type": "application/pdf",
"disposition": "attachment"
},
{
"filename": "logo.png",
"content": "iVBORw0KGgoAAAANSUhEUgAAA...",
"content_type": "image/png",
"disposition": "inline",
"content_id": "logo"
}
]
}
Параметры вложения
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| filename | string | Да | Имя файла |
| content | string | Да | Содержимое в base64 |
| content_type | string | Нет | MIME-тип файла |
| disposition | string | Нет | attachment или inline (по умолчанию: attachment) |
| content_id | string | Нет | ID для inline изображений |
Вложения по URL
Вы можете указать URL файла вместо его содержимого:
{
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Report attached",
"html": "Monthly report is attached.
",
"attachments": [
{
"filename": "report.pdf",
"url": "https://yourdomain.com/files/report-2025-12.pdf"
}
]
}
Inline изображения
Для встраивания изображений в HTML-содержимое используйте content_id:
{
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Newsletter",
"html": "Our Newsletter

Content here...
",
"attachments": [
{
"filename": "header.jpg",
"content": "iVBORw0KGgoAAAANSUhEUgAAA...",
"content_type": "image/jpeg",
"disposition": "inline",
"content_id": "header-image"
}
]
}
Ограничения
| Ограничение | Значение |
|---|---|
| Максимальный размер одного файла | 25 MB |
| Максимальный общий размер | 50 MB |
| Максимальное количество вложений | 20 |
Поддерживаемые типы файлов
TrainAPI поддерживает все стандартные типы файлов. Исполняемые файлы (.exe, .bat, .sh) и потенциально опасные форматы могут быть заблокированы некоторыми почтовыми провайдерами.
Пример на Python
import requests
import base64
# Read and encode file
with open('document.pdf', 'rb') as file:
encoded_file = base64.b64encode(file.read()).decode('utf-8')
payload = {
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Document attached",
"html": "Please find the document attached.
",
"attachments": [
{
"filename": "document.pdf",
"content": encoded_file,
"content_type": "application/pdf"
}
]
}
response = requests.post(
"https://api.trainmail.online/v1/emails/send",
json=payload,
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(response.json())
Вебхуки
Получайте уведомления о событиях в реальном времени
Обзор
Вебхуки позволяют получать HTTP-уведомления о событиях, связанных с вашими письмами. TrainAPI отправляет POST-запрос на указанный URL при возникновении события.
Создание вебхука
Создает новый вебхук.
{
"url": "https://yourdomain.com/webhooks/trainmail",
"events": ["email.sent", "email.delivered", "email.opened", "email.clicked"],
"description": "Production webhook",
"secret": "your_webhook_secret_key"
}
Типы событий
| Событие | Описание |
|---|---|
| email.sent | Письмо отправлено |
| email.delivered | Письмо доставлено |
| email.opened | Письмо открыто |
| email.clicked | Клик по ссылке |
| email.bounced | Письмо отскочило |
| email.spam | Помечено как спам |
| email.unsubscribed | Получатель отписался |
| email.failed | Ошибка отправки |
Формат данных
TrainAPI отправляет следующую структуру данных:
{
"event": "email.opened",
"timestamp": "2025-12-01T03:46:00Z",
"webhook_id": "wh_abc123def456",
"data": {
"email_id": "msg_xyz789abc123",
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Your order has shipped",
"opened_at": "2025-12-01T04:15:30Z",
"user_agent": "Mozilla/5.0...",
"ip_address": "192.168.1.1",
"location": {
"country": "US",
"city": "New York"
}
}
}
Проверка подписи
Каждый webhook-запрос включает заголовок X-TrainMail-Signature для верификации подлинности:
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
computed_signature = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed_signature, signature)
# В вашем webhook-обработчике
@app.route('/webhooks/trainmail', methods=['POST'])
def handle_webhook():
payload = request.get_data(as_text=True)
signature = request.headers.get('X-TrainMail-Signature')
if not verify_webhook(payload, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
event_data = request.json
# Обработка события
return 'OK', 200
Повторные попытки
Если ваш endpoint не отвечает или возвращает ошибку, TrainAPI будет повторять попытки:
- Первая попытка: немедленно
- Вторая попытка: через 5 минут
- Третья попытка: через 30 минут
- Четвертая попытка: через 2 часа
- Пятая попытка: через 6 часов
Тайм-аут
Ваш webhook endpoint должен ответить в течение 10 секунд со статусом 2xx. Более длительные операции выполняйте асинхронно.
Список вебхуков
Получает список всех вебхуков.
Удаление вебхука
Удаляет вебхук.
Тестирование вбхуке
Отправляет тестовое событие на ваш webhook endpoint.
SDK и библиотеки
Официальные клиентские библиотеки для различных языков программирования
Обзор
TrainAPI предоставляет официальные SDK для популярных языков программирования, упрощающие интеграцию.
pip install trainmail
npm install trainmail
composer require trainmail/trainmail-php
gem install trainmail
go get github.com/trainmail/trainmail-go
Maven/Gradle доступен
Python SDK
from trainmail import TrainMail
# Инициализация клиента
client = TrainMail(api_key='train_sk_1234567890abcdef')
# Отправка письма
email = client.emails.send(
from_email='sender@yourdomain.com',
to='recipient@example.com',
subject='Hello from Python SDK',
html='Welcome!
This email was sent using Python SDK.
',
text='Welcome! This email was sent using Python SDK.'
)
print(f"Email sent with ID: {email.id}")
# Получение информации о письме
email_info = client.emails.get(email.id)
print(f"Status: {email_info.status}")
# Список писем
emails = client.emails.list(limit=10, status='delivered')
for email in emails:
print(f"{email.subject} - {email.status}")
# Создание шаблона
template = client.templates.create(
name='welcome-python',
subject='Welcome {{name}}!',
html='Hello {{name}}!
'
)
# Отправка с шаблоном
client.emails.send(
from_email='sender@yourdomain.com',
to='recipient@example.com',
template='welcome-python',
variables={'name': 'John Doe'}
)
Node.js SDK
const TrainMail = require('trainmail');
// Инициализация клиента
const client = new TrainMail('train_sk_1234567890abcdef');
// Отправка письма
async function sendEmail() {
const email = await client.emails.send({
from: 'sender@yourdomain.com',
to: 'recipient@example.com',
subject: 'Hello from Node.js SDK',
html: 'Welcome!
This email was sent using Node.js SDK.
',
text: 'Welcome! This email was sent using Node.js SDK.'
});
console.log(`Email sent with ID: ${email.id}`);
// Получение информации о письме
const emailInfo = await client.emails.get(email.id);
console.log(`Status: ${emailInfo.status}`);
}
// Работа с шаблонами
async function useTemplate() {
const template = await client.templates.create({
name: 'welcome-nodejs',
subject: 'Welcome {{name}}!',
html: 'Hello {{name}}!
'
});
await client.emails.send({
from: 'sender@yourdomain.com',
to: 'recipient@example.com',
template: 'welcome-nodejs',
variables: { name: 'John Doe' }
});
}
sendEmail().catch(console.error);
PHP SDK
emails->send([
'from' => 'sender@yourdomain.com',
'to' => 'recipient@example.com',
'subject' => 'Hello from PHP SDK',
'html' => 'Welcome!
This email was sent using PHP SDK.
',
'text' => 'Welcome! This email was sent using PHP SDK.'
]);
echo "Email sent with ID: " . $email->id . "\n";
// Получение информации о письме
$emailInfo = $client->emails->get($email->id);
echo "Status: " . $emailInfo->status . "\n";
// Список писем
$emails = $client->emails->list(['limit' => 10, 'status' => 'delivered']);
foreach ($emails as $email) {
echo $email->subject . " - " . $email->status . "\n";
}
// Создание шаблона
$template = $client->templates->create([
'name' => 'welcome-php',
'subject' => 'Welcome {{name}}!',
'html' => 'Hello {{name}}!
'
]);
// Отправка с шаблоном
$client->emails->send([
'from' => 'sender@yourdomain.com',
'to' => 'recipient@example.com',
'template' => 'welcome-php',
'variables' => ['name' => 'John Doe']
]);
?>
Go SDK
package main
import (
"fmt"
"github.com/trainmail/trainmail-go"
)
func main() {
// Инициализация клиента
client := trainmail.NewClient("train_sk_1234567890abcdef")
// Отправка письма
email, err := client.Emails.Send(&trainmail.EmailRequest{
From: "sender@yourdomain.com",
To: []string{"recipient@example.com"},
Subject: "Hello from Go SDK",
HTML: "Welcome!
This email was sent using Go SDK.
",
Text: "Welcome! This email was sent using Go SDK.",
})
if err != nil {
panic(err)
}
fmt.Printf("Email sent with ID: %s\n", email.ID)
// Получение информации о письме
emailInfo, err := client.Emails.Get(email.ID)
if err != nil {
panic(err)
}
fmt.Printf("Status: %s\n", emailInfo.Status)
// Список писем
emails, err := client.Emails.List(&trainmail.ListOptions{
Limit: 10,
Status: "delivered",
})
for _, email := range emails {
fmt.Printf("%s - %s\n", email.Subject, email.Status)
}
}
Поддержка и обновления
Все SDK поддерживаются официально и регулярно обновляются. Исходный код доступен на GitHub.
Лимиты запросов
Ограничения API и управление нагрузкой
Обзор
TrainAPI применяет лимиты на количество запросов для обеспечения справедливого использования и стабильности сервиса.
Текущие лимиты
| Уровень | Запросов в минуту | Писем в день | Burst |
|---|---|---|---|
| Free | 60 | 1,000 | 100 |
| Standard | 300 | 10,000 | 500 |
| Pro | 1,000 | 100,000 | 2,000 |
| Enterprise | Индивидуально | Индивидуально | Индивидуально |
Бесплатный уровень
TrainAPI предоставляет щедрый бесплатный уровень, которого достаточно для большинства небольших проектов и разработки.
Заголовки ответа
Каждый ответ API включает заголовки с информацией о лимитах:
X-RateLimit-Limit: 60 X-RateLimit-Remaining: 45 X-RateLimit-Reset: 1638360000 X-RateLimit-Burst: 100
| Заголовок | Описание |
|---|---|
| X-RateLimit-Limit | Максимальное количество запросов в минуту |
| X-RateLimit-Remaining | Оставшееся количество запросов |
| X-RateLimit-Reset | Unix timestamp сброса лимита |
| X-RateLimit-Burst | Максимальное количество burst-запросов |
Превышение лимита
При превышении лимита API вернет ошибку 429:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 30 seconds.",
"retry_after": 30
}
}
Лучшие практики
- Кэшируйте результаты запросов где это возможно
- Используйте экспоненциальную задержку при повторных попытках
- Группируйте операции в пакетные запросы
- Мониторьте заголовки лимитов и адаптируйте скорость запросов
- Используйте вебхуки вместо polling для получения событий
- Распределяйте нагрузку равномерно во времени
Пример обработки retry
import time
import requests
def send_email_with_retry(payload, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.post(
'https://api.trainmail.online/v1/emails/send',
json=payload,
headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
if response.status_code == 429:
# Получаем время ожидания из заголовка
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limit exceeded. Waiting {retry_after} seconds...")
time.sleep(retry_after)
continue
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
if attempt == max_retries - 1:
raise
# Экспоненциальная задержка
wait_time = (2 ** attempt) * 1
print(f"Attempt {attempt + 1} failed. Retrying in {wait_time}s...")
time.sleep(wait_time)
raise Exception("Max retries exceeded")
Нужны более высокие лимиты?
Если вашему проекту требуются более высокие лимиты, свяжитесь с нами для обсуждения корпоративного плана.
Коды ошибок
Справочник по кодам ответов и ошибкам API
HTTP коды ответа
TrainAPI использует стандартные HTTP коды ответа:
Успешные ответы (2xx)
| Код | Статус | Описание |
|---|---|---|
| 200 | OK | Запрос выполнен успешно |
| 201 | Created | Ресурс успешно создан |
| 202 | Accepted | Запрос принят в обработку |
| 204 | No Content | Успешно, но без содержимого ответа |
Ошибки клиента (4xx)
| Код | Статус | Описание |
|---|---|---|
| 400 | Bad Request | Неверный формат запроса |
| 401 | Unauthorized | Отсутствует или недействителен API-ключ |
| 403 | Forbidden | Недостаточно прав для операции |
| 404 | Not Found | Ресурс не найден |
| 409 | Conflict | Конфликт с существующим ресурсом |
| 422 | Unprocessable Entity | Ошибка валидации данных |
| 429 | Too Many Requests | Превышен лимит запросов |
Ошибки сервера (5xx)
| Код | Статус | Описание |
|---|---|---|
| 500 | Internal Server Error | Внутренняя ошибка сервера |
| 502 | Bad Gateway | Ошибка шлюза |
| 503 | Service Unavailable | Сервис временно недоступен |
| 504 | Gateway Timeout | Тайм-аут шлюза |
Формат ошибок
Все ошибки возвращаются в стандартном JSON формате:
{
"error": {
"code": "validation_error",
"message": "Invalid email address format",
"field": "to",
"details": {
"to": "Must be a valid email address"
}
}
}
Распространенные коды ошибок
| Код ошибки | Описание | Решение |
|---|---|---|
| unauthorized | Недействительный API-ключ | Проверьте правильность API-ключа |
| forbidden | Недостаточно прав | Проверьте права доступа ключа |
| validation_error | Ошибка валидации данных | Проверьте формат отправляемых данных |
| not_found | Ресурс не найден | Проверьте ID ресурса |
| rate_limit_exceeded | Превышен лимит | Подождите и повторите запрос |
| insufficient_quota | Превышена квота | Обновите план или подождите сброса |
| invalid_email | Неверный email | Проверьте формат email-адреса |
| template_not_found | Шаблон не найден | Создайте шаблон или проверьте имя |
| attachment_too_large | Вложение слишком большое | Уменьшите размер файла |
| domain_not_verified | Домен не верифицирован | Завершите верификацию домена |
Обработка ошибок
import requests
def send_email(payload):
try:
response = requests.post(
'https://api.trainmail.online/v1/emails/send',
json=payload,
headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
error_data = e.response.json()
error_code = error_data['error']['code']
error_message = error_data['error']['message']
if e.response.status_code == 429:
print(f"Rate limit exceeded: {error_message}")
# Реализуйте retry логику
elif e.response.status_code == 422:
print(f"Validation error: {error_message}")
print(f"Details: {error_data['error'].get('details')}")
else:
print(f"Error {e.response.status_code}: {error_message}")
raise
except requests.exceptions.RequestException as e:
print(f"Network error: {str(e)}")
raise
Нужна помощь?
Если вы столкнулись с ошибкой, которую не можете решить, свяжитесь с нашей службой поддержки с подробностями запроса.
История изменений
Последние обновления и изменения API
Version 1.4.0 — 01/12/2025
Новые возможности
- Добавлена поддержка планирования отправки писем
- Новый endpoint для пакетной отправки писем
- Расширенная аналитика кликов с геолокацией
- Поддержка AMP for Email
Улучшения
- Улучшена производительность API на 40%
- Оптимизирована обработка больших вложений
- Добавлены дополнительные фильтры для списка писем
Version 1.3.0 — 15/10/2025
Новые возможности
- Поддержка шаблонов с условной логикой
- Webhook события для отписок
- Автоматическая оптимизация изображений
Улучшения
- Улучшена документация с большим количеством примеров
- Добавлена поддержка IPv6
Исправления
- Исправлена проблема с кодировкой в некоторых заголовках
- Улучшена обработка ошибок валидации
Version 1.2.0 — 01/09/2025
Новые возможности
- Входящая обработка почты через API
- Управление почтовыми ящиками
- Автоответчики и правила пересылки
- SDK для Ruby и Go
Улучшения
- Увеличены лимиты для бесплатного уровня
- Улучшена доставляемость писем
Version 1.1.0 — 20/07/2025
Новые возможности
- Система шаблонов с переменными
- Отслеживание открытий и кликов
- Поддержка вебхуков
- Управление доменами и верификация
Улучшения
- Ускорена отправка писем на 25%
- Добавлена подробная аналитика
Version 1.0.0 — 01/06/2025
Первый релиз
- Базовая отправка электронных писем
- Поддержка HTML и текстового содержимого
- Вложения файлов
- SDK для Python, Node.js и PHP
- REST API с аутентификацией
Планируемые функции
- Расширенная сегментация аудитории
- A/B тестирование писем
- Интеграция с популярными CRM системами
- Визуальный редактор шаблонов
- Поддержка SMTP relay