Email API
The Email class represents a decrypted email message in VaultSandbox. All emails are automatically decrypted when retrieved, so you can access content, headers, links, and attachments directly.
Properties
Section titled “Properties”id: strUnique identifier for this email. Use this to reference the email in API calls.
Example
Section titled “Example”emails = await inbox.list_emails()print(f"Email ID: {emails[0].id}")
# Get specific emailemail = await inbox.get_email(emails[0].id)from_address
Section titled “from_address”from_address: strThe sender’s email address.
Note: This property is named
from_addressinstead offrombecausefromis a reserved word in Python.
Example
Section titled “Example”email = await inbox.wait_for_email()print(f"From: {email.from_address}")
to: list[str]List of recipient email addresses.
Example
Section titled “Example”email = await inbox.wait_for_email()print(f"To: {', '.join(email.to)}")
# Check if specific recipient is includedassert inbox.email_address in email.tosubject
Section titled “subject”subject: strThe email subject line.
Example
Section titled “Example”import refrom vaultsandbox import WaitForEmailOptions
email = await inbox.wait_for_email( WaitForEmailOptions( timeout=10000, subject=re.compile(r"Welcome"), ))
print(f"Subject: {email.subject}")assert "Welcome" in email.subjecttext: str | NonePlain text content of the email. May be None if the email only has HTML content.
Example
Section titled “Example”email = await inbox.wait_for_email()
if email.text: print("Plain text version:") print(email.text)
# Validate content assert "Thank you for signing up" in email.texthtml: str | NoneHTML content of the email. May be None if the email only has plain text.
Example
Section titled “Example”email = await inbox.wait_for_email()
if email.html: print("HTML version present")
# Validate HTML structure assert "<a href=" in email.html assert "</html>" in email.html
# Check for specific elements import re assert re.search(r'<img[^>]+src="', email.html)received_at
Section titled “received_at”received_at: datetimeThe date and time when the email was received by VaultSandbox.
Example
Section titled “Example”from datetime import datetime, timezone
email = await inbox.wait_for_email()print(f"Received at: {email.received_at.isoformat()}")
# Check if email was received recentlynow = datetime.now(timezone.utc)age_in_seconds = (now - email.received_at).total_seconds()
assert age_in_seconds < 60 # Within last minuteis_read
Section titled “is_read”is_read: boolWhether this email has been marked as read.
Example
Section titled “Example”email = await inbox.wait_for_email()print(f"Read status: {email.is_read}")
# Mark as readawait email.mark_as_read()
# Verify status changedupdated = await inbox.get_email(email.id)assert updated.is_read is Truelinks: list[str]All URLs automatically extracted from the email content (both text and HTML).
Example
Section titled “Example”import refrom urllib.parse import urlparse, parse_qsfrom vaultsandbox import WaitForEmailOptions
email = await inbox.wait_for_email( WaitForEmailOptions( timeout=10000, subject=re.compile(r"Password Reset"), ))
print(f"Found {len(email.links)} links:")for url in email.links: print(f" - {url}")
# Find specific linkreset_link = next( (url for url in email.links if "/reset-password" in url), None)assert reset_link is not Noneassert reset_link.startswith("https://")
# Extract query parametersparsed = urlparse(reset_link)params = parse_qs(parsed.query)token = params.get("token", [None])[0]assert token is not Noneheaders
Section titled “headers”headers: dict[str, str]All email headers as a key-value dictionary.
Example
Section titled “Example”email = await inbox.wait_for_email()
print("Headers:")print(f" Content-Type: {email.headers.get('content-type')}")print(f" Message-ID: {email.headers.get('message-id')}")
# Check for custom headersif "x-custom-header" in email.headers: print(f"Custom header: {email.headers['x-custom-header']}")attachments
Section titled “attachments”attachments: list[Attachment]List of email attachments, automatically decrypted and ready to use.
@dataclassclass Attachment: filename: str content_type: str size: int content: bytes content_id: str | None = None content_disposition: str | None = None checksum: str | None = None| Property | Type | Description |
|---|---|---|
filename | str | Attachment filename |
content_type | str | MIME content type |
size | int | Attachment size in bytes |
content | bytes | Attachment content as bytes |
content_id | str | None | Content ID for inline attachments |
content_disposition | str | None | Content disposition (attachment/inline) |
checksum | str | None | SHA-256 hash of the attachment content |
Example
Section titled “Example”import refrom vaultsandbox import WaitForEmailOptions
email = await inbox.wait_for_email( WaitForEmailOptions( timeout=10000, subject=re.compile(r"Invoice"), ))
print(f"Attachments: {len(email.attachments)}")
for attachment in email.attachments: print(f" - {attachment.filename} ({attachment.size} bytes)") print(f" Type: {attachment.content_type}")
# Find PDF attachmentpdf = next( (att for att in email.attachments if att.content_type == "application/pdf"), None)if pdf: with open(f"./downloads/{pdf.filename}", "wb") as f: f.write(pdf.content) print(f"Saved {pdf.filename}")
# Process text attachmenttext_file = next( (att for att in email.attachments if "text" in att.content_type), None)if text_file: text = text_file.content.decode("utf-8") print("Text content:", text)
# Parse JSON attachmentjson_file = next( (att for att in email.attachments if "json" in att.content_type), None)if json_file: import json data = json.loads(json_file.content.decode("utf-8")) print("JSON data:", data)See the Attachments Guide for more examples.
auth_results
Section titled “auth_results”auth_results: AuthResultsEmail authentication results including SPF, DKIM, DMARC, and Reverse DNS validation.
@dataclassclass AuthResults: spf: SPFResult | None = None dkim: list[DKIMResult] = field(default_factory=list) dmarc: DMARCResult | None = None reverse_dns: ReverseDNSResult | None = None
def validate(self) -> AuthResultsValidation: ...Example
Section titled “Example”email = await inbox.wait_for_email()
# Validate all authenticationvalidation = email.auth_results.validate()print(f"Authentication passed: {validation.passed}")
if not validation.passed: print("Failures:") for failure in validation.failures: print(f" - {failure}")
# Check individual resultsif email.auth_results.spf: print(f"SPF Result: {email.auth_results.spf.result.value}")
if email.auth_results.dkim: print(f"DKIM Result: {email.auth_results.dkim[0].result.value}")
if email.auth_results.dmarc: print(f"DMARC Result: {email.auth_results.dmarc.result.value}")See the Authentication Guide for more details.
metadata
Section titled “metadata”metadata: dict[str, Any]Raw decrypted metadata from encryptedMetadata.
Example
Section titled “Example”email = await inbox.wait_for_email()
if email.metadata: print("Metadata:", email.metadata)parsed_metadata
Section titled “parsed_metadata”parsed_metadata: dict[str, Any]Additional metadata from parsed content (from encryptedParsed).
Example
Section titled “Example”email = await inbox.wait_for_email()
if email.parsed_metadata: print("Parsed metadata:", email.parsed_metadata)Methods
Section titled “Methods”mark_as_read()
Section titled “mark_as_read()”Marks this email as read.
async def mark_as_read(self) -> NoneExample
Section titled “Example”email = await inbox.wait_for_email()
print(f"Read status: {email.is_read}") # False
await email.mark_as_read()print("Marked as read")
# Verify status changedupdated = await inbox.get_email(email.id)assert updated.is_read is Truedelete()
Section titled “delete()”Deletes this email from the inbox.
async def delete(self) -> NoneExample
Section titled “Example”email = await inbox.wait_for_email()
# Delete the emailawait email.delete()print("Email deleted")
# Verify deletionemails = await inbox.list_emails()assert not any(e.id == email.id for e in emails)get_raw()
Section titled “get_raw()”Gets the raw MIME source of this email (decrypted).
async def get_raw(self) -> RawEmailReturns
Section titled “Returns”RawEmail - Object containing the email ID and raw MIME content
@dataclassclass RawEmail: id: str # The email ID raw: str # The raw MIME email contentExample
Section titled “Example”email = await inbox.wait_for_email()raw_email = await email.get_raw()
print(f"Email ID: {raw_email.id}")print("Raw MIME source:")print(raw_email.raw)
# Save to .eml filewith open(f"email-{raw_email.id}.eml", "w") as f: f.write(raw_email.raw)AuthResults
Section titled “AuthResults”The AuthResults object provides email authentication validation.
Properties
Section titled “Properties”spf: SPFResult | NoneSPF (Sender Policy Framework) validation result.
@dataclassclass SPFResult: result: SPFStatus domain: str | None = None ip: str | None = None details: str | None = None
class SPFStatus(str, Enum): PASS = "pass" FAIL = "fail" SOFTFAIL = "softfail" NEUTRAL = "neutral" NONE = "none" TEMPERROR = "temperror" PERMERROR = "permerror"dkim: list[DKIMResult]DKIM (DomainKeys Identified Mail) validation results. May have multiple signatures.
@dataclassclass DKIMResult: result: DKIMStatus domain: str | None = None selector: str | None = None signature: str | None = None
class DKIMStatus(str, Enum): PASS = "pass" FAIL = "fail" NONE = "none"dmarc: DMARCResult | NoneDMARC (Domain-based Message Authentication) validation result.
@dataclassclass DMARCResult: result: DMARCStatus policy: DMARCPolicy | None = None aligned: bool | None = None domain: str | None = None
class DMARCStatus(str, Enum): PASS = "pass" FAIL = "fail" NONE = "none"
class DMARCPolicy(str, Enum): NONE = "none" QUARANTINE = "quarantine" REJECT = "reject"reverse_dns
Section titled “reverse_dns”reverse_dns: ReverseDNSResult | NoneReverse DNS lookup result.
@dataclassclass ReverseDNSResult: verified: bool ip: str | None = None hostname: str | None = NoneMethods
Section titled “Methods”validate()
Section titled “validate()”Validates all authentication results and returns a summary.
def validate(self) -> AuthResultsValidationReturns
Section titled “Returns”@dataclassclass AuthResultsValidation: passed: bool # True if SPF, DKIM, and DMARC all passed spf_passed: bool # Whether SPF check passed dkim_passed: bool # Whether at least one DKIM signature passed dmarc_passed: bool # Whether DMARC check passed reverse_dns_passed: bool # Whether reverse DNS check passed failures: list[str] = field(default_factory=list)Note: The
passedfield reflects whether SPF, DKIM, and DMARC all passed. Reverse DNS is tracked separately but does not affectpassed.
Example
Section titled “Example”email = await inbox.wait_for_email()validation = email.auth_results.validate()
print(f"Overall: {'PASS' if validation.passed else 'FAIL'}")
if not validation.passed: print("\nFailures:") for failure in validation.failures: print(f" - {failure}")Complete Example
Section titled “Complete Example”import asyncioimport osimport refrom vaultsandbox import VaultSandboxClient, WaitForEmailOptions
async def complete_email_example(): async with VaultSandboxClient( api_key=os.environ["VAULTSANDBOX_API_KEY"], ) as client: inbox = await client.create_inbox() print(f"Created inbox: {inbox.email_address}")
# Trigger test email await send_test_email(inbox.email_address)
# Wait for email email = await inbox.wait_for_email( WaitForEmailOptions( timeout=10000, subject=re.compile(r"Test"), ) )
# Basic info print("\n=== Email Details ===") print(f"ID: {email.id}") print(f"From: {email.from_address}") print(f"To: {', '.join(email.to)}") print(f"Subject: {email.subject}") print(f"Received: {email.received_at.isoformat()}") print(f"Read: {email.is_read}")
# Content print("\n=== Content ===") if email.text: print("Plain text:") print(email.text[:200] + "...") if email.html: print("HTML version present")
# Links print("\n=== Links ===") print(f"Found {len(email.links)} links:") for link in email.links: print(f" - {link}")
# Attachments print("\n=== Attachments ===") print(f"Found {len(email.attachments)} attachments:") for att in email.attachments: print(f" - {att.filename} ({att.content_type}, {att.size} bytes)")
# Save attachment with open(f"./downloads/{att.filename}", "wb") as f: f.write(att.content) print(f" Saved to ./downloads/{att.filename}")
# Authentication print("\n=== Authentication ===") validation = email.auth_results.validate() print(f"Overall: {'PASS' if validation.passed else 'FAIL'}")
if email.auth_results.spf: print(f"SPF: {email.auth_results.spf.result.value}") if email.auth_results.dkim: print(f"DKIM: {email.auth_results.dkim[0].result.value}") if email.auth_results.dmarc: print(f"DMARC: {email.auth_results.dmarc.result.value}")
if not validation.passed: print("Failures:", validation.failures)
# Mark as read await email.mark_as_read() print("\nMarked as read")
# Get raw source raw_email = await email.get_raw() with open(f"email-{raw_email.id}.eml", "w") as f: f.write(raw_email.raw) print(f"Saved raw source to email-{raw_email.id}.eml")
# Clean up await inbox.delete()
asyncio.run(complete_email_example())Next Steps
Section titled “Next Steps”- Inbox API Reference - Learn about inbox methods
- Attachments Guide - Working with attachments
- Authentication Guide - Email authentication testing
- Waiting for Emails - Best practices for email waiting