MailLandDocs
إرسال البريد

REST API

إرسال رسائل البريد الإلكتروني باستخدام REST API الخاص بـ Mail.Land مع مرجع كامل للطلبات والاستجابات

أرسل رسائل البريد الإلكتروني التحويلية عبر POST /v1/transactional/send. هذه هي الطريقة الأساسية لإرسال البريد الإلكتروني من خلال MailLand.

المصادقة

أدرج مفتاح API الخاص بك في رأس X-API-Key:

X-API-Key: ml_pet_Ab3Kx9mN2pQ7rT4wL8yD...

يجب أن تحتوي بيانات الاعتماد على قناة Api مُفعَّلة وأن تكون بيانات اعتماد منتج Sending.

إرسال بريد إلكتروني واحد

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>"
  }'

نص الطلب

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"
}

مرجع الحقول

الحقلالنوعمطلوبالوصف
fromobjectنعمعنوان المُرسِل
from.emailstringنعمبريد المُرسِل الإلكتروني (يجب أن يكون على نطاق موثَّق)
from.namestringلاالاسم المعروض
toarrayنعمقائمة المستلمين
to[].emailstringنعمعنوان البريد الإلكتروني للمستلم
to[].namestringلاالاسم المعروض للمستلم
to[].variablesobjectلامتغيرات القالب الخاصة بكل مستلم
subjectstringمشروطمطلوب ما لم يُستخدم قالب
templateIdstringلااستخدام قالب مخزَّن بدلاً من المحتوى المضمَّن
htmlContentstringمشروطنص HTML (إذا لم يكن هناك templateId، يلزم htmlContent أو textContent)
textContentstringلاالنص العادي الاحتياطي
variablesobjectلامتغيرات القالب العامة. تُطبَّق سواء استُخدم templateId أم لا؛ وعند تكرار المفتاح، تفوز قيمة to[].variables الخاصة بالمستلم
replyTostringلاعنوان البريد الإلكتروني للرد
tagsarrayلاعلامات للتصفية في التحليلات والخطافات
customHeadersobjectلارؤوس بريد إلكتروني مخصصة (أزواج مفتاح-قيمة)
trackingobjectلاتجاوز إعدادات التتبع
tracking.opensbooleanلاطلب تتبع الفتح لهذه الرسالة (الافتراضي: متوقف في النوعين). يُستخدم فقط ما دام نطاق الإرسال لم يختر بعد؛ اختيار النطاق نفسه لكل نوع، من صفحة النطاقات، هو الذي يسري. false يوقفه دائمًا
tracking.clicksbooleanلاتفعيل تتبع النقر (الافتراضي: false للرسائل التعاملية ما لم يفعّله حسابك، وtrue للتسويق)
ipPoolIdstringلامحجوز لمجمّعات IP المخصّصة. غير متاح بعد: إرساله يُرجع 400 IP_POOL_NOT_FOUND. يُحذف.
scheduledAtdatetimeلاجدولة للتسليم المستقبلي (UTC)، بحد أقصى 7 أيام مقدَّماً
idempotencyKeystringلامنع الإرسال المكرر لنفس المفتاح. يُفضّل استخدام ترويسة X-Idempotency-Key
attachmentsarrayلامرفقات الملفات (بحد أقصى 10، وبحد أقصى 10 ميجابايت إجمالي بعد فك الترميز)
priorityenumلاLow أو Normal (الافتراضي) أو High أو Critical

المرفقات

يتطلب كل مرفق ثلاثة حقول:

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
    }
  ]
}
الحقلالنوعمطلوبالوصف
fileNamestringنعماسم الملف مع الامتداد
contentTypestringنعمنوع MIME (مثلاً application/pdf)
contentstringنعممحتوى الملف بترميز Base64 قياسي: مع الحشو (padding) وبدون مسافات أو فواصل أسطر
contentIdstringلامعرّف المحتوى للمرفقات المضمَّنة (يُشار إليه في HTML بـ cid:company-logo)
inlinebooleanلاهل هذه صورة مضمَّنة (الافتراضي: false)

بحد أقصى 10 مرفقات لكل بريد إلكتروني، وبحد أقصى 10 ميجابايت إجمالي بعد فك الترميز (Base64). عدم وجود contentType، أو ترميز Base64 غير قياسي، أو تجاوز العدد أو الحجم المسموح به، يُرجع 400 VALIDATION_FAILED. لا يحتوي POST /v1/transactional/send-batch على حقل attachments.

الاستجابة

