Skip to main content
The Courier Python SDK gives you typed access to the . It includes sync and async clients, Pydantic response models, and TypedDict request params. Available on GitHub and PyPI.

Installation

Requires Python 3.9+.

Quick start

The client reads COURIER_API_KEY from your environment automatically. You can also pass it explicitly: Courier(api_key='YOUR_COURIER_API_KEY').

Authentication

Get your API key from in the Courier dashboard. Set it as an environment variable:
The SDK picks this up by default. To pass it explicitly:
Use a .env file with python-dotenv to keep your API key out of source control.

Sending notifications

With a template

Design your notification in , then reference it by ID:

To multiple recipients

Send to a list of users in a single call:

Async usage

Basic async client

Import AsyncCourier instead of Courier and use await:
The async client has the same API as the sync client. Every method returns an awaitable.

Using aiohttp instead of httpx

For better concurrency, swap the HTTP backend to aiohttp:

Available resources

The SDK covers the full Courier API. Every method is typed and documented with docstrings.

Common operations

Checking message status

After sending, use the request_id to check delivery status or get the full event timeline:
List recent messages with optional filters:

Managing user profiles

Profiles store recipient data (email, phone, custom fields) that Courier uses for delivery. You need a profile before you can send to a user_id.
create merges with any existing profile. Use replace for a full overwrite (any fields not included will be removed).

Issuing JWT tokens

Courier’s (React, JavaScript, mobile) authenticate users with a JWT your backend issues. covers the token flow, the scope strings, and token refresh. Use auth.issue_token:
The scope string controls what the token can access. Common scopes:

Type safety

Request parameters are TypedDicts, and responses are Pydantic models. You get autocomplete and inline docs in your editor.
For VS Code type checking, set python.analysis.typeCheckingMode to basic in your settings.

Configuration

Error handling

The SDK throws typed errors for API failures. All errors extend courier.APIError:

Retries

The SDK retries failed requests up to 2 times with exponential backoff. Retried errors include connection failures, timeouts, 408, 409, 429, and 5xx responses. Only network errors are retried. Any other exception raised while a request is in flight reaches your code unchanged. That includes a Celery or RQ time limit that fires while the SDK waits for Courier, so your task’s cleanup runs and the SDK doesn’t send the request again. A retry after a timeout can still repeat a send that Courier already received. To stop a retried send from going out twice, pass an idempotency key.

Timeouts

Requests time out after 60 seconds by default. Configure globally or per-request:
A timeout raises APITimeoutError. Timed-out requests are retried by default.

Logging

Enable debug logging with the COURIER_LOG environment variable:
The SDK uses Python’s standard logging module, so it works with your existing setup.

Raw response access

Access HTTP headers or stream the response body:

Custom HTTP client

Override the default httpx client for proxies or custom transports:

Journeys

are multi-step workflows (send, delay, branch, throttle, digest, and more). Invoke one by ID or alias to start a run, then cancel runs by ID or a shared cancelation token.
cancel takes exactly one of run_id or cancelation_token (spelled with one “l”). You can also build and manage journeys from code with client.journeys.create, list, publish, and archive. See .

More operations

A few more resources from the full :

API Reference

Full REST API docs with request/response examples.

Send API

Learn about the Send endpoint, routing, and message options.

Quickstart

Send your first notification in under two minutes.

GitHub

Source code, issues, and changelog.

Idempotent sends

Pass an idempotency key and Courier replays the first response for that key instead of sending again. The SDK sets the Idempotency-Key header for you. covers the scoping rule and the replay window.