Skip to main content

local-letter

Render an email template from your local-letter project and send it through Resend — in one call.

Your templates and their translations live in the local-letter dashboard, so copy changes ship without a deploy. Your Resend key never leaves your server: the SDK renders against your API, then talks to Resend directly.

pip install local-letter

Requires Python 3.9+.

Usage

import os
from local_letter import TemplateClient

letters = TemplateClient(
    base_url="https://letters.yourcompany.com",
    api_key=os.environ["LOCAL_LETTER_API_KEY"],
    resend_api_key=os.environ["RESEND_API_KEY"],
    from_="hello@yourcompany.com",
)

result = letters.send(
    template="welcome-email",
    to="customer@example.com",
    variables={"first_name": "Sagar"},
)

print(result.id)  # Resend message id

variables fill {{token}} placeholders in the template's subject and body. A token you don't supply is left in place rather than blanked, so a missing variable shows up in the output instead of vanishing silently.

Localisation

Pass the recipient's locale and a fallback. The API normalises casing, so en-us and EN-US both match en-US:

result = letters.send(
    template="welcome-email",
    to=user.email,
    variables={"first_name": user.first_name},
    locale=user.locale,          # "fr" — uses the French version if it exists
    fallback_locale="en",        # otherwise English, then the template default
)

result.locale tells you which version actually went out.

API

TemplateClient(base_url, api_key, resend_api_key, from_)

Argument Type Notes
base_url str Your local-letter API, e.g. https://letters.yourcompany.com.
api_key str Project API key, from the dashboard's API Keys page.
resend_api_key str Sent only to Resend. local-letter never receives it.
from_ str Default sender for every send().

letters.send(...)

Argument Type Notes
template str Template key, e.g. "welcome-email".
to str | list[str] One or more recipients.
variables dict Values for the template's {{tokens}}.
locale str Preferred locale.
fallback_locale str Used when locale has no translation.
from_ str Overrides the client default, this send only.
reply_to str Reply-to address.

Returns a SendResult with id, subject, html, and locale — the Resend message id plus what was actually rendered.

Errors

Both error types are exported, so you can tell a template problem from a delivery problem:

from local_letter import TemplateRenderError, TemplateSendError

try:
    letters.send(template="welcome-email", to=user.email)
except TemplateRenderError as err:
    # Your API rejected the render. err.status: 401 bad key, 404 no such
    # template, 403 key not linked to a project.
    ...
except TemplateSendError as err:
    # Rendered fine, Resend refused it — often an unverified sender domain.
    # err.cause holds Resend's own exception.
    ...

Examples

Runnable integrations live in examples/.

License

MIT

Metadata

Release files for local-letter 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for local-letter 0.1.0
File Size Uploaded
local_letter-0.1.0.tar.gz 5.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for local-letter 0.1.0
File Interpreter ABI Platform
local_letter-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 10.0 kB

Release files / local_letter-0.1.0.tar.gz

Download URL local_letter-0.1.0.tar.gz
Size 5.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6db4f9a30bcab08cecc75f5356140747dd4492dd8379e1ff4e3a9b94139c89a0
BLAKE2b-256 checksum
How to use checksums
5813c5ac2932e920427065fd706b7582d33f645e78afe9bfbbc8f7a8435d24ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Release files / local_letter-0.1.0-py3-none-any.whl

Download URL local_letter-0.1.0-py3-none-any.whl
Size 4.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
da63f6f32f24d6145f878b26d46d7fbb51eb7df33182485d03a0e7531da49832
BLAKE2b-256 checksum
How to use checksums
2a5dd50efacb56b0637c15b48abe24cd487f605250e90cf177db825db24d69d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page