# Send - Email marketing on autopilot — Full documentation (for AI) > Everything about Send in one file: overview, agent skill, full help, full API docs, and the REST endpoint table. Short version: https://send.ad/llms.txt · Machine schema: https://send.ad/api/v1/openapi.json · Sitemap: https://send.ad/sitemap.xml ## 1. Overview (llms.txt) # Send > Autopilot email marketing for the AI era: give a one-line brief → AI writes copy and designs the email → you approve once (or let it run on autopilot) → it sends, measures, and turns results into learning notes that improve the next campaign. Built for AI agents (CLI · MCP · API). Unlimited contacts; pay only per email sent ($0.002/email = $2.00 per 1,000). 1,000 free sends on signup. Compliance is automatic — workspace region `kr` (Korean 정보통신망법): "(광고)" subject prefix, legal footer with sender identity + unsubscribe, night-time (21:00–08:00 KST) consent gate; region `global` (CAN-SPAM): sender identity + physical address + unsubscribe footer. Both: one-click List-Unsubscribe headers, suppression of unsubscribes/bounces/complaints. ## Use it from an agent - REST: Authorization: Bearer sd_live_… → https://send.ad/api/v1/* (OpenAPI: https://send.ad/api/v1/openapi.json) - CLI: npx send.ad login --key sd_live_… ; npx send.ad ai "brief" --list --send - MCP: claude mcp add sendad -e SEND_API_KEY=sd_live_… -- npx -y send.ad mcp - Agent skill: https://send.ad/skill.md ## The one call that matters POST /api/v1/ai/campaign { "brief": "추석 프로모션 20% 할인, 9/25까지", "list_names": ["고객"], "send": false } → creates a campaign draft (subjects, preheader, block design) using the workspace brand profile; returns preview_url + estimate. Set send:true to send immediately, or scheduled_at to schedule. Then POST /api/v1/campaigns/{id}/send. ## Loop brief → POST /api/v1/ai/campaign (draft, status: pending approval) → user approves → POST /api/v1/campaigns/{id}/send → GET /{id}/report → learning notes feed the next brief. Autopilot modes: manual / approve (default) / auto. Migration from Mailchimp, SendGrid, Stibee: POST /api/v1/contacts/import (+ /api/v1/suppressions/import for unsubscribes). ## Core resources - Contacts/Lists/Tags/Segments/Suppressions: /api/v1/contacts (upsert by email), /api/v1/contacts/bulk, /api/v1/contacts/import (CSV, Mailchimp export recognized), /api/v1/lists, /api/v1/tags, /api/v1/segments, /api/v1/suppressions - Templates & designs: /api/v1/templates, POST /api/v1/designs/render (Design JSON → HTML). Design = { version:1, settings, blocks:[header|heading|text|image|button|divider|spacer|columns|social|footer|html|product] }. Merge tags {{first_name|고객}} {{name}} {{email}} {{attr.key}} {{unsubscribe_url}} {{view_url}}. - Campaigns: /api/v1/campaigns (draft) → /{id}/estimate → /{id}/send | /{id}/test → /{id}/report, /{id}/recipients - Single send: POST /api/v1/send { to, subject, html|design|text } - Sending domains: /api/v1/domains (returns CNAME records to add; then /{id}/verify) - Billing: GET /api/v1/billing, POST /api/v1/billing/topup, PUT /api/v1/billing/auto-recharge ## Docs - Full text in one file (overview + skill + help + API docs + endpoint table): https://send.ad/llms-full.txt - Sitemap: https://send.ad/sitemap.xml · robots: https://send.ad/robots.txt - https://send.ad/docs (guides, code samples · ko/en) - https://send.ad/help (product help · ko/en) - https://send.ad/terms · https://send.ad/privacy ## 2. Agent skill (skill.md) --- name: send description: Autopilot email marketing through Send — give it a one-line brief and it writes copy + design, queues the campaign for approval (or sends automatically), sends, measures, and learns from results for the next campaign. Pay-per-send, unlimited contacts, Korean ad-mail compliance built in. Use when the user asks to email a list, run a newsletter/promotion, migrate subscribers from Mailchimp/SendGrid/Stibee, create an email template, or check campaign results. --- # Send — promotional email for AI agents Send's loop: **brief → AI writes subject/body/design → approval (or autopilot) → send → measure → learning notes improve the next campaign**. Autopilot mode per campaign: `manual` (edit yourself), `approve` (default: AI drafts, human approves once), `auto` (send without review). Send bills only per email sent ($0.002/email); contacts are free. Compliance is automatic per workspace region — `kr` (Korean 정보통신망법): "(광고)" subject prefix, legal footer (company, address, contact, unsubscribe), and 21:00–08:00 KST scheduling is blocked unless the workspace confirmed night consent; `global` (CAN-SPAM): sender identity, physical address, and unsubscribe link in the footer. Both regions get one-click List-Unsubscribe headers and suppression of unsubscribed/bounced/complained addresses. ## Auth - API key from Settings → API 키 (`sd_live_…`). Set `SEND_API_KEY` (and optionally `SEND_BASE_URL`, default https://send.ad). - REST: `Authorization: Bearer $SEND_API_KEY`. CLI: `npx send.ad …`. MCP: `claude mcp add sendad -e SEND_API_KEY=… -- npx -y send.ad mcp`. - Check: `npx send.ad whoami` or `GET https://send.ad/api/v1/me`. ## Approval + autopilot commands - `npx send.ad approvals` → awaiting campaigns; `npx send.ad approve [--at ISO]` sends (or schedules); `npx send.ad reject --note "…"` returns it to draft. REST: `GET /api/v1/approvals`, `POST /api/v1/campaigns/{id}/approve|reject`. The approval mail also carries a no-login one-click page `/a/{token}`. - `npx send.ad autopilot mode [manual|approve|auto]` (REST `GET/PUT /api/v1/autopilot/settings`, guardrails: max_sends_per_day, quiet_hours, min_balance_krw, require_approval_over_recipients). - Recurring campaigns: `npx send.ad autopilot create --name 주간뉴스 --brief "{{date}} 이번 주 소식: {{recent_posts}}" --cadence weekly --dow 2 --hour 10 --list 고객 --rss `; `autopilot list|run |pause |resume ` (REST `/api/v1/autopilot/plans`). - `npx send.ad learning` (REST `GET /api/v1/learning`) — what worked (subjects, length, send hours); Send injects it into the next AI campaign automatically. `POST /api/v1/learning/next-suggestions?campaign_id=` gives concrete next-campaign suggestions. - `sendad ai … --send` in approve mode stops at `awaiting_approval` and prints `approval_url` (exit 0) — do not poll; ask the user to approve, or call `approve` if they already said yes. ## The 5 things you will actually do 1. **Import subscribers**: `npx send.ad contacts import ./subscribers.csv --list 고객` (Mailchimp export CSV works as-is) or `POST /api/v1/contacts/bulk`. 2. **Create + send a campaign from a brief** (the one-liner): `npx send.ad ai "추석 프로모션 20% 할인, 9/25까지, 무료배송" --list 고객` → prints subjects + preview URL + cost estimate. Add `--send` to send now, or `--at 2026-09-20T10:00:00+09:00` to schedule. REST: `POST /api/v1/ai/campaign { brief, list_names, send }`. 3. **Send one email**: `npx send.ad send --to a@b.com --subject "…" --html "

