Courier (trycourier)

raw JSON →
7.9.0 verified Tue May 12 auth: no python install: verified quickstart: stale

Python SDK for Courier notification API (multi-channel: email, SMS, push, in-app). Current version is 7.9.0. Install name is trycourier (pip install trycourier) but import name changed to courier in v5+ (from courier.client import Courier). The SDK was completely rewritten with Fern code generation in v5, breaking all v4 code.

pip install trycourier
error ModuleNotFoundError: No module named 'trycourier.client'
cause The import path for the Courier SDK changed from `trycourier.client` to `courier.client` starting from version 5.0.0.
fix
from courier.client import Courier
error AttributeError: 'Courier' object has no attribute 'send_message'
cause The method for sending notifications was renamed from `send_message` (or `send`) to `send_notification` in SDK version 5.0.0.
fix
client.send_notification(recipient_id="RECIPIENT_ID", event_id="EVENT_ID", data={"key": "value"})
error TypeError: send_notification() missing 2 required positional arguments: 'recipient_id' and 'event_id'
cause The `send_notification` method in SDK v5+ requires explicit `recipient_id` and `event_id` arguments, replacing the single `message` dictionary from older versions.
fix
client.send_notification(recipient_id="YOUR_RECIPIENT_ID", event_id="YOUR_EVENT_ID", data={"key": "value"})
error courier.exceptions.CourierAuthError: Not Authorized
cause The Courier API key used for authentication is missing, invalid, or lacks the necessary permissions.
fix
Ensure the COURIER_AUTH_TOKEN environment variable is correctly set or pass a valid authorization_token when initializing the Courier client.
breaking Install name (trycourier) and import name (courier) differ since v5. pip install trycourier then from courier.client import Courier. LLMs frequently generate from trycourier import Courier which raises ImportError on v5+.
fix pip install trycourier then import from courier: from courier.client import Courier
breaking Complete API rewrite in v5 using Fern code generation. v4 API (Courier(auth_token=), client.send(event=, recipient=, data=)) is completely gone. All v4 code raises ImportError or AttributeError on v5+.
fix Migrate to: from courier.client import Courier; client = Courier(authorization_token=...); client.send(message=courier.TemplateMessage(template=..., to=courier.UserRecipient(...)))
breaking auth_token= parameter renamed to authorization_token= in v5. Passing auth_token= raises TypeError.
fix Replace Courier(auth_token='...') with Courier(authorization_token='...') or set COURIER_AUTH_TOKEN env var.
breaking Resource-scoped methods introduced in v5. Old flat methods like courier.deleteBrands() replaced with courier.brands.delete(). All flat method calls raise AttributeError.
fix Use resource-scoped API: client.brands.delete(...), client.lists.get(...), etc.
gotcha The COURIER_AUTH_TOKEN environment variable is read automatically if authorization_token= is not passed. Useful for 12-factor apps but can cause silent auth failures if the wrong env var is set.
fix Set COURIER_AUTH_TOKEN in your environment, or pass authorization_token= explicitly. Verify with: python -c "import os; print(os.environ.get('COURIER_AUTH_TOKEN'))"
python os / libc status wheel install import disk
3.10 alpine (musl) - - - 36.3M
3.10 slim (glibc) - - - 36M
3.11 alpine (musl) - - - 39.5M
3.11 slim (glibc) - - - 39M
3.12 alpine (musl) - - - 31.0M
3.12 slim (glibc) - - - 31M
3.13 alpine (musl) - - - 30.6M
3.13 slim (glibc) - - - 30M
3.9 alpine (musl) - - - 35.6M
3.9 slim (glibc) - - - 35M

v5+ API. Install is trycourier, import is courier. Sync and async clients available.

# pip install trycourier
from courier.client import Courier
import courier

client = Courier(
    authorization_token='YOUR_COURIER_AUTH_TOKEN'
    # or set env var COURIER_AUTH_TOKEN
)

# Send using a template (workflow)
response = client.send(
    message=courier.TemplateMessage(
        template='your-template-id',  # template ID from Courier dashboard
        to=courier.UserRecipient(
            email='user@example.com',
            user_id='user-123'
        ),
        data={
            'name': 'Alice',
            'action_url': 'https://yourapp.com'
        }
    )
)
print('Request ID:', response.request_id)

# Async client
from courier.client import AsyncCourier
import asyncio

async def send():
    async with AsyncCourier(authorization_token='YOUR_TOKEN') as client:
        await client.send(message=courier.TemplateMessage(
            template='your-template-id',
            to=courier.UserRecipient(email='user@example.com')
        ))

asyncio.run(send())