Skip to main content

python sdk for the venumzmail temp email api

Project description

VenumzMail Docs

VenumzMail's Python SDK and CLI tool. Create inboxes, read messages, extract OTPs, stream live mail, manage custom domains etc.. Everything which is possible through our API!


Contents


Install

pip install venumzmail

Auth

Pass your API key when creating a VMail instance. Keys always start with vz-.

from venumzmail import VMail

m = VMail(api_key="vz-yourkey")

No key = guest mode — tracked by IP, limited to public inboxes and basic creation. Most features require a key.

g = VMail()  # guest

SDK

VMail

VMail(api_key=None, timeout=15)
param type default description
api_key str None your API key, must start with vz-
timeout int 15 request timeout in seconds
m = VMail(api_key="vz-yourkey")
m = VMail(api_key="vz-yourkey", timeout=30)
m = VMail()  # guest mode

create_inbox

Create a single inbox.

m.create_inbox(username=None, domain=None, type="private", username_length=None)
param type default description
username str None custom username, random if omitted
domain str None domain to use, random built-in if omitted
type str "private" "private" or "public"
username_length int None length of random username (3–25)

Returns an inbox object.

box = m.create_inbox()
box = m.create_inbox(username="myinbox", domain="bomboclato.store")
box = m.create_inbox(type="public")
box = m.create_inbox(username_length=15)

print(box.email)       # myinbox@bomboclato.store
print(box.expires_at)  # 2026-06-20T10:30:00Z
print(box.active)      # True

create_inboxes

Create multiple inboxes in one call (up to 50).

m.create_inboxes(count=1, usernames=None, domain=None, type="private")
param type default description
count int 1 how many inboxes to create
usernames list[str] None custom usernames, must match count if passed
domain str None domain for all inboxes
type str "private" "private" or "public"

Returns a list of inbox objects.

boxes = m.create_inboxes(count=5)

boxes = m.create_inboxes(
    count=3,
    usernames=["alice", "bob", "carol"],
    domain="bomboclato.store"
)

for box in boxes:
    print(box.email)

list_inboxes

List all inboxes on your account.

m.list_inboxes()

Returns a list of inbox objects.

boxes = m.list_inboxes()
for box in boxes:
    print(box.email, box.active)

reactivate

Extend an inbox's expiry.

m.reactivate(email)

Returns a dict with the new expires_at.

res = m.reactivate("myinbox@bomboclato.store")
print(res["expires_at"])

delete_inboxes

Delete inboxes by email list or wipe the oldest N.

m.delete_inboxes(emails=None, count=None)

Pass one of — not both.

m.delete_inboxes(emails=["a@bomboclato.store", "b@bomboclato.store"])
m.delete_inboxes(count=3)  # deletes 3 oldest

get_messages

Get all messages in an inbox.

m.get_messages(email)

Returns a list of message objects (empty list if no mail yet).

msgs = m.get_messages("myinbox@bomboclato.store")
for msg in msgs:
    print(msg.sender, msg.subject, msg.otp)

get_message

Get a single message by its ID.

m.get_message(message_id)

Returns a message object. Raises notFoundError if ID doesn't exist.

msg = m.get_message("48f732e8-c2e0-477e-9073-03a33d89f2cc")
print(msg.body)
print(msg.body_html)

wait_for_message

Poll an inbox until a message arrives or timeout is hit.

m.wait_for_message(email, timeout=60, poll_every=2, subject_contains=None)
param type default description
email str required inbox to watch
timeout int 60 seconds before giving up
poll_every int 2 seconds between checks
subject_contains str None only match messages with this in the subject

Returns a message object or None if timed out.

msg = m.wait_for_message("myinbox@bomboclato.store")

msg = m.wait_for_message(
    "myinbox@bomboclato.store",
    timeout=120,
    poll_every=3,
    subject_contains="welcome"
)

if msg:
    print(msg.sender, msg.subject)
else:
    print("timed out")

wait_for_otp

Poll an inbox until a message with an OTP is found.