…

"` or `POST /api/v1/send`. 4. **Check results**: `npx send.ad campaigns report ` or `GET /api/v1/campaigns/{id}/report` (sent/delivered/opens/clicks/bounces/unsubscribes, per-link clicks). 5. **Check balance before big sends**: `npx send.ad balance` or `GET /api/v1/campaigns/{id}/estimate` (returns recipients, cost_krw, balance_krw, ok). Top up: `POST /api/v1/billing/topup { packId: "t30k" }` (requires a registered card). ## Workflow guidance - Default to the approval flow: create with `send:false` → the campaign appears in the user's 승인 대기 queue → share `preview_url` → after the user approves, `POST /api/v1/campaigns/{id}/send`. Use `send:true` only when the user explicitly asked for autopilot/no review. - After a campaign finishes, read `GET /api/v1/campaigns/{id}/report`; Send stores learning notes from results and applies them to the next `/ai/campaign` call automatically — you can mention what changed (subject style, length, send time). - Migrating from Mailchimp/SendGrid/Stibee: upload their export CSV via `POST /api/v1/contacts/import` (columns auto-mapped) and the unsubscribed export via `POST /api/v1/suppressions/import`. - Before the first send, make sure the workspace sender profile is complete (company name, address, phone/email): `GET /api/v1/workspace` → `sender_profile_complete`. If false, ask the user for those and `PUT /api/v1/workspace`. - Fill the **brand profile** (tone, products with URLs/prices, links) once via `PUT /api/v1/workspace { brand_profile }` — AI output quality depends on it. - Prefer `send:false` first, share `preview_url`, then `POST /api/v1/campaigns/{id}/send` after the user confirms — unless the user explicitly asked to send without review. - Never upload lists without consent; never remove addresses from the suppression list on the user's behalf without explicit instruction. - Use `--json` on CLI commands for machine-readable output. ## Design JSON (when composing templates yourself) `{ "version": 1, "settings": { "brandColor": "#0f7b6c" }, "blocks": [ { "id": "h1", "type": "heading", "text": "{{first_name|고객}}님, 추석 선물 20% 할인" }, { "id": "t1", "type": "text", "html": "

9월 25일까지…

