Skip to content

Questions · Published 2026-10-31 · Updated 2026-10-31 · AgentiSend

Resend-compatible email API: switch with one import

The Resend-compatible email API lets you switch with one import from agentisend/compat-resend, so an existing send call runs here and a refusal names the fix.

The Resend-compatible email API lets you switch with one import from agentisend/compat-resend, so an existing send call runs here and a refusal names the fix. The shim is the Node client. A call that the shim does not implement still exists as a function and answers that it is not available.

Before

import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
  from: 'Acme <hello@acme.example>',
  to: 'ada@example.com',
  subject: 'Hello',
  html: '<p>Hello</p>',
});

After

import { Resend } from 'agentisend/compat-resend';

const resend = new Resend(process.env.AGENTISEND_API_KEY, {
  baseUrl: 'https://api.agentisend.com',
});
await resend.emails.send({
  from: 'Acme <hello@acme.example>',
  to: 'ada@example.com',
  subject: 'Hello',
  html: '<p>Hello</p>',
});

The samples above are the whole change for a send that already uses the Resend client.

What you gain

A key carries a send budget. PATCH /limits/keys/{id} sets budget_per_period, and the key that sends cannot raise it. POST /limits/keys/{id}/kill pauses that key. A refusal from POST /emails includes fix, naming the next call, beside the message.

The request shapes for contacts, domains, templates, topics, broadcasts, segments and webhooks are accepted on those routes too. The field-by-field account of a migration is Migrating from Resend. The price comparison is AgentiSend vs Resend.

Supported methods

  • emails.send
  • emails.create
  • emails.get
  • emails.list
  • emails.update
  • emails.cancel
  • emails.metrics
  • emails.batch.send
  • emails.batch.create
  • emails.attachments.get
  • emails.attachments.list
  • emails.receiving.get
  • emails.receiving.list
  • emails.receiving.attachments.get
  • emails.receiving.attachments.list
  • batch.send
  • batch.create
  • domains.create
  • domains.list
  • domains.get
  • domains.update
  • domains.verify
  • domains.remove
  • apiKeys.create
  • apiKeys.list
  • apiKeys.update
  • apiKeys.remove
  • contacts.create
  • contacts.list
  • contacts.get
  • contacts.update
  • contacts.remove
  • contacts.topics.list
  • contacts.topics.update
  • contacts.segments.list
  • contacts.segments.add
  • contacts.segments.remove
  • topics.create
  • topics.list
  • topics.get
  • topics.update
  • topics.remove
  • segments.create
  • segments.list
  • segments.get
  • segments.update
  • segments.remove
  • broadcasts.create
  • broadcasts.list
  • broadcasts.get
  • broadcasts.update
  • broadcasts.send
  • broadcasts.remove
  • broadcasts.cancel
  • broadcasts.duplicate
  • broadcasts.recipients
  • broadcasts.clickedLinks
  • templates.create
  • templates.list
  • templates.get
  • templates.update
  • templates.publish
  • templates.render
  • templates.duplicate
  • templates.remove
  • suppressions.add
  • suppressions.list
  • suppressions.get
  • suppressions.remove
  • suppressions.batch.add
  • suppressions.batch.remove
  • automations.create
  • automations.list
  • automations.get
  • automations.update
  • automations.enable
  • automations.disable
  • automations.remove
  • automations.duplicate
  • automations.stop
  • automations.runs.get
  • automations.runs.list
  • webhooks.create
  • webhooks.list
  • webhooks.get
  • webhooks.update
  • webhooks.remove
  • webhooks.verify
  • webhooks.rotateSigningSecret
  • events.send

Send fields

A send accepts from, to, subject, html, text, react, cc, bcc, reply_to, replyTo, headers, tags, attachments, scheduled_at, scheduledAt, timezone, topic_id, topicId, template, template_id, template_values, expires_at.

react is turned into html when the renderer package is installed. Without it, the send is refused and the message names the package to install, or says to pass html.

replyTo is sent as reply_to. topicId is sent as topic_id. A tag list of name and value is sent as a map. Attachment content given as bytes is sent as base64 text. Any other key on the send is forwarded, and the API refuses one it does not accept.

Methods that are not available

Each of these is a function, so a missing method does not crash the caller. Calling it answers that the method is not available. Any method on the claims namespace of domains answers the same way as domains.claims.list.

  • emails.receiving.forward
  • contacts.imports.create
  • contacts.imports.list
  • contacts.imports.get
  • webhooks.events.get
  • webhooks.events.list
  • webhooks.events.replay
  • events.create
  • events.get
  • events.list
  • events.update
  • events.remove
  • contactProperties.create
  • contactProperties.list
  • contactProperties.get
  • contactProperties.update
  • contactProperties.remove
  • logs.get
  • logs.list
  • usage.get
  • oauthGrants.list
  • oauthGrants.revoke
  • domains.claims.list

FAQ

What do I change in the import?

Replace the Resend SDK import with agentisend/compat-resend, and point the client at this API. The samples above are the whole change for a send.

Which methods are not available?

The list under Methods that are not available. A call to one of them answers that it is not available. It does not crash on a missing function.

What does a refusal add?

A fix that names the next call, beside the message. The budget and the kill switch are the calls in What you gain.

Next