m.wait_for_otp(email, timeout=60, poll_every=2)

Returns the OTP as a plain string, or None if timed out.

otp = m.wait_for_otp("myinbox@bomboclato.store")
print(otp)  # "482910"

stream

Live stream incoming messages for one of your own inboxes via SSE. Blocks until you break or the connection drops.

m.stream(email)

Yields message objects as they arrive.

for msg in m.stream("myinbox@bomboclato.store"):
    print(msg.sender, msg.subject, msg.otp)

email_login

Read a public inbox without an API key.

VMail().email_login(email)

Returns a dict with inbox info + a messages key containing a list of message objects.

g = VMail()
data = g.email_login("public-inbox@bomboclato.store")

print(data["email"])
print(data["active"])
print(data["expires_at"])
for msg in data["messages"]:
    print(msg.sender, msg.subject)

email_stream

Live stream a public inbox without an API key.

VMail().email_stream(email)

Yields message objects as they arrive.

g = VMail()
for msg in g.email_stream("public-inbox@bomboclato.store"):
    print(msg.sender, msg.subject)

download_attachment

Download an attachment by its ID.

m.download_attachment(attachment_id, save_to=None, public=False)
param type default description
attachment_id str required ID from message.attachments
save_to str None file path to save to, returns path if given
public bool False set True for attachments from public inboxes

Returns the save path if save_to is given, otherwise raw bytes.

# save to file
m.download_attachment("uuid-here", save_to="./invoice.pdf")

# get bytes
data = m.download_attachment("uuid-here")

# public inbox attachment, no key needed
g = VMail()
g.download_attachment("uuid-here", save_to="file.pdf", public=True)

me

Get account info for the current API key.

m.me()

Returns a raw dict.

info = m.me()
print(info)
# {"email": "you@example.com", "plan": "shadow", "inboxes_used": 3, ...}

Domains

Manage custom domains on your account. Requires a paid plan.

m.add_domain(domain)     # register a domain
m.list_domains()         # list all registered domains
m.remove_domain(domain)  # remove a domain

Before add_domain works, you need to add an MX record on your domain:

Type: MX
Host: @
Value: mail.venumzmail.xyz
Priority: 10
m.add_domain("example.com")

for d in m.list_domains():
    print(d["domain"], d["status"])

m.remove_domain("example.com")

Subdomains

Create subdomains on venumzmail's built-in base domains. Requires a registered account.

m.add_subdomain(label, base_domain)   # e.g. "team", "venumzmail.lol" → team.venumzmail.lol
m.list_subdomains()
m.remove_subdomain(subdomain)         # full subdomain string e.g. "team.venumzmail.lol"
m.add_subdomain("team", "venumzmail.lol")

print(m.list_subdomains())

# create an inbox on your subdomain
box = m.create_inbox(domain="team.venumzmail.lol")
print(box.email)  # something@team.venumzmail.lol

m.remove_subdomain("team.venumzmail.lol")

Objects

inbox

attribute type description
.email str full email address
.domain str domain part
.id str unique inbox ID
.active bool whether inbox is active
.encrypted bool whether inbox is encrypted
.expires_at str ISO 8601 expiry timestamp
.created_at str ISO 8601 creation timestamp

message

attribute type description
.id str unique message ID
.sender str sender email
.subject str subject line
.body str plain text body
.body_html str HTML body
.otp str or None extracted OTP if found, else None
.received_at str ISO 8601 timestamp
.attachments list[attachment] list of attachment objects

attachment

attribute type description
.id str attachment ID (use with download_attachment)
.filename str original filename
.size int size in bytes
.content_type str MIME type e.g. application/pdf

Errors

All errors extend venumzerror and print a colored error: + fix: hint automatically.

error when
authError bad/missing key, guest trying a restricted feature
rateLimitError too many requests for your plan
notFoundError inbox, message, or attachment doesn't exist
apiError any other 4xx/5xx — has .status_code
from venumzmail import authError, rateLimitError, notFoundError, apiError

try:
    msg = m.get_message("bad-id")
