Launch-Free 3 months Builder plan-

Agent Quickstart

Build an AI agent that provisions its own inbox and handles verification emails.

Last updated 2026-04-28

LobsterMail is designed for AI agents that operate without a human in the loop. This guide walks through a complete agent workflow: self-provisioning an inbox, signing up for an external service, and extracting a verification code from the confirmation email.

Token Resolution#

When you call LobsterMail.create(), the SDK resolves your API token in this order:

  1. Explicit — Pass a token directly: LobsterMail.create({ token: 'lm_sk_live_...' })
  2. Environment variableLOBSTERMAIL_TOKEN
  3. Token file~/.lobstermail/token
  4. Auto-signup — If none of the above exist, the SDK signs up for a free account and writes the token to ~/.lobstermail/token.

This means an agent can start from zero with no configuration at all.

Token Persistence#

After auto-signup the token is written to ~/.lobstermail/token. Subsequent calls to LobsterMail.create() will read it from disk, so your agent reuses the same account across runs.

To disable persistence, pass { persistToken: false }:

const lm = await LobsterMail.create({ persistToken: false });

Full Example: Verification Email Flow#

import { LobsterMail } from '@lobsterkit/lobstermail';

const lm = await LobsterMail.create();
const inbox = await lm.createSmartInbox({
  name: 'My Agent',
  org: 'Acme',
});

console.log(`Inbox ready: ${inbox.address}`);

// Your agent signs up for a third-party service using inbox.address
// ... (call the service's signup API here)

// Wait for the verification email (returns instantly when it arrives)
const email = await inbox.waitForEmail({
  filter: { from: 'noreply@service.com' },
  timeout: 60000,
});

// Get the email body with injection-safe boundary markers
const content = email.safeBodyForLLM();
console.log(content);

// Extract the verification code (your LLM or a regex can do this)
const code = content.match(/\d{6}/)?.[0];
console.log(`Verification code: ${code}`);

Key Points#

  • createSmartInbox() generates a meaningful address from your agent's name and handles collisions automatically. Falls back to a random address if all variations are taken.
  • waitForEmail() uses server-side long-polling for near-instant delivery — it returns within milliseconds of the email arriving, not seconds. Returns null if the timeout is reached.
  • filter accepts from (exact match) and subject (substring match for strings, pattern match for RegExp) fields.
  • safeBodyForLLM() returns the email body wrapped in boundary markers that help LLMs distinguish email content from their own instructions. See the Security guide for details.

MCP Server (Zero Code)#

If your agent supports the Model Context Protocol (MCP), you can use the LobsterMail MCP server instead of writing code. Add this to your MCP configuration:

{
  "mcpServers": {
    "lobstermail": {
      "command": "npx",
      "args": ["@lobsterkit/lobstermail-mcp"]
    }
  }
}

This gives your agent tools like create_inbox, wait_for_email, check_inbox, send_email, and more — no SDK code required. The MCP server handles auto-signup and token persistence automatically.

Verifying via X (free Tier 1)#

Tier 0 → Tier 1 (Free Verified) is free and unlocks email send + permanent inboxes. Three-step shortcode flow with no X API key needed (we use Twitter's public oEmbed endpoint):

// 1. Start: server issues a one-time code and a pre-filled compose URL
const challenge = await lm.startXVerification();
console.log(challenge.composeUrl);
// → https://twitter.com/intent/tweet?text=Just%20spun%20up...
// → tweet body: "Just spun up an autonomous email inbox with @lobster_mail 🦞 verify:lm-9f3a-7q8b"

// 2. User opens composeUrl, clicks Tweet (body is pre-filled)

// 3. User copies the URL of the new tweet and submits it
const result = await lm.completeXVerification(
  'https://x.com/myhandle/status/1234567890',
);
console.log(result.tier); // 1 — Free Verified
console.log(result.xHandle); // 'myhandle' (taken from oEmbed, not trusted from caller)

Or via HTTP: POST /v1/verify/x/startPOST /v1/verify/x/complete {tweetUrl}. Poll status anytime with GET /v1/verify/x/status.

The X account must be public (the oEmbed endpoint 404s on protected/private accounts). The verified handle comes back from X's own oEmbed response, so callers can't claim a handle they don't own.

The tweet is public on purpose — every verify creates an organic post about LobsterMail. Users can edit the body before posting; the only constraint is the shortcode and @lobster_mail mention must remain.

Billing & Early-Bird Promotion#

New accounts start at the Anonymous tier (free, receive-only, 30-day inbox expiry). To unlock sending and higher limits without paying, verify via X. To go beyond Tier 1, subscribe via Stripe.

If a Tier 0 inbox does hit its 30-day limit, the address stays reserved to your account indefinitely — but reactivation requires upgrading to Tier 1+ first (verify your X account or add a card via Stripe Checkout).

You'll know this happened in two ways:

  • Trying to recreate the same address returns 409 inbox_expired_reclaimable with inboxId, expiredAt, and a reactivateUrl in the response body — that's "you already own this address, just reactivate it" (not "address taken").
  • Trying to send from the address returns 403 inbox_expired_reclaimable with the same fields.

After upgrading, reclaim it permanently:

const inbox = await lm.reactivateInbox('ibx_...');
console.log(inbox.expiresAt); // null — permanent

Or via HTTP: POST /v1/inboxes/:id/reactivate. Tier 0 callers get 403 insufficient_tier — the upgrade is the gate. Only inboxes deactivated by the expiry worker are eligible; inboxes you soft-deleted yourself must be recreated.

The first 1,000 accounts to subscribe to the Builder tier ($9/mo) get a 90-day free trial. Your card is collected during checkout but not charged until the trial ends. After 90 days the subscription renews at $9/mo — cancel anytime via the billing portal.

To check eligibility and claim the promotion:

  1. GET /v1/account — check the promo field for "status": "available"
  2. POST /v1/billing/checkout with {"tier": 2} — returns a Stripe Checkout URL
  3. Complete the checkout (card required, not charged during trial)
  4. GET /v1/accountpromo.status is now "claimed", tier is "builder"

Note: The promotion requires completing the Stripe Checkout session. Simply calling the checkout endpoint is not enough — the returned URL must be opened and payment setup completed to activate the trial.

Environment Variables#

VariablePurpose
LOBSTERMAIL_TOKENAPI token (overrides file-based token)
LOBSTERMAIL_BASE_URLCustom API base URL (default: https://api.lobstermail.ai)

Next Steps#