Skip to main content

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 .json attribute 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

foolmail-0.1.0.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

foolmail-0.1.0-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

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

Hashes for foolmail-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6ccf968d32ae61d54e9c1229c7fa1c3bbd425d06aa07500bda3c25f7732ba7d4
MD5 c2701bf8384ed28205066ea6642d6081
BLAKE2b-256 aac81bd24bc8ecba8006c615779c85c3e294b116b9fa9e868b009d5feed48367

See more details on using hashes here.

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

Hashes for foolmail-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 072bc31e4af887688aaf01bd7ae3319ddf92128c4560685504fd63d5ac284ed4
MD5 618719204a6dfa5d3c38056d668e4968
BLAKE2b-256 e7bb539e505d7935410fe3d9abcc615499f4f30c05f3a1ac19c9125b65f4aac1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page