For the agent era
Email marketing your coding agents can run
Every other email platform is a dashboard — click-ops your agent can't drive. On SendOps, the entire email program is plain text in a git repo: segments are SendQL queries, drip campaigns are .flow files, templates are React Email components. Your agent drafts the change, SendOps validates it, you merge the PR, it deploys — and every send goes out through your own Amazon SES.
The Problem
Click-ops can't be delegated
Your agent ships product code every day — migrations, refactors, whole features, reviewed and merged like anything else. Then the work touches email, and the delegation dead-ends at "log in and click around."
Your codebase
The agent reads the current state as files, proposes a diff, runs it through CI, and a human reviews exactly what will change before it merges. That loop is why you trust it with production code.
Your email platform
The campaign exists only as dashboard state. There are no files to read, no diff to propose, no artifact to review. The best an agent can do is drive a browser and hope — and nobody code-reviews a screenshot.
The result: the one growth channel with the best-understood mechanics is the one your agent can't touch. Not because the work is hard — because the medium is wrong.
The Insight
Everything is text
On SendOps, every piece of your email program has a plain-text representation that lives in your repo. If it can be a file, an agent can author it — and a human can review it.
attr.plan in ["pro", "team"] and count(open within 60d) = 0 and last(order) < now - 90dA segment is one SendQL query over attributes, raw events, consent, and list membership. This one: paying customers who haven't opened anything in 60 days and haven't ordered in 90. Readable in a diff, checkable by a compiler.
workflow "Cart abandonment" v1 {
enter on event cart_updated where not exists(order within 1h)
exit "purchased" when exists(order)
wait 1 hour
hold out 10%
send "cart-reminder" via topic marketing
repeat up to 2 every 24 hours until exists(order) {
send "cart-nudge" via topic marketing
}
}A drip campaign is a .flow file — entry triggers, waits, branches, holdout groups, and bounded repeats, with SendQL as the condition language throughout. The same file renders as a visual canvas in the dashboard, losslessly, in both directions.
import { Html, Body, Heading, Text, Button } from "@react-email/components"
type Props = { name: string; cartUrl: string }
export default function CartReminder({ name, cartUrl }: Props) {
return (
<Html>
<Body>
<Heading>Still thinking it over?</Heading>
<Text>Hi {name}, your cart is saved and waiting.</Text>
<Button href={cartUrl}>Finish checking out</Button>
</Body>
</Html>
)
} A template is a React Email component — the format your agent already writes fluently. SendOps compiles it to SES-native Handlebars on deploy, so what runs in production is exactly what SES expects.
Lists and topics are definitions in the same repo. Which means your entire email program — audience, journeys, content, consent structure — has a canonical form your agent can read, reason about, and change.
How It Works
How an agent ships a campaign
The same loop your agent already runs for product code, applied to email.
- 1
Prompt your agent
"Win back paying customers who've gone quiet — a three-email sequence over two weeks, with a 10% holdout so we can measure it." Plain English, in the terminal you already live in.
- 2
The agent drafts a branch
A SendQL segment, a .flow workflow, and the React Email templates it references — ordinary files on an ordinary branch, alongside the rest of your code.
- 3
SendOps validates on push
Syntax for every file, SendQL analysis against your real attribute and event registries, template reference checks, and rendered previews — so a hallucinated field or a broken merge tag dies in CI, not in an inbox.
- 4
You review the PR like any code
The entire campaign is one readable diff: who it targets, what it says, when it sends, when it stops. Ten minutes of review instead of an afternoon of dashboard archaeology.
- 5
Merge, and SendOps deploys
Sends go out through your own Amazon SES — your domains, your reputation, $0.10 per 1,000 — with consent checks and frequency caps applied to every single send.
Guardrails
Safe no matter who authors
The guardrails don't ask whether a human or an agent wrote the change. They're enforced at the platform layer, on every path to a send.
PR review
Nothing deploys from a branch. A human merges every change to segments, flows, and templates — the same gate your production code already has.
Validation before deploy
Every push is checked: grammar, SendQL semantic analysis against your registries, template references, rendered previews. Invalid definitions never go live.
Manual send approval
Workflows can require an explicit human approval before emails leave — a hold gate between "the campaign is deployed" and "the campaign is sending."
Frequency caps
Per-contact caps across all workflows keep an enthusiastic automation — or an over-eager agent — from burying anyone's inbox.
Consent on every send
Topic subscriptions, unsubscribes, and suppression are re-checked at the moment of sending. No file in any repo can override a recipient's opt-out.
Your infrastructure
Everything sends through your own SES account, connected via CloudFormation and short-lived STS credentials — no stored AWS keys, and revocation is deleting a stack.
Today
What agents can do right now
Not a roadmap — the working surface area, today, with the tools your agent already has: a file editor, git, and HTTP.
- ✓ Draft lifecycle campaigns — welcome sequences, onboarding, cart abandonment, win-backs — as .flow workflows in a branch.
- ✓ Tune segments by editing SendQL — widen a window, add an exclusion, split an audience — with semantic validation catching mistakes on push.
- ✓ Adjust templates in React Email TSX — copy changes, new variants, shared components — compiled to SES-native Handlebars by SendOps on deploy.
- ✓ Analyze results via the API — contacts, lists, broadcasts, and delivery outcomes are all queryable, so "how did last week's campaign do?" is a script, not a screenshot.
- ✓ Ingest product events through activity ingestion, so segments and workflow triggers react to what users actually do — logins, orders, feature usage.
Honest Limits
Agents propose. Humans approve.
An agent on SendOps cannot merge its own PR, and workflows can hold every send for explicit human approval. That's not a limitation we're working around — it's the design. Email is a channel where one bad send costs real reputation with real people, so the human review gate is the point: your agent does the drafting, the tuning, and the analysis, and a person stays accountable for what actually reaches an inbox.
FAQ
Agents and email, answered
Can Claude Code or Cursor really manage email campaigns? +
Yes — because on SendOps there is nothing to click. Segments are SendQL queries, drip campaigns are .flow files, templates are React Email components, and they all live in a git repository. Any agent that can edit files and open a pull request can author a campaign; SendOps validates the branch on push and deploys on merge. For runtime work — managing contacts, sending broadcasts, reading results — agents use the public API.
What stops an agent from emailing my whole list? +
Nothing sends because an agent said so. A campaign only reaches production through a pull request a human merges, and workflows can require manual send approval before any email leaves. Beyond that, guardrails are enforced at the platform layer on every send regardless of author: consent and suppression checks, and frequency caps. An agent can propose anything; the platform decides what actually goes out.
Do I need the API or is git enough? +
Git is enough for authoring: segments, workflows, templates, lists, and topics are all definitions in your repo, validated and deployed through pull requests. The API covers what a repo can't — creating and updating contacts, managing lists, sending broadcasts, uploading assets, ingesting product activity events, and reading results. Most teams give their agent both: git for the program, the API for the runtime.
What is SendLang? +
SendLang is the umbrella for the plain-text languages your email program is written in: SendQL, the query language that defines segments and the conditions inside workflows, and SendFlow, the .flow format that defines drip campaigns. Both are small, human-readable, and designed to be easy for agents to author and easy for humans to review in a diff — and both are validated by SendOps before anything deploys.
Does this work with my existing SES account? +
Yes. SendOps connects to the AWS account you already have through a CloudFormation stack and short-lived STS credentials — no stored keys. Every campaign email goes out through your own SES, on your domains and your reputation, at SES's $0.10 per 1,000 pricing. Your application's existing transactional sending is untouched.
Get Started
Give your agent an email program
The free plan is $0 with unlimited volume and no contact limits — you pay only SES's $0.10 per 1,000, in your own AWS account. Connect SES, point SendOps at a repo, and hand your agent the keys to the one channel it couldn't touch.