Skip to content

Send Email by Tags

Send email messages to contacts that have specific tags assigned. The operation is asynchronous: the API records every message in persistence, schedules delivery in BullMQ, and returns an enqueue summary.

  • Include the bearer token in Authorization: Bearer <token>.
  • Only members that accepted the current terms can trigger messaging actions; otherwise the service returns 403 Forbidden.
interface EmailTagsMessagePayload extends EmailMessageBasePayload {
tagIds: string[]; // UUID identifiers of contact tags
}
interface EmailMessageBasePayload {
subject: string;
message: string; // HTML or plain text supported by the provider
}
FieldTypeRequiredDescription
subjectstringYesEmail subject
messagestringYesEmail content (HTML or plain text)
tagIdsstring[]YesList of tag IDs (UUID)
{
"subject": "Exclusive offer for VIP customers",
"message": "<h1>Just for you!</h1><p>As a VIP customer, you have access to this special offer with 40% discount.</p><a href='#'>Claim Offer</a>",
"tagIds": ["vip-customers-uuid", "frequent-buyers-uuid"]
}

The API responds with the shared MessageEnqueueResultDto contract:

interface MessageEnqueueResultDto {
queueId: string; // BullMQ job identifier, empty when nothing was enqueued
channel: 'email';
messages: Array<{
id: string; // UUID of the persisted message
recipient: string; // Email address normalized by the backend
}>;
}
{
"queueId": "email-queue-13579",
"channel": "email",
"messages": [
{
"id": "msg-uuid-1",
"recipient": "[email protected]"
},
{
"id": "msg-uuid-2",
"recipient": "[email protected]"
}
]
}

When the specified tags have no associated contacts, the service responds with 200 OK, an empty queueId, and an empty messages array.

{
"queueId": "",
"channel": "email",
"messages": []
}
async function sendEmailToTags(token: string, payload: EmailTagsMessagePayload) {
const response = await fetch('/api/messages/email/tags', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`Email enqueue failed: ${response.status}`);
}
const data: MessageEnqueueResultDto = await response.json();
return data;
}
// Campaign for new users
const result = await sendEmailToTags('your-token', {
subject: 'Welcome to SendMe - Getting Started Guide',
message: `
<div style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif;">
<h1 style="color: #007cba;">Welcome to SendMe!</h1>
<p>We're excited to have you with us. Here's a quick guide to get started:</p>
<div style="background: #f8f9fa; padding: 20px; margin: 20px 0; border-radius: 8px;">
<h3>First Steps:</h3>
<ol>
<li>Set up your profile</li>
<li>Import your contacts</li>
<li>Send your first message</li>
</ol>
</div>
<a href="#" style="background: #007cba; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px;">
Get Started Now
</a>
</div>
`,
tagIds: ['new-users-uuid']
});
console.log(`Welcome emails sent: ${result.messages.length}`);
// For users who have opened emails recently
await sendEmailToTags('your-token', {
subject: 'Personalized content based on your interests',
message: '<!-- Dynamic content based on behavior -->',
tagIds: ['email-openers-uuid', 'engaged-users-uuid']
});
// For users who have clicked on previous promotions
await sendEmailToTags('your-token', {
subject: 'New promotion you\'ll love',
message: '<!-- Promotion similar to their previous interests -->',
tagIds: ['promo-clickers-uuid']
});
// For healthcare clients
await sendEmailToTags('your-token', {
subject: 'New communication regulations in healthcare sector',
message: `
<div style="max-width: 600px; margin: 0 auto;">
<h2>Important Regulatory Updates</h2>
<p>As a healthcare professional, it's important to know...</p>
<!-- Sector-specific content -->
</div>
`,
tagIds: ['healthcare-clients-uuid']
});
// For e-commerce
await sendEmailToTags('your-token', {
subject: 'Boost your sales with these email marketing strategies',
message: '<!-- E-commerce specific content -->',
tagIds: ['ecommerce-clients-uuid']
});
// Birthday congratulations
await sendEmailToTags('your-token', {
subject: '🎉 Happy Birthday! Here\'s a gift for you',
message: `
<div style="text-align: center; padding: 40px;">
<h1>🎂 Happy Birthday!</h1>
<p>To celebrate you, we're giving you 20% off</p>
<p>Code: <strong>BIRTHDAY20</strong></p>
</div>
`,
tagIds: ['birthday-today-uuid']
});
  • The backend removes duplicated recipients per batch and silently skips invalid destinations.
  • Contacts can have multiple tags; the system prevents duplicate sends when a contact meets multiple tag criteria.
  • Balance validation runs before queuing; insufficient credits return an error response without enqueuing messages.
  • Use the returned queueId to correlate delivery status inside the admin UI or via dedicated status endpoints.
  • Each message persists provider metadata and can be audited through the messaging module filters.
  • Tag-based campaigns allow for more precise segmentation and better engagement rates.