MailLandDocs
E-posta Gönderimi

REST API

Tam istek ve yanıt referansı ile Mail.Land REST API kullanarak e-posta gönderin

POST /v1/transactional/send aracılığıyla işlemsel e-postalar gönderin. Bu, MailLand üzerinden e-posta göndermenin birincil yoludur.

Kimlik Doğrulama

API anahtarınızı X-API-Key başlığına ekleyin:

X-API-Key: ml_pet_Ab3Kx9mN2pQ7rT4wL8yD...

Kimlik bilgisi Api kanalının etkin olmasını ve bir Sending ürün kimlik bilgisi olmasını gerektirir.

Tek E-posta Gönderme

POST https://api.mail.land/v1/transactional/send
Send an email
curl -X POST https://api.mail.land/v1/transactional/send \
  -H "X-API-Key: ml_pet_Ab3Kx9mN2pQ7rT4wL8yD..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": {"email": "[email protected]"},
    "to": [{"email": "[email protected]"}],
    "subject": "Hello from MailLand",
    "htmlContent": "<p>Your email content here</p>"
  }'

İstek Gövdesi

Full request example
{
  "from": {
    "email": "[email protected]",
    "name": "Your App"
  },
  "to": [
    {
      "email": "[email protected]",
      "name": "Jane Doe",
      "variables": {
        "firstName": "Jane",
        "orderNumber": "ORD-12345"
      }
    }
  ],
  "subject": "Your order #{{orderNumber}} has shipped",
  "htmlContent": "<h1>Hi {{firstName}},</h1><p>Your order #{{orderNumber}} is on its way.</p>",
  "textContent": "Hi {{firstName}}, Your order #{{orderNumber}} is on its way.",
  "replyTo": "[email protected]",
  "tags": ["order-shipped", "transactional"],
  "customHeaders": {
    "X-Entity-Ref-ID": "order-12345"
  },
  "tracking": {
    "opens": true,
    "clicks": true
  },
  "priority": "High",
  "idempotencyKey": "order-12345-shipped-v1"
}

Alan Referansı

AlanTürZorunluAçıklama
fromobjectEvetGönderici adresi
from.emailstringEvetGönderici e-postası (doğrulanmış bir alan adında olmalıdır)
from.namestringHayırGörünen ad
toarrayEvetAlıcı listesi
to[].emailstringEvetAlıcı e-posta adresi
to[].namestringHayırAlıcı görünen adı
to[].variablesobjectHayırAlıcıya özgü şablon değişkenleri
subjectstringKoşulluŞablon kullanılmadıkça zorunludur
templateIdstringHayırSatır içi içerik yerine kayıtlı şablon kullanın
htmlContentstringKoşulluHTML gövdesi (templateId yoksa htmlContent veya textContent zorunludur)
textContentstringHayırDüz metin yedek
variablesobjectHayırGenel şablon değişkenleri. templateId ayarlansın ya da ayarlanmasın uygulanır; anahtar çakışmasında alıcının kendi to[].variables değeri kazanır
replyTostringHayırYanıt e-posta adresi
tagsarrayHayırAnalitik ve webhook'larda filtreleme için etiketler
customHeadersobjectHayırÖzel e-posta başlıkları (anahtar-değer çiftleri)
trackingobjectHayırİzleme ayarlarını geçersiz kılın
tracking.opensbooleanHayırBu mesaj için açılış izleme isteyin (varsayılan: iki akışta da kapalı). Yalnızca gönderen alan adı henüz seçim yapmamışken kullanılır; alan adının Alan Adları sayfasında akış başına yaptığı seçim önceliklidir. false her zaman kapatır
tracking.clicksbooleanHayırTıklama izlemeyi etkinleştirin (varsayılan: işlemsel akışlar için hesabınız etkinleştirmedikçe false, pazarlama için true)
ipPoolIdstringHayırÖzel IP havuzları için ayrılmıştır. Henüz kullanılamıyor: göndermek 400 IP_POOL_NOT_FOUND döndürür. Boş bırakın.
scheduledAtdatetimeHayırGelecekteki teslimat için zamanlama (UTC), en fazla 7 gün öncesine kadar
idempotencyKeystringHayırAynı anahtar için yinelenen gönderimleri önleyin. X-Idempotency-Key başlığını tercih edin
attachmentsarrayHayırDosya ekleri (en fazla 10, çözümlenmiş toplam en fazla 10 MB)
priorityenumHayırLow, Normal (varsayılan), High veya Critical

Ekler

Her ek üç alan gerektirir:

