A modern, feature-rich Python SDK for the Acumbamail API. This library provides both synchronous and asynchronous clients for managing email campaigns, mailing lists, subscribers, and analytics.
- Referral program
- Features
- Quick Start
- Postman Collection
- Configuration
- Basic Usage
- Asynchronous Usage
- Analytics and Statistics
- Advanced Examples
- API Reference
- Error Handling
- Examples
- Contributing
- License
- Support
If you sign up using this link, you'll get 15% off.
https://acumbamail.com/?refered=243965
- Dual Client Support: Both synchronous (
AcumbamailClient) and asynchronous (AsyncAcumbamailClient) clients - Modern HTTP Client: Built on
httpxfor better performance and HTTP/2 support - Type Hints: Full type annotation support for better IDE integration
- Comprehensive API Coverage: All major Acumbamail API endpoints supported
- Error Handling: Robust exception handling with specific error types
- Rate Limiting: Built-in rate limit handling with exponential backoff
- Data Models: Structured data models for all API responses
- Documentation: Extensive docstrings and examples
pip install acumbamailfrom acumbamail import AcumbamailClient
# Initialize the client
client = AcumbamailClient(
auth_token='your-api-token',
default_sender_name='Your Company',
default_sender_email='noreply@yourcompany.com'
)
# Create a mailing list
mailing_list = client.create_list(
name="Newsletter Subscribers",
description="Our monthly newsletter list"
)
# Add a subscriber
subscriber = client.add_subscriber(
email="user@example.com",
list_id=mailing_list.id,
fields={"name": "John Doe", "company": "Acme Corp"}
)
# Create and send a campaign
campaign = client.create_campaign(
name="Welcome Campaign",
subject="Welcome to our newsletter!",
content="<h1>Welcome!</h1><p>Thank you for subscribing.</p>",
list_ids=[mailing_list.id]
)For testing and exploring the API, you can use the included Postman collection:
- Acumbamail.postman_collection.json: Complete collection with all API endpoints pre-configured
The collection includes:
- Campaigns: All campaign-related endpoints (getCampaignBasicInformation, getCampaignClicks, getCampaignLinks, etc.)
- Subscribers: All subscriber and list management endpoints (getLists, getSubscribers, getListStats, etc.)
- Import the
Acumbamail.postman_collection.jsonfile into Postman - Set up your environment variables:
token: Your Acumbamail API tokenbasepath:https://acumbamail.com/api/1/campaign_id: Your campaign ID (for campaign-specific endpoints)list_id: Your list ID (for list-specific endpoints)
- Start testing the API endpoints directly from Postman
from acumbamail import AcumbamailClient
# Basic configuration
client = AcumbamailClient(auth_token='your-token')
# Full configuration (optional)
client = AcumbamailClient(
auth_token='your-token',
default_sender_name='Your Company',
default_sender_email='noreply@yourcompany.com',
sender_company='Your Company Inc.',
sender_country='US'
)# Get all lists
lists = client.get_lists()
for mail_list in lists:
print(f"{mail_list.name}: {mail_list.subscribers_count} subscribers")
# Create a new list
new_list = client.create_list(
name="Product Updates",
description="List for product announcements"
)
# Get list statistics
stats = client.get_list_stats(new_list.id)
print(f"Total subscribers: {stats['total_subscribers']}")# Add a subscriber
subscriber = client.add_subscriber(
email="user@example.com",
list_id=mailing_list.id,
fields={
"name": "John Doe",
"company": "Acme Corp",
"preferences": "weekly"
}
)
# Get all subscribers
subscribers = client.get_subscribers(mailing_list.id)
for subscriber in subscribers:
print(f"Email: {subscriber.email}")
print(f"Fields: {subscriber.fields}")
# Remove a subscriber
client.delete_subscriber("user@example.com", mailing_list.id)# Create a campaign
campaign = client.create_campaign(
name="Monthly Newsletter",
subject="This month's updates",
content="""
<h1>Monthly Newsletter</h1>
<p>Here are the latest updates:</p>
<ul>
<li>New feature released</li>
<li>Upcoming events</li>
<li>Special offers</li>
</ul>
""",
list_ids=[mailing_list.id],
pre_header="Stay updated with our latest news"
)
# Create a campaign with custom tracking domain
campaign_with_tracking = client.create_campaign(
name="Branded Newsletter",
subject="Special offer just for you!",
content="""
<h1>Special Offer</h1>
<p>Check out our latest deals:</p>
<a href="https://example.com/offer">View Offer</a>
""",
list_ids=[mailing_list.id],
tracking_domain="links.midominio.com" # Custom tracking domain
)
# Schedule a campaign
from datetime import datetime, timedelta
scheduled_time = datetime.now() + timedelta(days=1)
scheduled_campaign = client.create_campaign(
name="Scheduled Campaign",
subject="Scheduled message",
content="<p>This will be sent tomorrow</p>",
list_ids=[mailing_list.id],
scheduled_at=scheduled_time
)# Send a single email
email_id = client.send_single_email(
to_email="customer@example.com",
subject="Order Confirmation",
content="<h1>Thank you for your order!</h1><p>Order #12345</p>",
category="order_confirmation"
)# Create an email template
template = client.create_template(
template_name="Welcome Template",
html_content="<h1>Welcome!</h1><p>Thank you for joining our community.</p>",
subject="Welcome to our community!",
custom_category="onboarding"
)
# Get all templates
templates = client.get_templates()
for template in templates:
print(f"Template: {template.name} - ID: {template.id}")import asyncio
from acumbamail import AsyncAcumbamailClient
async def main():
# Using context manager (recommended)
async with AsyncAcumbamailClient(
auth_token='your-token',
default_sender_name='Your Company',
default_sender_email='noreply@yourcompany.com'
) as client:
# Get lists
lists = await client.get_lists()
# Create campaign
campaign = await client.create_campaign(
name="Async Campaign",
subject="Hello from async!",
content="<p>This was sent asynchronously</p>",
list_ids=[lists[0].id]
)
# Create campaign with custom tracking domain
branded_campaign = await client.create_campaign(
name="Branded Async Campaign",
subject="Special async offer!",
content="<p>Check out our async deals!</p>",
list_ids=[lists[0].id],
tracking_domain="links.midominio.com" # Custom tracking domain
)
# Get campaign statistics
stats = await client.get_campaign_total_information(campaign.id)
print(f"Opened: {stats.opened}")
# Run the async function
asyncio.run(main())# Get comprehensive campaign statistics
stats = client.get_campaign_total_information(campaign_id)
print(f"Total delivered: {stats.total_delivered}")
print(f"Opened: {stats.opened}")
print(f"Unique clicks: {stats.unique_clicks}")
print(f"Hard bounces: {stats.hard_bounces}")
print(f"Unsubscribes: {stats.unsubscribes}")
# Calculate rates
if stats.total_delivered > 0:
open_rate = (stats.opened / stats.total_delivered) * 100
click_rate = (stats.unique_clicks / stats.total_delivered) * 100
print(f"Open rate: {open_rate:.2f}%")
print(f"Click rate: {click_rate:.2f}%")# Get detailed click statistics
clicks = client.get_campaign_clicks(campaign_id)
for click in clicks:
print(f"URL: {click.url}")
print(f"Total clicks: {click.clicks}")
print(f"Unique clicks: {click.unique_clicks}")
print(f"Click rate: {click.click_rate:.2%}")# Get information about who opened the campaign
openers = client.get_campaign_openers(campaign_id)
for opener in openers:
print(f"Email: {opener.email}")
print(f"Opened at: {opener.opened_at}")
print(f"Country: {opener.country}")
print(f"Browser: {opener.browser}")
print(f"OS: {opener.os}")# Get statistics by browser
browser_stats = client.get_campaign_openers_by_browser(campaign_id)
for browser, count in browser_stats.items():
print(f"{browser}: {count} opens")
# Get statistics by operating system
os_stats = client.get_campaign_openers_by_os(campaign_id)
for os_name, count in os_stats.items():
print(f"{os_name}: {count} opens")# Add multiple subscribers efficiently
subscribers_data = [
("user1@example.com", {"name": "User One", "company": "Corp A"}),
("user2@example.com", {"name": "User Two", "company": "Corp B"}),
("user3@example.com", {"name": "User Three", "company": "Corp C"})
]
for email, fields in subscribers_data:
try:
subscriber = client.add_subscriber(
email=email,
list_id=mailing_list.id,
fields=fields
)
print(f"Added: {subscriber.email}")
except Exception as e:
print(f"Failed to add {email}: {e}")def monitor_campaign_performance(campaign_id):
"""Monitor campaign performance and alert on issues."""
stats = client.get_campaign_total_information(campaign_id)
# Calculate key metrics
if stats.total_delivered > 0:
open_rate = (stats.opened / stats.total_delivered) * 100
click_rate = (stats.unique_clicks / stats.total_delivered) * 100
bounce_rate = (stats.hard_bounces / stats.total_delivered) * 100
print(f"Campaign Performance:")
print(f" Open rate: {open_rate:.2f}%")
print(f" Click rate: {click_rate:.2f}%")
print(f" Bounce rate: {bounce_rate:.2f}%")
# Alert on poor performance
if open_rate < 15:
print("β οΈ Warning: Low open rate detected")
if bounce_rate > 5:
print("β οΈ Warning: High bounce rate detected")
if stats.complaints > 0:
print("β οΈ Warning: Complaints detected")from datetime import datetime, timedelta
def send_weekly_newsletter():
"""Send weekly newsletter to all active subscribers."""
# Get the newsletter list
lists = client.get_lists()
newsletter_list = next((l for l in lists if "newsletter" in l.name.lower()), None)
if not newsletter_list:
print("Newsletter list not found")
return
# Create newsletter content
content = """
<h1>Weekly Newsletter</h1>
<p>Here's what happened this week:</p>
<ul>
<li>New product features</li>
<li>Upcoming events</li>
<li>Community highlights</li>
</ul>
<p>Stay tuned for more updates!</p>
"""
# Create and send campaign
campaign = client.create_campaign(
name=f"Weekly Newsletter - {datetime.now().strftime('%Y-%m-%d')}",
subject="Your weekly update is here!",
content=content,
list_ids=[newsletter_list.id],
pre_header="Your weekly dose of updates and insights"
)
print(f"Newsletter sent! Campaign ID: {campaign.id}")def run_ab_test(subject_a, subject_b, content_a, content_b, list_id):
"""Run A/B test with two different subject lines and content."""
# Create two campaigns
campaign_a = client.create_campaign(
name="A/B Test - Version A",
subject=subject_a,
content=content_a,
list_ids=[list_id]
)
campaign_b = client.create_campaign(
name="A/B Test - Version B",
subject=subject_b,
content=content_b,
list_ids=[list_id]
)
print(f"Created A/B test campaigns:")
print(f" Version A: {campaign_a.id}")
print(f" Version B: {campaign_b.id}")
return campaign_a.id, campaign_b.id
def analyze_ab_test(campaign_a_id, campaign_b_id):
"""Analyze A/B test results."""
stats_a = client.get_campaign_total_information(campaign_a_id)
stats_b = client.get_campaign_total_information(campaign_b_id)
# Calculate performance metrics
open_rate_a = (stats_a.opened / stats_a.total_delivered) * 100 if stats_a.total_delivered > 0 else 0
open_rate_b = (stats_b.opened / stats_b.total_delivered) * 100 if stats_b.total_delivered > 0 else 0
click_rate_a = (stats_a.unique_clicks / stats_a.total_delivered) * 100 if stats_a.total_delivered > 0 else 0
click_rate_b = (stats_b.unique_clicks / stats_b.total_delivered) * 100 if stats_b.total_delivered > 0 else 0
print("A/B Test Results:")
print(f"Version A - Open rate: {open_rate_a:.2f}%, Click rate: {click_rate_a:.2f}%")
print(f"Version B - Open rate: {open_rate_b:.2f}%, Click rate: {click_rate_b:.2f}%")
# Determine winner
if open_rate_b > open_rate_a:
print("π Version B wins for open rate!")
elif open_rate_a > open_rate_b:
print("π Version A wins for open rate!")
else:
print("π€ Tie for open rate")class AcumbamailClient:
def __init__(
self,
auth_token: str,
default_sender_name: str = None,
default_sender_email: str = None,
*,
sender_company: str = None,
sender_country: str = None
)class AsyncAcumbamailClient:
def __init__(
self,
auth_token: str,
default_sender_name: str = None,
default_sender_email: str = None,
*,
sender_company: str = None,
sender_country: str = None,
timeout: float = 30.0
)get_lists()- Retrieve all mailing listscreate_list(name, description)- Create a new mailing listget_list_stats(list_id)- Get list statisticsget_list_fields(list_id)- Get custom fieldsget_list_segments(list_id)- Get list segments
get_subscribers(list_id)- Get all subscribersadd_subscriber(email, list_id, fields)- Add a subscriberdelete_subscriber(email, list_id)- Remove a subscriber
create_campaign(name, subject, content, list_ids, ...)- Create a campaignget_campaigns(complete_json)- Get all campaignssend_single_email(to_email, subject, content, ...)- Send single emailcreate_template(template_name, html_content, subject, custom_category)- Create email template
The SDK provides methods to create and manage email templates:
get_templates()- Retrieve all available email templatescreate_template(template_name, html_content, subject, custom_category)- Create a new email template
Template Parameters:
template_name(str): Name of the template for internal organizationhtml_content(str): HTML content of the template (can include merge tags)subject(str): Default subject line for emails using this templatecustom_category(str, optional): Category to organize templates
Example:
# Create a welcome template
template = client.create_template(
template_name="Welcome Email",
html_content="<h1>Welcome!</h1><p>Thank you for joining.</p>",
subject="Welcome to our community!",
custom_category="onboarding"
)
# Get all templates
templates = client.get_templates()
for template in templates:
print(f"Template: {template.name} - ID: {template.id}")The create_campaign method supports several parameters for customization:
name(str): Campaign name for internal organizationsubject(str): Email subject linecontent(str): HTML content of the email (must include*|UNSUBSCRIBE_URL|*)list_ids(List[int]): Target mailing list IDsfrom_name(str, optional): Sender name (uses default if not specified)from_email(str, optional): Sender email (uses default if not specified)scheduled_at(datetime, optional): When to schedule the campaigntracking_enabled(bool, optional): Enable click/open tracking (default: True)tracking_domain(str, optional): Custom domain for tracking URLs (e.g., "links.midominio.com")pre_header(str, optional): Preview text shown in email clients
Tracking Domain: The tracking_domain parameter allows you to customize the domain used for tracking URLs in your emails. Instead of using Acumbamail's default tracking domain, you can specify your own domain (e.g., "links.midominio.com") to maintain brand consistency and improve deliverability.
get_campaign_total_information(campaign_id)- Get comprehensive statsget_campaign_clicks(campaign_id)- Get click statisticsget_campaign_openers(campaign_id)- Get opener informationget_campaign_soft_bounces(campaign_id)- Get bounce information
The SDK provides specific exception types for different error scenarios:
from acumbamail import (
AcumbamailError,
AcumbamailRateLimitError,
AcumbamailAPIError,
AcumbamailValidationError
)
try:
campaign = client.create_campaign(
name="Test Campaign",
subject="Hello",
content="<p>Test</p>",
list_ids=[123]
)
except AcumbamailValidationError as e:
print(f"Validation error: {e}")
except AcumbamailRateLimitError as e:
print(f"Rate limit exceeded: {e}")
except AcumbamailAPIError as e:
print(f"API error: {e}")
except AcumbamailError as e:
print(f"General error: {e}")You can find examples in the examples directory.
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
I don't offer support for this project apart from the free time I can dedicate to it. If you find a bug, please report it in the GitHub Issues section.
[!NOTE] If you need commercial support for this project, please contact me at cr0hn<-at->cr0hn.com.