مرور کلی Webhookها
دریافت اعلانهای بلادرنگ درباره رویدادهای ایمیل از طریق webhook
Webhookها اعلانهای HTTP بلادرنگ را هنگام وقوع رویدادهای ایمیل (تحویل، برگشت، شکایت و موارد دیگر) به سرور شما ارسال میکنند. به جای بررسی دورهای وضعیت، MailLand رویدادها را در همان لحظه وقوع به endpoint شما ارسال میکند.
نحوه عملکرد Webhookها
پیکربندی یک webhook
آدرس endpoint خود را ثبت کنید و رویدادهایی را که میخواهید دریافت کنید انتخاب نمایید.
Mail.Land رویدادها را ارسال میکند
هنگامی که یک رویداد رخ میدهد (مثلاً یک ایمیل تحویل داده میشود)، MailLand یک HTTP POST امضاشده را با payload رویداد به endpoint شما ارسال میکند.
سرور شما پاسخ میدهد
یک کد وضعیت 2xx برای تأیید دریافت بازگردانید. پاسخهای غیر 2xx باعث تلاش مجدد خودکار میشوند.
ایجاد یک Webhook
POST https://api.mail.land/v1/webhookscurl -X POST https://api.mail.land/v1/webhooks \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"name": "Production Events",
"webhookUrl": "https://your-app.com/webhooks/mailland",
"products": ["transactional", "marketing"],
"events": ["message.delivered", "message.bounced", "message.deferred", "message.complained"],
"includeFutureEvents": true,
"scope": "all_domains"
}'فیلدهای درخواست
| فیلد | نوع | اجباری | توضیحات |
|---|---|---|---|
name | string | خیر | نام قابل خواندن برای این webhook |
webhookUrl | string | بله | آدرس endpoint با HTTPS برای دریافت رویدادها |
products | array | خیر | فیلتر محصول: transactional، marketing، inbound، system |
events | array | خیر | رویدادهای خاص برای اشتراک (به رویدادها مراجعه کنید) |
includeFutureEvents | boolean | خیر | دریافت رویدادهای جدید اضافهشده به محصولات مشترک (پیشفرض: true) |
scope | string | خیر | all_domains (پیشفرض) یا selected_domains |
domainIds | array | خیر | شناسههای دامنه برای فیلتر کردن (در صورتی که scope برابر selected_domains باشد اجباری است) |
پاسخ
وضعیت: 201 Created
{
"webhook": {
"id": "k3m9x2p7qw4rtz",
"name": "Production Events",
"webhookUrl": "https://your-app.com/webhooks/mailland",
"products": ["transactional", "marketing"],
"events": ["message.delivered", "message.bounced", "message.deferred", "message.complained"],
"includeFutureEvents": true,
"scope": "all_domains",
"domainIds": [],
"isActive": true,
"createdAt": "2026-02-17T10:00:00Z",
"successCount": 0,
"failureCount": 0,
"consecutiveFailures": 0,
"pauseThreshold": 10
},
"secret": "whsec_a1b2c3d4e5f6g7h8i9j0..."
}secret تنها یک بار، هنگام ایجاد webhook، نمایش داده میشود. آن را بهصورت ایمن ذخیره کنید: برای تأیید امضاهای webhook به آن نیاز خواهید داشت. اگر آن را گم کردید، میتوانید مجدداً تولید کنید، که secret قدیمی را نامعتبر میکند.
آدرسهای URL webhook باید از HTTPS استفاده کنند. MailLand آدرسها را در برابر حملات SSRF اعتبارسنجی میکند: آدرسهای شبکه خصوصی (127.0.0.1، 10.x، 192.168.x و غیره) رد میشوند. تحویل فقط روی HTTPS و درگاه ۴۴۳ انجام میشود؛ نشانی روی درگاهی دیگر، یا نشانیای که به سرورها یا نامهای میزبان خود MailLand اشاره کند، با 400 WEBHOOK_DESTINATION_NOT_ALLOWED رد میشود. استفاده از درگاه TLS دیگر نیازمند تأیید صریح پشتیبانی MailLand است.
فهرست Webhookها
GET https://api.mail.land/v1/webhookscurl -X GET https://api.mail.land/v1/webhooks \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."[
{
"id": "k3m9x2p7qw4rtz",
"name": "Production Events",
"webhookUrl": "https://your-app.com/webhooks/mailland",
"products": ["transactional", "marketing"],
"events": ["message.delivered", "message.bounced"],
"isActive": true,
"lastTriggeredAt": "2026-02-17T12:30:00Z",
"lastSuccessAt": "2026-02-17T12:30:00Z",
"successCount": 1542,
"failureCount": 3,
"consecutiveFailures": 0,
"createdAt": "2026-02-10T08:00:00Z"
}
]حداکثر ۱۰۰ webhook را بر اساس تاریخ ایجاد (جدیدترین اول) باز میگرداند.
دریافت جزئیات Webhook
GET https://api.mail.land/v1/webhooks/{id}curl -X GET https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."پیکربندی کامل webhook به علاوه ۵۰ گزارش تحویل اخیر را بازمیگرداند. برای جزئیات گزارش تحویل به منطق تلاش مجدد مراجعه کنید.
بروزرسانی یک Webhook
PUT https://api.mail.land/v1/webhooks/{id}curl -X PUT https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"name": "All Events",
"events": ["message.delivered", "message.bounced", "message.deferred", "message.complained"],
"isActive": true
}'همه فیلدها اختیاری هستند: فقط فیلدهایی را که میخواهید تغییر دهید درج کنید.
آزمایش یک Webhook
یک رویداد آزمایشی برای تأیید عملکرد endpoint خود ارسال کنید:
POST https://api.mail.land/v1/webhooks/{id}/testcurl -X POST https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz/test \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"success": true,
"statusCode": 200,
"statusText": "OK",
"durationMs": 145,
"responseBody": "{\"received\": true}",
"headersSent": {
"X-MLND-Signature": "t=1708171200,v1=abc123...",
"X-MLND-Event-Id": "evt_test_abc123",
"X-MLND-Event-Version": "1",
"X-MLND-Event": "webhook.test",
"X-MLND-Webhook-Id": "k3m9x2p7qw4rtz",
"X-MLND-Attempt": "1"
},
"wouldReceiveRealEvents": true,
"liveEvents": ["message.delivered", "message.bounced"],
"dormantEvents": {},
"subscriptionWarning": null
}ارسال آزمایشی از همان امضا و همان مسیر تحویل یک رویداد واقعی استفاده میکند؛ بنابراین موفقیت در اینجا درستی نشانی، TLS و راستیآزمایی امضای شما را ثابت میکند.
اما اشتراک شما را ثابت نمیکند: آزمایش بنا به درخواست فرستاده میشود و بر اساس رویدادهای انتخابشدهی شما مسیریابی نمیشود. چهار فیلد آخر این موضوع را جداگانه پاسخ میدهند:
| فیلد | معنا |
|---|---|
wouldReceiveRealEvents | آیا اصلاً رویدادی واقعی میتواند به این نقطهی پایانی برسد |
liveEvents | رویدادهای مشترکشده که از همان فیلتر توزیعکننده عبور میکنند |
dormantEvents | رویدادهای مشترکشده که هرگز نمیرسند، هرکدام با دلیلش |
subscriptionWarning | وقتی مقدار دارد که نقطهی پایانی در دسترس است اما همیشه بیکار میماند |
حالت مهم، "success": true در کنار "wouldReceiveRealEvents": false است: نقطهی پایانی کار میکند، اما در هیچ رویدادِ قابلتحویلی مشترک نیست.
اگر آزمایش ناموفق باشد، فیلد errorType دلیل را نشان میدهد: ssrf_blocked (نشانی یا یک ریدایرکت از آن به مقصدی اشاره کرده که پلتفرم از ارسال به آن خودداری میکند) یا network_error (پایان مهلت، خطای TLS یا رد اتصال؛ جزئیات در errorMessage است).
بازتولید Secret
اگر secret webhook خود را گم کردید یا نیاز به تغییر آن دارید:
POST https://api.mail.land/v1/webhooks/{id}/regenerate-secretcurl -X POST https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz/regenerate-secret \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"secretKey": "whsec_x9y8z7w6v5u4..."
}بازتولید secret بلافاصله secret قدیمی را نامعتبر میکند. کد تأیید سرور خود را قبل از تحویل بعدی webhook بروزرسانی کنید، وگرنه رویدادهای معتبر را رد خواهید کرد.
محدوده دامنه
به طور پیشفرض، webhookها رویدادهای تمام دامنههای workspace شما را دریافت میکنند. برای محدود کردن یک webhook به دامنههای خاص:
{
"webhookUrl": "https://your-app.com/webhooks/mailland",
"scope": "selected_domains",
"domainIds": ["d4n8q1zt5wm3xc", "b7r2mv9k0jy4pw"]
}تنها رویدادهای مرتبط با آن دامنهها، webhook را فعال میکنند.
توقف خودکار در صورت خرابی
MailLand پس از ۱۰ بار شکست متوالی در تحویل (قابل تنظیم از طریق pauseThreshold) webhookها را بهطور خودکار متوقف میکند. این امر از اتلاف منابع برای endpointهایی که خاموش هستند جلوگیری میکند.
هنگامی که یک webhook متوقف میشود:
- مُهر زمانی
pausedAtتنظیم میشود pausedReasonدلیل توقف را توضیح میدهد- یک رویداد
account.webhook_pausedبه سایر webhookهای فعال شما ارسال میشود - یک اعلان درونبرنامهای ایجاد میشود
از سرگیری یک Webhook متوقفشده
پس از رفع مشکل، تحویل را از سر بگیرید:
POST https://api.mail.land/v1/webhooks/{id}/resumecurl -X POST https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz/resume \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."این عمل وضعیت توقف را پاک میکند، شمارندهی شکستهای متوالی را بازنشانی میکند و webhook را دوباره فعال میسازد (مقدار isActive دوباره true میشود)، بهطوریکه رویدادهای بعدی بهطور معمول به آن تحویل داده میشوند.
حذف یک Webhook
DELETE https://api.mail.land/v1/webhooks/{id}curl -X DELETE https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."204 No Content بازمیگرداند. اگر webhook توسط مسیرهای ایمیل ورودی استفاده شود، آن مسیرها بهطور خودکار بروزرسانی یا غیرفعال میشوند.
پاسخهای خطا
| وضعیت | کد | توضیحات |
|---|---|---|
400 | INVALID_REQUEST | آدرس URL، رویدادها یا پیکربندی scope نامعتبر است |
403 | PLAN_LIMIT_REACHED | حداکثر تعداد webhook برای پلن شما به پایان رسیده است |
404 | (بدنه خالی) | شناسهی webhook وجود ندارد: در get، update، delete، regenerate-secret و resume بازگردانده میشود |
404 | RESOURCE_NOT_FOUND | شناسهی webhook وجود ندارد: فقط از /test بازگردانده میشود |
مراحل بعدی
- رویدادها: مرجع کامل تمام انواع رویداد و payloadها
- تأیید امضا: تأیید اصالت webhook
- منطق تلاش مجدد: درک رفتار تلاش مجدد و مدیریت خرابی