Developer API
Developer API
The iResendly Developer API is a REST API for sending email from your application. It is compatible with Resend: the same paths, JSON bodies, responses and error names — so the official Resend SDKs work by changing the base URL.
Using a Resend SDK?
Quickstart
1. Sign in at developers.iresendly.com and activate the Developer API (free, no card).
2. Add and verify your sending domain (Domains). Domains you already verified for Email Marketing or Mail are imported instantly.
3. Create an API key (API Keys) and store it in your server's environment.
4. Send your first email:
curl -X POST 'https://api.iresendly.com/emails' \
-H 'Authorization: Bearer irs_xxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"from": "Acme <onboarding@acme.com>",
"to": ["delivered@example.com"],
"subject": "Hello World",
"html": "<strong>It works!</strong>"
}'// npm install resend
// .env: RESEND_BASE_URL=https://api.iresendly.com
import { Resend } from "resend"
const resend = new Resend(process.env.IRESENDLY_API_KEY)
const { data, error } = await resend.emails.send({
from: "Acme <onboarding@acme.com>",
to: ["delivered@example.com"],
subject: "Hello World",
html: "<strong>It works!</strong>",
})Base URL
All requests go to https://api.iresendly.com. Requests must use HTTPS. The API is meant to be called from servers — browsers are blocked (no CORS) so your keys never leak.
Authentication
Send your API key in the Authorization header as a Bearer token. Keys start with irs_.
Full-access keys can call every endpoint. Sending-access keys can only send email and can be restricted to specific domains.
Authorization: Bearer irs_xxxxxxxxxErrors
Errors return a JSON body with statusCode, name and message. The name is stable — branch on it in your code.
| Status | name | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | The Idempotency-Key header is empty or longer than 256 characters. |
| 401 | missing_api_key | No Authorization header. |
| 401 | restricted_api_key | A sending-only key called another endpoint, or a domain it isn't allowed to use. |
| 403 | invalid_api_key | The key doesn't exist or was revoked. |
| 403 | domain_not_verified | The from domain isn't verified on your account. |
| 403 | suspended | Sending is paused on the account (high bounce or complaint rate). |
| 403 | plan_limit_reached | Your plan's limit for this resource is reached. |
| 404 | not_found | The resource doesn't exist. |
| 409 | idempotency_conflict | Same idempotency key with a different body, or still in flight. |
| 409 | domain_in_use | The domain belongs to another iResendly account (you can claim it). |
| 422 | validation_error | The request body or parameters are invalid. |
| 422 | invalid_from_address | The from field isn't a valid address. |
| 429 | rate_limit_exceeded | Too many requests per second. |
| 429 | daily_quota_exceeded | Free plan daily limit reached. |
| 429 | monthly_quota_exceeded | Monthly email quota reached. |
| 500 | internal_server_error | Something went wrong on our side. Retry with the same idempotency key. |
Rate limits
Requests per second depend on your plan (Free 2, Pro 10, Scale 25). Every response includes ratelimit-limit, ratelimit-remaining and ratelimit-reset headers; 429 responses add retry-after.
Email quotas are counted per recipient and reset on the 1st of each month (UTC). The Free plan also has a daily limit of 100.
Idempotency
Add an Idempotency-Key header to any POST to make retries safe. Within 24 hours, the same key and body return the original response (with idempotent-replayed: true) instead of sending twice.
Idempotency-Key: welcome-user-123Pagination
List endpoints return { object: "list", has_more, data }. Pass limit (1–100, default 20) and after=<last id> to get the next page, or before=<first id> to go back.