Docs/Core Concepts/Sending Emails

Sending Emails

Complete guide to sending transactional emails with the IvyMail API. Request format, response handling, and code examples in cURL, Python, Node.js, and Java.

Send transactional emails with a single API call. IvyMail handles delivery, DKIM signing, bounce processing, and event tracking automatically. For details on sending volume limits, warmup periods, and reputation monitoring, see Sending Limits & Safety.

Endpoint

Code
POST https://api.ivymail.io/v1/send

Request body

FieldTypeRequiredDescription
tostring[]YesRecipient email addresses (max 50)
from_emailstringYesSender address, e.g. "Name <you@domain.com>"
subjectstringYesEmail subject line
htmlstringNoHTML body
textstringNoPlain text body (recommended as fallback)
reply_tostringNoReply-to address

At least one of html or text must be provided.

Headers

HeaderValue
x-api-keyYour API key
Content-Typeapplication/json

Code examples

cURL

Bash
curl -X POST https://api.ivymail.io/v1/send \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from_email": "Your Name <you@yourdomain.com>",
    "to": ["recipient@example.com"],
    "subject": "Hello from IvyMail",
    "html": "<h1>Hello!</h1><p>Sent via the IvyMail API.</p>",
    "text": "Hello! Sent via the IvyMail API.",
    "reply_to": "support@yourdomain.com"
  }'

Python

python
import requests

resp = requests.post(
    "https://api.ivymail.io/v1/send",
    headers={
        "x-api-key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "from_email": "Your Name <you@yourdomain.com>",
        "to": ["recipient@example.com"],
        "subject": "Hello from IvyMail",
        "html": "<h1>Hello!</h1><p>Sent via the IvyMail API.</p>",
        "text": "Hello! Sent via the IvyMail API.",
        "reply_to": "support@yourdomain.com",
    },
)
print(resp.json())

Node.js

javascript
const resp = await fetch("https://api.ivymail.io/v1/send", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from_email: "Your Name <you@yourdomain.com>",
    to: ["recipient@example.com"],
    subject: "Hello from IvyMail",
    html: "<h1>Hello!</h1><p>Sent via the IvyMail API.</p>",
    text: "Hello! Sent via the IvyMail API.",
    reply_to: "support@yourdomain.com",
  }),
});

const data = await resp.json();
console.log(data);

Java

java
HttpClient client = HttpClient.newHttpClient();

String json = """
    {
        "from_email": "Your Name <you@yourdomain.com>",
        "to": ["recipient@example.com"],
        "subject": "Hello from IvyMail",
        "html": "<h1>Hello!</h1><p>Sent via the IvyMail API.</p>",
        "text": "Hello! Sent via the IvyMail API.",
        "reply_to": "support@yourdomain.com"
    }
    """;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.ivymail.io/v1/send"))
    .header("x-api-key", "YOUR_API_KEY")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();

HttpResponse<String> response =
    client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Response

Success (200)

JSON
{
  "success": true,
  "data": {
    "message_id": "abc123-def456-ghi789",
    "status": "sent"
  }
}

Error (4xx/5xx)

JSON
{
  "success": false,
  "error": "Description of what went wrong"
}

Suppression

If a recipient has previously bounced or filed a complaint, IvyMail blocks the send automatically and returns a log entry with status: suppressed. No email is sent to SES, protecting your sender reputation.

See Bounce & Complaint Handling for details.


For AI agents & LLMs

If you're an AI agent sending email on behalf of a user, use this template:

Bash
curl -X POST https://api.ivymail.io/v1/send \
  -H "x-api-key: $IVYMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from_email": "App Name <sender@verified-domain.com>",
    "to": ["recipient@example.com"],
    "subject": "Your subject here",
    "html": "<p>Your HTML content</p>",
    "text": "Your plain text fallback"
  }'

Always include both html and text fields. Check success in the response before proceeding. If the response contains "status": "suppressed", the recipient was previously bounced. Do not retry.