الحالة: 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
}
الحقلالنوعالوصف
successbooleanهل تم قبول الطلب
jobIdstringمعرّف المهمة الفريد للتتبع
messageIdsarrayمعرّفات الرسائل لكل مستلم (البادئة t_ للتحويلية، m_ للتسويقية)
acceptedRecipientsarrayعناوين البريد الإلكتروني المقبولة للتسليم
rejectedRecipientsarrayالمستلمون الذين تم رفضهم
queuedAtdatetimeوقت وضع البريد الإلكتروني في قائمة الانتظار
isSandboxedbooleantrue إذا استخدم الطلب بيانات اعتماد sandbox (انظر وضع Sandbox)
sandboxReasonstringcredential_sandbox_mode (سُجّلت ولم تُسلَّم) أو all_recipients_not_in_sandbox_allowlist (لم يكن أي مستلم في قائمة السماح)؛ وغائب في الحالات الأخرى

المستلمون المرفوضون

يمكن رفض المستلمين لعدة أسباب:

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]"
    }
  ]
}

أسباب الرفض الشائعة:

  • Suppressed: العنوان موجود في قائمة القمع (ارتدادات أو شكاوى سابقة)
  • disposable_domain: تم اكتشاف مزود بريد إلكتروني مؤقت
  • domain_typo: خطأ مطبعي محتمل في النطاق (يتضمن حقل suggestion)

الفحص المسبق

تحقق من قدرتك على الإرسال قبل تقديم الطلب الفعلي:

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 يساوي false، يوضح حقل reason السبب (حد المعدل أو الحصة أو حالة الحساب وما إلى ذلك).

قابلية التكرار (Idempotency)

إعادة محاولة الإرسال بعد انتهاء مهلة الشبكة يجب ألا تُسلّم البريد مرتين. عند تمرير مفتاح تكرار، تُعيد المحاولة الاستجابة الأصلية بدلاً من الإرسال من جديد.

أرسل المفتاح كترويسة (مستحسن):

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

أو استخدم الحقل idempotencyKey في الجسم. كلاهما مقبول، ويمكن إرسالهما معاً فقط إذا تطابقت القيمتان.

القواعد

  • النطاق. تُقبل X-Idempotency-Key على POST /v1/transactional/send وPOST /v1/transactional/send-batch فقط، ولا تقرأها أي نقطة نهاية أخرى.
  • الصيغة. من 1 إلى 255 محرفاً: حروف وأرقام و_ و-. تُقارن المفاتيح تماماً دون اقتطاع أو توحيد لحالة الأحرف.
  • النافذة. يبقى المفتاح قابلاً للتكرار 24 ساعة، وبعدها يُعامل المفتاح نفسه كطلب جديد.
  • التكرار. إعادة المحاولة ضمن النافذة تُعيد الاستجابة الأصلية حرفياً، الأرقام نفسها والحالة نفسها، ولا تُرسل شيئاً.
  • التفرّد. المفاتيح فريدة لكل حساب. إعادة استخدام مفتاح لنقطة نهاية مختلفة تُرفض بالرمز 409؛ استخدم مفتاحاً مستقلاً لكل عملية.

معرّف الارتباط

تتبع الطلبات عبر الأنظمة بتضمين معرّف ارتباط:

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

أو

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

يظهر معرّف الارتباط في السجلات وسجل النشاط.

رؤوس حد المعدل

تتضمن الاستجابات الناجحة معلومات حد المعدل لكل عنوان IP:

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

عند تطبيق محرك سياسة الإرسال لحد المعدل (429)، يشير رأس Retry-After إلى ثواني الانتظار:

Retry-After: 30

يمكن أن يتضمن الطلب التعاملي ما يصل إلى 5 مستلمين، ويُحتسب كل منهم ضمن حدود المعدل لديك. إذا تجاوز ذلك حدّك في الثانية (مثلًا 1 في الثانية في خطة بمعدل 60 في الدقيقة)، يُقبل الطلب عندما لا يكون أي طلب آخر قد قُبل في الثانية نفسها؛ وإلا فإنه يتلقى 429 مع Retry-After: 1 وينجح عند إعادة المحاولة في الثانية التالية، ضمن حدّك في الدقيقة. انظر حدود المعدل.

تتضمن استجابة 429 على مستوى IP أيضاً X-RateLimit-Reset كوقت UTC بصيغة ISO-8601.

استجابات الأخطاء

تُرجع جميع الأخطاء نصاً بتنسيق JSON:

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

رموز الأخطاء