Attachment format
{
  "attachments": [
    {
      "fileName": "invoice.pdf",
      "contentType": "application/pdf",
      "content": "JVBERi0xLjQKJ...",
      "inline": false
    },
    {
      "fileName": "logo.png",
      "contentType": "image/png",
      "content": "iVBORw0KGgoAAAA...",
      "contentId": "company-logo",
      "inline": true
    }
  ]
}
AlanTürZorunluAçıklama
fileNamestringEvetUzantılı dosya adı
contentTypestringEvetMIME türü (örn. application/pdf)
contentstringEvetStandart Base64 ile kodlanmış dosya içeriği: dolgulu (padding), boşluksuz ve satır sonu içermeyen
contentIdstringHayırSatır içi ekler için içerik kimliği (HTML'de cid:company-logo olarak başvurun)
inlinebooleanHayırSatır içi resim mi (varsayılan: false)

E-posta başına en fazla 10 ek ve çözümlenmiş (Base64 sonrası) toplamda en fazla 10 MB. Eksik bir contentType, standart olmayan Base64, sayının veya boyutun aşılması 400 VALIDATION_FAILED döndürür. POST /v1/transactional/send-batch içinde attachments alanı yoktur.

Yanıt

Durum: 202 Accepted

Success response
{
  "success": true,
  "jobId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "messageIds": ["t_a1b2c3d4e5f6..."],
  "acceptedRecipients": ["[email protected]"],
  "rejectedRecipients": [],
  "queuedAt": "2026-02-17T10:30:00Z",
  "isSandboxed": false
}
AlanTürAçıklama
successbooleanİsteğin kabul edilip edilmediği
jobIdstringİzleme için benzersiz iş tanımlayıcısı
messageIdsarrayAlıcı başına mesaj kimlikleri (işlemsel için t_ öneki, pazarlama için m_)
acceptedRecipientsarrayTeslim için kabul edilen e-posta adresleri
rejectedRecipientsarrayReddedilen alıcılar
queuedAtdatetimeE-postanın kuyruğa alındığı zaman
isSandboxedbooleanİstek bir sandbox kimlik bilgisi kullandıysa true (Sandbox Modu)
sandboxReasonstringcredential_sandbox_mode (kaydedildi, teslim edilmedi) veya all_recipients_not_in_sandbox_allowlist (hiçbir alıcı izin listesinde değildi); aksi halde yok

Reddedilen Alıcılar

Alıcılar çeşitli nedenlerle reddedilebilir:

Response with rejected recipients
{
  "success": true,
  "jobId": "...",
  "acceptedRecipients": ["[email protected]"],
  "rejectedRecipients": [
    {
      "email": "[email protected]",
      "reason": "Suppressed"
    },
    {
      "email": "[email protected]",
      "reason": "domain_typo",
      "suggestion": "[email protected]"
    }
  ]
}

Yaygın red nedenleri:

  • Suppressed: adres engelleme listesinde (önceki geri dönüşler/şikayetler)
  • disposable_domain: tek kullanımlık e-posta sağlayıcısı tespit edildi
  • domain_typo: alan adında muhtemel yazım hatası (suggestion alanını içerir)

Ön Kontrol

Gerçek isteği yapmadan önce gönderme yeteneğinizi doğrulayın:

GET https://api.mail.land/v1/transactional/send/check?recipientCount=1
Pre-flight check
curl https://api.mail.land/v1/transactional/send/check?recipientCount=1 \
  -H "X-API-Key: ml_pet_Ab3Kx9mN2pQ7rT4wL8yD..."
Pre-flight response
{
  "canSend": true,
  "rateLimitStatus": {
    "currentSecond": 2,
    "limitPerSecond": 50,
    "currentHour": 450,
    "limitPerHour": 5000,
    "currentDay": 8200,
    "limitPerDay": 50000
  },
  "monthlyUsed": 125000,
  "monthlyLimit": 500000
}

canSend değeri false ise, reason alanı nedenini açıklar (hız sınırı, kota, hesap durumu vb.).

Eşgüçlülük (Idempotency)

Ağ zaman aşımından sonra yapılan yeniden deneme e-postayı iki kez teslim etmemelidir. Bir eşgüçlülük anahtarı verirseniz, yeniden deneme tekrar göndermek yerine özgün yanıtı tekrarlar.

Anahtarı başlık olarak gönderin (önerilir):

X-Idempotency-Key: order-12345-shipped-v1

Veya gövdedeki idempotencyKey alanını kullanın. Her ikisi de kabul edilir; ikisini birlikte yalnızca değerler aynıysa gönderebilirsiniz.

Kurallar

  • Kapsam. X-Idempotency-Key yalnızca POST /v1/transactional/send ve POST /v1/transactional/send-batch uç noktalarında kabul edilir. Başka hiçbir uç nokta onu okumaz.
  • Biçim. 1–255 karakter: harf, rakam, _ ve -. Anahtarlar birebir karşılaştırılır; boşluk kırpma veya büyük/küçük harf eşitleme yapılmaz.
  • Pencere. Bir anahtar 24 saat boyunca tekrarlanabilir kalır. Sonrasında aynı anahtar yeni bir istek sayılır.
  • Tekrar. Pencere içindeki yeniden deneme özgün yanıtı birebir döndürür (aynı kimlikler, aynı durum) ve hiçbir şey göndermez.
  • Benzersizlik. Anahtarlar hesap başına benzersizdir. Bir anahtarı farklı bir uç nokta için yeniden kullanmak 409 ile reddedilir; her işlem için ayrı anahtar kullanın.

Korelasyon Kimliği

Bir korelasyon kimliği ekleyerek istekleri sistemler genelinde izleyin:

X-Correlation-ID: my-app-order-12345

veya

X-Request-ID: my-app-order-12345

Korelasyon kimliği günlüklerde ve etkinlik akışında görünür.

Hız Sınırı Başlıkları

Başarılı yanıtlar IP başına hız sınırı bilgisi içerir:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 295

Gönderim ilke motoru tarafından hız sınırlandığında (429), Retry-After başlığı beklenecek saniyeyi belirtir:

Retry-After: 30

İşlemsel bir istek en fazla 5 alıcı içerebilir ve her alıcı hız sınırlarınıza sayılır. Bu sayı saniye başına sınırınızı aşıyorsa (örneğin dakikada 60 olan bir planda saniyede 1), aynı saniyede başka bir istek kabul edilmemişse istek kabul edilir; aksi halde Retry-After: 1 ile 429 alır ve dakika başına sınırınız içinde bir sonraki saniyede yeniden denendiğinde başarılı olur. Bkz. Hız Sınırları.

IP düzeyinde bir 429 ayrıca ISO-8601 UTC zamanı olarak X-RateLimit-Reset içerir.

Hata Yanıtları

Tüm hatalar bir JSON gövdesi döndürür:

Error response format
{
  "code": "ERROR_CODE",
  "message": "Human-readable description",
  "timestamp": "2026-02-17T10:30:00Z",
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}

Hata Kodları

DurumKodAçıklama
400INVALID_REQUESTHatalı biçimlendirilmiş istek gövdesi, veya scheduledAt 7 günden fazla ileride ("Cannot schedule email more than 7 days in advance")
400VALIDATION_FAILEDhtmlContent, textContent veya templateId yok; ya da bir ek doğrulamayı geçemedi (yukarıdaki ek sınırlarına bakın). Yanıt, başarısız olan alan ve kuralı içeren bir errors[] dizisi içerir. (Önceden: MISSING_CONTENT: 2026-04 itibarıyla kullanımdan kaldırıldı.)
413CONTENT_TOO_LARGE"The message is too large to send: it would exceed the platform's message-size limit. Reduce the HTML, text, attachments or recipients.", Mesaj platformun boyut sınırını aşıyor. POST /v1/transactional/send ve send-batch bunu 413 ile döndürür; hiçbir şey kuyruğa alınmaz. Mesajı küçültün. CSV içe aktarmada 400 olur
400transactional_recipient_limit_exceededBir işlemsel kimlik bilgisinde 5'ten fazla alıcı (pazarlamada 1.000)
400TEMPLATE_NOT_FOUNDtemplateId bu hesabın hiçbir aktif şablonunu adlandırmıyor (silinmiş bir şablon için de döndürülür)
400IP_POOL_NOT_FOUNDipPoolId bu hesaba atanmış hiçbir havuzu adlandırmıyor (şu anda her zaman, çünkü henüz atanabilecek bir havuz yok, yukarıdaki alan referansına bakın)
422TEMPLATE_VARIABLE_MISSINGİçerikte değeri olmayan bir {{placeholder}} var; details.missingVariables adları listeler. Hiçbir şey kuyruğa alınmaz
400IDEMPOTENCY_KEY_INVALIDAnahtar boş, hatalı biçimli, 255 karakterden uzun ya da başlık birden çok kez gönderildi
400IDEMPOTENCY_KEY_CONFLICTBaşlık ve idempotencyKey gövde alanı birlikte gönderildi ve farklılar
400SEND_FAILEDTüm alıcılar engellendi (mesaj: "All recipients are suppressed")
409IDEMPOTENCY_KEY_REUSEDAnahtar bu hesapta farklı bir uç nokta için hâlihazırda kullanımda
401UNAUTHORIZEDX-API-Key eksik, geçersiz, süresi dolmuş veya iptal edilmiş
403ACCOUNT_SUSPENDEDHesap askıya alındı
403ACCOUNT_DISABLEDHesap devre dışı bırakıldı
403ACCOUNT_NOT_ACTIVEHesap aktif değil
403NO_ACTIVE_SUBSCRIPTIONHesabın aktif bir aboneliği yok
403SUBSCRIPTION_EXPIREDHesabın aboneliği sona erdi
403IP_NOT_ALLOWEDİstek IP'si kimlik bilgisinin izin verilen listesinde değil
403SENDING_BLOCKEDBu hesap için gönderim engellendi
403ACTION_REQUIREDGöndermeden önce hesapta bir işlem gerekiyor
403TENANT_APPROVAL_REQUIREDHesap göndermeden önce incelemeyi bekliyor. Yeniden denemek yardımcı olmaz; destekle iletişime geçin
422DOMAIN_NOT_VERIFIEDGönderici alan adı doğrulanmamış
422DOMAIN_NOT_ALLOWED_FOR_CREDENTIALAlan adı kimlik bilgisinin kapsamında değil
422DOMAIN_NOT_FOUNDGönderici alan adı bulunamadı
429RATE_LIMIT_EXCEEDEDHız sınırı aşıldı
429QUOTA_EXCEEDEDAylık kota tükendi
429WARMUP_LIMIT_EXCEEDEDHesabın yeni gönderim için günlük ısınma sınırına ulaşıldı; 00:00 UTC'de sıfırlanır
429DAILY_LIMIT_EXCEEDEDGünlük gönderim sınırına ulaşıldı
429WARMUP_POOL_BUDGET_EXCEEDED"Sending is temporarily paused for today. It resumes automatically at 00:00 UTC; no action is needed." / "Sending is briefly delayed. Please retry in a few minutes."
429WARMUP_POOL_EMPTY"Sending is temporarily paused. It resumes automatically; no action is needed."
429PLATFORM_DAILY_CAPACITY_REACHED"Platform sending capacity for today is fully booked. This is a temporary platform-wide limit, not your account quota, and it resets at midnight UTC."
429PLATFORM_CAPACITY_PROTECTION"New sending is briefly paused to protect platform capacity. Mail already accepted is not affected. This is transient and clears on its own; retry shortly."
429PROBATION_CAP_REACHED"New accounts can send to N recipients per rolling 24 hours until our team has reviewed the account. Capacity returns as earlier sends age out of the 24-hour window; contact support to request a review."
429PAYMENT_DAILY_LIMIT_EXCEEDEDÖdemesi gecikmiş bir hesapta günlük sınıra ulaşıldı
429MARKETING_PAUSEDBu hesap için pazarlama gönderimi duraklatıldı
429SENDING_BLOCKEDHesabın doğrulama düzeyi bu gönderime izin vermiyor (sandbox/doğrulama düzeyi reddi; sert bir gönderim engeli bunun yerine 403 döndürür, yukarıya bakın)
503SERVICE_UNAVAILABLEE-posta hizmeti geçici olarak kullanılamıyor

İşlemsel Alıcı Sınırı

İşlemsel kimlik bilgileri, gönderme isteği başına en fazla 5 alıcı zorlar. Bu, işlemsel akışların toplu gönderim için kötüye kullanılmasını önler. Daha fazla alıcıya ihtiyacınız varsa toplu gönderim ile Pazarlama kimlik bilgisi kullanın.

Şablon Kullanımı

Satır içi HTML yerine kayıtlı bir şablona başvurun:

Send with a template
{
  "from": { "email": "[email protected]" },
  "to": [
    {
      "email": "[email protected]",
      "variables": {
        "firstName": "Jane",
        "resetLink": "https://app.example.com/reset?token=abc123"
      }
    }
  ],
  "templateId": "t8x2m4q9zk7wpr",
  "variables": {
    "companyName": "Acme Inc"
  }
}

subject şablondan gelir. Anahtar çakışmasında, alıcının kendi to[].variables değeri genel variables değerlerini geçersiz kılar, satır içi içerikle aynı kural. Şablon oluşturma ve yönetme için Şablonlar sayfasına bakın.

Sonraki Adımlar

Bu sayfada