Mail API Reference¶
Module functions¶
create_mailbox ¶
create_mailbox(
name: str | None = None,
ttl: int | None = None,
domain_id: str | None = None,
) -> Mailbox
Create a mailbox. Returns a Mailbox ready to send and receive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Mailbox name (used in address prefix). Omit for random. |
None
|
ttl
|
int | None
|
Optional TTL in seconds (max 30 days). |
None
|
domain_id
|
str | None
|
Optional custom domain ID. |
None
|
Example
from primitif import mail mb = mail.create_mailbox(name="agent") print(mb.address)
list_mailboxes ¶
List all mailboxes in the namespace.
Example
for mb in mail.list_mailboxes(): ... print(mb.address, mb.received_count)
delete_mailbox ¶
Delete a mailbox by ID.
Example
mail.delete_mailbox("mb_...")
account ¶
Get account info (plan, usage, limits).
Example
info = mail.account() print(info.plan, info.email_count)
add_protected_recipient ¶
Add a protected recipient pattern (email or @domain).
Example
mail.add_protected_recipient("ceo@bigcorp.com")
list_protected_recipients ¶
List all protected recipient patterns.
Mailbox¶
Mailbox ¶
Mailbox(
token: str | None = None,
*,
base_url: str | None = None,
max_retries: int = DEFAULT_MAX_RETRIES,
timeout: float = 30.0,
_client: Client | None = None,
)
A single ephemeral mailbox — send, receive, and manage email.
Typically created via p.mail.create_mailbox(), but can also
be instantiated directly with a token for agent-scoped operations.
Usage::
with Mailbox() as mb: # reads PRIMITIF_MAIL_TOKEN from env
mb.send(to="user@example.com", subject="Hi", body_text="Hello")
for msg in mb.inbox():
detail = mb.read(msg.id)
mb.delete()
Create a Mailbox client for agent-scoped email operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str | None
|
Mailbox token ( |
None
|
base_url
|
str | None
|
Mail API base URL. Defaults to |
None
|
max_retries
|
int
|
Number of automatic retries on transient errors. Defaults to 2. |
DEFAULT_MAX_RETRIES
|
timeout
|
float
|
HTTP request timeout in seconds. Defaults to 30.0. |
30.0
|
Raises:
| Type | Description |
|---|---|
MailError
|
If no token is provided and |
Example
mb = Mailbox(token="mb_tok_abc123") print(mb.address) 'agent-7f3a@mail.primitif.ai'
address
property
¶
The mailbox email address (fetched and cached).
Calls info() on first access to populate the cache.
Returns:
| Type | Description |
|---|---|
str
|
The full email address (e.g. |
Example
print(mb.address) 'agent-7f3a@mail.primitif.ai'
token
property
¶
The mailbox token, if available.
Present when created via p.mail.create_mailbox() or when
token= was passed to the constructor. Useful for persisting
tokens so a crashed agent can reconnect with Mailbox(token=...).
Returns:
| Type | Description |
|---|---|
str | None
|
The token string ( |
Example
token = mb.token
persist token, then later:¶
mb = Mailbox(token=token)
send ¶
send(
to: str,
subject: str,
body_text: str,
body_html: str | None = None,
require_approval: bool = False,
) -> SendResult
Send an email from this mailbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
to
|
str
|
Recipient email address. |
required |
subject
|
str
|
Email subject line. |
required |
body_text
|
str
|
Plain-text email body. |
required |
body_html
|
str | None
|
Optional HTML email body. |
None
|
require_approval
|
bool
|
If True, the email is held for human approval before sending. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
SendResult
|
SendResult with |
SendResult
|
( |
SendResult
|
approval is required, |
Raises:
| Type | Description |
|---|---|
MailValidationError
|
If the payload is invalid (e.g. bad address). |
MailAuthError
|
If the token is invalid. |
Example
result = mb.send( ... to="user@example.com", ... subject="Invoice #42", ... body_text="Please find your invoice attached.", ... ) print(result.message_id)
reply ¶
reply(
message: str | InboxMessage,
body_text: str,
body_html: str | None = None,
require_approval: bool = False,
) -> SendResult
Reply to a message.
Sends a reply in the same thread as the original message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str | InboxMessage
|
Message ID string or an InboxMessage object. |
required |
body_text
|
str
|
Plain-text reply body. |
required |
body_html
|
str | None
|
Optional HTML reply body. |
None
|
require_approval
|
bool
|
If True, the reply is held for human approval. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
SendResult
|
SendResult with |
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If the original message does not exist. |
MailValidationError
|
If the payload is invalid. |
MailAuthError
|
If the token is invalid. |
Example
for msg in mb.inbox(unread_only=True): ... mb.reply(msg, "Got it, thanks!")
inbox ¶
inbox(
*,
unread_only: bool = False,
limit: int = 20,
cursor: str | None = None,
) -> PaginatedList[InboxMessage]
List inbox messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
unread_only
|
bool
|
If True, return only unread messages. Defaults to False. |
False
|
limit
|
int
|
Maximum number of messages per page. Defaults to 20. |
20
|
cursor
|
str | None
|
Pagination cursor from a previous response. |
None
|
Returns:
| Type | Description |
|---|---|
PaginatedList[InboxMessage]
|
PaginatedList[InboxMessage] supporting iteration and |
PaginatedList[InboxMessage]
|
|
Raises:
| Type | Description |
|---|---|
MailAuthError
|
If the token is invalid. |
MailNetworkError
|
On connection failure. |
Example
for msg in mb.inbox(unread_only=True): ... print(msg.from_address, msg.subject)
Auto-paginate through all messages:¶
for msg in mb.inbox().auto_paging_iter(): ... print(msg.id)
read ¶
Read a full message.
Marks the message as read on the server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str | InboxMessage
|
Message ID string or an InboxMessage object. |
required |
Returns:
| Type | Description |
|---|---|
MessageDetail
|
MessageDetail with full body, headers, and auth results |
MessageDetail
|
( |
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If the message does not exist. |
MailAuthError
|
If the token is invalid. |
Example
for msg in mb.inbox(): ... detail = mb.read(msg) ... print(detail.body_text)
threads ¶
List email threads.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum number of threads per page. Defaults to 20. |
20
|
cursor
|
str | None
|
Pagination cursor from a previous response. |
None
|
Returns:
| Type | Description |
|---|---|
PaginatedList[ThreadSummary]
|
PaginatedList[ThreadSummary] supporting iteration and |
PaginatedList[ThreadSummary]
|
|
Raises:
| Type | Description |
|---|---|
MailAuthError
|
If the token is invalid. |
MailNetworkError
|
On connection failure. |
Example
for t in mb.threads(): ... print(t.subject, t.message_count)
thread ¶
Get a full thread with all messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thread
|
str | ThreadSummary
|
Thread ID string or a ThreadSummary object. |
required |
Returns:
| Type | Description |
|---|---|
ThreadDetail
|
ThreadDetail containing the thread metadata and a |
ThreadDetail
|
list of MessageDetail objects. |
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If the thread does not exist. |
MailAuthError
|
If the token is invalid. |
Example
for t in mb.threads(): ... detail = mb.thread(t) ... for msg in detail.messages: ... print(msg.from_address, msg.body_text)
list_attachments ¶
List attachments on a message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str | InboxMessage
|
Message ID string or an InboxMessage object. |
required |
Returns:
| Type | Description |
|---|---|
list[AttachmentInfo]
|
List of AttachmentInfo with |
list[AttachmentInfo]
|
|
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If the message does not exist. |
MailAuthError
|
If the token is invalid. |
Example
for att in mb.list_attachments(msg): ... print(att.filename, att.size_bytes)
download ¶
Download an attachment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attachment
|
AttachmentInfo
|
An AttachmentInfo object from |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
Raw file bytes. |
Example
for att in mb.list_attachments(msg): ... data = mb.download(att) ... with open(att.filename, "wb") as f: ... f.write(data)
download_attachment ¶
Download a raw attachment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str | InboxMessage
|
Message ID string or an InboxMessage object. |
required |
attachment_id
|
str
|
The attachment ID (from AttachmentInfo.id). |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
Raw file bytes. |
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If the message or attachment does not exist. |
MailAuthError
|
If the token is invalid. |
MailNetworkError
|
On connection failure after retries. |
Example
data = mb.download_attachment("msg_abc123", "att_def456") with open("invoice.pdf", "wb") as f: ... f.write(data)
get_allowlist ¶
List allowed senders.
Returns:
| Type | Description |
|---|---|
list[AllowlistEntry]
|
List of AllowlistEntry with |
list[AllowlistEntry]
|
|
Raises:
| Type | Description |
|---|---|
MailAuthError
|
If the token is invalid. |
Example
for entry in mb.get_allowlist(): ... print(entry.sender_address)
add_allowlist ¶
Add an allowed sender.
Only emails from allowlisted senders will be delivered to this mailbox (when the allowlist is non-empty).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sender_address
|
str
|
Email address to allow (e.g. |
required |
Returns:
| Type | Description |
|---|---|
AllowlistEntry
|
The created AllowlistEntry. |
Raises:
| Type | Description |
|---|---|
MailConflictError
|
If the address is already allowlisted. |
MailValidationError
|
If the address is invalid. |
MailAuthError
|
If the token is invalid. |
Example
entry = mb.add_allowlist("noreply@github.com") print(entry.id)
remove_allowlist ¶
Remove an allowed sender.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry_id
|
str
|
The allowlist entry ID (from AllowlistEntry.id). |
required |
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If the entry does not exist. |
MailAuthError
|
If the token is invalid. |
Example
mb.remove_allowlist("ale_abc123")
set_webhook ¶
Register a webhook. Returns WebhookCreated with signing secret (shown once).
Replaces any existing webhook on this mailbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The HTTPS URL to receive webhook POST requests. |
required |
events
|
list[str] | None
|
List of event types to subscribe to (e.g.
|
None
|
Returns:
| Type | Description |
|---|---|
WebhookCreated
|
WebhookCreated with |
WebhookCreated
|
and |
Raises:
| Type | Description |
|---|---|
MailValidationError
|
If the URL is invalid. |
MailAuthError
|
If the token is invalid. |
Example
wh = mb.set_webhook("https://example.com/hook") print(wh.secret) # save this -- shown only once
webhook ¶
Get current webhook config.
Returns:
| Type | Description |
|---|---|
WebhookInfo
|
WebhookInfo with |
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If no webhook is configured. |
MailAuthError
|
If the token is invalid. |
Example
wh = mb.webhook() print(wh.url, wh.events)
delete_webhook ¶
Remove the webhook.
Raises:
| Type | Description |
|---|---|
MailNotFoundError
|
If no webhook is configured. |
MailAuthError
|
If the token is invalid. |
Example
mb.delete_webhook()
info ¶
Get mailbox details.
Returns:
| Type | Description |
|---|---|
MailboxInfo
|
MailboxInfo with |
MailboxInfo
|
and |
Raises:
| Type | Description |
|---|---|
MailAuthError
|
If the token is invalid or expired. |
MailNetworkError
|
On connection failure. |
Example
info = mb.info() print(info.address, info.expires_at)
delete ¶
Delete this mailbox from the server and close the HTTP client.
This permanently destroys the mailbox and all its messages. The Mailbox instance cannot be used after this call.
Raises:
| Type | Description |
|---|---|
MailAuthError
|
If the token is invalid. |
MailNetworkError
|
On connection failure. |
Example
mb.delete() # mailbox is gone
close ¶
Close the HTTP client.
The mailbox remains active on the server. Use delete() to
destroy it entirely. Called automatically when used as a context
manager.
Example
mb.close()
Models¶
InboxMessage ¶
Bases: BaseModel
MessageDetail ¶
Bases: BaseModel
SendResult ¶
Bases: BaseModel
ThreadSummary ¶
Bases: BaseModel
ThreadDetail ¶
Bases: BaseModel
AttachmentInfo ¶
Bases: BaseModel
MailboxInfo ¶
Bases: BaseModel
MailboxListItem ¶
Bases: BaseModel
AllowlistEntry ¶
Bases: BaseModel
WebhookCreated ¶
Bases: BaseModel
WebhookInfo ¶
Bases: BaseModel
ProtectedRecipient ¶
Bases: BaseModel
AccountInfo ¶
Bases: BaseModel