Send your first email with the API

Turn on the Developer API, verify a domain, create a sending key and make your first POST /emails call, in cURL, Node.js or Python.

Getting started3 min read

You need three things to send an email with the iResendly Developer API: the API turned on for your account, a verified domain to send from, and an API key. None of them costs anything on the Free plan, and no card is needed.

1. Turn on the Developer API#

Sign in at developers.iresendly.com with your iResendly account and choose Activate Developer API. Calling the API before this returns 403 no_access.

2. Verify the domain you'll send from#

Under Domains, add your domain (or use POST /domains) and publish its three DNS records:

TypeNameValue
TXTiresendly._domainkeyp=… (shown in the console)
MXsendfeedback-smtp.<region>.amazonses.com, priority 10
TXTsendv=spf1 include:amazonses.com ~all

Choose Verify; pending domains are also re-checked automatically, and DNS can take up to 48 hours to spread. Domains you've already verified for iResendly Marketing or Business Email appear here as verified, with nothing to add. You can send from the verified domain or any subdomain of it.

3. Create a sending key#

Under API Keys, create a key with Sending access. It can only call POST /emails and POST /emails/batch, so if it ever leaks, the damage is limited. You can also restrict it to chosen domains. The full key starts with irs_ and is shown once.

  • Store it in your server's environment, for example as IRESENDLY_API_KEY, never in source control.
  • Call the API from your server only. Requests from browsers are blocked, so a key can't be lifted from your website's code.
  • Send it as Authorization: Bearer irs_…. The x-api-key header works too.

4. Send the email#

POST /emails
curl -X POST 'https://api.iresendly.com/emails' \
  -H 'Authorization: Bearer irs_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: welcome-user-8812' \
  -d '{
    "from": "Acme <hello@acme.com>",
    "to": ["jane@example.com"],
    "subject": "Welcome to Acme",
    "html": "<p>Thanks for signing up, Jane.</p>",
    "text": "Thanks for signing up, Jane.",
    "tags": [{ "name": "category", "value": "welcome" }]
  }'

A 200 response with an id means the email was accepted. It's usually delivered in seconds. Open Emails in the console to follow its delivery journey, or fetch it with GET /emails/{id} using a full-access key.

A few details in that example are worth keeping in your real code:

  • Both `html` and `text`. A plain-text version helps readers whose mail apps don't show HTML.
  • `tags` (up to 10 { name, value } pairs) let you find emails later, and they come back in webhook events.
  • `Idempotency-Key` built from something unique, such as the user's id, means a retried request never sends twice.

If it doesn't work#

Every error has the same shape, with a statusCode, a stable name to branch on, and a message that says what to fix:

StatusnameUsual cause
401missing_api_keyThe Authorization header is missing.
403invalid_api_keyThe key is mistyped or was revoked.
401restricted_api_keyA sending key used another endpoint, or a domain it isn't allowed.
403domain_not_verifiedThe from domain isn't verified on your account yet.
422validation_errorA field is missing or invalid; the message names it.
422invalid_from_addressfrom isn't a valid address.

Free plan limits#

The Free plan includes 3,000 emails a month and 100 a day, 1 domain and 2 requests a second. Each recipient counts as one email, across to, cc and bcc.

Tip
Next, add a webhook endpoint so your app hears about deliveries and bounces as they happen, rather than polling.