const { EmailApi, EmailMessage } = require('sendpost_js');
const email = new EmailApi();
const apiKey = 'your_api_key'; // {String} Sub-Account API Key
(async function() {
const message = new EmailMessage();
message.from = { email: 'richard@piedpiper.com' };
message.to = [{ email: 'gavin@hooli.com' }]
message.subject = 'Hello'
message.htmlBody = '<strong>it works!</strong>';
message.ippool = 'PiedPiper'
const opts = {
emailMessage: message
};
try {
const data = await email.sendEmail(apiKey, opts)
console.log('API called successfully. Returned data: ', data);
} catch (error) {
console.error(error);
}
})()require_once(__DIR__ . '/vendor/autoload.php');
$client = new GuzzleHttp\Client();
$apiInstance = new sendpost\api\EmailApi($client);
$x_sub_account_api_key = 'your_api_key'; // string | Sub-Account API Key
$email_message = new \sendpost\model\EmailMessage();
$email_message->setSubject('Hello World');
$email_message->setHtmlBody('<strong>it works!</strong>');
$email_message->setIppool('PiedPiper');
$from = new \sendpost\model\From();
$from->setEmail('richard@piedpiper.com');
$to = new \sendpost\model\To();
$to->setEmail('gavin@hooli.com');
$email_message->setTo(array($to));
$email_message->setFrom($from);
try {
$result = $apiInstance->sendEmail($x_sub_account_api_key, $email_message);
print_r($result);
} catch (Exception $e) {
echo 'Exception when calling EmailApi->sendEmail: ', $e->getMessage(), PHP_EOL;
}
import sendpost_python_sdk
from pprint import pprint
from sendpost_python_sdk.apis.tags import email_api
# Enter a context with an instance of the API client
with sendpost_python_sdk.ApiClient() as api_client:
# Create an instance of the API class
api_instance = email_api.EmailApi(api_client)
x_sub_account_api_key = "your_api_key" # str | Sub-Account API Key
email = {
"from": {
"email": "richard@piedpiper.com",
},
"to": [
{
"email": "gavin@hooli.com",
}
],
"subject": "Hello World",
"htmlBody": "<strong>it works!</strong>",
"ippool": "PiedPiper",
}
try:
api_response = api_instance.send_email(header_params={ 'X-SubAccount-ApiKey': x_sub_account_api_key}, body=email)
pprint(api_response)
except sendpost_python_sdk.ApiException as e:
print("Exception when calling EmailApi->send_email: %s\n" % e)
require 'sendpost_ruby_sdk'
api_instance = Sendpost::EmailApi.new
x_sub_account_api_key = 'your_api_key' # String | Sub-Account API Key
email_message = Sendpost::EmailMessage.new
email_message.from = {
email: 'richard@piedpiper.com'
}
email_message.to = [{
email: 'gavin@hooli.com'
}]
email_message.subject = 'Hello World'
email_message.html_body = '<strong>it works!</strong>'
email_message.ippool = 'PiedPiper'
opts = {
email_message: email_message # EmailMessage | Email message
}
begin
result = api_instance.send_email(x_sub_account_api_key, opts)
p result
rescue Sendpost::ApiError => e
puts "Exception when calling EmailApi->send_email: #{e}"
end
cfg := sendpost.NewConfiguration()
client := sendpost.NewAPIClient(cfg)
emailMessage := sendpost.EmailMessage{}
emailMessage.SetSubject("Hello World")
emailMessage.SetHtmlBody("<strong>it works!</strong>")
emailMessage.SetIppool("PiedPiper")
emailMessage.From = &sendpost.From{}
emailMessage.From.SetEmail("richard@piedpiper.com")
tos := make([]sendpost.To, 0)
to := &sendpost.To{}
to.SetEmail("gavin@hooli.com")
tos = append(tos, *to)
emailMessage.To = tos
emailRequest := sendpost.ApiSendEmailRequest{}
emailRequest = emailRequest.XSubAccountApiKey("your_api_key")
emailRequest = emailRequest.EmailMessage(emailMessage)
res, _, err := client.EmailApi.SendEmailExecute(emailRequest)
curl -X POST "https://api.sendpost.io/api/v1/subaccount/email/" \
-H "accept: application/json" \
-H "X-SubAccount-ApiKey: your_api_key" \
-d '{
"from": { "email": "richard@piedpiper.com" },
"to": [{ "email": "gavin@hooli.com" }],
"subject": "Hello World",
"htmlBody": "<strong>it works!</strong>",
"ippool": "PiedPiper"
}'
HttpResponse<String> response = Unirest.post("https://api.sendpost.io/api/v1/subaccount/email/")
.header("X-SubAccount-ApiKey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from\": {\n \"email\": \"notifications@yourcompany.com\",\n \"name\": \"Your Company\"\n },\n \"replyTo\": {\n \"email\": \"support@yourcompany.com\",\n \"name\": \"Support Team\"\n },\n \"to\": [\n {\n \"email\": \"customer@example.com\",\n \"name\": \"John Doe\",\n \"customFields\": {\n \"firstName\": \"John\",\n \"orderId\": \"ORD-12345\",\n \"orderTotal\": \"$99.99\"\n }\n }\n ],\n \"subject\": \"Your order {{orderId}} has been shipped!\",\n \"htmlBody\": \"<h1>Hi {{firstName}}</h1><p>Your order {{orderId}} worth {{orderTotal}} is on its way!</p>\",\n \"textBody\": \"Hi {{firstName}}, Your order {{orderId}} worth {{orderTotal}} is on its way!\",\n \"ippool\": \"transactional\",\n \"trackOpens\": true,\n \"trackClicks\": true,\n \"groups\": [\n \"order-shipped\",\n \"transactional\"\n ]\n}")
.asString();[
{
"to": "customer@example.com",
"submittedAt": 1704067200000000000,
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"errorCode": 0,
"message": "Email submitted successfully"
}
]Send Email
Send transactional or marketing emails to one or multiple recipients. This is the primary endpoint for all email sending through SendPost.
Capabilities:
- Single Email: Send to one recipient with full personalization
- Batch Sending: Send to up to 500 recipients in a single API call
- Personalization: Use Handlebars templating (
{{variableName}}) in subject, HTML body, and text body - Attachments: Include base64-encoded files (max 25MB total per request)
- Tracking: Enable/disable open and click tracking per email
- IP Pool Routing: Route emails through specific IP pools
Common Use Cases:
| Use Case | Example |
|---|---|
| Order Confirmation | Send receipt with order details after purchase |
| Password Reset | Time-sensitive security email with reset link |
| Welcome Email | Onboard new users with personalized greeting |
| Shipping Notification | Update customers when orders ship |
| Invoice/Receipt | Attach PDF invoices to billing emails |
Personalization Example:
{
"to": [{
"email": "john@example.com",
"customFields": {
"firstName": "John",
"orderTotal": "$99.99"
}
}],
"subject": "Hi {{firstName}}, your order is confirmed!",
"htmlBody": "<p>Thanks {{firstName}}! Your total: {{orderTotal}}</p>"
}
Test Email Addresses:
SendPost provides special test email addresses for testing webhooks and events without sending real emails:
| Test Email | Behavior |
|---|---|
test@playwithsendpost.io | Generates delivered event, then simulates opens and clicks after a few seconds |
deliver@playwithsendpost.io | Generates delivered event only (no opens/clicks) |
hardbounce@playwithsendpost.io | Always generates a hard bounce event |
softbounce@playwithsendpost.io | Always generates a soft bounce event |
dropped@playwithsendpost.io | Always generates a dropped event (SMTPDropped) |
Self-Test Email (Send to Yourself):
Use hello@playwithsendpost.io as the from address to send emails to yourself for testing:
- Sender: Must be
hello@playwithsendpost.io - Recipient: Must be your account owner email (the email you used to sign up)
- Behavior: Real email delivery to your inbox (no domain verification required, no mock mode)
- Use Case: Test your API integration by sending real emails to yourself without domain setup
Example:
{
"from": {"email": "hello@playwithsendpost.io"},
"to": [{"email": "your-account-email@example.com"}],
"subject": "Test Email to Myself",
"htmlBody": "<p>This is a test email to myself</p>"
}
This will send a real email to your inbox that you can actually receive and open.
Note: If you send to any email other than your account email, the request will be rejected with an error.
Using Test Emails:
- Simply send to any test email address like a normal recipient
- Mock mode is automatically enabled for test emails
- All events trigger webhooks normally
- Events are marked as mock messages but follow the same structure as real events
- Perfect for testing webhook integrations without using real email addresses
Example:
{
"to": [{"email": "test@playwithsendpost.io"}],
"from": {"email": "sender@example.com"},
"subject": "Test Email",
"htmlBody": "<p>This is a test</p>"
}
This will generate: Sent → Delivered → Opened (after 2-5s) → Clicked (after 1-3s more)
Response: Returns an array of responses, one per recipient, each containing:
messageId- Unique ID for trackingsubmittedAt- Timestamp of acceptanceerrorCodeandmessage- Status information
const { EmailApi, EmailMessage } = require('sendpost_js');
const email = new EmailApi();
const apiKey = 'your_api_key'; // {String} Sub-Account API Key
(async function() {
const message = new EmailMessage();
message.from = { email: 'richard@piedpiper.com' };
message.to = [{ email: 'gavin@hooli.com' }]
message.subject = 'Hello'
message.htmlBody = '<strong>it works!</strong>';
message.ippool = 'PiedPiper'
const opts = {
emailMessage: message
};
try {
const data = await email.sendEmail(apiKey, opts)
console.log('API called successfully. Returned data: ', data);
} catch (error) {
console.error(error);
}
})()require_once(__DIR__ . '/vendor/autoload.php');
$client = new GuzzleHttp\Client();
$apiInstance = new sendpost\api\EmailApi($client);
$x_sub_account_api_key = 'your_api_key'; // string | Sub-Account API Key
$email_message = new \sendpost\model\EmailMessage();
$email_message->setSubject('Hello World');
$email_message->setHtmlBody('<strong>it works!</strong>');
$email_message->setIppool('PiedPiper');
$from = new \sendpost\model\From();
$from->setEmail('richard@piedpiper.com');
$to = new \sendpost\model\To();
$to->setEmail('gavin@hooli.com');
$email_message->setTo(array($to));
$email_message->setFrom($from);
try {
$result = $apiInstance->sendEmail($x_sub_account_api_key, $email_message);
print_r($result);
} catch (Exception $e) {
echo 'Exception when calling EmailApi->sendEmail: ', $e->getMessage(), PHP_EOL;
}
import sendpost_python_sdk
from pprint import pprint
from sendpost_python_sdk.apis.tags import email_api
# Enter a context with an instance of the API client
with sendpost_python_sdk.ApiClient() as api_client:
# Create an instance of the API class
api_instance = email_api.EmailApi(api_client)
x_sub_account_api_key = "your_api_key" # str | Sub-Account API Key
email = {
"from": {
"email": "richard@piedpiper.com",
},
"to": [
{
"email": "gavin@hooli.com",
}
],
"subject": "Hello World",
"htmlBody": "<strong>it works!</strong>",
"ippool": "PiedPiper",
}
try:
api_response = api_instance.send_email(header_params={ 'X-SubAccount-ApiKey': x_sub_account_api_key}, body=email)
pprint(api_response)
except sendpost_python_sdk.ApiException as e:
print("Exception when calling EmailApi->send_email: %s\n" % e)
require 'sendpost_ruby_sdk'
api_instance = Sendpost::EmailApi.new
x_sub_account_api_key = 'your_api_key' # String | Sub-Account API Key
email_message = Sendpost::EmailMessage.new
email_message.from = {
email: 'richard@piedpiper.com'
}
email_message.to = [{
email: 'gavin@hooli.com'
}]
email_message.subject = 'Hello World'
email_message.html_body = '<strong>it works!</strong>'
email_message.ippool = 'PiedPiper'
opts = {
email_message: email_message # EmailMessage | Email message
}
begin
result = api_instance.send_email(x_sub_account_api_key, opts)
p result
rescue Sendpost::ApiError => e
puts "Exception when calling EmailApi->send_email: #{e}"
end
cfg := sendpost.NewConfiguration()
client := sendpost.NewAPIClient(cfg)
emailMessage := sendpost.EmailMessage{}
emailMessage.SetSubject("Hello World")
emailMessage.SetHtmlBody("<strong>it works!</strong>")
emailMessage.SetIppool("PiedPiper")
emailMessage.From = &sendpost.From{}
emailMessage.From.SetEmail("richard@piedpiper.com")
tos := make([]sendpost.To, 0)
to := &sendpost.To{}
to.SetEmail("gavin@hooli.com")
tos = append(tos, *to)
emailMessage.To = tos
emailRequest := sendpost.ApiSendEmailRequest{}
emailRequest = emailRequest.XSubAccountApiKey("your_api_key")
emailRequest = emailRequest.EmailMessage(emailMessage)
res, _, err := client.EmailApi.SendEmailExecute(emailRequest)
curl -X POST "https://api.sendpost.io/api/v1/subaccount/email/" \
-H "accept: application/json" \
-H "X-SubAccount-ApiKey: your_api_key" \
-d '{
"from": { "email": "richard@piedpiper.com" },
"to": [{ "email": "gavin@hooli.com" }],
"subject": "Hello World",
"htmlBody": "<strong>it works!</strong>",
"ippool": "PiedPiper"
}'
HttpResponse<String> response = Unirest.post("https://api.sendpost.io/api/v1/subaccount/email/")
.header("X-SubAccount-ApiKey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from\": {\n \"email\": \"notifications@yourcompany.com\",\n \"name\": \"Your Company\"\n },\n \"replyTo\": {\n \"email\": \"support@yourcompany.com\",\n \"name\": \"Support Team\"\n },\n \"to\": [\n {\n \"email\": \"customer@example.com\",\n \"name\": \"John Doe\",\n \"customFields\": {\n \"firstName\": \"John\",\n \"orderId\": \"ORD-12345\",\n \"orderTotal\": \"$99.99\"\n }\n }\n ],\n \"subject\": \"Your order {{orderId}} has been shipped!\",\n \"htmlBody\": \"<h1>Hi {{firstName}}</h1><p>Your order {{orderId}} worth {{orderTotal}} is on its way!</p>\",\n \"textBody\": \"Hi {{firstName}}, Your order {{orderId}} worth {{orderTotal}} is on its way!\",\n \"ippool\": \"transactional\",\n \"trackOpens\": true,\n \"trackClicks\": true,\n \"groups\": [\n \"order-shipped\",\n \"transactional\"\n ]\n}")
.asString();[
{
"to": "customer@example.com",
"submittedAt": 1704067200000000000,
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"errorCode": 0,
"message": "Email submitted successfully"
}
]Authorizations
This api key can be used only for sub account level operations
Body
Email message details
Email message object containing all the details required to send an email.
At minimum, you need to provide from, to, and either subject with htmlBody/textBody or a template.
The sender's email address and optional display name
Show child attributes
Show child attributes
{
"email": "sender@example.com",
"name": "John Doe"
}
List of recipients. Each recipient can have their own CC, BCC, and custom fields for personalization. Maximum 1000 recipients per API call.
1 - 1000 elementsShow child attributes
Show child attributes
The reply-to email address. If not specified, replies will go to the from address
Show child attributes
Show child attributes
{
"email": "sender@example.com",
"name": "John Doe"
}
Email subject line. Supports Handlebars templating for personalization. Example: "Hello, {{firstName}}! Your order is ready"
998"Welcome to SendPost, {{firstName}}!"
Preview text (preheader) shown in email clients before opening the email. This text appears after the subject line in most email clients' inbox view.
200"Your weekly digest is here with 5 new updates..."
HTML content of the email. Supports Handlebars templating for personalization. Use {{customFieldName}} to insert recipient-specific values.
"<html><body><h1>Hello {{firstName}}</h1><p>Welcome to our platform!</p></body></html>"
Plain text content of the email. Used as fallback when HTML cannot be rendered. Also improves deliverability as some spam filters prefer multipart emails.
"Hello {{firstName}},\n\nWelcome to our platform!\n\nBest regards,\nThe Team"
AMP HTML content for supported email clients (Gmail, Yahoo). Enables interactive email experiences like carousels, forms, and real-time content. See https://amp.dev/about/email/ for more details.
"<!doctype html><html ⚡4email><head>...</head><body>...</body></html>"
Name of a pre-defined template to use for this email. When specified, the template's subject, htmlBody, and textBody will be used unless explicitly overridden in this request.
"welcome-email-v2"
Name of the IP pool to use for sending this email. If not specified, the default IP pool for the sub-account will be used.
"transactional"
Custom email headers to include in the message. Common uses: adding List-Unsubscribe headers, custom tracking IDs, or priority flags. Note: Some headers like From, To, Subject are set automatically and cannot be overridden.
Show child attributes
Show child attributes
{
"X-Custom-Header": "custom-value",
"X-Campaign-ID": "summer-sale-2024",
"List-Unsubscribe": "<mailto:unsubscribe@example.com>"
}
Whether to track email opens using a tracking pixel. When enabled, a 1x1 transparent image is inserted into the HTML body. Default: true (if not specified)
true
Whether to track link clicks by rewriting URLs through SendPost's tracking domain. When enabled, all links in htmlBody are replaced with tracking URLs. Default: true (if not specified)
true
Tags/groups to categorize this email for analytics and reporting. Use groups to segment your email statistics (e.g., by campaign, email type, or customer segment).
[
"transactional",
"order-confirmation",
"premium-customers"
]
File attachments to include with the email. Maximum total attachment size: 25MB. Supported formats: PDF, images, documents, etc.
Show child attributes
Show child attributes
Custom webhook URL to receive events for this specific email. Overrides the default webhook configured at the account level. Useful for per-email or per-customer webhook routing.
"https://your-app.com/webhooks/email-events"
Response
A list of email message response objects.
The recipient email address this response corresponds to
"customer@example.com"
UNIX epoch timestamp in nanoseconds when the email was accepted for processing. Use this for precise timing and correlation with webhook events.
1704067200000000000
Unique identifier (UUID) for this email message. Use this ID to track the email through webhooks and the message lookup API.
"550e8400-e29b-41d4-a716-446655440000"
Error code if the email submission failed. Common codes:
- 0: Success (no error)
- 1: Invalid recipient email
- 2: Recipient in suppression list
- 3: Domain not verified
- 4: Rate limit exceeded
- 5: Invalid sender email
0
Human-readable message describing the result. On success: "Email submitted successfully" On error: Description of what went wrong
"Email submitted successfully"
Was this page helpful?