/** * `email` namespace — project mailboxes (defaults, send / list / get / raw / * delete) and mailbox webhooks. */ import type { Client } from "../kernel.js"; declare const MESSAGE_DIRECTIONS: readonly ["inbound", "outbound"]; declare const DELIVERY_STATUSES: readonly ["pending", "in_flight", "delivered", "failed_permanent"]; declare const MAILBOX_FOOTER_POLICIES: readonly ["run402_transparency", "none"]; /** Direction filter for `email.list`. Omit to list both sent + received. */ export type MessageDirection = (typeof MESSAGE_DIRECTIONS)[number]; /** Durable webhook delivery lifecycle status. `failed_permanent` is the DLQ. */ export type WebhookDeliveryStatus = (typeof DELIVERY_STATUSES)[number]; /** Outbound footer policy configured on a mailbox. */ export type MailboxFooterPolicy = (typeof MAILBOX_FOOTER_POLICIES)[number]; export interface MailboxRecord { mailbox_id: string; /** Primary address for sends. This is custom-domain address only after DKIM is verified and inbound is enabled. */ address: string; /** Immutable Run402-managed address, usually `@.mail.run402.com`. */ managed_address?: string; slug: string; project_id: string; status: "active" | "suspended" | "deleted"; sends_today: number; unique_recipients: number; created_at: string; updated_at: string; /** True when this mailbox is configured as the project's outbound default. */ is_default_outbound?: boolean; /** True when this mailbox is configured as the auth/session email sender. */ is_auth_sender?: boolean; /** Whether the mailbox can currently send outbound mail. */ can_send?: boolean; /** Present when `can_send` is false, e.g. domain verification or suspension. */ send_blocked_reason?: string | null; /** Run402-managed project mail host vs a project-owned sender domain. Future strings are valid. */ domain_kind?: string; /** Domain portion of `address`. */ address_domain?: string; /** Domain portion of `managed_address`. */ managed_domain?: string; /** True when a custom sender domain is verified and inbound-enabled, so it can be primary. */ custom_domain_ready?: boolean; /** Whether inbound mail can be received at `address`. */ can_receive?: boolean; /** Configured outbound footer policy for this mailbox. */ footer_policy?: MailboxFooterPolicy; /** Effective policy after tier locks/defaults are applied. */ effective_footer_policy?: MailboxFooterPolicy; /** Present when the requested footer policy is locked by tier or platform policy. */ footer_policy_locked_reason?: string | null; } export interface MailboxSettings { default_outbound_mailbox_id: string | null; auth_sender_mailbox_id: string | null; } export interface MailboxNextAction { type?: string; action?: string; method?: string; path?: string; auth?: string; why?: string; command?: string; [key: string]: unknown; } export interface MailboxProviderReadiness { status?: string; provider?: string; reason?: string; [key: string]: unknown; } export interface MailboxSelectionEnvelope { mailbox_settings?: MailboxSettings; provider_readiness?: MailboxProviderReadiness; next_actions?: MailboxNextAction[]; } export type CreateMailboxResult = MailboxRecord & MailboxSelectionEnvelope; export type MailboxInfo = MailboxRecord; export interface MailboxListResult extends MailboxSelectionEnvelope { mailboxes: MailboxRecord[]; } export type MailboxListResponse = MailboxListResult; export interface SetMailboxDefaultsOptions { default_outbound_mailbox_id?: string | null; auth_sender_mailbox_id?: string | null; } export type SetMailboxDefaultsResult = MailboxListResult; export interface UpdateMailboxOptions { /** Target mailbox by slug or `mbx_...` id; omit only on single-mailbox projects. */ mailbox?: MailboxSelector; /** Outbound footer policy. Prototype projects are locked to `run402_transparency`. */ footer_policy?: MailboxFooterPolicy; } export type UpdateMailboxResult = MailboxInfo; export interface DeleteMailboxResult { mailbox_id: string; address: string; managed_address?: string; } export type EmailTemplate = "project_invite" | "magic_link" | "notification"; /** Selects a target mailbox on a project: a mailbox id (`mbx_…`) or a project-scoped local-part slug. */ export type MailboxSelector = string; /** A single binary attachment (raw mode only). `content_base64` is the file's bytes, base64-encoded. */ export interface EmailAttachment { filename: string; content_base64: string; content_type: string; } /** Attachment metadata recorded on a sent message (names/types/sizes — never the bytes). */ export interface EmailAttachmentMeta { filename: string; content_type: string; size_bytes: number; } export interface SendEmailOptions { to: string; template?: EmailTemplate; variables?: Record; subject?: string; html?: string; text?: string; from_name?: string; /** * Binary attachments — RAW MODE ONLY (with `subject` + `html`, not `template`). * At most 5; each ≤ 7 MB and ≤ 7 MB total (decoded). The platform sends a * multipart/mixed MIME when present. */ attachments?: EmailAttachment[]; in_reply_to?: string; /** * Target mailbox (slug or `mbx_…` id). Omit to use the configured * `default_outbound_mailbox_id` when the gateway returns mailbox settings. * Missing or invalid defaults surface typed repair errors. */ mailbox?: MailboxSelector; } /** Options carrying just a mailbox selector, for `get` / `getRaw` / webhook reads. */ export interface MailboxScopedOptions { mailbox?: MailboxSelector; } export interface SendEmailResult { message_id: string; status: string; to: string; template: string | null; subject: string | null; sent_at: string; /** The actual mailbox used for the send, echoed by the gateway. */ mailbox_id?: string; /** The actual From address used for the send, echoed by the gateway. */ from_address?: string; } export interface EmailSummary { id: string; /** Core gateways may expose this spelling on the wire; SDK normalizes `id`. */ message_id?: string; /** "inbound" (received) or "outbound" (sent). */ direction: string; template: string | null; to: string; status: string; created_at: string; /** Present (non-null) when the send carried attachments; names/types/sizes only. */ attachments_meta?: EmailAttachmentMeta[] | null; } export interface EmailDetail { id: string; /** Core gateways may expose this spelling on the wire; SDK normalizes `id`. */ message_id?: string; template: string | null; to: string; status: string; variables?: Record; subject?: string | null; mailbox_id?: string; from_address?: string; delivery_state?: string; provider?: string | null; provider_message_id?: string | null; created_at: string; updated_at?: string; sent_at?: string | null; /** Present (non-null) when the send carried attachments; names/types/sizes only. */ attachments_meta?: EmailAttachmentMeta[] | null; replies?: Array<{ id: string; from: string; body: string; received_at: string; }>; } export interface ListEmailsOptions { limit?: number; after?: string; /** * Filter to one direction. Omit to list BOTH sent (outbound) and received * (inbound) messages — `inbound` is the reconciliation backstop for a lost * `reply_received` webhook. */ direction?: MessageDirection; /** Target mailbox (slug or `mbx_…` id); omit only on single-mailbox projects. */ mailbox?: MailboxSelector; } export interface RawEmailResult { content_type: string; bytes: Uint8Array; } export interface MailboxWebhookSummary { webhook_id: string; url: string; events: string[]; created_at: string; } export interface MailboxWebhooksResult { webhooks: MailboxWebhookSummary[]; } export interface RegisterWebhookOptions { url: string; events: string[]; /** Target mailbox (slug or `mbx_…` id); omit only on single-mailbox projects. */ mailbox?: MailboxSelector; } export interface UpdateWebhookOptions { url?: string; events?: string[]; /** Target mailbox (slug or `mbx_…` id); omit only on single-mailbox projects. */ mailbox?: MailboxSelector; } /** * A single durable webhook delivery row. Delivery is at-least-once: the same * event may arrive more than once, so consumers MUST dedupe on the envelope's * `idempotency_key` (also sent as the `Run402-Webhook-Id` header). */ export interface WebhookDeliverySummary { delivery_id: string; webhook_id: string | null; event_type: string; status: WebhookDeliveryStatus; attempts: number; last_status: number | null; last_error: string | null; next_attempt_at: string | null; delivered_at: string | null; created_at: string; } export interface WebhookDeliveriesResult { deliveries: WebhookDeliverySummary[]; has_more: boolean; next_cursor: string | null; } export interface ListDeliveriesOptions { /** Filter by lifecycle status. `failed_permanent` is the dead-letter queue. */ status?: WebhookDeliveryStatus; limit?: number; after?: string; /** Target mailbox (slug or `mbx_…` id); omit only on single-mailbox projects. */ mailbox?: MailboxSelector; } export interface RedriveDeliveryResult { status: "requeued"; delivery: WebhookDeliverySummary; } export declare class Webhooks { private readonly client; private readonly resolveMailbox; constructor(client: Client, resolveMailbox: (projectId: string, selector?: MailboxSelector) => Promise<{ id: string; serviceKey: string; }>); /** * List durable webhook delivery rows for the mailbox, optionally filtered by * status. `failed_permanent` is the dead-letter queue. Delivery is * at-least-once — consumers MUST dedupe on the envelope `idempotency_key`. */ listDeliveries(projectId: string, opts?: ListDeliveriesOptions): Promise; /** Re-queue a dead-lettered (`failed_permanent`) delivery for another attempt. */ redriveDelivery(projectId: string, deliveryId: string, opts?: MailboxScopedOptions): Promise; register(projectId: string, opts: RegisterWebhookOptions): Promise; list(projectId: string, opts?: MailboxScopedOptions): Promise; get(projectId: string, webhookId: string, opts?: MailboxScopedOptions): Promise; update(projectId: string, webhookId: string, opts: UpdateWebhookOptions): Promise; delete(projectId: string, webhookId: string, opts?: MailboxScopedOptions): Promise; } export declare class Email { private readonly client; readonly webhooks: Webhooks; readonly create: (projectId: string, slug: string) => Promise; readonly status: (projectId: string, mailbox?: MailboxSelector) => Promise; readonly info: (projectId: string, mailbox?: MailboxSelector) => Promise; readonly delete: (projectId: string, mailbox?: MailboxSelector) => Promise; readonly update: (projectId: string, opts: UpdateMailboxOptions) => Promise; constructor(client: Client); /** * Resolve a project mailbox to `{ id, serviceKey }` for an operation. * * - `selector` is a mailbox id (`mbx_…`) → used directly; the gateway 403s * if the id belongs to a different project, so no list call is needed. * - `selector` is a slug → the project's mailboxes are listed and matched. * - `selector` omitted for sends → use the configured * `default_outbound_mailbox_id`. When the gateway returns * `mailbox_settings` and no default is set, throw * `DEFAULT_MAILBOX_REQUIRED`; do not silently pick the first/single row. * - `selector` omitted for reads/webhooks → require a unique mailbox, as * before. This keeps non-send flows from guessing that the outbound * default is also the intended read/webhook target. * * The cached `mailbox_id` is intentionally NOT used to resolve when a * selector is omitted — trusting it would silently target an arbitrary * mailbox on a multi-mailbox project. */ private resolveMailbox; private pickDefaultOutboundMailbox; /** * Choose a mailbox from a project's list given an optional selector. * `selector` matches by exact mailbox id or slug. With no selector: 0 → * "create one first" (404), 1 → that one, 2+ → ambiguity error (409) naming * the available slugs. */ private pickMailbox; /** Best-effort refresh of the single-mailbox convenience cache. */ private cacheMailbox; private listMailboxEnvelope; /** List project mailboxes plus default-role settings and gateway repair hints. */ listMailboxes(projectId: string): Promise; /** * Configure the project's mailbox defaults. Values are mailbox ids * (`mbx_…`) or `null` to clear when the gateway allows clearing. */ setMailboxDefaults(projectId: string, opts: SetMailboxDefaultsOptions): Promise; /** * Update per-mailbox settings. Currently supports the outbound * `footer_policy` field accepted by PATCH /mailboxes/v1/:mailbox_id. */ updateMailbox(projectId: string, opts: UpdateMailboxOptions): Promise; /** * Create a mailbox for a project. * * NOT idempotent. A 409 from the gateway now means `Slug already in use`, * `Address is in cooldown period`, or `Project mailbox limit reached (5)` — * none of which mean "you already own this slug" — so the 409 is surfaced * verbatim rather than silently returning some other existing mailbox. * Callers that want create-or-get should `list`/`getMailbox` explicitly. */ createMailbox(projectId: string, slug: string): Promise; /** Send an email via template or raw (subject + html) mode. */ send(projectId: string, opts: SendEmailOptions): Promise; /** List messages in the project's mailbox. */ list(projectId: string, opts?: ListEmailsOptions): Promise; /** Get a single message by id, including any replies. */ get(projectId: string, messageId: string, opts?: MailboxScopedOptions): Promise; /** * Fetch the raw RFC-822 bytes of an inbound message. Returns `Uint8Array` * so the consumer can decode / store / forward without re-encoding. */ getRaw(projectId: string, messageId: string, opts?: MailboxScopedOptions): Promise; /** * Get a project mailbox's info. With a `selector` (slug or `mbx_…` id), * returns that mailbox; without one, returns the project's only mailbox or * throws an ambiguity error when it has more than one. */ getMailbox(projectId: string, selector?: MailboxSelector): Promise; /** * Delete the project's mailbox. Destructive — drops all messages and * webhook subscriptions. Pass `mailboxId` explicitly to delete a specific * mailbox; otherwise the project's current mailbox is resolved. Returns * the deleted record echoed by the gateway. */ deleteMailbox(projectId: string, selector?: MailboxSelector): Promise; } export {}; //# sourceMappingURL=email.d.ts.map