Table of Contents
July 6, 2026 · View on GitHub
MailerSend Python SDK
Table of Contents
- Table of Contents
- Installation
- SDK Architecture
- Response Data Access
- Logging
- Usage
- Activity
- Analytics
- Domains
- Sender Identities
- Inbound Routes
- Messages
- Scheduled messages
- Recipients
- Get a list of recipients
- Get a single recipient
- Delete a recipient
- Get recipients from a blocklist
- Get recipients from hard bounces
- Get recipients from spam complaints
- Get recipients from unsubscribes
- Add recipients to blocklist
- Add hard bounced recipients
- Add spam complaints
- Add recipients to unsubscribe list
- Delete recipients from blocklist
- Delete hard bounced recipients
- Delete spam complaints
- Delete recipients from unsubscribe list
- Templates
- Webhooks
- Email Verification
- SMS
- SMS Activity
- SMS Phone Numbers
- SMS Recipients
- SMS Messages
- SMS Webhooks
- SMS Inbound Routing
- Tokens
- SMTP Users
- Users
- DMARC Monitoring
- Other Endpoints
- Async Usage
- Error Handling
- Testing
- Available endpoints
- Support and Feedback
- License
Installation
pip install mailersend
Requirements
- Python 3.10+
- An API Key from mailersend.com
Authentication
The SDK supports multiple authentication methods:
Environment Variable (Recommended)
Option 1: System Environment Variable
Set your API key as a system environment variable:
export MAILERSEND_API_KEY="your-api-key"
Then initialize the client:
from mailersend import MailerSendClient
# Automatically uses MAILERSEND_API_KEY environment variable
ms = MailerSendClient()
Option 2: Using .env File
For development, you can use a .env file. First install python-dotenv:
pip install python-dotenv
Create a .env file in your project root:
# .env
MAILERSEND_API_KEY=your-api-key
Then load it in your Python code:
from mailersend import MailerSendClient
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Client automatically uses the loaded MAILERSEND_API_KEY
ms = MailerSendClient()
Direct API Key
from mailersend import MailerSendClient
ms = MailerSendClient(api_key="your-api-key")
SDK Architecture
The MailerSend Python SDK v2 introduces a modern, clean architecture that follows industry best practices. Both a synchronous client (MailerSendClient) and an async client (AsyncMailerSendClient) are available — they share the same resources, builders, and models.
Builder Pattern
The SDK uses the builder pattern for constructing API requests. This provides a fluent, readable interface for setting parameters:
from mailersend import MailerSendClient
from mailersend import SmsRecipientsBuilder
ms = MailerSendClient()
# Build a request using the fluent builder pattern
request = (SmsRecipientsBuilder()
.sms_number_id("sms123")
.status("active")
.page(1)
.limit(25)
.build_list_request())
# Execute the request
response = ms.sms_recipients.list_sms_recipients(request)
Resource Classes
Each API endpoint group has its own resource class that provides clean method interfaces:
# Access different API resources
ms.sms_recipients # SMS Recipients operations
ms.sms_webhooks # SMS Webhooks operations
ms.sms_inbounds # SMS Inbound Routing operations
ms.email # Email operations
ms.domains # Domain operations
# ... and more
Request and Response Models
All data is validated using Pydantic models ensuring type safety and data integrity:
# All responses are strongly typed
response = ms.sms_recipients.get_sms_recipient(request)
print(response.id) # Validated string
print(response.number) # Validated phone number
print(response.created_at) # Validated datetime object
Async Support
The SDK ships an async client built on httpx for use in async applications (FastAPI, asyncio, etc.). It exposes the exact same resource namespaces and builder/model interfaces as the sync client.
from mailersend import AsyncMailerSendClient
# Recommended — use as an async context manager
async with AsyncMailerSendClient() as client:
response = await client.emails.send(email_request)
print(response["id"])
The async client accepts the same configuration parameters:
client = AsyncMailerSendClient(
api_key="your_api_key", # or set MAILERSEND_API_KEY env var
timeout=30,
max_retries=3,
debug=True,
)
Retries, rate-limit handling, and the error exception hierarchy (AuthenticationError, RateLimitExceeded, ServerError, etc.) behave identically to the sync client.
Response Data Access
The MailerSend SDK provides flexible ways to access and work with API response data. All API calls return a unified APIResponse object that supports multiple access patterns and data formats.
Multiple Access Patterns
Dict-like Access
Access response data using dictionary-style syntax:
from mailersend import MailerSendClient
from mailersend import SmsRecipientsBuilder
ms = MailerSendClient()
request = SmsRecipientsBuilder().sms_recipient_id("recipient-123").build_get_request()
response = ms.sms_recipients.get_sms_recipient(request)
# Dict-style access
recipient_id = response["data"]["id"]
phone_number = response["data"]["number"]
status = response["data"]["status"]
# Nested access
if "sms" in response["data"]:
latest_sms = response["data"]["sms"][0]["text"]
# Check if key exists
if "error" in response:
error_message = response['error']
Attribute Access
Access data using dot notation for cleaner code:
# Attribute-style access (most convenient)
recipient_id = response.id
phone_number = response.number
status = response.status
# Nested attribute access for complex data
if hasattr(response, 'sms') and response.sms:
latest_sms = response.sms[0].text
Safe Access with Defaults
Use the get() method for safe access with fallback values:
# Safe access with defaults
recipient_id = response.get("data", {}).get("id", "unknown")
error_message = response.get("error", "No error")
# Safe nested access
meta_info = response.get("meta", {})
total_count = meta_info.get("total", 0)
current_page = meta_info.get("page", 1)
Handling Method Name Conflicts
When response data contains fields that conflict with built-in methods, use the data_ prefix:
# If response contains fields like 'items', 'keys', 'values', etc.
response_data = {
"items": [{"id": 1, "name": "Item 1"}],
"keys": ["key1", "key2"],
"values": [100, 200]
}
# Use dict access (recommended for conflicts)
items_list = response["items"]
key_list = response["keys"]
# Or use data_ prefix for attribute access
items_list = response.data_items
key_list = response.data_keys
value_list = response.data_values
Data Format Conversion
Convert to Dictionary
Get the complete response as a dictionary:
# Convert entire response to dict
response_dict = response.to_dict()
# Returns:
# {
# "data": {"id": "123", "number": "+1234567890", ...},
# "headers": {"x-request-id": "req-456", ...},
# "status_code": 200,
# "request_id": "req-456",
# "rate_limit_remaining": 1000,
# "success": True
# }
# Or use dict() constructor
response_dict = dict(response)
# Access specific parts
data_only = response_dict["data"]
headers_only = response_dict["headers"]
Convert to JSON
Get JSON string representation with various formatting options:
# Compact JSON
json_string = response.to_json()
# Pretty-printed JSON with indentation
pretty_json = response.to_json(indent=2)
# Custom JSON options
unicode_json = response.to_json(ensure_ascii=False, indent=4)
# Direct json.dumps() also works
import json
json_string = json.dumps(response)
Extract Raw Data
Access just the API response data without metadata:
# Get raw response data
raw_data = response.data
# For paginated responses
if isinstance(raw_data, dict) and "data" in raw_data:
items = raw_data["data"] # List of items
meta = raw_data.get("meta", {}) # Pagination info
links = raw_data.get("links", {}) # Pagination links
else:
# Single item response
item_data = raw_data
Headers and Metadata
Access Response Headers
Headers can be accessed in multiple ways with automatic case handling:
# Dictionary-style access (case-sensitive)
request_id = response.headers["x-request-id"]
content_type = response.headers["content-type"]
# Attribute-style access (dashes become underscores)
request_id = response.headers.x_request_id
content_type = response.headers.content_type
rate_limit = response.headers.x_rate_limit_remaining
# Nested dictionary access
request_id = response["headers"]["x-request-id"]
# Safe access with defaults
retry_after = response.headers.get("retry-after", "0")
Response Metadata
Access useful metadata about the API response:
# HTTP status information
status_code = response.status_code
is_successful = response.success # True for 2xx status codes
# Rate limiting information
remaining_requests = response.rate_limit_remaining
retry_delay = response.retry_after # Seconds to wait before retry
# Request tracking
request_id = response.request_id
# Pagination (for list responses)
if "meta" in response.data:
total_items = response.data["meta"]["total"]
current_page = response.data["meta"]["current_page"]
per_page = response.data["meta"]["per_page"]
Error Handling with Responses
Check Response Status
Always check if the response was successful:
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
try:
email = EmailBuilder().from_email("sender@domain.com").build()
response = ms.emails.send(email)
if response.success:
email_id = response.id
remaining_quota = response.rate_limit_remaining
else:
status_code = response.status_code
error_details = response.data
# Handle rate limiting
if response.status_code == 429 and response.retry_after:
retry_seconds = response.retry_after
except Exception as e:
# Handle exception
Access Error Information
When requests fail, error details are available in the response:
if not response.success:
error_data = response.data
# API error response structure
error_message = error_data.get("message", "Unknown error")
error_code = error_data.get("code")
# Validation errors (422 responses)
if "errors" in error_data:
for field, messages in error_data["errors"].items():
validation_errors = {field: messages}
Working with Different Response Types
# Single item responses (get operations)
user_response = ms.users.get_user(request)
if user_response.success:
user_name = user_response.name
user_email = user_response.email
# List responses (paginated)
users_response = ms.users.list_users(request)
if users_response.success:
users = users_response.data["data"] # Array of users
total_count = users_response.data["meta"]["total"]
for user in users:
user_name = user['name']
user_email = user['email']
# Empty responses (delete operations)
delete_response = ms.users.delete_user(request)
if delete_response.success:
# delete_response.data is typically empty or contains confirmation
deletion_confirmed = True
Logging
The SDK includes comprehensive logging to help with debugging and monitoring:
Enable Debug Logging
import logging
from mailersend import MailerSendClient
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
ms = MailerSendClient()
# All API calls will now be logged with detailed information
Custom Logging Configuration
import logging
from mailersend import MailerSendClient
# Configure logging with custom format
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('mailersend.log'),
logging.StreamHandler()
]
)
ms = MailerSendClient()
# Logs will include:
# - API request details
# - Response status codes
# - Parameter information
# - Error details
Usage
Send an email
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.subject("Hello from MailerSend!")
.html("<h1>Hello World!</h1>")
.text("Hello World!")
.build())
response = ms.emails.send(email)
Add CC, BCC recipients
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.cc([
{"email": "cc1@example.com", "name": "CC User 1"},
{"email": "cc2@example.com", "name": "CC User 2"}
])
.bcc([
{"email": "bcc1@example.com", "name": "BCC User 1"},
{"email": "bcc2@example.com"}
])
.subject("Hello with CC/BCC!")
.html("<h1>Hello World!</h1>")
.build())
response = ms.emails.send(email)
Send a template-based email
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.template("template-id")
.personalize_many([{
"email": "recipient@domain.com",
"data": {
"name": "John",
"company": "MailerSend"
}
}])
.build())
response = ms.emails.send(email)
You can also set a language code for a template-based email. It is
only meaningful with a template and is ignored for raw html/text sends.
Supported codes: de, en, es, fr, it, lt, nl, pl, pt-BR.
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.template("template-id")
.language("de")
.build())
response = ms.emails.send(email)
Personalization
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.subject("Hello {$name}!")
.html("<h1>Hello {$name} from {$company}!</h1>")
.personalize_many([{
"email": "recipient@domain.com",
"data": {
"name": "John",
"company": "MailerSend",
"items": ["item1", "item2"],
"total": 99.99
}
}])
.build())
response = ms.emails.send(email)
Send email with attachment
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.subject("Email with attachment")
.html("<h1>Please find attached document</h1>")
.attach_file("document.pdf")
.build())
response = ms.emails.send(email)
Send bulk email
from mailersend import MailerSendClient, EmailBuilder
ms = MailerSendClient()
# Create individual EmailRequest objects
emails = [
EmailBuilder()
.from_email("sender@domain.com", "Sender")
.to_many([{"email": "recipient1@domain.com", "name": "Recipient 1"}])
.subject("Bulk email 1")
.html("<h1>Hello from bulk email 1</h1>")
.text("Hello from bulk email 1")
.build(),
EmailBuilder()
.from_email("sender@domain.com", "Sender")
.to_many([{"email": "recipient2@domain.com", "name": "Recipient 2"}])
.subject("Bulk email 2")
.html("<h1>Hello from bulk email 2</h1>")
.text("Hello from bulk email 2")
.build()
]
response = ms.emails.send_bulk(emails)
Get bulk email status
from mailersend import MailerSendClient
ms = MailerSendClient()
response = ms.emails.get_bulk_status("bulk-email-id")
Activity
Get a list of activities
from mailersend import MailerSendClient, ActivityBuilder
from datetime import datetime, timedelta
ms = MailerSendClient()
# Get activities from last 7 days (maximum allowed timeframe)
date_from = int((datetime.now() - timedelta(days=7)).timestamp())
date_to = int(datetime.now().timestamp())
request = (ActivityBuilder()
.domain_id("domain-id")
.date_from(date_from)
.date_to(date_to)
.page(1)
.limit(25)
.build_list_request())
response = ms.activities.get(request)
Get activity with filters
from mailersend import MailerSendClient, ActivityBuilder
from datetime import datetime, timedelta
ms = MailerSendClient()
# Get activities from last 7 days
date_from = int((datetime.now() - timedelta(days=7)).timestamp())
date_to = int(datetime.now().timestamp())
request = (ActivityBuilder()
.domain_id("domain-id")
.date_from(date_from)
.date_to(date_to)
.events(["sent", "delivered", "opened"])
.page(1)
.limit(50)
.build_list_request())
response = ms.activities.get(request)
Get a single activity
from mailersend import MailerSendClient, SingleActivityBuilder
ms = MailerSendClient()
request = (SingleActivityBuilder()
.activity_id("activity-id")
.build_get_request())
response = ms.activities.get_single(request)
Analytics
Activity data by date
from mailersend import MailerSendClient, AnalyticsBuilder
from datetime import datetime, timedelta
ms = MailerSendClient()
date_from = int((datetime.now() - timedelta(days=30)).timestamp())
date_to = int(datetime.now().timestamp())
request = (AnalyticsBuilder()
.date_from(date_from)
.date_to(date_to)
.events("sent", "delivered", "opened")
.domain_id("domain-id")
.group_by("days")
.build())
response = ms.analytics.get_activity_by_date(request)
Opens by country
from mailersend import MailerSendClient, AnalyticsBuilder
ms = MailerSendClient()
request = (AnalyticsBuilder()
.date_from(date_from)
.date_to(date_to)
.domain_id("domain-id")
.build())
response = ms.analytics.get_opens_by_country(request)
Opens by user-agent name
from mailersend import MailerSendClient, AnalyticsBuilder
ms = MailerSendClient()
request = (AnalyticsBuilder()
.date_from(date_from)
.date_to(date_to)
.domain_id("domain-id")
.build())
response = ms.analytics.get_opens_by_user_agent(request)
Opens by reading environment
from mailersend import MailerSendClient, AnalyticsBuilder
ms = MailerSendClient()
request = (AnalyticsBuilder()
.date_from(date_from)
.date_to(date_to)
.domain_id("domain-id")
.build())
response = ms.analytics.get_opens_by_reading_environment(request)
Domains
Get a list of domains
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.page(1)
.limit(25)
.build_list_request())
response = ms.domains.list_domains(request)
Get a single domain
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_id("domain-id")
.build_get_request())
response = ms.domains.get_domain(request)
Add a domain
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_name("mydomain.com")
.return_path_subdomain("rp")
.custom_tracking_subdomain("ct")
.inbound_routing_subdomain("ir")
.build_create_request())
response = ms.domains.create_domain(request)
Delete a domain
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_id("domain-id")
.build_delete_request())
response = ms.domains.delete_domain(request)
Get a list of recipients per domain
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_id("domain-id")
.page(1)
.limit(25)
.build_recipients_request())
response = ms.domains.get_domain_recipients(request)
Update domain settings
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_id("domain-id")
.send_paused(False)
.track_clicks(True)
.track_opens(True)
.track_unsubscribe(True)
.track_content(True)
.custom_tracking_enabled(True)
.custom_tracking_subdomain("email")
.precedence_bulk(False)
.build_update_settings_request())
response = ms.domains.update_domain_settings(request)
Get DNS Records
from mailersend import MailerSendClient, DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_id("domain-id")
.build_dns_records_request())
response = ms.domains.get_domain_dns_records(request)
Verify a domain
from mailersend import MailerSendClient
from mailersend import DomainsBuilder
ms = MailerSendClient()
request = (DomainsBuilder()
.domain_id("domain-id")
.build_verification_request())
response = ms.domains.get_domain_verification_status(request)
Sender Identities
Get a list of sender identities
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.domain_id("domain-id")
.build_list_request())
response = ms.identities.list_identities(request)
Get a sender identity
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.identity_id("identity-id")
.build_get_request())
response = ms.identities.get_identity(request)
Create a sender identity
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.domain_id("domain-id")
.name("John Doe")
.email("john@yourdomain.com")
.reply_to_email("support@yourdomain.com")
.reply_to_name("Support Team")
.add_note(True)
.build_create_request())
response = ms.identities.create_identity(request)
Update a sender identity
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.identity_id("identity-id")
.name("Jane Doe")
.reply_to_email("support@yourdomain.com")
.reply_to_name("Support Team")
.add_note(True)
.build_update_request())
response = ms.identities.update_identity(request)
Update a sender identity by email
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.email("support@yourdomain.com")
.name("Doe Jane")
.reply_to_email("support@yourdomain.com")
.reply_to_name("Support Team")
.add_note(True)
.build_update_by_email_request())
response = ms.identities.update_identity(request)
Delete a sender identity
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.identity_id("identity-id")
.build_delete_request())
response = ms.identities.delete_identity(request)
Delete a sender identity by email
from mailersend import MailerSendClient, IdentityBuilder
ms = MailerSendClient()
request = (IdentityBuilder()
.email("support@yourdomain.com")
.build_delete_by_email_request())
response = ms.identities.delete_identity_by_email(request)
Inbound Routes
Get a list of inbound routes
from mailersend import MailerSendClient, InboundBuilder
ms = MailerSendClient()
request = (InboundBuilder()
.domain_id("domain-id")
.build_list_request())
response = ms.inbound.list(request)
Get a single inbound route
from mailersend import MailerSendClient, InboundBuilder
ms = MailerSendClient()
request = (InboundBuilder()
.inbound_id("inbound-id")
.build_get_request())
response = ms.inbound.get(request)
Add an inbound route
from mailersend import MailerSendClient, InboundBuilder
ms = MailerSendClient()
request = (InboundBuilder()
.domain_id("domain-id")
.name("My Inbound Route")
.domain_enabled(False)
.inbound_priority(1)
.catch_type("all")
.match_type("all")
.add_forward("email", "support@mycompany.com")
.catch_recipient([{"comparer": "equal", "value": "support"}])
.add_match_filter("match_sender", [{"comparer": "equal", "value": "support"}])
.add_webhook_forward("https://mycompany.com/webhook")
.build_create_request())
response = ms.inbound.create_inbound_route(request)
Update an inbound route
from mailersend import MailerSendClient, InboundBuilder
ms = MailerSendClient()
request = (InboundBuilder()
.inbound_id("inbound-id")
.name("Updated Route Name")
.enabled(False)
.build_update_request())
response = ms.inbound.update_inbound_route(request)
Delete an inbound route
from mailersend import MailerSendClient, InboundBuilder
ms = MailerSendClient()
request = (InboundBuilder()
.inbound_id("inbound-id")
.build_delete_request())
response = ms.inbound.delete_inbound_route(request)
Messages
Get a list of messages
from mailersend import MailerSendClient, MessagesBuilder
ms = MailerSendClient()
request = (MessagesBuilder()
.build_list_request())
response = ms.messages.list_messages(request)
Get a single message
from mailersend import MailerSendClient, MessagesBuilder
ms = MailerSendClient()
request = (MessagesBuilder()
.message_id("message-id")
.build_get_request())
response = ms.messages.get_message(request)
Scheduled messages
Get a list of scheduled messages
from mailersend import MailerSendClient, SchedulesBuilder
ms = MailerSendClient()
request = (SchedulesBuilder()
.domain_id("domain-id")
.build_list_request())
response = ms.schedules.list_schedules(request)
Get a single scheduled message
from mailersend import MailerSendClient, SchedulesBuilder
ms = MailerSendClient()
request = (SchedulesBuilder()
.message_id("scheduled-id")
.build_get_request())
response = ms.schedules.get_schedule(request)
Delete a scheduled message
from mailersend import MailerSendClient, SchedulesBuilder
ms = MailerSendClient()
request = (SchedulesBuilder()
.message_id("scheduled-id")
.build_delete_request())
response = ms.schedules.delete_schedule(request)
Recipients
Get a list of recipients
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.build_recipients_list_request())
response = ms.recipients.list_recipients(request)
Get a single recipient
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.recipient_id("recipient-id")
.build_recipient_get_request())
response = ms.recipients.get_recipient(request)
Delete a recipient
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.recipient_id("recipient-id")
.build_recipient_delete_request())
response = ms.recipients.delete_recipient(request)
Get recipients from a blocklist
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.build_suppression_list_request())
response = ms.recipients.list_blocklist(request)
Get recipients from hard bounces
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.build_suppression_list_request())
response = ms.recipients.list_hard_bounces(request)
Get recipients from spam complaints
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.build_suppression_list_request())
response = ms.recipients.list_spam_complaints(request)
Get recipients from unsubscribes
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.build_suppression_list_request())
response = ms.recipients.list_unsubscribes(request)
Add recipients to blocklist
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
# Using specific emails
request = (RecipientsBuilder()
.domain_id("domain-id")
.recipients(["blocked@example.com", "spam@example.com"])
.build_suppression_add_request())
response = ms.recipients.add_to_blocklist(request)
# Using patterns
request = (RecipientsBuilder()
.domain_id("domain-id")
.patterns(["*@spammer.com", "*@blocked-domain.com"])
.build_suppression_add_request())
response = ms.recipients.add_to_blocklist(request)
Add hard bounced recipients
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.recipients(["bounced@example.com"])
.build_suppression_add_request())
response = ms.recipients.add_hard_bounces(request)
Add spam complaints
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.recipients(["complainer@example.com"])
.build_suppression_add_request())
response = ms.recipients.add_spam_complaints(request)
Add recipients to unsubscribe list
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
request = (RecipientsBuilder()
.domain_id("domain-id")
.recipients(["unsubscribed@example.com"])
.build_suppression_add_request())
response = ms.recipients.add_unsubscribes(request)
Delete recipients from blocklist
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
# Delete specific entries by IDs
request = (RecipientsBuilder()
.domain_id("domain-id")
.ids(["recipient-id-1", "recipient-id-2"])
.build_suppression_delete_request())
response = ms.recipients.delete_from_blocklist(request)
# Or delete all entries
request = (RecipientsBuilder()
.domain_id("domain-id")
.all(True)
.build_suppression_delete_request())
response = ms.recipients.delete_from_blocklist(request)
Delete hard bounced recipients
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
# Delete specific entries by IDs
request = (RecipientsBuilder()
.domain_id("domain-id")
.ids(["recipient-id"])
.build_suppression_delete_request())
response = ms.recipients.delete_hard_bounces(request)
# Or delete all entries
request = (RecipientsBuilder()
.domain_id("domain-id")
.all(True)
.build_suppression_delete_request())
response = ms.recipients.delete_hard_bounces(request)
Delete spam complaints
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
# Delete specific entries by IDs
request = (RecipientsBuilder()
.domain_id("domain-id")
.ids(["recipient-id"])
.build_suppression_delete_request())
response = ms.recipients.delete_spam_complaints(request)
# Or delete all entries
request = (RecipientsBuilder()
.domain_id("domain-id")
.all(True)
.build_suppression_delete_request())
response = ms.recipients.delete_spam_complaints(request)
Delete recipients from unsubscribe list
from mailersend import MailerSendClient, RecipientsBuilder
ms = MailerSendClient()
# Delete specific entries by IDs
request = (RecipientsBuilder()
.domain_id("domain-id")
.ids(["recipient-id"])
.build_suppression_delete_request())
response = ms.recipients.delete_unsubscribes(request)
# Or delete all entries
request = (RecipientsBuilder()
.domain_id("domain-id")
.all(True)
.build_suppression_delete_request())
response = ms.recipients.delete_unsubscribes(request)
Templates
Get a list of templates
from mailersend import MailerSendClient, TemplatesBuilder
ms = MailerSendClient()
request = (TemplatesBuilder()
.domain_id("domain-id")
.page(1)
.limit(25)
.build_templates_list_request())
response = ms.templates.list_templates(request)
Get a single template
from mailersend import MailerSendClient, TemplatesBuilder
ms = MailerSendClient()
request = (TemplatesBuilder()
.template("template-id")
.build_template_get_request())
response = ms.templates.get_template(request)
Delete template
from mailersend import MailerSendClient, TemplatesBuilder
ms = MailerSendClient()
request = (TemplatesBuilder()
.template("template-id")
.build_delete_request())
response = ms.templates.delete_template(request)
Webhooks
Get a list of webhooks
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
request = (WebhooksBuilder()
.domain_id("domain-id")
.build_webhooks_list_request())
response = ms.webhooks.list_webhooks(request)
Get a single webhook
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
request = (WebhooksBuilder()
.webhook_id("webhook-id")
.build_webhook_get_request())
response = ms.webhooks.get_webhook(request)
Create a Webhook
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
request = (WebhooksBuilder()
.domain_id("domain-id")
.url("https://yourdomain.com/webhook")
.name("My webhook")
.events(["activity.sent", "activity.delivered"])
.enabled(True)
.build_webhook_create_request())
response = ms.webhooks.create_webhook(request)
Create a disabled webhook
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
request = (WebhooksBuilder()
.domain_id("domain-id")
.url("https://yourdomain.com/webhook")
.name("My disabled webhook")
.events(["activity.sent", "activity.delivered"])
.enabled(False)
.build_webhook_create_request())
response = ms.webhooks.create_webhook(request)
Update a Webhook
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
request = (WebhooksBuilder()
.webhook_id("webhook-id")
.url("https://yourdomain.com/webhook-updated")
.name("My updated webhook")
.events(["activity.sent"])
.enabled(True)
.build_webhook_update_request())
response = ms.webhooks.update_webhook(request)
Disable/Enable a Webhook
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
# Disable webhook
request = (WebhooksBuilder()
.webhook_id("webhook-id")
.enabled(False)
.build_webhook_update_request())
response = ms.webhooks.update_webhook(request)
# Enable webhook
request = (WebhooksBuilder()
.webhook_id("webhook-id")
.enabled(True)
.build_webhook_update_request())
response = ms.webhooks.update_webhook(request)
Delete a Webhook
from mailersend import MailerSendClient, WebhooksBuilder
ms = MailerSendClient()
request = (WebhooksBuilder()
.webhook_id("webhook-id")
.build_webhook_delete_request())
response = ms.webhooks.delete_webhook(request)
Email Verification
Get all email verification lists
from mailersend import MailerSendClient, EmailVerificationBuilder
ms = MailerSendClient()
request = EmailVerificationBuilder().build_lists()
response = ms.email_verification.list_verifications(request)
Get a single email verification list
from mailersend import MailerSendClient, EmailVerificationBuilder
ms = MailerSendClient()
request = (EmailVerificationBuilder()
.email_verification_id("list-id")
.build_get())
response = ms.email_verification.get_verification(request)
Create an email verification list
from mailersend import MailerSendClient, EmailVerificationBuilder
ms = MailerSendClient()
request = (EmailVerificationBuilder()
.name("My Verification List")
.emails(["test1@example.com", "test2@example.com"])
.build_create())
response = ms.email_verification.create_verification(request)
Verify a list
from mailersend import MailerSendClient, EmailVerificationBuilder
ms = MailerSendClient()
request = (EmailVerificationBuilder()
.email_verification_id("list-id")
.build_verify_list())
response = ms.email_verification.verify_list(request)
Get list results
from mailersend import MailerSendClient, EmailVerificationBuilder
ms = MailerSendClient()
request = (EmailVerificationBuilder()
.email_verification_id("list-id")
.build_results())
response = ms.email_verification.get_results(request)
SMS
Sending SMS messages
from mailersend import MailerSendClient, SmsSendingBuilder
ms = MailerSendClient()
# Simple SMS
request = (SmsSendingBuilder()
.from_number("sms-number")
.to(["+1234567890", "+1234567891"])
.text("Hello from MailerSend SMS!")
.build())
response = ms.sms_sending.send(request)
# SMS with personalization
request = (SmsSendingBuilder()
.from_number("sms-number")
.to(["+1234567890", "+1234567891"])
.text("Hello {{name}}, your order {{order_id}} is ready!")
.personalization([
{
"phone_number": "+1234567890",
"data": {"name": "John", "order_id": "12345"}
},
{
"phone_number": "+1234567891",
"data": {"name": "Jane", "order_id": "12346"}
}
])
.build())
response = ms.sms_sending.send(request)
SMS Activity
Get a list of SMS activities
from mailersend import MailerSendClient, SmsActivityBuilder
from datetime import datetime, timedelta
ms = MailerSendClient()
# Get activities from last 7 days
date_from = int((datetime.now() - timedelta(days=7)).timestamp())
date_to = int(datetime.now().timestamp())
request = (SmsActivityBuilder()
.sms_number_id("sms-number-id")
.date_from(date_from)
.date_to(date_to)
.status(["sent", "delivered", "failed"])
.page(1)
.limit(25)
.build_list_request())
response = ms.sms_activity.list(request)
Get activity of a single SMS message
from mailersend import MailerSendClient, SmsActivityBuilder
ms = MailerSendClient()
request = (SmsActivityBuilder()
.sms_message_id("sms-message-id")
.build_get_request())
response = ms.sms_activity.get(request)
SMS Phone Numbers
Get a list of SMS phone numbers
from mailersend import MailerSendClient, SmsNumbersBuilder
ms = MailerSendClient()
request = (SmsNumbersBuilder()
.paused(False)
.page(1)
.limit(25)
.build_list_request())
response = ms.sms_numbers.list(request)
Get an SMS phone number
from mailersend import MailerSendClient, SmsNumbersBuilder
ms = MailerSendClient()
request = (SmsNumbersBuilder()
.sms_number_id("sms-number-id")
.build_get_request())
response = ms.sms_numbers.get(request)
Update a single SMS phone number
from mailersend import MailerSendClient, SmsNumbersBuilder
ms = MailerSendClient()
request = (SmsNumbersBuilder()
.sms_number_id("sms-number-id")
.paused(True)
.build_update_request())
response = ms.sms_numbers.update(request)
Delete an SMS phone number
from mailersend import MailerSendClient, SmsNumbersBuilder
ms = MailerSendClient()
request = (SmsNumbersBuilder()
.sms_number_id("sms-number-id")
.build_delete_request())
response = ms.sms_numbers.delete(request)
SMS Recipients
Get a list of SMS recipients
from mailersend import MailerSendClient, SmsRecipientsBuilder
from mailersend.models.sms_recipients import SmsRecipientStatus
ms = MailerSendClient()
request = (SmsRecipientsBuilder()
.sms_number_id("sms-number-id")
.status(SmsRecipientStatus.ACTIVE)
.page(1)
.limit(25)
.build_list_request())
response = ms.sms_recipients.list_sms_recipients(request)
Get an SMS recipient
from mailersend import MailerSendClient, SmsRecipientsBuilder
ms = MailerSendClient()
request = (SmsRecipientsBuilder()
.sms_recipient_id("recipient-id")
.build_get_request())
response = ms.sms_recipients.get_sms_recipient(request)
Update a single SMS recipient
from mailersend import MailerSendClient, SmsRecipientsBuilder
from mailersend.models.sms_recipients import SmsRecipientStatus
ms = MailerSendClient()
request = (SmsRecipientsBuilder()
.sms_recipient_id("recipient-id")
.build_update_request(SmsRecipientStatus.OPT_OUT))
response = ms.sms_recipients.update_sms_recipient(request)
SMS Messages
Get a list of SMS messages
from mailersend import MailerSendClient, SmsMessagesBuilder
ms = MailerSendClient()
request = (SmsMessagesBuilder()
.page(1)
.limit(25)
.build_sms_messages_list())
response = ms.sms_messages.list_sms_messages(request)
Get an SMS message
from mailersend import MailerSendClient, SmsMessagesBuilder
ms = MailerSendClient()
request = (SmsMessagesBuilder()
.sms_message_id("message-id")
.build_sms_message_get())
response = ms.sms_messages.get_sms_message(request)
SMS Webhooks
Get a list of SMS webhooks
from mailersend import MailerSendClient, SmsWebhooksBuilder
ms = MailerSendClient()
request = (SmsWebhooksBuilder()
.sms_number_id("sms-number-id")
.build_list_request())
response = ms.sms_webhooks.list_sms_webhooks(request)
Get a single SMS webhook
from mailersend import MailerSendClient, SmsWebhooksBuilder
ms = MailerSendClient()
request = (SmsWebhooksBuilder()
.sms_webhook_id("webhook-id")
.build_get_request())
response = ms.sms_webhooks.get_sms_webhook(request)
Create an SMS webhook
from mailersend import MailerSendClient, SmsWebhooksBuilder
from mailersend.models.sms_webhooks import SmsWebhookEvent
ms = MailerSendClient()
request = (SmsWebhooksBuilder()
.from_number("sms-number-id")
.url("https://webhook.example.com/sms")
.name("SMS Webhook")
.add_event(SmsWebhookEvent.SMS_SENT)
.add_event(SmsWebhookEvent.SMS_DELIVERED)
.add_event(SmsWebhookEvent.SMS_FAILED)
.enabled(True)
.build_create_request())
response = ms.sms_webhooks.create_sms_webhook(request)
Update a single SMS webhook
from mailersend import MailerSendClient, SmsWebhooksBuilder
from mailersend.models.sms_webhooks import SmsWebhookEvent
ms = MailerSendClient()
request = (SmsWebhooksBuilder()
.sms_webhook_id("webhook-id")
.name("Updated SMS Webhook")
.url("https://new-webhook.example.com/sms")
.events([SmsWebhookEvent.SMS_DELIVERED, SmsWebhookEvent.SMS_FAILED])
.enabled(False)
.build_update_request())
response = ms.sms_webhooks.update_sms_webhook(request)
Delete an SMS webhook
from mailersend import MailerSendClient, SmsWebhooksBuilder
ms = MailerSendClient()
request = (SmsWebhooksBuilder()
.sms_webhook_id("webhook-id")
.build_delete_request())
response = ms.sms_webhooks.delete_sms_webhook(request)
SMS Inbound Routing
Get a list of SMS inbound routes
from mailersend import MailerSendClient, SmsInboundsBuilder
ms = MailerSendClient()
request = (SmsInboundsBuilder()
.sms_number_id("sms-number-id")
.enabled(True)
.build_list_request())
response = ms.sms_inbounds.list_sms_inbounds(request)
Get a single SMS inbound route
from mailersend import MailerSendClient, SmsInboundsBuilder
ms = MailerSendClient()
request = (SmsInboundsBuilder()
.sms_inbound_id("inbound-id")
.build_get_request())
response = ms.sms_inbounds.get_sms_inbound(request)
Create an SMS inbound route
from mailersend import MailerSendClient, SmsInboundsBuilder
from mailersend.models.sms_inbounds import FilterComparer
ms = MailerSendClient()
request = (SmsInboundsBuilder()
.sms_number_id("sms-number-id")
.name("Support Route")
.forward_url("https://api.example.com/sms/support")
.filter(FilterComparer.STARTS_WITH, "SUPPORT")
.enabled(True)
.build_create_request())
response = ms.sms_inbounds.create_sms_inbound(request)
Update an SMS inbound route
from mailersend import MailerSendClient, SmsInboundsBuilder
from mailersend.models.sms_inbounds import FilterComparer
ms = MailerSendClient()
request = (SmsInboundsBuilder()
.sms_number_id("inbound-id")
.name("Updated Support Route")
.forward_url("https://api.example.com/sms/new-support")
.filter(FilterComparer.CONTAINS, "HELP")
.enabled(False)
.build_update_request())
response = ms.sms_inbounds.update_sms_inbound(request)
Delete an SMS inbound route
from mailersend import MailerSendClient, SmsInboundsBuilder
ms = MailerSendClient()
request = (SmsInboundsBuilder()
.sms_inbound_id("inbound-id")
.build_delete_request())
response = ms.sms_inbounds.delete_sms_inbound(request)
Tokens
Create a token
from mailersend import MailerSendClient, TokensBuilder
ms = MailerSendClient()
request = (TokensBuilder()
.name("My API Token")
.scopes(["email_full", "analytics_read"])
.domain_id("domain-id")
.build_token_create())
response = ms.tokens.create_token(request)
Pause / Unpause Token
from mailersend import MailerSendClient, TokensBuilder
ms = MailerSendClient()
# Pause token
request = (TokensBuilder()
.token_id("token-id")
.status("pause")
.build_token_update())
response = ms.tokens.update_token(request)
# Unpause token
request = (TokensBuilder()
.token_id("token-id")
.status("unpause")
.build_token_update())
response = ms.tokens.update_token(request)
Delete a Token
from mailersend import MailerSendClient, TokensBuilder
ms = MailerSendClient()
request = (TokensBuilder()
.token_id("token-id")
.build_token_delete())
response = ms.tokens.delete_token(request)
SMTP Users
Get a list of SMTP users
from mailersend import MailerSendClient, SmtpUsersBuilder
ms = MailerSendClient()
request = (SmtpUsersBuilder()
.domain_id("domain-id")
.build_smtp_users_list())
response = ms.smtp_users.list_smtp_users(request)
Get a single SMTP user
from mailersend import MailerSendClient, SmtpUsersBuilder
ms = MailerSendClient()
request = (SmtpUsersBuilder()
.domain_id("domain-id")
.smtp_user_id("smtp-user-id")
.build_smtp_user_get())
response = ms.smtp_users.get_smtp_user(request)
Create an SMTP user
from mailersend import MailerSendClient, SmtpUsersBuilder
ms = MailerSendClient()
request = (SmtpUsersBuilder()
.domain_id("domain-id")
.name("SMTP User Name")
.enabled(True)
.build_smtp_user_create())
response = ms.smtp_users.create_smtp_user(request)
Update an SMTP user
from mailersend import MailerSendClient, SmtpUsersBuilder
ms = MailerSendClient()
request = (SmtpUsersBuilder()
.domain_id("domain-id")
.smtp_user_id("smtp-user-id")
.name("Updated SMTP User Name")
.enabled(False)
.build_smtp_user_update())
response = ms.smtp_users.update_smtp_user(request)
Delete an SMTP user
from mailersend import MailerSendClient, SmtpUsersBuilder
ms = MailerSendClient()
request = (SmtpUsersBuilder()
.domain_id("domain-id")
.smtp_user_id("smtp-user-id")
.build_smtp_user_delete())
response = ms.smtp_users.delete_smtp_user(request)
Users
Get a list of account users
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.page(1)
.limit(25)
.build_users_list())
response = ms.users.list_users(request)
Get a single account user
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.user_id("user-id")
.build_user_get())
response = ms.users.get_user(request)
Invite a user to account
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
# Basic invite with admin role
request = (UsersBuilder()
.email("newuser@example.com")
.admin_role()
.build_user_invite())
response = ms.users.invite_user(request)
# Custom invite with specific permissions and access
request = (UsersBuilder()
.email("designer@example.com")
.designer_role()
.add_permission("read-all-templates")
.add_permission("manage-template")
.add_template("template-id")
.add_domain("domain-id")
.requires_periodic_password_change(True)
.build_user_invite())
response = ms.users.invite_user(request)
Update an account user
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.user_id("user-id")
.manager_role()
.add_permission("read-analytics")
.add_permission("read-activity")
.add_domain("domain-id")
.build_user_update())
response = ms.users.update_user(request)
Delete a user from account
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.user_id("user-id")
.build_user_delete())
response = ms.users.delete_user(request)
Get a list of invites
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.page(1)
.limit(25)
.build_invites_list())
response = ms.users.list_invites(request)
Get a single invite
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.invite_id("invite-id")
.build_invite_get())
response = ms.users.get_invite(request)
Resend an invite
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.invite_id("invite-id")
.build_invite_resend())
response = ms.users.resend_invite(request)
Cancel an invite
from mailersend import MailerSendClient, UsersBuilder
ms = MailerSendClient()
request = (UsersBuilder()
.invite_id("invite-id")
.build_invite_cancel())
response = ms.users.cancel_invite(request)
DMARC Monitoring
Get a list of monitors
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.page(1)
.limit(25)
.build_list_request())
response = ms.dmarc_monitoring.list_monitors(request)
Create a monitor
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.domain_id("your-domain-id")
.build_create_request())
response = ms.dmarc_monitoring.create_monitor(request)
Update a monitor
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.wanted_dmarc_record("v=DMARC1; p=reject; rua=mailto:dmarc@example.com")
.build_update_request())
response = ms.dmarc_monitoring.update_monitor(request)
Delete a monitor
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.build_delete_request())
response = ms.dmarc_monitoring.delete_monitor(request)
Get aggregated reports
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.page(1)
.limit(25)
.build_report_request())
response = ms.dmarc_monitoring.get_aggregated_report(request)
Get IP-specific reports
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.ip("192.168.1.1")
.page(1)
.limit(25)
.build_ip_report_request())
response = ms.dmarc_monitoring.get_ip_report(request)
Get report sources
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.build_report_sources_request())
response = ms.dmarc_monitoring.get_report_sources(request)
Mark IP as favorite
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.ip("192.168.1.1")
.build_mark_favorite_request())
response = ms.dmarc_monitoring.mark_ip_favorite(request)
Remove IP from favorites
from mailersend import MailerSendClient, DmarcMonitoringBuilder
ms = MailerSendClient()
request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.ip("192.168.1.1")
.build_remove_favorite_request())
response = ms.dmarc_monitoring.remove_ip_favorite(request)
Other Endpoints
Get API Quota
from mailersend import MailerSendClient
ms = MailerSendClient()
response = ms.api_quota.get_quota()
Async Usage
The AsyncMailerSendClient exposes the same resources and methods as the synchronous MailerSendClient — prefixed with async/await — so you can use it anywhere asyncio is available.
Basic Async Usage
Use AsyncMailerSendClient as an async context manager (recommended) to ensure the underlying HTTP connection is properly closed:
import asyncio
from mailersend import AsyncMailerSendClient, EmailBuilder
async def main():
async with AsyncMailerSendClient() as client:
email = (EmailBuilder()
.from_email("sender@domain.com", "Your Name")
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.subject("Hello from MailerSend!")
.html("<h1>Hello World!</h1>")
.text("Hello World!")
.build())
response = await client.emails.send(email)
print(response.status_code)
asyncio.run(main())
If you prefer to manage the lifecycle manually, call await client.close() when finished:
from mailersend import AsyncMailerSendClient
client = AsyncMailerSendClient(api_key="your-api-key")
try:
response = await client.api_quota.get_quota()
finally:
await client.close()
All resources available on MailerSendClient are also available on AsyncMailerSendClient:
async with AsyncMailerSendClient() as client:
client.emails # Email operations
client.activities # Activity operations
client.analytics # Analytics operations
client.domains # Domain operations
client.identities # Sender identity operations
client.inbound # Inbound route operations
client.templates # Template operations
client.tokens # Token operations
client.webhooks # Webhook operations
client.email_verification # Email verification operations
client.users # User operations
client.messages # Message operations
client.recipients # Recipient & suppression operations
client.schedules # Scheduled message operations
client.smtp_users # SMTP user operations
client.sms_sending # SMS sending operations
client.sms_numbers # SMS phone number operations
client.sms_activity # SMS activity operations
client.sms_inbounds # SMS inbound routing operations
client.sms_recipients # SMS recipient operations
client.sms_webhooks # SMS webhook operations
client.sms_messages # SMS message operations
client.api_quota # API quota operations
client.dmarc_monitoring # DMARC monitoring operations
Concurrent Requests
The main benefit of AsyncMailerSendClient is the ability to run multiple API calls concurrently with asyncio.gather:
import asyncio
from mailersend import AsyncMailerSendClient, DomainsBuilder, TemplatesBuilder
async def main():
async with AsyncMailerSendClient() as client:
domains_request = DomainsBuilder().build_list_request()
templates_request = TemplatesBuilder().build_templates_list_request()
# Both requests run concurrently
domains_response, templates_response = await asyncio.gather(
client.domains.list_domains(domains_request),
client.templates.list_templates(templates_request),
)
print(f"Domains: {domains_response.data}")
print(f"Templates: {templates_response.data}")
asyncio.run(main())
Async Error Handling
AsyncMailerSendClient raises the same exception types as the synchronous client:
import asyncio
from mailersend import AsyncMailerSendClient
from mailersend.exceptions import (
AuthenticationError,
RateLimitExceeded,
ResourceNotFoundError,
BadRequestError,
ServerError,
MailerSendError,
)
async def main():
async with AsyncMailerSendClient() as client:
try:
response = await client.api_quota.get_quota()
except AuthenticationError:
print("Invalid API key")
except RateLimitExceeded as e:
print(f"Rate limit hit: {e}")
except ResourceNotFoundError:
print("Resource not found")
except BadRequestError as e:
print(f"Bad request: {e}")
except ServerError as e:
print(f"Server error: {e}")
except MailerSendError as e:
print(f"Unexpected error: {e}")
asyncio.run(main())
The client automatically retries transient errors (429, 500, 502, 503, 504) with exponential backoff. For 429 responses the Retry-After header is respected if present.
Async Debug Logging
Debug logging works the same way as the synchronous client:
import asyncio
from mailersend import AsyncMailerSendClient
async def main():
# Enable debug at construction time
async with AsyncMailerSendClient(debug=True) as client:
response = await client.api_quota.get_quota()
# Or toggle at runtime
async with AsyncMailerSendClient() as client:
client.enable_debug()
response = await client.api_quota.get_quota()
client.disable_debug()
asyncio.run(main())
Error Handling
The SDK provides comprehensive error handling with detailed error information:
from mailersend import MailerSendClient
from mailersend.exceptions import MailerSendError
from mailersend import EmailBuilder
ms = MailerSendClient()
try:
email = (EmailBuilder()
.from_email("invalid-email", "Sender") # Invalid email
.to_many([{"email": "recipient@domain.com", "name": "Recipient"}])
.subject("Test")
.html("<h1>Test</h1>")
.build())
response = ms.emails.send(email)
except MailerSendError as e:
print(f"MailerSend API Error: {e}")
print(f"Status Code: {e.status_code}")
print(f"Error Details: {e.details}")
except Exception as e:
print(f"Unexpected error: {e}")
Common error types:
- ValidationError: Invalid data in request models (handled by Pydantic)
- AuthenticationError: Invalid or missing API key (401)
- RateLimitExceeded: API rate limit exceeded (429)
- BadRequestError: Malformed or invalid request (400)
- ResourceNotFoundError: Requested resource not found (404)
- ServerError: Server-side error (5xx)
- MailerSendError: Base exception; also raised for network connectivity failures
Testing
Running Unit Tests
# Install development dependencies
pip install -e ".[dev]"
# Run all tests
pytest
# Run specific test module
pytest tests/unit/test_sms_recipients_*.py
# Run with coverage
pytest --cov=mailersend --cov-report=html
Testing with VCR
The SDK uses VCR.py for integration tests to record and replay API responses:
import pytest
from mailersend import MailerSendClient
from mailersend import SmsRecipientsBuilder
@pytest.mark.vcr
def test_list_sms_recipients():
ms = MailerSendClient()
request = SmsRecipientsBuilder().build_list_request()
response = ms.sms_recipients.list_sms_recipients(request)
assert response.data is not None
Available endpoints
| Feature group | Endpoint | Available |
|---|---|---|
| Activity | GET activity | ✅ |
| Analytics | GET analytics | ✅ |
| Domains | {GET, POST, PUT, DELETE} domains | ✅ |
POST send | ✅ | |
| Email Verification | {GET, POST, PUT} email-verification | ✅ |
| Bulk Email | POST bulk-email | ✅ |
| Inbound Routes | {GET, POST, PUT, DELETE} inbound | ✅ |
| Messages | GET messages | ✅ |
| Scheduled Messages | {GET, DELETE} scheduled-messages | ✅ |
| Recipients | {GET, POST, DELETE} recipients | ✅ |
| Templates | {GET, DELETE} templates | ✅ |
| Tokens | {POST, PUT, DELETE} tokens | ✅ |
| SMTP Users | {GET, POST, PUT, DELETE} smtp-users | ✅ |
| Users | {GET, POST, PUT, DELETE} users | ✅ |
| User Invites | {GET, POST, DELETE} invites | ✅ |
| Webhooks | {GET, POST, PUT, DELETE} webhooks | ✅ |
| SMS Sending | POST sms | ✅ |
| SMS Activity | GET sms-activity | ✅ |
| SMS Phone Numbers | {GET, PUT, DELETE} sms-numbers | ✅ |
| SMS Recipients | {GET, PUT} sms-recipients | ✅ |
| SMS Messages | GET sms-messages | ✅ |
| SMS Webhooks | {GET, POST, PUT, DELETE} sms-webhooks | ✅ |
| SMS Inbound Routing | {GET, POST, PUT, DELETE} sms-inbounds | ✅ |
| Sender Identities | {GET, POST, PUT, DELETE} identities | ✅ |
| API Quota | GET api-quota | ✅ |
| DMARC Monitoring | {GET, POST, PUT, DELETE} dmarc-monitoring | ✅ |
All endpoints are available and fully tested. Refer to official API docs for the most up-to-date API specifications.
Support and Feedback
In case you find any bugs, submit an issue directly here in GitHub.
If you have any troubles using our API or SDK free to contact our support by email info@mailersend.com
The official documentation is at https://developers.mailersend.com