" }, { "id": "b1", "type": "button", "text": "쿠폰 받기", "href": "https://…" } ] }` Render/preview: `POST /api/v1/designs/render { design }`. Full schema: https://send.ad/api/v1/openapi.json (components.schemas.Design). ## Errors `{ error, code }`. Notable codes: `insufficient_balance` (402 — top up), `admin_only` (403), `bad_api_key` (401), `sender_profile_incomplete` (400 — fill workspace), `night_consent_required` (400 — schedule outside 21:00–08:00 KST or set night_consent). ## 3. Help — full text (https://send.ad/help) ### Get started — Sign in · Sender details · First campaign https://send.ad/help/start Send is an email marketing tool where you just say what you want to send — AI writes the copy, builds the design, and once you approve, it handles the send and the results. Those results become material for the next campaign, so it gets better the more you send. You only pay for emails sent. Fill in three things and you're off. #### 1. Sign in Sign in with Google or a 6-digit email code. Teammates on your company email domain (e.g. @company.com) are grouped into the same workspace automatically, and the first person becomes the owner. Sign up and you get $2 (1,000 emails) free. _Figure: Sign in — continue with Google, or get a 6-digit code by email. (https://send.ad/help/start-1.jpg)_ #### 2. Sender details Fill in your company name, address, and contact info under Settings → Workspace. These are legally required in the footer of marketing email, so sending is blocked while they're empty. Add your logo and brand color and they'll show up in templates too. _Figure: Settings → Workspace — company name, address, contact, brand color (https://send.ad/help/start-2.jpg)_ #### 3. Brand profile In Settings → Brand profile, enter your tone, target audience, signature, words to avoid, products (name, description, link, price), and frequently used links. AI reads this every time it writes a campaign — following your tone, using product links and prices exactly as written, ending the body with your signature, and never using the words you've flagged. The editor's rewrite and subject line suggestions, autopilot plans, and sendad ai in the CLI all read the same profile. _Figure: Settings → Brand profile — tone, key customers, signature, words to avoid, products (https://send.ad/help/start-3.jpg)_ #### 4. First campaign — one-line brief, one approval Write a single line in "What should we send?" on Home (e.g. Holiday promo, 20% off, through 11/25) and you'll get 3 subject line options, body copy, and a design, queued up as awaiting approval. Check the preview, approve, and the send and results tracking run on their own. Want changes? Tweak it in the editor, then approve. _Figure: Home — brief field, 1 campaign awaiting approval, this month's numbers, recent campaigns and the autopilot plan (https://send.ad/help/start-4.jpg)_ #### 5. Move over from another tool If you were using Mailchimp, SendGrid, or Stibee, go to Subscribers → Import and upload your export CSV. We'll automatically match column names and import your unsubscribe list too. _Figure: Subscribers → Import — Pick the tool you were using and upload your CSV. (https://send.ad/help/start-5.jpg)_ **Tips** - Hover the question mark (?) anywhere on screen for an explanation of that field. - Invite teammates under Settings → Team. The number of teammates doesn't affect your bill. --- ### Subscribers — Contacts · Lists · Tags · Segments · Import https://send.ad/help/audience A contact is one email address, once per workspace. Organize with lists (folders) and tags, and use segments for conditions. Your bill is the same no matter how many contacts you have. #### Import from CSV or Excel (Mailchimp · monday.com · anywhere) Drag a file into Audience → Import CSV (CSV or Excel .xlsx) and Send reads the column names to automatically match email, name, company, job title, phone, and more. Even with title rows or group rows mixed in, like a monday.com export, Send can find the header row. You can fix the auto-matched results in the "map to" table for each column, and use attributes like company or job title in your email body as {{attr.company}}. Duplicates are updated, and addresses on the suppression list are skipped. _Figure: Import subscribers — column names are mapped automatically per tool. (https://send.ad/help/start-5.jpg)_ #### Suppression list Unsubscribed, bounced, and spam-reported addresses go on the suppression list automatically and are excluded from every send. Export "Unsubscribed" from Mailchimp and import it into the suppression list so you never email someone who opted out. _Figure: Subscribers → Suppression list — View by reason, add manually, or import via CSV. (https://send.ad/help/audience-2.jpg)_ #### Lists · tags · segments A list is a folder people go into, like "Newsletter subscribers" or "Paying customers." A tag is a label you attach to a person. A segment is a saved condition like "in list A and tagged VIP." Campaign recipients are built from these three. _Figure: Subscribers → Segments — Save conditions like "Customer list + VIP tag" and pick them directly in your campaigns. (https://send.ad/help/audience-3.jpg)_ #### Signup forms Create a form and you'll get a hosted page URL plus embed code for your website. Turn on double opt-in and subscribers have to click a confirmation email before they're confirmed (great for proof of consent). _Figure: Signup form — pick fields, copy, and colors, and the preview and embed code appear on the right. (https://send.ad/help/audience-4.jpg)_ --- ### Templates & editor — Block editing · Merge tags · Starters · AI rewrite https://send.ad/help/templates Build your design from blocks (header, heading, body, image, button, product, two-column, divider, social, footer, HTML). Edit text right on the canvas, and change colors, sizes, and links in the right panel. Changes save automatically. #### Starter templates Start from sixteen: newsletter, promotion, launch, event, welcome and win-back, plus testimonials, report, survey and pricing. Your brand color and logo drop in automatically, and 10 themes in the editor change the mood at once. Save as your own template and pick it for the next campaign. _Figure: Templates → Starters — all sixteen rendered in your brand color. (https://send.ad/help/templates-1.jpg)_ #### Block editor Click a block on the left to insert it below the selected block, or drag it exactly where you want. Edit text directly on the canvas, and change image URLs, links, alignment, and background color in the right panel. Merge tags like {{first_name}} {{name}} {{email}} {{attr.property}} work in the body and subject and change per recipient; set a default like {{first_name|there}}. _Figure: Editor — blocks on the left · canvas in the middle · properties panel on the right. Rename it and it saves automatically. (https://send.ad/help/templates-2.jpg)_ #### Polish with AI Select a block with text and "Rewrite this block" appears above it. Give an instruction (shorter · more formal · lead with the benefit) and only that block is rewritten. "Create with AI" rebuilds the whole email from a one- or two-line brief (you can undo it). _Figure: Select a block and hit "Rewrite this block" — one line of instruction fixes just that block. (https://send.ad/help/templates-3.jpg)_ #### Mobile view and test sends Check it with the desktop/mobile toggle, and use a test send to see the real rendering in your own inbox. Test sends are billed at the per-email rate too ($0.002). _Figure: Mobile view — see exactly how it looks at 390px wide. (https://send.ad/help/templates-4.jpg)_ --- ### Campaigns — Recipients · Sender · Schedule · Reports https://send.ad/help/campaigns A campaign is "this email, to these people, at this time." It's organized into four steps: Settings → Recipients → Content → Review & send. When sending starts, recipient count × unit price is reserved from your balance, and any unsent portion is refunded once it's done. #### Recipients Pick lists, tags, and segments, and add exclusion lists. Only people who are subscribed and not on the suppression list become actual recipients. "Pre-send check" in the Review step shows the recipient count, cost, and whether your balance covers it. _Figure: 2 Recipients — Check lists, select tags/segments, and set exclusion lists. Unsubscribed, bounced, and suppressed addresses are always excluded automatically. (https://send.ad/help/campaigns-1.jpg)_ #### Sender Use an address on a verified domain (Settings → Sending domains & providers), or, if you don't have one, mail goes out from a platform address and replies come to your company inbox. Write a sender name people will recognize, like "Acme Marketing Team." _Figure: Settings → Sending domains & providers — add your company domain and register just a few records as the screen instructs. (https://send.ad/help/campaigns-2b.jpg)_ #### (Ad) · Scheduling For promotional mail, keep (Ad) on (it's on by default). Scheduling between 9pm and 8am is only possible if you've checked "We have night-time consent." You can also turn it on for everything in workspace settings. _Figure: 4 Review & send → When to send — send now or schedule, with the night-time consent checkbox. (https://send.ad/help/campaigns-3.jpg)_ #### When should we send — now · scheduled · best time to read · gradually At the review step, choose "Send now," "Schedule," or "At the best time to read." "At the best time to read" learns when these subscribers opened and clicked the most over the last 90 days and schedules the send for that time (or 10am Tue/Wed/Thu if there isn't enough history). Choose "Send gradually" to spread even tens of thousands of emails evenly over 30 minutes to 8 hours. Send handles the sending pace automatically, ramping up gradually for newly verified company domains over the first 2 weeks to reduce spam-folder placement. Use "Copy final review link" to show teammates exactly what recipients will see, no sign-in required. _Figure: Review & send — choose when to send and share the final review link. (https://send.ad/help/campaigns-4.jpg)_ #### Reports See counts for sent, delivered, opened, clicked, bounced, reported, and unsubscribed, plus clicks by link and an activity graph over time. In "Who read it, where, and how," see device, email app, and country breakdowns, what time of day people read it, how many times each person opened it, and who read it the most. Filter the recipient table by opened, unopened, or clicked, sort by most opens, and download it as a CSV. Gmail and Apple Mail may prefetch images on a recipient's behalf, which can hide their device and location (shown as proxy open). _Figure: A completed campaign — the numbers, response by hour, clicks by link, and per-recipient status. (https://send.ad/help/campaigns-4.jpg)_ --- ### Create with AI — One-line brief → subject, body, design https://send.ad/help/ai Write a one-line brief (what · to whom · by when · the offer) and Send reads your brand profile to generate 3 subject options, a preheader, and a design, then queues it as a campaign awaiting approval. Approve it and the send and performance tracking run on autopilot, with results saved as learning memos that feed into the next campaign. AI usage is free. #### A good brief Include the offer, deadline, and audience — like "20% off holiday gift sets, through 11/25, free shipping, for past customers." Links and prices come from the products in your brand profile, so fill that in first for accuracy. _Figure: Create campaign with AI — enter a brief and examples, pick a tone and a list, then hit "Create draft." (https://send.ad/help/ai-1.jpg)_ #### Awaiting approval → Preview → Approve AI-generated campaigns land in "Awaiting approval." Check the subject, sender, recipients, and cost, view the real email in the preview on the right, then hit "Approve and send." Want changes? Just edit it and then approve. Not a single email goes out before approval. _Figure: A campaign awaiting approval — the pre-send check and a real preview, side by side. (https://send.ad/help/cover-ai.jpg)_ #### Same result everywhere "Create campaign with AI" in the app, sendad ai in the CLI, the send_ai_campaign MCP tool, and POST /api/v1/ai/campaign in REST all use the same generator. #### Autopilot modes — Manual · Approval · Auto Choose in Autopilot → Modes & guardrails. In Manual, AI only drafts and a person sends. In Approval, it queues for approval and emails the admin (default). In Auto, it sends without approval as long as it stays inside your guardrails (daily limit, quiet hours, minimum balance, recipient cap). The CLI's --send is the same as Auto mode. _Figure: Autopilot → Modes & guardrails — the three modes and the safeguards for Auto. (https://send.ad/help/ai-3.jpg)_ #### Learning memos — better with every send When a campaign ends, its open, click, and unsubscribe results are summarized as a learning memo. Which subjects got opened, which lengths got clicked, and which times got the best response all feed into the subject, length, and send-time suggestions for your next brief. You can view and edit memos from Home. _Figure: Home → Learning memos — rules pulled from your results, stacked up as short sentences. (https://send.ad/help/ai-4.jpg)_ --- ### CLI · MCP · API — npx send.ad · claude mcp add · REST https://send.ad/help/cli Everything in Send is available over the REST API, and the CLI and MCP server are thin tools built on top of it. One API key works for all three. #### API keys Create one in Settings → API keys. A key is shown only once, when you create it. Make a separate key per agent so if one leaks, you only have to revoke that one. _Figure: Settings → API keys — create keys per use case, see when each was last used, and revoke them. (https://send.ad/help/cli-1.jpg)_ #### CLI Save your key with npx send.ad login --key sd_live_…, then run things like sendad whoami · sendad contacts import file.csv --list customers · sendad ai "brief" --list customers --send · sendad campaigns report . Add --json for machine-readable output. _Figure: API docs → CLI — every command and option. (https://send.ad/help/cli-2.jpg)_ #### MCP (Claude Code and more) One line — claude mcp add sendad -e SEND_API_KEY=sd_live_… -- npx -y send.ad mcp — and Claude Code picks up the send_* tools. Say "send the holiday promo to the customers list" and the agent picks the right tool. _Figure: API docs → MCP server — how to register with Claude Code, Cursor, and the tool list. (https://send.ad/help/cli-3.jpg)_ #### REST Call /api/v1/* with an Authorization: Bearer sd_live_… header. The OpenAPI spec lives at /api/v1/openapi.json, and AI-readable summaries are at /llms.txt and /skill.md. --- ### Pricing and balance — $2 per 1,000 emails · Top up · Auto top-up · Refunds https://send.ad/help/billing Pricing is one thing: emails sent × unit price. Contacts, teammates, and AI generation are free. Top up your balance first, and it draws down as you send. #### Top up Add a card (Toss Payments) and top up from $10. The full top-up amount goes into your balance, and your card is charged that amount plus 10% VAT. Receipts are available in your payment history. _Figure: Pricing — balance, payment card, and top-up packs. Once your card is added, tap a pack to top up. (https://send.ad/help/billing-1.jpg)_ #### Reservations and settlement When a campaign starts, recipients × unit price is reserved, and each batch settles as it goes out. Emails rejected by the provider aren't charged, and any unused reservation is returned when the campaign finishes. You can review it line by line in the ledger. _Figure: Ledger — top-ups, send reservations, send settlements, and refunds each get their own line. (https://send.ad/help/billing-2.jpg)_ #### Auto top-up When your balance drops below the threshold, the amount you set is charged automatically. This keeps a big campaign from stalling on an empty balance. After 5 consecutive failed payments, auto top-up turns off. _Figure: Auto top-up — set a threshold and a top-up amount, and your saved card is charged. (https://send.ad/help/billing-3.jpg)_ #### Refund Unused paid balance can be refunded to your payment method — just contact us. Free balance and emails already sent aren't refundable. --- ### Ad mail compliance — (Ad) · Footer · Night-time · Unsubscribe · Consent https://send.ad/help/compliance Send automatically handles what Article 50 of Korea's Network Act requires. One thing stays on you: only sending to people who opted in. #### What Send does automatically (Ad) prefix in the subject line, company name, address, contact, and unsubscribe link at the bottom of the email, one-click unsubscribe in mail apps, automatic exclusion of unsubscribed, bounced, and complaint addresses, and blocked night-time scheduling (until you confirm consent). _Figure: The bottom of the email as it actually goes out — company details, unsubscribe, and view in browser are added automatically. (https://send.ad/help/compliance-1.jpg)_ #### What you need to handle Only send to people who gave explicit prior consent (opt-in). Don't upload purchased lists or lists with an unclear source. For night-time sends, get separate consent before checking the box. Reflect unsubscribe requests immediately (Send does this automatically). _Figure: Scheduling between 9pm and 8am requires checking "I have night-time consent." (https://send.ad/help/campaigns-3.jpg)_ #### Domain reputation Start a new domain at a low send rate per minute and ramp up over 2–3 weeks. Going past a 2% bounce rate or 0.1% complaint rate can get you blocked by mail providers. Check bounces and complaints in Reports after every campaign. _Figure: Reports — sends, opens, clicks, bounces, and complaints by period, at a glance. (https://send.ad/help/reports-1.jpg)_ **Tips** - If you need proof of consent, use a double opt-in form. - Sending marketing email from a dedicated subdomain like news.yourdomain.com keeps it separate from your business mail reputation. ## 4. API · CLI · MCP docs — full text (https://send.ad/docs) ### Quick start (for AI agents) — Create a key → contacts → AI campaign → send https://send.ad/docs/quickstart Everything you can do in the UI **REST API·CLI·MCP** works too. All three use the same API key, so AI agents like Claude Code can call Send as a tool. You only pay for emails sent ($0.002 each), and contacts are unlimited. ### 1. API key Create one in Settings → API keys. The key is shown only once, at creation. Pass it as an environment variable or save it in the CLI. ``` export SEND_API_KEY=sd_live_… npx send.ad login --key $SEND_API_KEY # saved to ~/.sendad/config.json npx send.ad whoami ``` ### 2. Sender details and brand profile Before your first send, you need a company name, address, and phone number (the legal footer). Your brand profile (tone, products, links) is the raw material the AI works with. curl ```bash curl -X PUT https://send.ad/api/v1/workspace -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" \\ -d '{"company_name":"Hanbit Inc.","address":"123 Market St, San Francisco, CA …","phone":"415-000-0000","brand_profile":{"tone":"friendly and polite","products":[{"name":"Hanbit Gift Set","url":"https://hanbit.kr/gift","price":"$59"}]}}' ``` ### 3. Add contacts curl ```bash npx send.ad contacts import ./mailchimp-export.csv --list customers # or curl -X POST https://send.ad/api/v1/contacts/bulk -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" \\ -d '{"contacts":[{"email":"kim@example.com","first_name":"Minsu","tags":["VIP"]}],"list_ids":[""]}' ``` ### 4. A campaign from a one-line brief curl ```bash npx send.ad ai "20% off holiday gift sets, through 11/25, free shipping" --list customers # → 3 subject lines · preview URL · cost estimate. Add --send to send right away, or --at to schedule. ``` Node.js ```js const r = await fetch('https://send.ad/api/v1/ai/campaign', { method: 'POST', headers: { authorization: \`Bearer \${process.env.SEND_API_KEY}\`, 'content-type': 'application/json' }, body: JSON.stringify({ brief: '20% off holiday gift sets, through 11/25', list_names: ['customers'], send: false }) }) const { campaign, preview_url, estimate } = await r.json() // send after reviewing await fetch(\`https://send.ad/api/v1/campaigns/\${campaign.id}/send\`, { method: 'POST', headers: { authorization: \`Bearer \${process.env.SEND_API_KEY}\` } }) ``` Python ```py import os, requests H = {"Authorization": f"Bearer {os.environ['SEND_API_KEY']}"} r = requests.post("https://send.ad/api/v1/ai/campaign", headers=H, json={"brief": "20% off holiday gift sets, through 11/25", "list_names": ["customers"], "send": False}).json() print(r["preview_url"], r["estimate"]) requests.post(f"https://send.ad/api/v1/campaigns/{r['campaign']['id']}/send", headers=H) ``` ### 5. Results ``` npx send.ad campaigns report curl https://send.ad/api/v1/campaigns//report -H "Authorization: Bearer $SEND_API_KEY" ``` OpenAPI spec: [/api/v1/openapi.json](/api/v1/openapi.json) · AI-readable summary: [/llms.txt](/llms.txt) · Agent skills: [/skill.md](/skill.md) --- ### Auth · errors · conventions — Bearer key · error format · pagination https://send.ad/docs/auth ### Verification All `/api/v1/*` is `Authorization: Bearer sd_live_…` authenticate with a header. API keys are scoped to a workspace and act with admin permissions. The web app uses the same API with session cookies. ``` curl https://send.ad/api/v1/me -H "Authorization: Bearer $SEND_API_KEY" ``` ### Error Failures return `{ "error": "human-readable message", "code": "machine_code" }` . Codes you'll see often: | code | HTTP | Meaning | | --- | --- | --- | | bad_api_key | 401 | Key is missing or revoked | | admin_only | 403 | Admin-only action (sending · settings · billing) | | insufficient_balance | 402 | Insufficient balance — /api/v1/billing/topup | | sender_profile_incomplete | 400 | Company name, address, or contact is empty | | night_consent_required | 400 | Scheduled for 9pm–8am without the night-time consent box checked | | rate_limited | 429 | Too many requests | ### Conventions IDs are UUIDs, times are ISO 8601, money is stored as whole units, and emails are stored lowercase. Lists accept `?page=&limit=`(default 50 · max 500) and return `{ items, total, page, limit }` . --- ### Contacts · lists · tags · segments — upsert · bulk · CSV · suppression list https://send.ad/docs/contacts A contact is one per email address within a workspace. `POST /api/v1/contacts` updates the existing record if the email already exists (upsert). Pass tags by name and they're created if they don't exist. curl ```bash curl -X POST https://send.ad/api/v1/contacts -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" \\\n -d '{"email":"kim@example.com","first_name":"Minsu","attrs":{"plan":"pro","city":"Seoul"},"list_ids":[""],"tags":["VIP"]}' ``` ### Bulk ``` POST /api/v1/contacts/bulk { contacts: [ … ≤5,000 ], list_ids: [ … ] } → { imported, updated, skipped, suppressed }\nPOST /api/v1/contacts/import (multipart: file=CSV, list_id, mapping?) — auto-detects Mailchimp export column names ``` ### Lists · tags · segments | Endpoint | Description | | --- | --- | | GET/POST /api/v1/lists | List and create lists {name, description, double_opt_in} | | POST /api/v1/lists/{id}/contacts | Add to a list by {emails\|contact_ids} | | GET/POST /api/v1/tags · POST /api/v1/tags/{id}/contacts | Tags · apply tags | | POST /api/v1/segments | {name, rules:{match:"all"\|"any", conditions:[{field, op, value}]}} | | POST /api/v1/segments/preview | Send rules only to preview the count and a sample | ### Suppression list Unsubscribed, bounced, and complaint addresses are added automatically and excluded from every send. Load a Mailchimp "Unsubscribed" CSV with `POST /api/v1/suppressions/import` . Only remove someone from the suppression list when a person explicitly asks for it. --- ### Campaigns — Draft → estimate → send/schedule → reports https://send.ad/docs/campaigns Create a campaign as a draft, check recipients, cost, and balance with `estimate` , then send or schedule it with `send` . When the send starts, recipients × unit price is reserved from your balance, and anything not sent is returned when it finishes. curl ```bash # 초안\ncurl -X POST https://send.ad/api/v1/campaigns -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" -d '{\n "name":"추석 프로모션","subject":"{{first_name|고객}}님, 추석 선물 20% 할인","preheader":"9월 25일까지 무료배송",\n "from_name":"한빛 마케팅팀","reply_to":"hello@hanbit.kr",\n "audience":{"list_ids":[""],"exclude_list_ids":[]},\n "ad_prefix":true,"track_opens":true,"track_clicks":true,\n "design":{"version":1,"blocks":[{"id":"h","type":"heading","text":"추석 선물 20% 할인"},{"id":"t","type":"text","html":"