except notFoundError as e:
    print(e)         # prints error + fix hint
except rateLimitError:
    time.sleep(2)
    # retry
except authError as e:
    print("check your key")
except apiError as e:
    print(e.status_code)

CLI

Install

pip install venumzmail

Auth

# inline
vmail -k vz-yourkey <command>

# or set once
export x-api-key=vz-yourkey
vmail <command>

No key = guest mode.


Commands

help

Show all commands.

vmail help

me

Get account info.

vmail me

create

Create one or more inboxes.

vmail create                                              # random
vmail create -u myinbox -d bomboclato.store              # custom username + domain
vmail create -t public                                   # public inbox
vmail create -l 15                                       # random 15-char username
vmail create -n 5                                        # bulk, 5 random inboxes
vmail create -n 3 --usernames alice bob carol -d bomboclato.store
flag short description
--username -u custom username
--domain -d domain
--type -t private (default) or public
--length -l random username length
--count -n number of inboxes
--usernames space-separated names for bulk

list

List all inboxes.

vmail list

reactivate

Extend inbox expiry.

vmail reactivate myinbox@bomboclato.store

delete

Delete inboxes.

vmail delete --emails a@bomboclato.store b@bomboclato.store
vmail delete --count 3   # deletes 3 oldest

messages

List messages in an inbox.

vmail messages myinbox@bomboclato.store
vmail messages myinbox@bomboclato.store --body   # include body preview

Output per message:

[id]  from=sender@x.com  subject='Hello'  otp=None  at=2026-06-20T09:00:00Z

message

Get a single message in full.

vmail message <message-id>

wait

Block until a message arrives.

vmail wait myinbox@bomboclato.store
vmail wait myinbox@bomboclato.store --otp                        # return just the OTP
vmail wait myinbox@bomboclato.store --subject "verify"           # filter by subject
vmail wait myinbox@bomboclato.store --timeout 120 --poll 5
flag default description
--otp off extract and print just the OTP
--subject none only match messages containing this text in subject
--timeout 60 seconds before giving up
--poll 2 seconds between checks

stream

Live stream messages as they arrive. Ctrl+C to stop.

vmail stream myinbox@bomboclato.store
vmail stream public-inbox@bomboclato.store --public   # public inbox, no key needed

download

Download an attachment.

vmail download <attachment-id> -o ./invoice.pdf
vmail download <attachment-id>                  # prints byte count, doesn't save
vmail download <attachment-id> --public         # public inbox attachment

login

Read a public inbox without a key.

vmail login public-inbox@bomboclato.store

domains

Manage custom domains (paid plan only).

vmail domains                        # list
vmail domains --add example.com
vmail domains --remove example.com

subdomains

Manage subdomains on built-in base domains.

vmail subdomains                                  # list
vmail subdomains --add team venumzmail.lol        # creates team.venumzmail.lol
vmail subdomains --remove team.venumzmail.lol

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

venumzmail-0.1.0.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

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

venumzmail-0.1.0-py3-none-any.whl (15.0 kB view details)

Uploaded Python 3

File details

Details for the file venumzmail-0.1.0.tar.gz.

File metadata

  • Download URL: venumzmail-0.1.0.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for venumzmail-0.1.0.tar.gz
Algorithm Hash digest
SHA256 998b806ef9018b5248c2cd5b54ad6cd120dddfe4a3fd31a064352bab68a2818b
MD5 7e48e0e722fafa6da3cab745e40388b4
BLAKE2b-256 82cd64cab393088eea67288881007959ef0810008914e3e41ee32b26d3fa0ac6

See more details on using hashes here.

File details

Details for the file venumzmail-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: venumzmail-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for venumzmail-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fb9c54fd2ba84e8ca4ef4dde09ad86d833bc50197fca73c1be1ce876653a129c
MD5 6f8bb797980c0e3fb91f8e92441783c8
BLAKE2b-256 646dc08e9c0e4ddf27935a44edf0859cc04a21b4b6784ec74035a39996eea22c

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