Content

SendGrid API for AI Agents

One boolean in the SendGrid payload mails people who unsubscribed. bypass_list_management is the field your agent must never be able to set.

Chaitrali Kakde

DevRel Engineer

IntegrationsOct 24, 2026

In SendGrid's mail send payload there is a setting called bypass_list_management. Set it to true and your email ignores every suppression: global unsubscribes, group unsubscribes, bounces, blocks, spam reports. All of it.

It exists for a legitimate narrow case, like a critical transactional notice that must reach an account holder. But think about what it means for an agent. Someone unsubscribed. That is a legal signal under CAN-SPAM and a withdrawal of consent under GDPR. One boolean in a JSON body overrides it.

A language model composing an email payload has no concept of why that flag is dangerous. It has seen it in documentation, it looks like a reasonable way to make sure an important message arrives, and the field name practically invites it. So deny it at the policy layer and stop thinking about it.

The deny rule, first, before anything else

policies.json
[
  {
    "id": "never-bypass-suppression",
    "target": ["<sendgrid mail-send canonical_id>"],
    "when": { "field": "mail_settings.bypass_list_management.enable", "operator": "==", "value": true },
    "action": {
      "type": "DENY",
      "message": "Suppression lists are not bypassable by agents"
    }
  },
  {
    "id": "bulk-sends-need-a-human",
    "target": ["<sendgrid mail-send canonical_id>"],
    "when": { "field": "recipient_count", "operator": ">", "value": 25 },
    "action": {
      "type": "REQUIRES_APPROVAL",
      "message": "Agent wants to send to more than 25 recipients"
    },
    "approval_timeout": "2h"
  }
]

Cover the related flags too: bypass_unsubscribe_groups, bypass_bounce_management and bypass_spam_management. They are narrower versions of the same problem, and bypassing bounce management in particular is how you keep mailing an address that has already told you it does not exist, which is how your sender reputation dies.

The second rule matters because email has no undo. A mistake that reaches twenty-five people is an apology; the same mistake at twenty-five thousand is an incident with a postmortem. Held calls go to Slack or Telegram and fail closed, so an unapproved bulk send is never dispatched. Setup is in the human approval docs, the schema in the policy reference, and the file lives in your repo so raising the threshold is a reviewed change. See policy-as-code for AI agents.

Let the agent read suppression lists

The flip side of denying the bypass is giving the agent the suppression endpoints as reads. Then it can check whether someone has unsubscribed before composing anything, and skip them with a note rather than discovering the problem at send time.

This is a small thing that changes the character of the agent. One that checks suppression first behaves like someone who respects the list; one that does not behaves like a tool that happens to be blocked by it. The second kind eventually finds a way around the block.

The 202 that is not a delivery

POST /v3/mail/send returns 202 Accepted with an empty body. That means SendGrid has queued your message. Not that it was delivered, not that it was accepted by the recipient's server, and certainly not that anyone read it.

Agents are bad at this distinction. A 202 feels like success, so the agent reports "email sent" and moves on, while the message bounces four seconds later into a void nobody is watching. If your workflow depends on the email actually arriving, wire up the Event Webhook and treat delivery as a separate fact from acceptance.

It is the same shape of mistake as a 200 OK with an error in the body: the status code answers a narrower question than the one the agent thinks it asked.

Setting it up

setup.sh
npx swytchcode
swy login
swy init --mode=sandbox

swy get sendgrid
swy auth connect sendgrid      # API key, stored outside the project
swy auth status

swy discover "send an email" --project sendgrid
swy discover "list global unsubscribes" --project sendgrid
swy discover "get email activity" --project sendgrid
swy list methods sendgrid

swy info <canonical_id>
swy add method <canonical_id>  # send + suppression reads. No list deletes.

Allowlist the send method, the suppression reads, and stats or activity if the agent reports on performance. Leave out anything that removes an address from a suppression list, since that is re-subscribing someone who opted out and is the write version of the bypass flag. Leave out template management too unless editing templates is genuinely the agent's job, because an agent that can rewrite a transactional template can change what every future email says.

Auth is a bearer API key against https://api.sendgrid.com/v3. Create a restricted key with only the permissions these methods need rather than a full-access key, so the credential and the allowlist agree with each other. The key is stored encrypted outside your project and injected at call time, never entering the model's context: see the authentication docs. Keep --project sendgrid on discover and run swy get before swy info.

Idempotency: the email sent twice

Sending is not idempotent and the failure reaches a human inbox, which makes it worse than most duplicates. The request lands, SendGrid queues it, the response never arrives, your agent retries, and a customer gets the same password reset twice, or the same marketing email twice, and forms a view about your product.

Writes are only auto-retried when an idempotency key is set, so an unprotected send fails visibly rather than quietly double-mailing. Derive the key from the reason for the email, such as the order ID plus the notification type, so a retry collapses onto the original and a genuinely new notification gets a new key. Background in API idempotency: the complete guide, mechanics in the retries guide.

Rate limits vary by endpoint and plan, with 429s handled by automatic backoff. The thing to watch is not the limit but the pattern: an agent that sends in a tight loop looks like a spam source to inbox providers whatever your quota says. Pacing is a deliverability concern more than a quota one, and API observability for AI agents covers seeing your own send pattern clearly.

Using it from Claude

Through MCP in Claude Desktop or Claude Code you can draft an email, check whether the recipient is suppressed, and send one message, with the deny rule and the recipient threshold standing between a draft and a disaster. Setup per client is in the MCP setup guide, the reference in the MCP docs, and skills.md hands a coding agent the commands. For a production sender, the Anthropic SDK guide has a tool-use loop you can build on.

What you can build

  1. Transactional notifications with real content. Instead of a template with placeholders, let the agent write the specifics: what changed, what it means for this customer, what they need to do. One recipient at a time, suppression checked, well within every threshold.
  2. Support follow-ups. When a ticket closes, send a summary of what was done and what to do if it recurs. Pairs well with an Intercom or Freshdesk integration on the reading side.
  3. A deliverability watchdog. Read stats and bounce data, and flag when a domain starts bouncing or spam complaints rise. Entirely read-only, and it catches the problem before your sender reputation does.
  4. Draft-then-approve campaigns. The agent writes the copy and assembles the audience, the approval gate holds the send, and a human reads it before anything goes out. This is the right shape for anything above a handful of recipients.

FAQ

Is there ever a case for bypass_list_management?

For a human operator sending a genuinely critical transactional notice, sometimes, with legal's view on record. For an agent, no. Keep it denied; if the rare case arises, a person can send that one email.

Can the agent remove someone from a suppression list?

It should not be able to. Removing an address is effectively re-subscribing someone who opted out, and consent is not something an agent can grant on a person's behalf. Leave those methods out of the allowlist.

How do I know what the agent actually sent?

swy audit network records every call with its payload, so you have the recipient, the subject and the body of everything that went out, which is the record you want when someone asks why they received an email. swy audit policy shows what the rules stopped. See how to log every API call an AI agent makes.

Should an agent send marketing email?

It can draft it. The send should go through approval, because marketing email carries consent and content obligations that someone has to own, and "the agent decided to" is not an answer that survives a complaint. The general pattern is in human-in-the-loop approval for AI agent tool calls.

More content