کمپینها
ایجاد، زمانبندی و ارسال کمپینهای بازاریابی ایمیلی با ردیابی و تحلیل
کمپینهای بازاریابی ایمیلی را ایجاد و مدیریت کنید. MailLand انتخاب گیرنده، ارسال، ردیابی تحویل و تحلیل تعامل را برای هر کمپین مدیریت میکند.
چرخه حیات کمپین
هر کمپین از یک جریان وضعیت مشخص عبور میکند:
| وضعیت | مقدار | توضیح |
|---|---|---|
Draft | 0 | وضعیت اولیه: قابل ویرایش، هنوز ارسال نشده |
Scheduled | 1 | در صف برای تحویل آینده |
Sending | 2 | در حال ارسال به گیرندگان |
Sent | 3 | تمام گیرندگان پردازش شدهاند |
Paused | 4 | ارسال در میانه راه متوقف شده |
Cancelled | 5 | ارسال لغو شده |
Failed | 6 | خطای سیستمی در حین ارسال |
انتقالهای مجاز:
Draft→Scheduled(زمانبندی) یاSending(ارسال فوری) یاCancelled(لغو)Scheduled→SendingیاCancelled: زمانبندی مجدد یک کمپینScheduledپشتیبانی نمیشودSending→Sent،Paused،CancelledیاFailedPaused→Sending(ادامه)SentیاCancelled→ بایگانی شده
انواع کمپین
| نوع | مقدار | توضیح |
|---|---|---|
Regular | 0 | کمپین استاندارد یکبار مصرف |
Automated | 1 | فعالشده از طریق اتوماسیونها |
ABTest | 2 | کمپین آزمون A/B |
شخصیسازی (Personalization)
خط موضوع و محتوای کمپین از تگهای ادغام {{variable}} پشتیبانی میکنند که به ازای هر گیرنده از رکورد خودِ آن مشترک جایگزین میشوند.
| تگ | مقدار |
|---|---|
{{firstName}} | نام مشترک |
{{lastName}} | نام خانوادگی مشترک |
{{fullName}} | نام و نام خانوادگی بههم پیوسته |
{{email}} | آدرس ایمیل مشترک |
{{subscriberId}} | شناسهی مبهم مشترک |
{{custom_<field>}} | هر فیلد سفارشی روی مشترک: همچنین بهصورت {{<field>}} هم در دسترس است |
<p>Hi {{firstName}}, here's what's new this month.</p>تگی که مقداری ندارد دقیقاً همانطور که نوشته شده باقی میماند: {{firstName}} برای مشترکی بدون نام، در ایمیل تحویلشده بهصورت {{firstName}} باقی میماند، نه یک فضای خالی. محتوایی بنویسید که در هر دو حالت درست خوانده شود؛ مثلاً Hi there{{firstName}} گزینهی نامناسبی است اما "Your account" امن است. زمانی که مطمئن نیستید همهی مشترکین آن فیلد را دارند، از یک سلام جایگزین استفاده کنید.
مقادیر بر اساس بخشی که در آن قرار میگیرند escape میشوند: محتوای HTML بهصورت HTML escape میشود (بنابراین نامی حاوی & یا < نمیتواند مارکآپ شما را بشکند)، در حالی که خط موضوع و بدنهی متن ساده هرگز escape نمیشوند، Ben & Jerry's دقیقاً همانگونه باقی میماند.
املای قدیمیتر snake_case ({{first_name}}، {{last_name}}، {{full_name}}، {{subscriber_id}}) همچنان بهعنوان نامهای مستعار کار میکنند.
ایجاد کمپین
پیش از ایجاد یا بهروزرسانی هر کمپینی، فضای کاری باید تأیید شده بهعنوان کسبوکار (Business Verified) باشد: این یک گلوگاه پیشین و جدا از بررسی fromEmail در پایین است. اگر اینطور نباشد، درخواست با خطای 400 INVALID_REQUEST رد میشود ("Marketing campaigns require Business Verified status…").
دامنهی fromEmail باید از قبل اضافه و بهطور کامل تأیید شده (SPF + DKIM + DMARC) باشد، در زمان ایجاد و بهروزرسانی، وگرنه درخواست رد میشود (400/404). این بررسی اینجا انجام میشود، نه در زمان ارسال، به ارسال فوری مراجعه کنید.
POST https://api.mail.land/v1/marketing/campaigns{
"name": "February Newsletter",
"subject": "What's new in February",
"previewText": "Product updates and tips",
"fromName": "MailLand Team",
"fromEmail": "[email protected]",
"replyTo": "[email protected]",
"htmlContent": "<html>...</html>",
"textContent": "Plain text version...",
"type": 0,
"mailingListId": "ddv6ou6kz4wbto",
"segmentId": "x4xa3ep1zmqq0b"
}| فیلد | نوع | الزامی | توضیح |
|---|---|---|---|
name | string | بله | نام کمپین |
subject | string | بله | موضوع ایمیل |
previewText | string | خیر | متن پیشنمایش نمایش داده شده در صندوق ورودی |
fromName | string | بله | نام نمایشی فرستنده |
fromEmail | string | بله | آدرس ایمیل فرستنده |
replyTo | string | خیر | آدرس پاسخ به |
htmlContent | string | بله | محتوای HTML ایمیل |
textContent | string | خیر | نسخه متن ساده جایگزین |
templateId | string | خیر | شناسه قالب برای استفاده |
type | int | خیر | نوع کمپین (پیشفرض: 0 معمولی) |
mailingListId | string | خیر* | لیست پستی هدف |
segmentId | string | خیر* | بخش هدف |
* mailingListId یا segmentId را ارسال کنید: یکی از این دو الزامی است مگر آنکه templateId تنظیم شده باشد.
curl -X POST https://api.mail.land/v1/marketing/campaigns \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"name": "February Newsletter",
"subject": "What'\''s new in February",
"fromName": "MailLand Team",
"fromEmail": "[email protected]",
"htmlContent": "<html><body><h1>Hello!</h1></body></html>",
"mailingListId": "ddv6ou6kz4wbto"
}'پاسخ
{
"id": "uivozyvucowj9w",
"name": "February Newsletter",
"subject": "What's new in February",
"previewText": "Product updates and tips",
"fromName": "MailLand Team",
"fromEmail": "[email protected]",
"status": "draft",
"statusName": "Draft",
"type": 0,
"typeName": "Regular",
"mailingListId": "ddv6ou6kz4wbto",
"mailingListName": "Main Newsletter",
"segmentId": null,
"segmentName": null,
"createdAt": "2026-02-17T12:00:00Z",
"updatedAt": "2026-02-17T12:00:00Z"
}فهرست کمپینها
GET https://api.mail.land/v1/marketing/campaigns| پارامتر | نوع | پیشفرض | توضیح |
|---|---|---|---|
cursor | string | - | نشانگر مبهم از nextCursor صفحهٔ قبل. برای صفحهٔ اول حذف کنید. |
limit | int | 20 | تعداد آیتمها در صفحه (حداکثر ۱۰۰) |
search | string | - | جستجو بر اساس نام |
status | int | - | فیلتر بر اساس CampaignStatus |
type | int | - | فیلتر بر اساس CampaignType |
mailingListId | string | - | فیلتر بر اساس لیست پستی |
sortBy | string | - | فیلد مرتبسازی |
sortDesc | bool | false | مرتبسازی نزولی |
includeArchived | bool | false | شامل کمپینهای بایگانی شده |
curl "https://api.mail.land/v1/marketing/campaigns?limit=20&status=3" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"items": [
{
"id": "uivozyvucowj9w",
"name": "February Newsletter",
"subject": "What's new in February",
"status": "sent",
"statusName": "Sent",
"type": 0,
"typeName": "Regular",
"mailingListId": "ddv6ou6kz4wbto",
"mailingListName": "Main Newsletter",
"totalRecipients": 5000,
"totalSent": 4980,
"totalDelivered": 4900,
"totalOpened": 1520,
"totalClicked": 195,
"totalBounced": 45,
"totalUnsubscribed": 12,
"sentAt": "2026-02-15T10:00:00Z",
"completedAt": "2026-02-15T10:35:00Z",
"createdAt": "2026-02-14T08:00:00Z"
}
],
"nextCursor": "eyJ2IjoxLCJzIjoiY3JlYXRlZGF0OmRlc2MiLCJrIjoi...",
"hasMore": true
}دریافت جزئیات کمپین
GET https://api.mail.land/v1/marketing/campaigns/{id}CampaignDetailDto کامل شامل محتوای HTML، تمام آمار و نرخهای تعامل محاسبهشده را برمیگرداند:
curl https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"id": "uivozyvucowj9w",
"name": "February Newsletter",
"subject": "What's new in February",
"previewText": "Product updates and tips",
"fromName": "MailLand Team",
"fromEmail": "[email protected]",
"replyTo": "[email protected]",
"status": "sent",
"statusName": "Sent",
"type": 0,
"typeName": "Regular",
"htmlContent": "<html>...</html>",
"textContent": "Plain text...",
"mailingListId": "ddv6ou6kz4wbto",
"mailingListName": "Main Newsletter",
"totalRecipients": 5000,
"totalSent": 4980,
"totalDelivered": 4900,
"totalOpened": 1520,
"totalClicked": 195,
"totalBounced": 45,
"totalUnsubscribed": 12,
"totalComplaints": 2,
"deliveryRate": 98.39,
"openRate": 31.02,
"clickRate": 3.98,
"clickToOpenRate": 12.83,
"bounceRate": 0.9,
"unsubscribeRate": 0.24,
"openTrackingEnabled": true,
"clickTrackingEnabled": true,
"sentAt": "2026-02-15T10:00:00Z",
"completedAt": "2026-02-15T10:35:00Z",
"createdAt": "2026-02-14T08:00:00Z",
"updatedAt": "2026-02-15T10:35:00Z"
}نرخهای تعامل
| نرخ | فرمول |
|---|---|
deliveryRate | totalDelivered / totalSent * 100 |
openRate | totalOpened / totalDelivered * 100 |
clickRate | totalClicked / totalDelivered * 100 |
clickToOpenRate | totalClicked / totalOpened * 100 |
bounceRate | totalBounced / totalSent * 100 |
unsubscribeRate | totalUnsubscribed / totalDelivered * 100 |
نرخها روی سرور از شمارندههای خام محاسبه میشوند (بازها و کلیکها بهازای هر گیرنده یکتا هستند). deliveryRate و bounceRate نسبت به ارسالشدهها و openRate، clickRate و unsubscribeRate نسبت به تحویلشدهها هستند؛ clickToOpenRate (CTOR) کلیککننده نسبت به بازکننده است و معیاری جدا از clickRate است. هر نرخ درصدی بدون سقف است (clickToOpenRate میتواند از ۱۰۰ بیشتر شود) و وقتی در دسترس نباشد null است، نه 0: مخرج صفر است یا ردیابیِ لازم در حساب خاموش است (openTrackingEnabled و clickTrackingEnabled تنظیم فعلی را نشان میدهند). برای ترکیب چند کمپین، شمارندهها را جمع کنید و یکبار تقسیم کنید؛ درصدها را میانگین نگیرید. همین فیلدها برای هر کمپین در فهرست هم برگردانده میشوند.
بهروزرسانی کمپین
PUT https://api.mail.land/v1/marketing/campaigns/{id}فقط کمپینهایی با وضعیت Draft یا Scheduled قابل بهروزرسانی هستند. بدنهی درخواست با درخواست ایجاد یکسان است، بهجز type که قابل تغییر نیست.
| وضعیت | کد | توضیح |
|---|---|---|
200 | - | کمپین بهروزرسانی شد |
400 | INVALID_REQUEST | فقط کمپینهای پیشنویس قابل ویرایش هستند |
404 | RESOURCE_NOT_FOUND | کمپین یافت نشد |
curl -X PUT https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"name": "February Newsletter (Updated)",
"subject": "What'\''s new in February - updated",
"fromName": "MailLand Team",
"fromEmail": "[email protected]",
"htmlContent": "<html><body><h1>Updated!</h1></body></html>",
"mailingListId": "ddv6ou6kz4wbto"
}'زمانبندی کمپین
POST https://api.mail.land/v1/marketing/campaigns/{id}/schedule{
"scheduledAt": "2026-02-20T14:00:00Z"
}زمان scheduledAt باید در آینده باشد. وضعیت کمپین به Scheduled تغییر میکند و CampaignWorker آن را در زمان مقرر اجرا میکند.
زمانبندی فقط از وضعیت Draft مجاز است: کمپینی که از قبل Scheduled است را نمیتوان از طریق این endpoint دوباره زمانبندی کرد.
| وضعیت | کد | توضیح |
|---|---|---|
200 | - | کمپین زمانبندی شد |
400 | VALIDATION_FAILED | زمان زمانبندی باید در آینده باشد |
404 | RESOURCE_NOT_FOUND | کمپین یافت نشد یا قابل زمانبندی نیست |
403 | MARKETING_NOT_YET_ALLOWED | بازاریابی هنوز برای حساب باز نشده است (به کدهای خطا نگاه کنید)؛ /send هم همین را برمیگرداند |
403 | MARKETING_SUSPENDED | بازاریابی در کل پلتفرم در دسترس نیست؛ /send هم همین را برمیگرداند |
422 | CAMPAIGN_LINK_BLOCKED | پیوندی در کمپین به مقصدی اشاره میکند که ناامن علامتگذاری شده است؛ /send هم همین را برمیگرداند. چیزی زمانبندی یا ارسال نمیشود |
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/schedule \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{ "scheduledAt": "2026-02-20T14:00:00Z" }'ارسال فوری
POST https://api.mail.land/v1/marketing/campaigns/{id}/sendکمپین را فوراً ارسال میکند. وضعیت کمپین به Sending تغییر میکند و CampaignWorker شروع به پردازش گیرندگان میکند.
خود /send تأیید دامنه را بررسی نمیکند: این بررسی در زمان ایجاد/بهروزرسانی انجام میشود (به ایجاد کمپین مراجعه کنید). اگر هیچکس در لیست/بخش هدف واجد شرایط دریافت کمپین نباشد (مثلاً همه سرکوب یا لغو اشتراک شده باشند)، /send کد 422 CAMPAIGN_NO_ELIGIBLE_RECIPIENTS برمیگرداند.
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/send \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."توقف و ادامه
توقف کمپینی که در حال ارسال است:
POST https://api.mail.land/v1/marketing/campaigns/{id}/pausecurl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/pause \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."ادامه کمپین متوقف شده:
POST https://api.mail.land/v1/marketing/campaigns/{id}/resumecurl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/resume \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."توقف باعث میشود CampaignWorker پردازش گیرندگان باقیمانده را متوقف کند. ایمیلهای از پیش ارسال شده تحت تأثیر قرار نمیگیرند. ادامه از جایی که متوقف شده بود ادامه میدهد.
لغو کمپین
POST https://api.mail.land/v1/marketing/campaigns/{id}/cancelیک کمپین Draft یا Scheduled یا Sending را لغو میکند. ایمیلهای از پیش ارسال شده فراخوانده نمیشوند.
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/cancel \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."کپی کمپین
POST https://api.mail.land/v1/marketing/campaigns/{id}/duplicate?name=Copy%20of%20Newsletterیک کمپین Draft جدید با تمام تنظیمات کپی شده از نسخه اصلی ایجاد میکند. پارامتر کوئری name اختیاری است.
curl -X POST "https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/duplicate?name=Copy%20of%20Newsletter" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."بایگانی و بازیابی از بایگانی
بایگانی کردن کمپین Sent یا Cancelled:
POST https://api.mail.land/v1/marketing/campaigns/{id}/archivecurl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/archive \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."بازیابی کمپین بایگانی شده:
POST https://api.mail.land/v1/marketing/campaigns/{id}/unarchivecurl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/unarchive \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."کمپینهای بایگانی شده از نمای پیشفرض فهرست پنهان میشوند مگر اینکه includeArchived=true ارسال شود.
گیرندگان کمپین
دریافت گیرندگان صفحهبندی شده با وضعیت تحویل برای یک کمپین:
GET https://api.mail.land/v1/marketing/campaigns/{id}/recipients| پارامتر | نوع | پیشفرض | توضیح |
|---|---|---|---|
cursor | string | - | نشانگر مبهم از nextCursor صفحهٔ قبل. برای صفحهٔ اول حذف کنید. |
limit | int | 20 | تعداد آیتمها در صفحه (حداکثر ۱۰۰) |
status | string | - | فیلتر بر اساس وضعیت گیرنده |
search | string | - | جستجو بر اساس ایمیل |
curl "https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/recipients?limit=20" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"items": [
{
"email": "[email protected]",
"status": "Opened",
"sentAt": "2026-02-15T10:00:30Z",
"deliveredAt": "2026-02-15T10:00:32Z",
"openedAt": "2026-02-15T11:15:00Z",
"clickedAt": "2026-02-15T11:16:30Z",
"bouncedAt": null,
"complainedAt": null,
"unsubscribedAt": null,
"openCount": 2,
"clickCount": 1,
"bounceReason": null
}
],
"nextCursor": "eyJ2IjoxLCJzIjoiY3JlYXRlZGF0OmRlc2MiLCJrIjoi...",
"hasMore": true
}وضعیتهای گیرنده
| وضعیت | مقدار | توضیح |
|---|---|---|
Pending | 0 | در صف، هنوز ارسال نشده |
Sent | 1 | پذیرفته شده توسط MTA |
Delivered | 2 | تحویل داده شده به گیرنده |
Opened | 3 | گیرنده باز کرده |
Clicked | 4 | گیرنده روی لینکی کلیک کرده |
Bounced | 5 | برگشت سخت |
Unsubscribed | 6 | گیرنده اشتراک را لغو کرده |
Complained | 7 | شکایت هرزنامه |
Failed | 8 | تحویل ناموفق |
openedAt/openCount و clickedAt/clickCount شامل فعالیت ماشینی هستند، پیشبارگذاری Apple Mail Privacy Protection و اسکنرهای امنیتی لینک، که MailLand امروز آنها را فیلتر نمیکند. نرخهای مبتنی بر باز شدن/کلیک را بهعنوان یک حد بالا در نظر بگیرید، نه یک عدد دقیق از تعامل انسانی.
حذف کمپین
DELETE https://api.mail.land/v1/marketing/campaigns/{id}کمپین و دادههای گیرندگان آن را به صورت دائمی حذف میکند. فقط کمپینهای در وضعیت Draft یا Scheduled قابل حذف هستند؛ حذف هر وضعیت دیگری کد 404 برمیگرداند: بهجای آن، کمپین ارسالشده را بایگانی کنید.
curl -X DELETE https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."پاسخهای خطا
| وضعیت | کد | توضیح |
|---|---|---|
400 | VALIDATION_FAILED | فیلدهای الزامی موجود نیست |
400 | INVALID_REQUEST | فقط کمپینهای پیشنویس قابل ویرایش هستند |
403 | FORBIDDEN | دسترسی کافی نیست |
404 | RESOURCE_NOT_FOUND | کمپین یافت نشد |
مراحل بعدی
- مشترکین: مدیریت مخاطبین مشترک
- لیستها: سازماندهی مشترکین در لیستهای پستی
- بخشها: هدفگیری کمپینها با بخشهای پویا
- اتوماسیونها: راهاندازی توالیهای ایمیل مبتنی بر رویداد