Wysyłanie emaili
6 min czytania
Ten przewodnik obejmuje wszystko, co musisz wiedzieć o wysyłaniu emaili przez MailingAPI.
Uwaga: Wysyłka odbywa się wyłącznie przez REST API. MailingAPI nie oferuje SMTP submission ani relay dla klientów.
Podstawowy email
Najprostszy email wymaga czterech pól:
curl -X POST https://api.mailingapi.com/v1/messages/send \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "powiadomienia@twojadomena.pl",
"to": "user@example.com",
"subject": "Twoje zamówienie zostało wysłane",
"html": "<h1>Zamówienie wysłane</h1><p>Twoja paczka jest w drodze!</p>",
"text": "Zamówienie wysłane\n\nTwoja paczka jest w drodze!"
}'
Wymagane pola:
-
from— Adres nadawcy (musi pasować do zweryfikowanej domeny) -
to— Adres odbiorcy -
subject— Temat wiadomości -
htmllubtext— Treść emaila (wymagane przynajmniej jedno)
Dane nadawcy
Adres from
Pole from może być samym adresem lub zawierać nazwę:
{
"from": "hello@twojadomena.pl"
}
{
"from": "Twoja Firma <hello@twojadomena.pl>"
}
Adres Reply-To
Ustaw inny adres do odpowiedzi za pomocą nagłówka Reply-To:
{
"from": "powiadomienia@twojadomena.pl",
"headers": {
"Reply-To": "support@twojadomena.pl"
}
}
Odbiorcy
Pojedynczy odbiorca
{
"to": "user@example.com"
}
Z nazwą:
{
"to": "Jan Kowalski <jan@example.com>"
}
Wielu odbiorców
Dla tego samego emaila do wielu osób (widzą się nawzajem):
{
"to": ["alice@example.com", "bob@example.com"]
}
CC i BCC
{
"to": "primary@example.com",
"cc": ["manager@example.com"],
"bcc": ["archive@twojadomena.pl"]
}
to, cc i bcc mogą łącznie zawierać najwyżej 50 odbiorców, a każdy odbiorca liczy się do limitu dziennego i miesięcznego. Adresy z Twojej suppression list są pomijane także w cc i bcc.
Uwaga: Dla spersonalizowanych emaili do wielu odbiorców użyj wysyłki batch.
Treść emaila
HTML i plain text
Zawsze podawaj oba dla maksymalnej dostarczalności:
{
"html": "<h1>Witaj!</h1><p>Dziękujemy za rejestrację.</p>",
"text": "Witaj!\n\nDziękujemy za rejestrację."
}
Jeśli podasz tylko HTML, automatycznie wygenerujemy wersję tekstową.
Zmienne dynamiczne
Użyj zmiennych szablonu do personalizacji:
{
"to": "jan@example.com",
"subject": "Witaj, {{name}}!",
"html": "<p>Cześć {{name}}, Twoje konto jest gotowe.</p>",
"template_data": {
"name": "Jan"
}
}
Wspierana składnia:
-
Mustache:
{{zmienna}} -
Styl Mailgun:
%recipient.zmienna%
Załączniki
Dodaj pliki do emaila (max 10 plików, 10 MB każdy po zdekodowaniu Base64). Każdy załącznik wymaga filename i content (Base64). Nieprawidłowe załączniki są odrzucane z 422 validation_failed — nigdy nie są po cichu pomijane. Całe body żądania może mieć maksymalnie 25 MB; Base64 zwiększa pliki o ok. 33%, więc w praktyce w jednym żądaniu mieści się ok. 18 MB załączników (np. jeden plik 10 MB plus kilka małych). Większe body jest odrzucane z HTTP 413:
{
"attachments": [
{
"filename": "faktura.pdf",
"content": "base64-encoded-content-here",
"content_type": "application/pdf"
}
]
}
Dla obrazów inline (wyświetlanych w HTML):
{
"attachments": [
{
"filename": "logo.png",
"content": "base64-encoded-content",
"content_type": "image/png",
"content_id": "logo"
}
],
"html": "<img src=\"cid:logo\" alt=\"Logo\">"
}
Własne nagłówki
Dodaj własne nagłówki email:
{
"headers": {
"X-Campaign-ID": "welcome-series-2024",
"X-Customer-ID": "cust_123"
}
}
Limity: max 20 własnych nagłówków; nazwa tylko z liter, cyfr i myślników (max 128 znaków); wartość to tekst do 1000 znaków bez łamań linii (CR/LF). Przekroczenie limitu zwraca 422 validation_failed.
Zarezerwowane nagłówki (ustawiane automatycznie, przekazanie ich skutkuje odrzuceniem):
-
From,To,Cc,Bcc,Subject,Date -
MIME-Version -
DKIM-Signature,Return-Path,Sender -
Content-Type,Content-Transfer-Encoding
Reply-To jest dozwolony. Message-ID jest przyjmowany, ale ignorowany: MailingAPI zawsze nadaje własną wartość. Do wątkowania odpowiedzi użyj In-Reply-To i References.
Śledzenie
Kontroluj śledzenie otwarć i kliknięć per wiadomość:
{
"tracking": {
"opens": true,
"clicks": true
}
}
Domyślnie: oba włączone (dziedziczone z ustawień domeny).
Emaile transakcyjne vs marketingowe
Gdy oba opens i clicks są wyłączone, email jest traktowany jako transakcyjny:
- Brak pixela śledzącego (śledzenie otwarć)
- Brak przepisywania linków (śledzenie kliknięć)
-
Brak nagłówka
List-Unsubscribe— ten nagłówek sygnalizuje Gmailowi że email jest promocyjny/bulk, co obniża dostarczalność wiadomości transakcyjnych
Wyłącz śledzenie dla:
- Resetów haseł i alertów bezpieczeństwa
- Potwierdzeń zamówień i paragonów
- Powiadomień systemowych (nowe logowanie, zmiany na koncie)
- Automatycznych powiadomień 1:1
Zostaw śledzenie włączone dla:
- Kampanii marketingowych i newsletterów
- Ofert promocyjnych
- Aktualizacji produktu i ogłoszeń
Przykład — powiadomienie transakcyjne bez śledzenia:
{
"from": "alerty@twojadomena.pl",
"to": "user@example.com",
"subject": "Zamówienie #12345 zostało wysłane",
"html": "<p>Twoja paczka jest w drodze!</p>",
"tracking": {
"opens": false,
"clicks": false
}
}
Zaplanowana wysyłka
Wyślij email o określonej godzinie:
{
"scheduled_at": "2024-12-25T09:00:00Z"
}
- Użyj formatu ISO 8601 ze strefą czasową
- Maksymalnie 7 dni wprzód
-
Anuluj przez
DELETE /v1/messages/{id}/schedule
Lista zaplanowanych wiadomości:
curl https://api.mailingapi.com/v1/messages/scheduled \
-H "Authorization: Bearer $API_KEY"
Wysyłka batch
Wyślij spersonalizowane emaile do wielu odbiorców efektywnie:
curl -X POST https://api.mailingapi.com/v1/messages/batch \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@twojadomena.pl",
"subject": "Witaj, {{name}}!",
"html": "<p>Cześć {{name}}, Twój kod to {{code}}.</p>",
"recipient_variables": {
"alice@example.com": {"name": "Alicja", "code": "ABC123"},
"bob@example.com": {"name": "Robert", "code": "XYZ789"}
}
}'
Lub wyślij całkowicie różne wiadomości:
{
"messages": [
{
"from": "hello@twojadomena.pl",
"to": "alice@example.com",
"subject": "Twoja faktura",
"html": "<p>Faktura #001 w załączniku.</p>"
},
{
"from": "hello@twojadomena.pl",
"to": "bob@example.com",
"subject": "Twój paragon",
"html": "<p>Paragon #002 w załączniku.</p>"
}
]
}
Limity:
-
Maksymalnie 1000 wiadomości na żądanie (lub 1000 odbiorców w trybie
recipient_variables); więcej zwraca400bad_requestdla całego żądania - Każda wiadomość jest walidowana i przetwarzana niezależnie
-
Częściowe błędy nie blokują innych — żądanie nadal zwraca HTTP
202, więc zawsze sprawdzajerrorsw odpowiedzi (patrz Odpowiedź) -
Idempotency-Keydotyczy całego batcha jako jednej całości — patrz Idempotencja
Używanie szablonów
Wyślij używając wcześniej zdefiniowanego szablonu:
{
"from": "hello@twojadomena.pl",
"to": "user@example.com",
"template_id": "tmpl_welcome_email",
"template_data": {
"name": "Jan",
"activation_link": "https://example.com/activate/abc123"
}
}
Zobacz przewodnik Szablony po tworzenie i zarządzanie szablonami.
Tagi i metadata
Dodaj tagi do filtrowania w analityce:
{
"tags": ["welcome", "onboarding", "2024"]
}
Dodaj metadata do własnego śledzenia:
{
"metadata": {
"user_id": "usr_123",
"campaign": "black-friday"
}
}
Metadata są zwracane w webhookach i szczegółach wiadomości.
Limity (przekroczenie któregokolwiek zwraca 422 validation_failed z details dla danego pola — nic nie jest po cichu pomijane):
-
tags: max 10, każdy 1–64 znaków -
metadata: obiekt JSON, max 50 kluczy, max 2 KB po serializacji do JSON -
subject: 1–998 znaków;scheduled_at: najwyżej 7 dni w przód
Odpowiedź
Udana wysyłka zwraca:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"from": "hello@yourdomain.com",
"to": "user@example.com",
"subject": "Your order has shipped",
"created_at": "2024-01-15T10:30:00Z"
}
}
Wysyłka batch zwraca HTTP 202, gdy samo żądanie jest poprawne — nawet jeśli część lub wszystkie wiadomości zostały odrzucone. errors to licznik; sprawdź go i przejrzyj messages (w kolejności żądania, każda pozycja ma index). status pozycji to queued lub error; odrzucone pozycje nie mają id, za to zawierają obiekt error (code to validation_failed, forbidden, bad_request lub send_failed; details tylko dla validation_failed):
{
"data": {
"total": 3,
"queued": 2,
"errors": 1,
"messages": [
{"index": 0, "status": "queued", "id": "550e8400-e29b-41d4-a716-446655440000", "to": "alice@example.com"},
{
"index": 1,
"status": "error",
"to": "bob@example.com",
"error": {
"code": "validation_failed",
"message": "subject: can't be blank",
"details": {"subject": ["can't be blank"]}
}
},
{"index": 2, "status": "queued", "id": "550e8400-e29b-41d4-a716-446655440002", "to": "carol@example.com"}
]
}
}
Walidacja przed wysyłką
Sprawdź email przed wysłaniem:
curl -X POST https://api.mailingapi.com/v1/messages/analyze \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@twojadomena.pl",
"to": "user@example.com",
"subject": "Test",
"html": "<p>Treść tutaj</p>"
}'
Zwraca spam score, potencjalne problemy i rekomendacje.
Dobre praktyki
- Zawsze dołączaj wersję tekstową — Niektóre klienty nie renderują HTML
- Używaj szablonów dla spójności — Unikaj inline HTML gdy to możliwe
- Ustaw reply-to odpowiednio — Nie używaj no-reply@ jeśli chcesz odpowiedzi
- Śledź przez metadata — Połącz emaile z wewnętrznymi systemami
-
Testuj przed produkcją — Użyj najpierw endpointu
/analyze - Obsługuj bouncy — Monitoruj webhooki i czyść listy
Następne kroki
- Skonfiguruj domenę do produkcyjnej wysyłki
- Skonfiguruj webhooki dla powiadomień o dostarczeniu
- Twórz szablony dla wielokrotnego użytku