Resletter Python SDK
Official Python SDK for the Resletter newsletter platform API.
Installation
pip install resletter
# or
poetry add resletter
# or
uv add resletter
Quick Start
from resletter import Resletter
client = Resletter("rsl_your_api_key")
# Create a subscriber
subscriber = client.subscribers.create(
email="user@example.com",
name="John Doe",
metadata={"source": "website"},
)
print(f"Created subscriber: {subscriber['id']}")
Requirements
- Python >= 3.9
- A Resletter account with Starter plan or above (API access required)
Authentication
Get your API key from your Resletter project settings:
- Navigate to your project settings
- Go to the "API Access" section
- Click "Create API Key"
- Select the required scopes for your use case
- Copy your API key (starts with
rsl_)
API Reference
Subscribers
# List subscribers
result = client.subscribers.list(
page=1,
limit=50,
status="subscribed",
group_id="uuid",
email="search@example.com",
)
subscribers = result["subscribers"]
pagination = result["pagination"]
# Get a subscriber
subscriber = client.subscribers.get("subscriber-id")
# Create a subscriber
new_subscriber = client.subscribers.create(
email="user@example.com",
name="John Doe",
metadata={"plan": "pro"},
group_ids=["group-id"],
bypass_double_opt_in=True,
)
# Create multiple subscribers
result = client.subscribers.create_bulk(
subscribers=[
{"email": "user1@example.com", "name": "User 1"},
{"email": "user2@example.com", "name": "User 2"},
],
group_ids=["group-id"],
skip_duplicates=True,
bypass_double_opt_in=True,
)
# Update a subscriber
updated = client.subscribers.update(
"subscriber-id",
name="Jane Doe",
metadata={"plan": "enterprise"},
group_ids=["new-group-id"],
)
# Unsubscribe (soft delete)
client.subscribers.delete("subscriber-id")
# Hard delete
client.subscribers.delete("subscriber-id", hard=True)
Groups
# List groups
groups = client.groups.list()
# Get a group
group = client.groups.get("group-id")
# Create a group
new_group = client.groups.create(
name="Product Updates",
description="Subscribers interested in product news",
color="#3B82F6",
)
# Update a group
updated = client.groups.update(
"group-id",
name="New Name",
)
# Delete a group
client.groups.delete("group-id")
# Add subscribers to a group
client.groups.add_subscribers(
"group-id",
subscriber_ids=["sub-1", "sub-2"],
)
# Remove subscribers from a group
client.groups.remove_subscribers(
"group-id",
subscriber_ids=["sub-1"],
)
Campaigns
# List campaigns
campaigns = client.campaigns.list(status="active")
# Get a campaign
campaign = client.campaigns.get("campaign-id")
# Create a campaign
new_campaign = client.campaigns.create(
name="Product Launch Campaign",
description="Campaign for new product announcement",
subscriber_group_ids=["group-1", "group-2"],
)
# Update a campaign
updated = client.campaigns.update(
"campaign-id",
name="Updated Campaign Name",
status="paused",
)
# Delete a campaign
client.campaigns.delete("campaign-id")
Events
# Track a custom event to trigger automations
result = client.events.track(
name="purchase_completed",
email="user@example.com",
data={
"product": "Premium Plan",
"amount": 99.0,
},
)
print(f"Triggered {result['automationsTriggered']} automations")
Configuration Options
client = Resletter(
"rsl_your_api_key",
base_url="https://app.resletter.com", # Custom base URL
timeout=30.0, # Request timeout in seconds
)
Context Manager
The client supports context manager protocol for automatic cleanup:
with Resletter("rsl_your_api_key") as client:
subscriber = client.subscribers.create(email="user@example.com")
# Connection is automatically closed when exiting the block
Error Handling
from resletter import Resletter, ResletterError
try:
client.subscribers.create(email="invalid")
except ResletterError as e:
print(f"Status: {e.status}")
print(f"Message: {e.message}")
print(f"Code: {e.code}")
Type Hints
This SDK includes full type hints for all methods and responses:
from resletter import (
Subscriber,
SubscriberGroup,
Campaign,
SubscriberStatus,
CampaignStatus,
)
License
MIT
Metadata
Release files for resletter 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| resletter-1.0.1.tar.gz | 9.0 kB | Without provenance | Details for resletter-1.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| resletter-1.0.1-py3-none-any.whl | Python 3 | none | any | Details for resletter-1.0.1-py3-none-any.whl |
Total release size: 21.9 kB
Release files / resletter-1.0.1.tar.gz
| Download URL | resletter-1.0.1.tar.gz |
|---|---|
| Size | 9.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ab431c3fe6331f912f14acc609ee574d8e918d4797cce9ffe3ce162152da88eb
|
|
BLAKE2b-256 checksum How to use checksums |
e04c3afc2cbac1b9432fc97ffe12b377e5e28c775575e53e3c2188c1775284af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / resletter-1.0.1-py3-none-any.whl
| Download URL | resletter-1.0.1-py3-none-any.whl |
|---|---|
| Size | 12.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
91ab089c74d089199a1e3935813609a572bdce68bc580b4718608956f2275276
|
|
BLAKE2b-256 checksum How to use checksums |
53bfb96de3119eab538795a24018b997b6bbd24762cd86e4b598507773ff9ff6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Security for resletter 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.