Skip to content

vincenzor/letter-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

letterapp (Python)

PyPI version License: MIT

Official Python client for letter.app - onboarding email drip campaigns for product teams.

pip install letterapp

Requires Python 3.8+. Zero runtime dependencies (standard library only).

Quick start

import os
from letterapp import Letter

letter = Letter(api_key=os.environ["LETTER_API_KEY"])  # Dashboard -> Settings -> API keys

# Tell Letter who your user is (call where users sign up or log in).
letter.identify(
    user_id="user_123",
    email="alice@example.com",
    traits={"name": "Alice", "plan": "free"},
)

# Report something they did.
letter.track(user_id="user_123", event="Signed Up", properties={"source": "web"})

# Required before the process exits so no events are lost.
letter.close()

Or use it as a context manager, which flushes on exit:

with Letter(api_key=os.environ["LETTER_API_KEY"]) as letter:
    letter.track(user_id="user_123", event="Workspace Created")

Serverless (Lambda, Cloud Functions)

There is no background time to flush in a serverless handler, so set flush_at=1 and flush() at the end of each invocation:

letter = Letter(api_key=os.environ["LETTER_API_KEY"], flush_at=1)

def handler(event, context):
    letter.track(user_id="user_123", event="Checkout Started")
    letter.flush()

What it does

  • Auto-batching - calls are queued and flushed every 100ms or 50 events by a background daemon thread.
  • Retries - 429 waits Retry-After; 5xx and network errors back off exponentially with jitter, up to max_retries (default 3).
  • Idempotent - every call gets a UUID message_id so retries are deduplicated server-side.
  • No dependencies - HTTP over the standard library urllib.

API

Letter(
    api_key,
    base_url="https://api.letter.app",  # only set for self-hosted / local
    flush_at=50,                          # 1 for serverless
    flush_interval=0.1,                   # seconds
    max_retries=3,
    timeout=10.0,
    on_error=None,                        # callback(Exception) for bg errors
)

letter.identify(user_id, email=None, traits=None, timezone=None, timestamp=None, message_id=None)
letter.group(user_id, account_id, name=None, traits=None, timestamp=None, message_id=None)
letter.track(user_id, event, properties=None, timestamp=None, message_id=None)
letter.flush()   # send queued calls now, block until done
letter.close()   # flush + stop the background thread (also runs at exit)

Configuration errors and non-retryable API responses raise LetterError (with .status and .body). Background transport errors are passed to on_error instead, since they cannot be raised to the caller.

Full documentation

License

MIT - see LICENSE.

About

Official Python SDK for letter.app - onboarding email drip campaigns

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages