---
name: sendforai
description: Set up and send transactional or broadcast email with SendForAI (sendforai.com), an email API an agent can sign up for and run without a dashboard or API key. Use when a project needs to send email (sign-in links, receipts, password resets, notifications, newsletters), when asked to add or replace an email provider such as Resend, SendGrid, Postmark or Mailgun with a cheaper one, or when the user mentions SendForAI.
---

# SendForAI

Email at cost for agents: $0 to build, $5 in months that send to the outside world (10,000 emails included), then $0.11 per 1,000. Send-only (no inbound). Full reference: https://sendforai.com/docs.md. Short reference: https://sendforai.com/llms.txt.

Use the CLI (`npx sendforai`, prints JSON, never prompts), the Node SDK (`@sendforai/sdk`), the MCP tools if a `sendforai` MCP server is connected, or plain HTTP with a connection token. All of them return the same JSON.

## Workflow

1. **Get an identity.** No API key exists; the identity is a local Ed25519 key.
   - No domain decided yet: `npx sendforai sandbox`. Works immediately, reaches only the simulator.
   - Domain known: `npx sendforai init example.com`. It prints the DNS TXT record that binds the key to the domain.
   - Keys are saved under `~/.sendforai/` with mode 0600. Never print, commit or paste a private key. In an app, load it from an environment variable or secret store (`SENDFORAI_PRIVATE_KEY`).
2. **Prove it works against the simulator** before touching DNS or money:
   `npx sendforai send --from agent@<identity> --to delivered@simulator.sendforai.com --subject Test --markdown "Hello"`.
   `bounced@` and `complained@simulator.sendforai.com` simulate those outcomes; check them with `npx sendforai events`.
3. **Set up the real domain.**
   - If `VERCEL_TOKEN` or `CLOUDFLARE_API_TOKEN` is in the environment: `npx sendforai dns setup --domain example.com --wait`. It publishes every record and waits. The token stays local.
   - Otherwise run `npx sendforai domains status example.com` (after `init` or `domains add`) and give the user the exact records to add at their DNS host. Do not guess records.
   - From a sandbox identity, the real domain is added by delegation; `dns setup --domain` and `domains add` both handle it and keep the same account.
4. **Check cost before sending for real.** `--dry-run` (API: `"dry_run": true`) returns cost, capacity and lint warnings without sending. Always pass `--max-cost` (API: `max_cost_usd`) on real sends so a mistake cannot overspend.
5. **Hand money to the human.** Sending to anyone outside the account's own domains needs prepaid credit. On `402 balance_required`, run `npx sendforai topup --amount 10` and give the user the `checkout_url`. Do not try to pay it yourself. Raising the monthly budget works the same way (`approval_url`).
6. **Send.** Use `idempotency_key` on anything that might be retried. Read `cost` and `capacity` from the response instead of assuming.
7. **Broadcasts need a person.** `npx sendforai broadcasts create ...` returns an `approval_url`; give it to the user and wait. Only pass `require_approval: false` when the user has explicitly said they approve sends themselves.
8. **Watch results** with `npx sendforai events` (keep the cursor). No webhook endpoint is needed.

## Integrating into an app (Node)

```ts
import { SendForAI } from "@sendforai/sdk";

const sfa = new SendForAI({ domain: process.env.SENDFORAI_DOMAIN!, privateKey: process.env.SENDFORAI_PRIVATE_KEY! });

const res = await sfa.emails.send({
  from: "login@example.com",
  to: user.email,
  subject: "Your sign-in link",
  markdown: `Click to sign in: ${url}`,
  idempotency_key: `signin-${tokenId}`,
  max_cost_usd: 0.01,
});
```

Other languages: mint a connection token (`npx sendforai token --days 90`), store it as a secret, and `POST https://api.sendforai.com/v1/emails` with `Authorization: Bearer <token>`. Tokens expire (90 days at most), so tell the user a renewal is needed, or sign each request instead (recipe in docs.md, "Signing").

## Rules

- Every error has a `fix` field. Read it and do what it says before trying anything else.
- Never send to purchased, scraped or guessed lists. Transactional mail goes to people who triggered it; broadcasts go to contacts who opted in. Policy: https://sendforai.com/acceptable-use.
- Keep transactional and broadcast mail on their own streams (`stream: "broadcast"` for list mail; it adds one-click unsubscribe).
- New domains warm up from a low daily cap. Check `npx sendforai capacity` before promising a volume, and tell the user if a migration has to be gradual.
- When replacing another provider, switch one email type first, behind a flag, and keep the old provider until real sends are confirmed in `events`.
- State plainly what still needs the human: DNS records (unless a DNS token is available), the first top-up, budget increases, and broadcast approval.