الحالةالرمزالوصف
400INVALID_REQUESTنص طلب مشوَّه، أو scheduledAt أبعد من 7 أيام ("لا يمكن جدولة البريد لأكثر من 7 أيام مقدَّماً")
400VALIDATION_FAILEDلا يوجد htmlContent أو textContent أو templateId؛ أو فشل مرفق في التحقق (راجع حدود المرفقات أعلاه). يتضمن الرد مصفوفة errors[] مع الحقل والقاعدة المخالفة. (سابقاً: MISSING_CONTENT: مهمل منذ 2026-04.)
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.": الرسالة تتجاوز حد حجم الرسائل في المنصة. تُعيدها POST /v1/transactional/send وsend-batch بالرمز 413؛ ولا يوضع شيء في الطابور. قلّص الرسالة. وفي استيراد CSV يكون الرمز 400
400transactional_recipient_limit_exceededأكثر من 5 مستلمين على بيانات اعتماد معاملاتية (1000 في التسويق)
400TEMPLATE_NOT_FOUNDلا يوجد لدى templateId قالب نشط في هذا الحساب (يُرجع أيضاً لقالب محذوف)
400IP_POOL_NOT_FOUNDلا يوجد لدى ipPoolId مجمّع مخصَّص لهذا الحساب (حالياً دائماً، لأنه لا يمكن تخصيص مجمّع بعد، راجع مرجع الحقول أعلاه)
422TEMPLATE_VARIABLE_MISSINGيحتوي المحتوى على {{placeholder}} بلا قيمة؛ تسرد details.missingVariables الأسماء. لا يوضع شيء في الطابور
400IDEMPOTENCY_KEY_INVALIDالمفتاح فارغ أو غير صالح أو يتجاوز 255 محرفاً، أو أُرسلت الترويسة أكثر من مرة
400IDEMPOTENCY_KEY_CONFLICTأُرسلت الترويسة وحقل idempotencyKey معاً وقيمتاهما مختلفتان
400SEND_FAILEDجميع المستلمين مقموعون (الرسالة: "All recipients are suppressed")
409IDEMPOTENCY_KEY_REUSEDالمفتاح مستخدم بالفعل لنقطة نهاية مختلفة في هذا الحساب
401UNAUTHORIZEDX-API-Key مفقود أو غير صالح أو منتهي الصلاحية أو مُلغى
403ACCOUNT_SUSPENDEDتم تعليق الحساب
403ACCOUNT_DISABLEDتم تعطيل الحساب
403ACCOUNT_NOT_ACTIVEالحساب غير نشط
403NO_ACTIVE_SUBSCRIPTIONلا يوجد اشتراك نشط للحساب
403SUBSCRIPTION_EXPIREDانتهى اشتراك الحساب
403IP_NOT_ALLOWEDعنوان IP للطلب ليس في القائمة المسموح بها لبيانات الاعتماد
403SENDING_BLOCKEDالإرسال محظور لهذا الحساب
403ACTION_REQUIREDيلزم اتخاذ إجراء على الحساب قبل الإرسال
403TENANT_APPROVAL_REQUIREDالحساب بانتظار المراجعة قبل أن يتمكن من الإرسال. إعادة المحاولة لا تفيد؛ تواصل مع الدعم
422DOMAIN_NOT_VERIFIEDنطاق المُرسِل غير موثَّق
422DOMAIN_NOT_ALLOWED_FOR_CREDENTIALالنطاق ليس ضمن نطاق بيانات الاعتماد
422DOMAIN_NOT_FOUNDنطاق المُرسِل غير موجود
429RATE_LIMIT_EXCEEDEDتم تجاوز حد المعدل
429QUOTA_EXCEEDEDاستُنفدت الحصة الشهرية
429WARMUP_LIMIT_EXCEEDEDبلغ حساب الحد اليومي لمرحلة تهيئة الإرسال؛ يُعاد ضبطه عند 00:00 UTC
429DAILY_LIMIT_EXCEEDEDتم بلوغ حد الإرسال اليومي
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تم بلوغ الحد اليومي لحساب متأخر السداد
429MARKETING_PAUSEDتم إيقاف إرسال التسويق مؤقتاً لهذا الحساب
429SENDING_BLOCKEDمستوى توثيق الحساب لا يسمح بهذا الإرسال (رفض متعلق بالـsandbox/مستوى التوثيق؛ أما الحظر الصارم للإرسال فيُرجع 403 بدلاً من ذلك، راجع أعلاه)
503SERVICE_UNAVAILABLEخدمة البريد الإلكتروني غير متاحة مؤقتاً

حد المستلمين للتحويلية

تفرض بيانات الاعتماد التحويلية حداً أقصى قدره 5 مستلمين لكل طلب إرسال. هذا يمنع إساءة استخدام تدفقات التحويلية للإرسال الجماعي. إذا كنت تحتاج إلى مستلمين أكثر، استخدم بيانات اعتماد التسويق مع الإرسال الجماعي.

استخدام القوالب

بدلاً من HTML المضمَّن، أشر إلى قالب مخزَّن:

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 من القالب. عند تكرار المفاتيح، تفوز قيمة to[].variables الخاصة بالمستلم على variables العامة، نفس قاعدة المحتوى المضمَّن. راجع القوالب لإنشاء القوالب وإدارتها.

الخطوات التالية

في هذه الصفحة