Transactional email API
Send single, personal emails from your own application through obanox: password resets, order confirmations, invoices, account notifications.
Each request sends one email to one recipient. Emails are queued and delivered within seconds. Addresses that bounce or report your mail as spam are blocked automatically, which protects your sender reputation.
Before you start
| Where to find it | |
|---|---|
| API key and API secret | In your obanox account under Settings → API access. See Authentication. |
| A verified sender domain | In your account under Email delivery. Add your domain (e.g. example.com) and publish the DNS records shown. You can only send from addresses on a domain with the status verified. |
| A newsletter approved for sending | Every email is sent on behalf of one of your newsletters. It must be approved for sending, and not paused. Request approval in your account under Settings → Sending approval; we usually reply within a few hours. |
| Your newsletter's slug | See Your newsletter's slug. |
Send an email
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
API-KEY | Your API key |
API-SECRET | Your API secret |
Body fields
| Field | Type | Required | Description |
|---|---|---|---|
from | string | yes | Sender address. Must be on one of your verified sender domains, e.g. [email protected]. Max. 255 characters. |
from_name | string | no | Sender name shown in the inbox, e.g. Example Shop. Max. 255 characters, single line. |
to | string | yes | Recipient address. Exactly one recipient. Max. 255 characters. |
reply_to | string | no | Address that replies go to. Max. 255 characters. |
subject | string | yes | Subject line. Max. 998 characters, single line. |
html | string | one of html / text | HTML body. |
text | string | one of html / text | Plain-text body. |
{
"from": "[email protected]",
"from_name": "Example Shop",
"to": "[email protected]",
"reply_to": "[email protected]",
"subject": "Your order #10023",
"html": "<p>Hello Max,</p><p>thank you for your order.</p>",
"text": "Hello Max,\n\nthank you for your order."
}
The whole request may be at most 512 KB. We recommend sending both html and text: many mail programs and spam filters prefer messages with a plain-text version.
Response
202 Accepted: the email was accepted and queued for delivery.
{
"id": 4711,
"status": "queued"
}
Store the id if you want to reference the email when contacting support.
Examples
curl -X POST "https://www.obanox.com/api/v1/my-newsletter/send" \
-H "Content-Type: application/json" \
-H "API-KEY: your-api-key" \
-H "API-SECRET: your-api-secret" \
-d '{
"from": "[email protected]",
"from_name": "Example Shop",
"to": "[email protected]",
"reply_to": "[email protected]",
"subject": "Your order #10023",
"html": "<p>Hello Max,</p><p>thank you for your order.</p>",
"text": "Hello Max,\n\nthank you for your order."
}'
<?php
$payload = [
'from' => '[email protected]',
'from_name' => 'Example Shop',
'to' => '[email protected]',
'subject' => 'Your order #10023',
'html' => '<p>Hello Max,</p><p>thank you for your order.</p>',
'text' => "Hello Max,\n\nthank you for your order.",
];
$ch = curl_init('https://www.obanox.com/api/v1/my-newsletter/send');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'API-KEY: ' . getenv('OBANOX_API_KEY'),
'API-SECRET: ' . getenv('OBANOX_API_SECRET'),
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 202) {
$error = json_decode($body, true)['error'] ?? $body;
// handle the error, see "Errors"
}
const response = await fetch('https://www.obanox.com/api/v1/my-newsletter/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'API-KEY': process.env.OBANOX_API_KEY,
'API-SECRET': process.env.OBANOX_API_SECRET,
},
body: JSON.stringify({
from: '[email protected]',
from_name: 'Example Shop',
to: '[email protected]',
subject: 'Your order #10023',
html: '<p>Hello Max,</p><p>thank you for your order.</p>',
text: 'Hello Max,\n\nthank you for your order.',
}),
});
if (response.status !== 202) {
const { error } = await response.json();
// handle the error, see "Errors"
}
import os
import requests
response = requests.post(
"https://www.obanox.com/api/v1/my-newsletter/send",
headers={
"API-KEY": os.environ["OBANOX_API_KEY"],
"API-SECRET": os.environ["OBANOX_API_SECRET"],
},
json={
"from": "[email protected]",
"from_name": "Example Shop",
"to": "[email protected]",
"subject": "Your order #10023",
"html": "<p>Hello Max,</p><p>thank you for your order.</p>",
"text": "Hello Max,\n\nthank you for your order.",
},
timeout=10,
)
if response.status_code != 202:
error = response.json().get("error")
# handle the error, see "Errors"
Errors
Errors return a JSON body with an error message:
{ "error": "The from address is not on a verified sender domain." }
| Status | error | What it means | What to do |
|---|---|---|---|
401 | Invalid api-key or api-secret. | Headers missing or wrong. | Check your credentials. Send them as API-KEY / API-SECRET (with a hyphen). |
403 | Access to this list denied. | The slug doesn't exist or belongs to another account. | Check the slug. |
413 | The request is too large. | The body is over 512 KB. | Make the email smaller, e.g. link to images instead of embedding them. |
422 | The body must be a JSON object. | The body isn't valid JSON. | Send a JSON object with Content-Type: application/json. |
422 | Missing or invalid fields: … | The listed fields are missing, invalid, too long or contain line breaks. | Fix the listed fields. |
422 | The from address is not on a verified sender domain. | The from domain isn't verified in your account. | Verify the domain, or use an address on a verified one. |
422 | The list is not approved for sending or sending is paused. | The newsletter isn't approved yet, or sending was paused (e.g. too many bounces or spam complaints). | Not approved yet: request approval under Settings → Sending approval. Paused: contact obanox support. |
422 | Your account has more subscribers than your plan allows. … | Your plan's subscriber limit is exceeded. | Upgrade your plan. |
422 | recipient_suppressed | The recipient is blocked because an earlier email bounced or was marked as spam (see below). | Don't retry. Ask the recipient for a different address. |
429 | The daily email limit of your plan is reached. | Your plan's daily email limit is used up. | Try again tomorrow, or upgrade your plan. |
5xx | – | Temporary problem on our side. | Retry after a short wait (e.g. 1 min, then 5 min). |
Only retry on 429 (the next day) and 5xx. A 4xx error won't succeed by repeating the same request.
Delivery
- Asynchronous:
202means the email was accepted, not yet delivered. It normally goes out within a few seconds. - Temporary problems at the recipient's side (e.g. their mail server is briefly unavailable) are retried automatically. You don't need to resend.
- If an accepted email can't be sent on our side, it is kept and can be resent by obanox support. Don't send it again yourself, or the recipient may get it twice.
- Counted towards your plan: every transactional email counts towards your plan's daily email limit, together with your newsletter emails.
Bounces and spam complaints
To protect your sender reputation, obanox blocks addresses automatically:
| Event | Blocked for |
|---|---|
| Hard bounce: the address doesn't exist or permanently rejects mail | All newsletters of your account, for transactional emails |
| Spam complaint: the recipient marked an email as spam | The newsletter the email was sent through |
| Soft bounce: temporary problem, e.g. full mailbox | Not blocked |
This also covers your newsletter emails: an address that hard-bounced on a newsletter issue can't receive transactional emails from your account either.
A request to a blocked address returns 422 recipient_suppressed. If an address was blocked by mistake (for example, the recipient has since fixed their mailbox), contact obanox support to unblock it.
A high bounce or complaint rate can pause your newsletter's sending, which also stops the API (422 … sending is paused). Keep your rates low by only emailing addresses that recently gave them to you, and removing addresses that return recipient_suppressed.
Good practice
- One request per recipient. To email several people, send several requests.
- Use a dedicated sender address, e.g.
[email protected]or[email protected], and setreply_toif recipients should be able to answer. - Transactional emails only. Use this API for emails a recipient triggered or expects (account, order, security). Send marketing and newsletters through your newsletter, so recipients can unsubscribe.
- Avoid duplicate sends. If your request times out, you can't tell whether the email was accepted. Retrying may send it twice, so for critical emails log the request before retrying.
Limits
| Recipients per request | 1 |
|---|---|
| Request size | 512 KB |
| Attachments | Not supported |
| Daily emails | According to your plan |
| Sender | Addresses on your verified sender domains only |
Support
Questions or an address to unblock? Contact obanox support and include the email id from the API response.