Python client for FoolMail / omegaonix — disposable mailboxes, custom domains, and account management.
Project description
foolmail
Python client for FoolMail / TalkinAPI — disposable temp-mail, custom domain management, and account operations — with full sync and async support.
pip install foolmail # httpx (sync + async)
pip install "foolmail[aiohttp]" # + aiohttp async transport
Quick start
from foolmail import FoolMailClient
client = FoolMailClient(
api_key = "Thefool-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
base_url = "https://your-server.com",
)
# Account snapshot — returns AccountSummary object
snap = client.account.summary()
print(snap.account.points_balance) # e.g. 380.0
print(snap.key.plan) # "free" | "paid" | …
# Create a random mailbox — returns Mailbox object
box = client.mail.create_random()
print(box.email) # e.g. a3f9bc12@mail.example.com
# Read inbox — returns InboxList object
inbox = client.mail.list_emails(box.email)
for msg in inbox.emails:
print(msg.subject, msg.from_addr)
# Read a full message — returns Email object
full = client.mail.get_email(box.email, inbox.emails[0].id)
print(full.text)
# Always available: .json gives the raw dict
print(snap.json["account"]["points_balance"])
Three client flavours
| Class | Transport | When to use |
|---|---|---|
FoolMailClient |
httpx sync | Scripts, CLI tools, Django, Flask |
AsyncFoolMailClient |
httpx async | FastAPI, async Django, asyncio apps |
AioFoolMailClient |
aiohttp async | Apps already using aiohttp |
All three expose identical resource namespaces:
client.account → AccountClient / AsyncAccountClient
client.mail → MailClient / AsyncMailClient
client.domains → DomainsClient / AsyncDomainsClient
Sync client (httpx)
from foolmail import FoolMailClient
# Use as a plain object
client = FoolMailClient(api_key="Thefool-...", base_url="https://...")
snap = client.account.summary()
client.close() # release connections
# Or as a context manager (recommended)
with FoolMailClient(api_key="...", base_url="...") as client:
box = client.mail.create_random("mail.example.com")
print(box.email)
Async client — httpx
import asyncio
from foolmail import AsyncFoolMailClient
async def main():
async with AsyncFoolMailClient(api_key="Thefool-...", base_url="https://...") as c:
snap = await c.account.summary()
box = await c.mail.create_random()
inbox = await c.mail.list_emails(box.email)
print(inbox.total, "emails")
asyncio.run(main())
Async client — aiohttp
import asyncio
from foolmail import AioFoolMailClient
async def main():
async with AioFoolMailClient(api_key="Thefool-...", base_url="https://...") as c:
box = await c.mail.create_custom("devtest", "mail.example.com")
print(box.email)
asyncio.run(main())
Response objects
Every API call returns a typed object instead of a plain dict. All objects have:
- Named attributes for every response field (
box.email,snap.key.plan, …) - A
.jsonattribute with the raw dict for full flexibility
from foolmail import (
AccountSummary, Mailbox, MailboxList,
InboxList, EmailSummary, Email, DeleteResult, CreditsBalance,
Domain, DomainList, DomainDnsInfo, DomainVerifyResult, DomainHealth,
DnsRecord, DnsChecks,
)
Account
snap = client.account.summary() # → AccountSummary
| Attribute | Type | Description |
|---|---|---|
snap.key |
KeyInfo |
plan, status, rate_limit, total_requests, expires_at |
snap.account |
AccountInfo |
points_balance, active_keys |
snap.mail |
MailStats |
active_mailboxes |
snap.domains |
DomainStats |
total, verified |
snap.webhooks |
WebhookStats |
total, active |
snap.costs |
CostTable |
create_mailbox, add_domain, … |
print(snap.key.plan) # "free"
print(snap.account.points_balance) # 380.0
print(snap.costs.create_mailbox) # 10.0
print(snap.costs.create_custom_mailbox) # 15.0
Mail — full reference
Create mailboxes
# Random username — 10 pts → Mailbox
box = client.mail.create_random()
box = client.mail.create_random(domain="mail.example.com")
# Custom username — 15 pts → Mailbox
box = client.mail.create_custom("alice", "mail.example.com")
print(box.email) # "alice@mail.example.com"
print(box.active_for_minutes) # 60
print(box.credits_remaining) # 365.0
Manage mailboxes
# List all mailboxes for this key → MailboxList
result = client.mail.list_mailboxes()
result = client.mail.list_mailboxes(status="active", limit=10)
for mb in result.mailboxes:
print(mb.email, mb.seconds_left)
# Get one mailbox → Mailbox
mb = client.mail.get_mailbox("alice@mail.example.com")
print(mb.seconds_left)
# Reactivate expired mailbox — 8 pts → Mailbox
result = client.mail.reactivate_mailbox("alice@mail.example.com")
print(result.active_until)
# Delete (soft-delete, irreversible) → DeleteResult
result = client.mail.delete_mailbox("alice@mail.example.com")
print(result.success) # True
Read inbox
# List emails (free) → InboxList
inbox = client.mail.list_emails("alice@mail.example.com")
inbox = client.mail.list_emails("alice@mail.example.com",
page=2, limit=50, unread_only=True)
inbox = client.mail.list_emails("alice@mail.example.com",
sender="orders@shop.com",
subject="invoice")
print(inbox.total, inbox.pages)
for msg in inbox.emails: # list of EmailSummary
print(msg.id, msg.subject, msg.from_addr)
# Get full email — auto-marks as read (free) → Email
msg = client.mail.get_email("alice@mail.example.com", "64a1b2c3...")
print(msg.subject)
print(msg.text)
print(msg.html)
for att_id in msg.attachment_ids:
data = client.mail.download_attachment(att_id) # → bytes
# Delete email → DeleteResult
client.mail.delete_email("alice@mail.example.com", "64a1b2c3...")
# Points balance → CreditsBalance
bal = client.mail.credits()
print(bal.points_balance)
Domains — full reference
# Add a custom domain — 50 pts → Domain
result = client.domains.add("mail.mycompany.com")
for rec in result.dns_records: # list of DnsRecord
print(rec.type, rec.host, rec.value)
# List all domains → DomainList
result = client.domains.list()
for d in result.domains: # list of Domain
print(d.domain, d.status, d.is_active)
# Get DNS records (if you lost them) → DomainDnsInfo
records = client.domains.dns_records("mail.mycompany.com")
# Trigger DNS verification → DomainVerifyResult
result = client.domains.verify("mail.mycompany.com")
if result.checks.all_ok:
print("Domain is live!")
print(result.checks.mx, result.checks.dkim)
# Live health check (no DB update) → DomainHealth
h = client.domains.health("mail.mycompany.com")
print(h.checks.all_ok)
# Delete domain + all mailboxes (irreversible!) → DeleteResult
client.domains.delete("mail.mycompany.com")
Error handling
from foolmail import (
FoolMailClient,
AuthenticationError,
InsufficientCreditsError,
ConflictError,
NotFoundError,
RateLimitError,
FoolMailAPIError,
)
try:
box = client.mail.create_random()
except AuthenticationError:
print("Invalid API key or key revoked")
except InsufficientCreditsError as e:
print(f"Not enough points: {e.detail}")
except ConflictError:
print("Address already taken — retry")
except RateLimitError:
print("Slow down — hit rate limit")
except FoolMailAPIError as e:
print(f"Unexpected error {e.status_code}: {e}")
All exceptions inherit from FoolMailError which carries:
.status_code— HTTP status int.detail— raw detail from the API (string or dict)
Client options
client = FoolMailClient(
api_key = "Thefool-...",
base_url = "https://your-server.com",
timeout = 60.0, # seconds (default 30)
verify_ssl = False, # disable TLS verify for local dev
)
Pagination example
skip = 0
limit = 50
while True:
result = client.mail.list_mailboxes(limit=limit, skip=skip)
for mb in result.mailboxes:
print(mb.email)
if skip + limit >= result.total:
break
skip += limit
License
MIT © 2025 TheFool
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file foolmail-0.1.0.tar.gz.
File metadata
- Download URL: foolmail-0.1.0.tar.gz
- Upload date:
- Size: 22.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ccf968d32ae61d54e9c1229c7fa1c3bbd425d06aa07500bda3c25f7732ba7d4
|
|
| MD5 |
c2701bf8384ed28205066ea6642d6081
|
|
| BLAKE2b-256 |
aac81bd24bc8ecba8006c615779c85c3e294b116b9fa9e868b009d5feed48367
|
File details
Details for the file foolmail-0.1.0-py3-none-any.whl.
File metadata
- Download URL: foolmail-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
072bc31e4af887688aaf01bd7ae3319ddf92128c4560685504fd63d5ac284ed4
|
|
| MD5 |
618719204a6dfa5d3c38056d668e4968
|
|
| BLAKE2b-256 |
e7bb539e505d7935410fe3d9abcc615499f4f30c05f3a1ac19c9125b65f4aac1
|