Alpha Mail — Integrations & API

Drive Alpha Mail programmatically: a public REST API, an MCP server for agents, and an iMessage bridge so founders can brainstorm + ship by text.

Base URL: https://email.gigacorp.org


1. API keys

Mint a key at Settings → API keys. The secret (am_live_…) is shown once; only a SHA-256 hash is stored. Authenticate every API call with:

Authorization: Bearer am_live_xxx

Keys are tenant-scoped — an agent sees only that manager's data, exactly like a logged-in user. Revoke anytime.


2. Public API (/api/v1)

All endpoints are API-key authed and return JSON.

Method & pathPurpose
POST /api/v1/campaignsCreate a campaign from a goal (or explicit fields). Async — returns { jobId }; poll sequences.
GET /api/v1/sequencesList sequences (newest first).
GET /api/v1/sequences/:idOne sequence with full steps.
GET /api/v1/sequences/:id/statsLive opens/clicks/replies/bounces per pushed campaign.
POST /api/v1/sequences/:id/pushIrreversible — push to lemlist/smartlead, optional listId leads.
GET /api/v1/repliesInbound replies (+?sequenceId=) with sentiment + AI draft.

Example — create from a goal:

curl -X POST https://email.gigacorp.org/api/v1/campaigns \
  -H "Authorization: Bearer am_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"goal":"book demos with heads of ops at Series-B fintechs in DACH"}'
# → { "jobId": "...", "status": "generating", "pollUrl": "/api/v1/sequences" }

Status codes: 401 bad key · 402 monthly spend cap · 409 setup incomplete · 412 sender not connected · 429 rate limited · 502 upstream failed.

Generation is asynchronous (research → write). Poll GET /api/v1/sequences until the new sequence appears, then GET /api/v1/sequences/:id for the steps.


3. MCP server

mcp/ is a standalone Model Context Protocol server that wraps /api/v1 as tools, so Claude Desktop or any MCP client can drive Alpha Mail.

Setup:

cd mcp && npm install
ALPHA_MAIL_API_KEY=am_live_xxx node index.mjs

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "alpha-mail": {
      "command": "node",
      "args": ["/absolute/path/to/mcp/index.mjs"],
      "env": { "ALPHA_MAIL_API_KEY": "am_live_xxx" }
    }
  }
}

Tools: create_campaign, list_sequences, get_sequence, list_replies, get_performance, push_sequence (push is gated as irreversible). See mcp/README.md.


4. iMessage bridge (Claw Messenger)

Founders text a single Alpha Mail iMessage number; an agent brainstorms and ships, confirming before any send. One number serves all customers — we route by the sender's phone.

How routing works

  • Each customer links their phone at Settings → API keys → Text Alpha Mail (stored as Manager.imessagePhone, unique).
  • Inbound texts carry the sender's number; we map it to that manager and scope everything to their account. Unlinked numbers get a "not linked" reply.
  • You need only ONE Claw Messenger subscription/number for all customers. Their messages share that plan's monthly quota — scale the one plan, not the number of subscriptions. (Per-brand numbers are a future option for white-label.)

Go-live config (one time)

  1. Vercel env vars (Production):
    • CLAWMESSENGER_API_KEY = your cm_live_…
    • IMESSAGE_WEBHOOK_TOKEN = a random secret (used to authenticate inbound) — or CLAWMESSENGER_WEBHOOK_SECRET for HMAC verification.
  2. Claw Messenger → set the inbound webhook to: https://email.gigacorp.org/api/imessage?token=YOUR_TOKEN
  3. Each founder links their number in the dashboard.

Behaviour

  • create_campaign, reads, and brainstorming are free.
  • Pushing to a sender (real outreach + spend) is staged, then only fires when the founder replies SEND — resolved deterministically, never by the model.
  • Generation is async: the agent replies "drafting…"; ask "is it ready?" to check.

Note on transport

Claw documents both a webhook and a WebSocket inbound mode. This bridge uses the webhook mode (serverless-friendly). If your Claw plan is WebSocket-only, a small always-on relay would forward socket events to /api/imessage.


Security

  • Secrets (am_live_…, cm_live_…, sender keys) live only in env vars / hashed columns — never in code or git. Rotate any key exposed in chat/logs.
  • Every programmatic call is tenant-scoped through the same data-access layer as the UI; an API key cannot widen its scope.
  • Irreversible actions (pushing live outreach) are explicit, separate calls — generation and reads never send anything.