Skip to main content

Python SDK

The spawnmail package provides a Python client for the SpawnMail API, built on httpx.

Installation

# uv (recommended)
uv add spawnmail

# pip
pip install spawnmail

Initialization

from spawnmail import SpawnMail

# Context manager (recommended — auto-closes httpx client)
with SpawnMail("fm_your_api_key") as client:
inbox = client.create_inbox()

# With custom base URL (for self-hosted instances)
with SpawnMail("fm_your_api_key", base_url="http://localhost:8000") as client:
inbox = client.create_inbox()
info

API keys must start with fm_. The default base URL is https://api.spawnmail.sh. Always use the context manager to ensure the HTTP client is properly closed.

Methods

create_inbox(*, ttl=None, password=None)

Create a new disposable inbox.

inbox = client.create_inbox(ttl=300, password="optional")
# inbox.id → unique ID
# inbox.address → full email: {id}@spawnmail.sh
# inbox.expires_at → ISO timestamp

wait_for_email(inbox_id, *, timeout=120, password=None)

Long-poll until an email arrives or timeout elapses.

email = client.wait_for_email(inbox.id, timeout=30)
# email.sender, email.subject, email.body_text, email.body_html
caution

Timeout is in seconds for the Python SDK (default: 120). The JS SDK uses milliseconds.

capture(*, ttl=None, password=None, timeout=120)

Create an inbox and wait for the first email in one call.

result = client.capture(ttl=300, timeout=30)
# result.inbox → the created Inbox
# result.email → the first received Email

get_emails(inbox_id, *, password=None)

List all emails in an inbox.

emails = client.get_emails(inbox.id)

get_email(inbox_id, email_id, *, password=None)

Get a single email by ID.

email = client.get_email(inbox.id, email_id)

delete_inbox(inbox_id, *, password=None)

Delete an inbox and all its emails.

client.delete_inbox(inbox.id)

Types

All types are frozen dataclasses with __slots__:

@dataclass(frozen=True, slots=True)
class Inbox:
id: str
address: str
created_at: str
expires_at: str
is_active: bool
password: str | None = None

@dataclass(frozen=True, slots=True)
class Email:
id: str
inbox_id: str
sender: str
subject: str | None
body_text: str | None
body_html: str | None
received_at: str

@dataclass(frozen=True, slots=True)
class CaptureResult:
inbox: Inbox
email: Email

Error Handling

from spawnmail.errors import SpawnMailError

try:
inbox = client.create_inbox()
except SpawnMailError as e:
print(f"API error {e.status}: {e}")

SpawnMailError has a .status attribute with the HTTP status code.