# Mailboxes

<!-- BEGIN GENERATED: guide-map -->
## Guide map

Read only the section needed for the next decision. Line ranges are exact
for this generated runtime target.

| Section | What it covers | Lines |
| --- | --- | --- |
| [Purpose](#purpose) | Scope, ownership, and the central operating question. | 32-41 |
| [Use This When](#use-this-when) | Tasks and conditions that belong in this guide. | 42-48 |
| [Do Not Use This For](#do-not-use-this-for) | Boundaries and the correct routes for excluded work. | 49-59 |
| [Mental Model](#mental-model) | Concepts and state boundaries needed for correct operation. | 60-84 |
| [Choose A Path](#choose-a-path) | Decision hierarchy for selecting the right capability or provider. | 85-96 |
| [Primary SDK Paths](#primary-sdk-paths) | Operating guidance and contracts for this section. | 97-110 |
| [Supporting References](#supporting-references) | Capability, provider, policy, and runtime guides for this outcome. | 111-120 |
| [Preflight](#preflight) | State, authority, inputs, and readiness to verify before execution. | 121-142 |
| [Risk And Side Effects](#risk-and-side-effects) | Effects, approvals, cost, privacy, and retry boundaries. | 143-157 |
| [Canonical Operating Pattern](#canonical-operating-pattern) | The normal end-to-end execution sequence. | 158-173 |
| [Core SDK Surfaces](#core-sdk-surfaces) | Exact source-backed callable contracts owned by this guide. | 174-184 |
| [Data Contracts](#data-contracts) | Required identities, fields, evidence, handles, and durable shapes. | 185-219 |
| [Examples](#examples) | Representative usage patterns and code. | 220-259 |
| [Verification](#verification) | Evidence required before reporting success. | 260-272 |
| [Troubleshooting](#troubleshooting) | Failure diagnosis and corrective routes. | 273-285 |
| [Related References](#related-references) | Adjacent boundaries and when to cross them. | 286-295 |
<!-- END GENERATED: guide-map -->

Connect, provision, inspect, and prepare mailbox and sender capacity for
outbound.

## Purpose

Mailboxes owns the readiness path from an organization-owned sending identity
to a connected, healthy, capacity-aware sender. It routes existing-mailbox
connections, sender inspection, domain readiness, and paid provisioning while
keeping credentials and purchase approval at their proper boundaries.

Readiness is the outcome. Creating a sender row or receiving an OAuth URL is
only an intermediate receipt.

## Use This When

Use this guide for mailbox OAuth or app-password connection, sender readiness,
capacity, sending-domain search and inventory, domain purchase, or mailbox
orders. Sending email and workspace subscription billing are different
outcomes.

## Do Not Use This For

| Task | Owning Reference |
| --- | --- |
| Sending an email or activating a sequence | `outbound-campaigns.md` or the owning email effect guide |
| Reading and replying to mailbox conversations | `inbox-and-replies.md` |
| Writing campaign copy | `copywriting.md` |
| Treating a CRM or Slack integration as a sender mailbox | `crm.md` or the integration's owning guide |
| Inspecting subscriptions, credits, plan limits, checkout, or billing reconciliation | `billing.md` |
| Raw credential extraction, storage, or display | Use only the supported user-owned connection flow; never expose secrets in artifacts or logs |

## Mental Model

Keep four states distinct:

1. Sender identity says who the organization intends to send as.
2. Provider connection proves the platform can act for that mailbox.
3. Readiness combines authentication, provider health, domain state, and
   configuration checks.
4. Capacity describes how much sending is currently eligible, not how much the
   user wants to send.

Provisioning adds a fifth state: an order can be quoted, approved, submitted,
fulfilled, or failed. A paid order is not a ready mailbox until fulfillment and
connection checks complete.

Domain availability and order state are server-owned facts. Do not calculate
prices in the client or treat an inserted billing intent as successful
provisioning. The provider must succeed before the backend reconciles the
charge, and an already-owned or in-flight domain must not create a duplicate
domain-purchase intent.

The operating rule is bill after provision, not before. Never present an
inserted intent as a completed purchase. Purchase/order state is not the same
as connected sender readiness.

## Choose A Path

1. Inspect existing sender, domain inventory, and integration state before
   creating anything.
2. Connect an existing mailbox through the supported user-owned flow.
3. Search or suggest a sending domain before provisioning new capacity.
4. Present the canonical scope and price facts, then obtain explicit approval
   immediately before a purchase.
5. Follow the same order through provisioning and reconciliation. Do not create
   a replacement because an intermediate state is slow or ambiguous.
6. Re-check readiness and preserve the sender or order receipt.

## Primary SDK Paths

<!-- BEGIN GENERATED: primary-sdk-paths -->
| Primary function | Choose it when | Required inputs | Returns | Exact contract |
| --- | --- | --- | --- | --- |
| `vf.senders.list` | Use first to find existing sender identities and avoid creating or reconnecting a duplicate mailbox. | None | `sender_list` | [`senders.md`](senders.md) · installed SDK: `verbiflow/senders.py:16-33` |
| `vf.senders.status` | Use to verify connection, readiness, warmup, health, and available sending capacity for a known sender. | None | `sender_readiness` | [`senders.md`](senders.md) · installed SDK: `verbiflow/senders.py:35-54` |
| `vf.senders.mailbox_oauth_quote` | Use before mailbox OAuth to retrieve the authoritative price and charge facts required for explicit approval. | None | `mailbox_oauth_quote` | [`senders.md`](senders.md) · installed SDK: `verbiflow/senders.py:89-102` |
| `vf.senders.connect_mailbox_oauth` | Use for a user-completed hosted OAuth connection when the mailbox provider supports OAuth and no raw credential should be supplied. | `sender_id` | `sender_account_auth` | [`senders.md`](senders.md) · installed SDK: `verbiflow/senders.py:104-122` |
| `vf.senders.connect_mailbox_app_password` | Use when the user explicitly supplies a mailbox app password and the provider connection requires that credential path. | `app_password`, `email`, `sender_id` | `sender_account_auth` | [`senders.md`](senders.md) · installed SDK: `verbiflow/senders.py:124-171` |
| `vf.domains.search` | Use to find available sending domains and inspect price facts before any purchase. | `domain` | `domain_search_result` | [`mailboxes.md`](mailboxes.md) · installed SDK: `verbiflow/domains.py:12-27` |
| `vf.domains.create_mailbox_order` | Use only after domain, mailbox quantity, price, and charge approval are explicit and a real order should be created. | `domain`, `is_new_domain`, `mailboxes` | `billing_intent` | [`mailboxes.md`](mailboxes.md) · installed SDK: `verbiflow/domains.py:58-73` |
<!-- END GENERATED: primary-sdk-paths -->

## Supporting References

Open only the child that resolves the next material decision.

| Reference | Use it for | Kind |
| --- | --- | --- |
| [`senders.md`](senders.md) | Sender identity, mailbox connections, movement, capacity, and delivery readiness. | capability |
| [`safety.md`](safety.md) | Approval, confirmation, side-effect, purchase, and external-communication boundaries. | policy |
| [`auth.md`](auth.md) | Runtime authority, provider integration readiness, and user-owned connection flows. | runtime |

## Preflight

Before connecting or provisioning anything, establish:

- the intended organization and the mailbox email, domain, provider, and sender
  identity;
- whether the mailbox or sender already exists;
- current connection, readiness, warmup, capacity, and ownership state;
- whether the provider requires an external OAuth interaction or a supported
  app-password flow;
- the requested quantity and identity pattern for any purchase;
- the current quote, price units, available credits, and explicit approval for
  paid work;
- domain availability, ban state, registration and renewal price, ownership,
  and any existing in-flight order;
- the exact mailbox emails, names, platform choices, sender IDs, registration
  term, and whether domain registration is included;
- the downstream campaign's channel and capacity requirements.

Do not create a duplicate sender merely because an existing sender is not yet
ready. Diagnose the existing identity first.

## Risk And Side Effects

| Operation | Risk And Boundary |
| --- | --- |
| Inspect sender, connection, readiness, or capacity | Read-only. Preserve organization and sender identity. |
| Search a sending domain | Provider-backed price and availability read. Preserve backend facts and do not infer approval. |
| Generate domain suggestions | Provider/LLM-backed read that may populate a bounded cache. Suggestions are not purchase approval. |
| Start OAuth or connect with an app password | Credential-bearing user flow. Keep secrets out of model output, logs, and durable artifacts. |
| Create or update a sender identity | Reversible platform write. Verify ownership and normalized mailbox identity. |
| Purchase a domain or mailboxes | Paid and potentially irreversible. Quote first and require explicit approval immediately before submission. |
| Move, delete, or disconnect a sender | Customer-visible capacity change. Confirm scope and downstream campaign impact. |

An ambiguous provider response must not trigger a blind reconnect or repeat
purchase. Inspect the existing connection or order receipt first.

## Canonical Operating Pattern

1. Inspect existing senders, purchased domains, and provider integration state.
2. Reuse the intended sender identity when it already exists.
3. Choose connection for an existing mailbox or provisioning for new capacity.
4. For connection, complete the supported user-owned interaction and re-check
   provider status.
5. For provisioning, search or suggest the domain, inspect current inventory,
   obtain a current quote, confirm exact scope, receive explicit approval, and
   preserve the returned order group and intent IDs.
6. Follow the same intent through provisioning and reconciliation without
   creating replacements.
7. Re-read purchased domains and sender readiness after fulfillment.
8. Verify identity, health, warmup, and usable capacity before handing the
   sender to a campaign.

## Core SDK Surfaces

<!-- BEGIN GENERATED: core-sdk-surfaces -->
| Function | Use When | Inputs | Output And Handles To Preserve | Side Effect | Source |
| --- | --- | --- | --- | --- | --- |
| `vf.domains.create_mailbox_order` | Use for billing, plan, checkout, purchased-domain, and mailbox-domain operations. | <strong>Required</strong>: `domain` (string; required): Domain to purchase mailboxes for, such as `example.com`.; `is_new_domain` (boolean; required): Whether the order should include domain registration. Backend treats this as advisory and suppresses duplicate domain-purchase intents when the org already owns or is already ordering the domain.; `mailboxes` (array; required): Mailbox order items. Each item must include a full email on the requested domain plus first and last name; platform defaults to GOOGLE.<br><strong>Optional</strong>: `registration_years` (integer; optional): Domain registration term when `is_new_domain` is true; backend accepts 1 through 10 years and defaults to 1. | `dict` with billing/order intent status and any checkout or order identifiers. | platform_write | installed SDK: `verbiflow/domains.py:58-73` |
| `vf.domains.list_purchased` | Use for billing, plan, checkout, purchased-domain, and mailbox-domain operations. | No inputs. | `dict` with purchased/sending domain records for the workspace. | read | installed SDK: `verbiflow/domains.py:43-56` |
| `vf.domains.search` | Use for billing, plan, checkout, purchased-domain, and mailbox-domain operations. | <strong>Required</strong>: `domain` (str; required): Domain name to search, order, enrich, or normalize.<br><strong>Optional</strong>: none | `dict` with domain availability/search results, prices when available, provider status, and suggestions. | read | installed SDK: `verbiflow/domains.py:12-27` |
| `vf.domains.suggest` | Use for billing, plan, checkout, purchased-domain, and mailbox-domain operations. | No inputs. | `dict` with available/suggested sending domains and purchasing metadata. | platform_write | installed SDK: `verbiflow/domains.py:29-41` |
<!-- END GENERATED: core-sdk-surfaces -->

## Data Contracts

Preserve:

| Record | Required Meaning |
| --- | --- |
| Sender | Stable sender identity, normalized email, organization, display identity, provider, and status. |
| Connection | Provider identity, connection state, interaction URL when needed, timestamps, and sanitized failure detail. |
| Readiness | Authentication, domain, warmup, health, restrictions, and eligibility reasons. |
| Capacity | Channel, current usable capacity, limits, reservations, and observation time. |
| Domain availability | Domain, availability, ban state, registration price, renewal price, and observation time from the backend. |
| Quote | Exact items, quantities, unit prices, currency or credits, expiration, and assumptions. |
| Order | Stable `order_group_id`, approved scope, submitted amount, lifecycle state, and fulfillment references. |
| Order intent | Stable `intent_id`, kind, status, provider facts, and reconciliation state for each domain or mailbox item. |

Never use an email string alone as proof that a sender is connected or ready.
Preserve the canonical sender and provider receipts.

`vf.domains.create_mailbox_order(...)` takes `domain`, `is_new_domain`, and one
to ten mailbox objects. Each mailbox requires a full email on that domain,
`first_name`, and `last_name`; optional fields include `platform` (`GOOGLE` or
`MICROSOFT`), `profile_pic_url`, and `sender_id`. Preserve every returned intent
instead of reducing the response to a boolean.

Order intents normally move through:

```text
pending -> provisioning -> provisioned -> reconciled
pending -> canceled
provisioning -> provision_failed
```

Treat `reconciled`, `provision_failed`, and `canceled` as terminal for operator
reporting. `provisioned` can still be waiting for billing reconciliation.

## Examples

Inspect a sending domain before purchase approval:

```python
import verbiflow as vf

vf.auth.ensure_logged_in()
availability = vf.domains.search(domain="example.com")
print(
    availability.get("domain"),
    availability.get("available"),
    availability.get("registration_price"),
    availability.get("renewal_price"),
)
```

Only submit the exact approved order:

```python
import verbiflow as vf

vf.auth.ensure_logged_in()
order = vf.domains.create_mailbox_order(
    domain="example.com",
    is_new_domain=True,
    registration_years=1,
    mailboxes=[
        {
            "email": "ada@example.com",
            "first_name": "Ada",
            "last_name": "Lovelace",
            "platform": "GOOGLE",
            "sender_id": "sender_...",
        }
    ],
)
print(order["order_group_id"], order["intents"])
```

## Verification

Verify organization ownership, provider connection, mailbox identity, readiness,
capacity, and any explicit approval or purchase receipt.

For paid provisioning, verify the submitted order matches the approved quote.
Confirm domain availability and price facts came from the backend, every order
intent is preserved, and the same order reaches a terminal state. Re-read
`vf.domains.list_purchased()` after provisioning; an accepted order alone is
not proof of a usable domain or mailbox.
For an existing mailbox, verify the provider reports a live connection and the
platform reports usable capacity before campaign handoff.

## Troubleshooting

| Symptom | Likely Cause | What To Do |
| --- | --- | --- |
| OAuth completed but sender is not ready | Provider connection exists but readiness checks remain false | Re-inspect readiness reasons; do not reconnect blindly. |
| Mailbox appears twice | A new sender was created instead of resolving the existing identity | Match normalized email and organization, then use the canonical sender. |
| Capacity is zero despite a healthy connection | Warmup, provider limits, assignment, or policy blocks sending | Inspect the capacity and readiness breakdown. |
| App-password connection fails | Provider settings or credential format is invalid | Keep the secret out of output and return the supported user remediation. |
| Domain search fails | Provider configuration or availability lookup failed | Preserve the provider error. Do not substitute a local price or availability guess. |
| Order validation fails | Domain, mailbox email domains, duplicates, count, names, or platform values are invalid | Correct the exact payload before retrying. Do not reuse unknown or stale rows. |
| Purchase timed out | Submission result is ambiguous | Reconcile the existing order group and intent IDs before retrying. |
| Order succeeded but mailbox is unavailable | Fulfillment is incomplete or failed downstream | Track the same order through fulfillment; do not create a replacement purchase. |

## Related References

| If You Are Doing This | Read Next |
| --- | --- |
| Sender identity, readiness, movement, and capacity | `senders.md` |
| Local login or provider integration readiness | `auth.md` |
| Subscription, credits, checkout, and billing reconciliation | `billing.md` |
| Approval and purchase boundaries | `safety.md` |
| Campaign activation with ready senders | `outbound-campaigns.md` |
| Reading or replying after delivery | `inbox-and-replies.md` |