9월 25일까지 무료배송이에요.

"},{"id":"b","type":"button","text":"쿠폰 받기","href":"https://hanbit.kr/gift"}]}\n}'\n# 예상 → 발송\ncurl https://send.ad/api/v1/campaigns//estimate -H "Authorization: Bearer $SEND_API_KEY"\ncurl -X POST https://send.ad/api/v1/campaigns//send -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" -d '{"scheduled_at":"2026-09-20T10:00:00+09:00"}' ``` ### Status `draft → scheduled → queued → sending → sent`, and everything else `paused · canceled · failed`. `pause/resume/cancel` is POST. Test sends use `POST /{id}/test { to: […] }`(charged per email). ### Reports ``` GET /api/v1/campaigns/{id}/report → counts · rates · links[] · timeline[]\nGET /api/v1/campaigns/{id}/recipients → per-recipient status (queued/sent/delivered/bounced/…)\nGET /api/v1/events?campaign_id=&type=open|click|bounce|unsubscribe ``` ### Automatic compliance `ad_prefix:true` , "(Ad)" is added to the front of the subject line, and your company name, address, contact, and unsubscribe link are added to the footer automatically. `List-Unsubscribe`·`List-Unsubscribe-Post` headers are automatic too. Scheduling between 21:00 and 08:00 KST requires the workspace's `night_consent` to be true. --- ### AI-generated — Brief → subject · body · design · rewrite https://send.ad/docs/ai AI reads your workspace's brand profile (tone, target audience, signature, words to avoid, products, links) when writing. Product links and prices are used exactly as written, the body ends with your signature, and words to avoid never appear in the subject or body. There's no charge for using AI. | Endpoint | Input | Output | | --- | --- | --- | | POST /api/v1/ai/campaign | { brief, url?, list_ids\|list_names, segment_id?, tone?, send?, scheduled_at? } | { campaign, subjects[], preview_url, estimate } — create a campaign draft (+ send/schedule) | | POST /api/v1/ai/design | { brief, url?, tone? } | { name, subjects[], preheader, design } — design only, no campaign created. Pass url (or put an address in the brief) and the AI reads the site first | | POST /api/v1/ai/rewrite | { text, instruction } | { text } | | POST /api/v1/ai/subjects | { brief \| design, n } | { subjects[] } | curl ```bash curl -X POST https://send.ad/api/v1/ai/campaign -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" \\\n -d '{"brief":"20% off holiday gift sets, through Sept 25, free shipping, for past customers","list_names":["Customers"],"tone":"calm and polite","send":false}' ``` A good brief includes **the offer, the deadline, and the audience**. Links and prices come from the products in your brand profile, so fill that in first. We recommend a flow where your agent builds with `send:false` to build `preview_url` , shows a person the `/send` , then calls --- ### Single send — POST /api/v1/send · check status https://send.ad/docs/send Send notifications, receipts, and one-off emails from your agent at the same unit price. `html`, `text`, or `design`(block JSON) — pass one of them. curl ```bash curl -X POST https://send.ad/api/v1/send -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" \\\n -d '{"to":"kim@example.com","subject":"We got your order","html":"

Thanks, {{first_name|there}}.

","merge":{"first_name":"Alex"}}'\n# → { delivery_id, token, cost_krw }\ncurl https://send.ad/api/v1/deliveries/ -H "Authorization: Bearer $SEND_API_KEY" ``` Node.js ```js await fetch('https://send.ad/api/v1/send', { method: 'POST', headers: { authorization: \`Bearer \${process.env.SEND_API_KEY}\`, 'content-type': 'application/json' },\n body: JSON.stringify({ to: 'kim@example.com', subject: 'We got your order', html: '

Thanks.

' }) }) ``` Single sends don't get the (Ad) prefix or the compliance footer — they're for transactional and notification email. If the content is promotional, send it as a campaign. --- ### Sending domain — 3 CNAMEs · verification · warm-up https://send.ad/docs/domains To send from your own domain, add the domain, add the CNAME records to your DNS, and verify. Until it's verified, email goes out from a platform address and replies come to your company inbox. curl ```bash curl -X POST https://send.ad/api/v1/domains -H "Authorization: Bearer $SEND_API_KEY" -H "content-type: application/json" -d '{"domain":"news.hanbit.kr"}' # → { domain: { id, dns_records: [ {type:"CNAME", host:"abc123._domainkey.news.hanbit.kr", value:"abc123.dkim.amazonses.com"}, … ] } } curl -X POST https://send.ad/api/v1/domains//verify -H "Authorization: Bearer $SEND_API_KEY" ``` We recommend a marketing-only subdomain (`news.`) — it keeps your business email reputation separate. For a new domain, start with a low send rate per minute (`send_rate_per_min`) and raise it over 2–3 weeks. --- ### Events and webhooks — How opens, clicks, and bounces get in https://send.ad/docs/webhooks Opens (pixel), clicks (redirect) and unsubscribes are handled by Send directly. Delivered, bounce, spam-report and drop events come from the sending infrastructure (Amazon SES) to `POST /api/webhooks/ses` and are matched to the recipient with the `delivery_token` tag. The platform manages this webhook — nothing to set up on your side. Outbound webhooks to you (campaign-finished notifications, etc.) aren't available yet. For now, poll `GET /api/v1/campaigns/{id}` 's `status` (that's what the CLI's `sendad ai --send` does). --- ### CLI — npx send.ad — all commands https://send.ad/docs/cli On Node 18 or later, use `npx send.ad` with no install. Settings live in `~/.sendad/config.json`, and the environment variable `SEND_API_KEY` · `SEND_BASE_URL` takes priority. Add `--json` to any command for machine-readable output. | Command | Description | | --- | --- | | sendad login [--key K] [--base URL] | Save your API key (prompts if omitted) | | sendad whoami | Workspace, role, balance | | sendad balance | Balance, price per email, emails remaining | | sendad lists list \| create | Lists | | sendad contacts list [--list L] [--q search] · add [--first-name] [--list L] [--tag T] | Contact | | sendad contacts import --list | Import CSV (recognizes Mailchimp format) | | sendad templates list | List templates | | sendad campaigns list \| status \| report | View campaigns | | sendad campaigns create --name N --subject S --list L (--design file.json \| --html file.html) | Create draft | | sendad campaigns send [--at ISO] | Send or schedule | | sendad send --to a@b.com --subject S (--html H \| --text T \| --html-file f) | Single send | | sendad ai "" [--list L] [--tone T] [--send \| --at ISO] | Brief → campaign (+ send). --send prints status until it finishes | | sendad approvals · approve [--at ISO] · reject [--note] | List items awaiting approval · approve (send now or scheduled) · reject (back to draft) | | sendad autopilot mode [manual\|approve\|auto] | View/change autopilot mode | | sendad autopilot list \| create --name N --brief "template" [--cadence weekly --dow 2 --hour 10] [--list L] [--rss URL] \| run \| pause \| resume | Recurring run plans (brief template {{date}} {{recent_posts}} {{products}} {{free_text}}) | | sendad learning | Learning memo — what we learned from performance · best send times | | sendad domains list \| add \| verify | Sending domain | | sendad mcp | Run the MCP server (stdio) | ``` npx send.ad login --key sd_live_…\nnpx send.ad contacts import ./subscribers.csv --list customers\nnpx send.ad ai "20% off holiday gift sets, through 11/25" --list customers # → awaiting approval + approval link\nnpx send.ad approvals && npx send.ad approve # approve → send\nnpx send.ad autopilot create --name weekly-news --brief "{{date}} This week: {{recent_posts}}" --cadence weekly --dow 2 --hour 10 --list customers --rss https://blog.example/rss\nnpx send.ad learning # what we learned from performance\nnpx send.ad campaigns report --json ``` `sendad ai … --send` If the workspace mode is **approve** , it stops at awaiting approval and gives you the approval link (exit 0). **auto** , it sends as soon as the guardrails pass; **manual** leaves a draft (sends with --send). `--wait` prints status until the send completes. --- ### MCP server — As a tool in Claude Code · Cursor and more https://send.ad/docs/mcp Turn on the MCP (Model Context Protocol) server and agents like Claude Code can use Send as a tool. One line is all it takes. ``` claude mcp add sendad -e SEND_API_KEY=sd_live_… -- npx -y send.ad mcp ``` For other clients (Cursor · Claude Desktop and more), add this to your config file. ```json { "mcpServers": { "send": { "command": "npx", "args": ["-y", "send.ad", "mcp"], "env": { "SEND_API_KEY": "sd_live_…" } } } } ``` ### Available tools | Tool | What it does | | --- | --- | | send_whoami | Check workspace and balance | | send_balance | Balance · unit price · emails remaining | | send_list_lists | List of lists | | send_list_contacts | Search and list contacts | | send_add_contacts | Add contacts (upsert) · lists and tags | | send_import_csv | Import a local CSV file | | send_ai_campaign | Brief → campaign draft (+send/schedule) | | send_create_campaign | Draft from subject, design, and recipients | | send_send_campaign | Send or schedule | | send_campaign_status | Status and totals | | send_send_email | Single send | | send_list_approvals · send_approve_campaign · send_reject_campaign | View awaiting approval · approve (send) · reject | | send_autopilot_plans · send_create_autopilot_plan · send_run_autopilot_plan | View, create, and run recurring plans now | | send_set_autopilot_mode | Autopilot mode manual / approve / auto | | send_learning_memo | Learning memo (what we learned from performance) | Tell your agent "Send the the holidays promo to the customers list" and it calls `send_ai_campaign` to create a draft, put it in awaiting approval, and show you the preview and approval link — then, once you confirm, it calls `send_approve_campaign` . "Send blog updates every Tuesday" is `send_create_autopilot_plan`, and "What did we learn from the last campaign?" is `send_learning_memo` . In auto mode, it finishes without approval. ## 5. REST endpoints (https://send.ad/api/v1/openapi.json) | Method | Path | What it does | | --- | --- | --- | | GET | `/api/v1/me` | Who am I (API key → workspace) | | GET | `/api/v1/workspace` | Get workspace (sender profile, brand profile, defaults) | | PUT | `/api/v1/workspace` | Update workspace (admin) | | PUT | `/api/v1/workspace/provider` | Set sending provider (BYO SendGrid/SMTP/SES) (admin) | | GET | `/api/v1/apikeys` | List API keys (admin) | | POST | `/api/v1/apikeys` | Create API key (full key returned once) (admin) | | DELETE | `/api/v1/apikeys/{id}` | Revoke API key (admin) | | GET | `/api/v1/team` | Members and pending invites | | POST | `/api/v1/team/invites` | Invite by email(s) (admin) | | DELETE | `/api/v1/team/invites/{id}` | Cancel invite (admin) | | POST | `/api/v1/team/invites/{id}/resend` | Resend invite mail (admin) | | PUT | `/api/v1/team/members/{userId}` | Change role or status (admin) | | DELETE | `/api/v1/team/members/{userId}` | Remove member (admin) | | POST | `/api/v1/team/transfer` | Transfer ownership (owner only) (admin) | | GET | `/api/v1/team/audit` | Audit log (admin) | | GET | `/api/v1/join/{token}` | Invite info | | POST | `/api/v1/join/{token}` | Accept invite (session) | | GET | `/api/v1/billing` | Balance, unit price, card, ledger, payments | | POST | `/api/v1/billing/card` | Register card (KRW only · Toss billing authKey → billing key). USD cards are saved by the first Stripe Checkout (admin) | | DELETE | `/api/v1/billing/card` | Remove the saved card (Toss key or Stripe payment method) and turn auto-recharge off (admin) | | POST | `/api/v1/billing/topup` | Top up balance — KRW: charge the registered Toss card now (VAT added); USD: returns a Stripe Checkout URL (admin) | | POST | `/api/v1/billing/stripe/confirm` | USD: settle a Checkout session if the webhook has not arrived yet (admin) | | PUT | `/api/v1/billing/auto-recharge` | Auto-recharge settings (admin) | | GET | `/api/v1/billing/usage` | Sends and cost per day for a month | | GET | `/api/v1/contacts` | List contacts | | POST | `/api/v1/contacts` | Create or update a contact (upsert by email) | | GET | `/api/v1/contacts/{id}` | Get contact | | PUT | `/api/v1/contacts/{id}` | Update contact | | DELETE | `/api/v1/contacts/{id}` | Delete contact | | POST | `/api/v1/contacts/bulk` | Bulk upsert contacts (≤ 5,000 per call) | | GET | `/api/v1/contacts/export.csv` | Export contacts as CSV | | POST | `/api/v1/contacts/import` | Import CSV (Mailchimp export recognized) | | GET | `/api/v1/lists` | List lists | | POST | `/api/v1/lists` | Create list | | GET | `/api/v1/lists/{id}` | Get list | | PUT | `/api/v1/lists/{id}` | Update list | | DELETE | `/api/v1/lists/{id}` | Delete list | | POST | `/api/v1/lists/{id}/contacts` | Add contacts to list | | DELETE | `/api/v1/lists/{id}/contacts` | Remove contacts from list | | GET | `/api/v1/tags` | List tags | | POST | `/api/v1/tags` | Create tag | | DELETE | `/api/v1/tags/{id}` | Delete tag | | POST | `/api/v1/tags/{id}/contacts` | Tag contacts | | GET | `/api/v1/segments` | List segments | | POST | `/api/v1/segments` | Create segment | | GET | `/api/v1/segments/{id}` | Get segment | | PUT | `/api/v1/segments/{id}` | Update segment | | DELETE | `/api/v1/segments/{id}` | Delete segment | | GET | `/api/v1/segments/{id}/preview` | Count + sample of a segment | | POST | `/api/v1/segments/preview` | Preview rules without saving | | GET | `/api/v1/suppressions` | Suppression list | | POST | `/api/v1/suppressions` | Add to suppression list | | DELETE | `/api/v1/suppressions/{id}` | Remove from suppression list | | POST | `/api/v1/suppressions/import` | Import suppression CSV (e.g. Mailchimp unsubscribed export) | | GET | `/api/v1/forms` | List signup forms | | POST | `/api/v1/forms` | Create signup form | | GET | `/api/v1/forms/{id}` | Get form | | PUT | `/api/v1/forms/{id}` | Update form | | DELETE | `/api/v1/forms/{id}` | Delete form | | POST | `/api/v1/forms/{slug}/submit` | Public submit (no auth, CORS *) | | GET | `/api/v1/templates` | List templates (starters + mine) | | POST | `/api/v1/templates` | Save template | | GET | `/api/v1/templates/{id}` | Get template | | PUT | `/api/v1/templates/{id}` | Update template | | DELETE | `/api/v1/templates/{id}` | Delete template | | POST | `/api/v1/templates/{id}/duplicate` | Duplicate template into my templates | | POST | `/api/v1/designs/render` | Render a design to HTML/text (preview with sample merge values) | | POST | `/api/v1/ai/design` | AI: brief → subjects, preheader, design (no campaign created) | | POST | `/api/v1/ai/rewrite` | AI: rewrite a block text with an instruction | | POST | `/api/v1/ai/subjects` | AI: subject line suggestions | | POST | `/api/v1/ai/campaign` | AI: brief → full campaign draft (optionally send/schedule) — the one-liner | | GET | `/api/v1/campaigns` | List campaigns | | POST | `/api/v1/campaigns` | Create campaign draft | | GET | `/api/v1/campaigns/{id}` | Get campaign | | PUT | `/api/v1/campaigns/{id}` | Update draft | | DELETE | `/api/v1/campaigns/{id}` | Delete draft/canceled campaign | | GET | `/api/v1/campaigns/{id}/estimate` | Recipients, cost and balance check | | POST | `/api/v1/campaigns/{id}/send` | Send now or schedule (reserves recipients × unit price) (admin) | | POST | `/api/v1/campaigns/{id}/pause` | Pause sending (admin) | | POST | `/api/v1/campaigns/{id}/resume` | Resume sending (admin) | | POST | `/api/v1/campaigns/{id}/cancel` | Cancel (refunds unsent reservation) (admin) | | POST | `/api/v1/campaigns/{id}/test` | Send test to addresses (charged per send) | | GET | `/api/v1/campaigns/{id}/preview` | Rendered HTML/text with sample merge values | | GET | `/api/v1/campaigns/{id}/report` | Report: counts, rates, links, timeline | | GET | `/api/v1/campaigns/{id}/recipients` | Per-recipient delivery status | | POST | `/api/v1/send` | Send a single email now (transactional or one-off; charged per send) | | GET | `/api/v1/deliveries/{token}` | Delivery status by token | | GET | `/api/v1/domains` | Sending domains | | POST | `/api/v1/domains` | Add sending domain → DNS records to add (admin) | | POST | `/api/v1/domains/{id}/verify` | Check DNS and mark verified (admin) | | DELETE | `/api/v1/domains/{id}` | Remove sending domain (admin) | | GET | `/api/v1/automations` | List automations | | POST | `/api/v1/automations` | Create automation (welcome series) | | GET | `/api/v1/automations/{id}` | Get automation | | PUT | `/api/v1/automations/{id}` | Update automation | | DELETE | `/api/v1/automations/{id}` | Delete automation | | POST | `/api/v1/automations/{id}/toggle` | Activate/pause | | GET | `/api/v1/events` | Raw events (open/click/bounce/…) | | GET | `/api/v1/reports/overview` | Workspace-wide daily sends/opens/clicks/cost | | GET | `/api/v1/approvals` | Campaigns awaiting approval (with estimate + approval_url) (admin) | | POST | `/api/v1/campaigns/{id}/approve` | Approve awaiting campaign → send now or at scheduled_at (admin) | | POST | `/api/v1/campaigns/{id}/reject` | Reject awaiting campaign → back to draft with note (admin) | | GET | `/a/{token}` | One-click approval page (HTML, no login): summary + preview; token expires after approve/reject | | POST | `/a/{token}` | Approval page form action: approve \| approve_suggested \| reject | | GET | `/api/v1/autopilot/settings` | Autopilot mode, guardrails, approval emails | | PUT | `/api/v1/autopilot/settings` | Update autopilot settings (admin) | | GET | `/api/v1/autopilot/plans` | Recurring autopilot plans | | POST | `/api/v1/autopilot/plans` | Create plan (cadence + brief template + sources + audience) (admin) | | GET | `/api/v1/autopilot/plans/{id}` | Plan with campaign history | | PUT | `/api/v1/autopilot/plans/{id}` | Update plan (status: active\|paused to pause/resume) (admin) | | DELETE | `/api/v1/autopilot/plans/{id}` | Delete plan (admin) | | POST | `/api/v1/autopilot/plans/{id}/run` | Run plan now → campaign (awaiting_approval or sent per mode) (admin) | | POST | `/api/v1/autopilot/feed` | Preview an RSS feed as plan source | | GET | `/api/v1/learning` | Learning memo, best hours, stats, recent insights | | POST | `/api/v1/learning/recompute` | Recompute insights + memo now (admin) | | POST | `/api/v1/learning/next-suggestions` | Suggestions for the next campaign (subjects, send time, CTA) | | POST | `/api/webhooks/sendgrid` | SendGrid Event Webhook receiver (internal · legacy) | | POST | `/api/webhooks/ses` | Amazon SES event receiver via SNS HTTPS subscription (internal) | ## 6. Legal - Terms of Service: https://send.ad/terms - Privacy Policy: https://send.ad/privacy - Support: support@send.ad