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 secretIn your obanox account under Account → API. See Authentication.
A verified sender domainIn 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 sendingEvery 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 slugSee Your newsletter's slug.

Send an email

POST https://obanox.com/api/v1/{slug}/send

Headers

HeaderValue
Content-Typeapplication/json
API-KEYYour API key
API-SECRETYour API secret

Body fields

FieldTypeRequiredDescription
fromstringyesSender address. Must be on one of your verified sender domains, e.g. [email protected]. Max. 255 characters.
from_namestringnoSender name shown in the inbox, e.g. Example Shop. Max. 255 characters, single line.
tostringyesRecipient address. Exactly one recipient. Max. 255 characters.
reply_tostringnoAddress that replies go to. Max. 255 characters.
subjectstringyesSubject line. Max. 998 characters, single line.
htmlstringone of html / textHTML body.
textstringone of html / textPlain-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.

If you turned on Approve transactional emails before sending in your settings, the status is awaiting_approval instead: the email is only sent once you approve it under Transactional emails. The same applies to emails sent over SMTP when approval is on for SMTP.

Examples

curl -X POST "https://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://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://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://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." }
StatuserrorWhat it meansWhat to do
401Invalid api-key or api-secret.Headers missing or wrong.Check your credentials. Send them as API-KEY / API-SECRET (with a hyphen).
403Access to this list denied.The slug doesn't exist or belongs to another account.Check the slug.
413The request is too large.The body is over 512 KB.Make the email smaller, e.g. link to images instead of embedding them.
422The body must be a JSON object.The body isn't valid JSON.Send a JSON object with Content-Type: application/json.
422Missing or invalid fields: …The listed fields are missing, invalid, too long or contain line breaks.Fix the listed fields.
422The 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.
422The 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.
422Your account has more subscribers than your plan allows. …Your plan's subscriber limit is exceeded.Upgrade your plan.
422recipient_suppressedThe recipient is blocked because an earlier email bounced or was marked as spam (see below).Don't retry right away. Ask the recipient for a different address; a block after an undeliverable email ends after 7 days.
429The 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.

Send over SMTP

If your application, shop or CMS can only send email over SMTP, use the obanox SMTP server instead of the HTTP API. It uses the same API key and secret, the same verified sender domains and the same limits. Unlike the API, SMTP also supports attachments, Cc and Bcc.

Serversmtp.obanox.com
Port and encryption587 with STARTTLS (recommended), or 465 with SSL/TLS
AuthenticationPLAIN or LOGIN (usually just "on" in your SMTP settings)
Usernamemy-newsletter:{your API key}, your newsletter's slug and API key joined by a colon
PasswordYour API secret

The From address of each email must be on a verified sender domain. Every recipient (To, Cc and Bcc) counts as one email and appears as its own entry under Transactional emails. Bcc recipients stay hidden from the others.

The server answers with standard SMTP codes, so your application can tell a permanent error from a temporary one:

ReplyWhat it meansWhat to do
250Accepted and queued.–
535Username or password wrong, or the slug belongs to another account.Check the username format and your API secret.
530Not logged in.Turn on SMTP authentication.
454Login temporarily not possible (problem on our side).Your SMTP client retries automatically.
550The email was refused, with the same reason as the matching API error (unverified sender, list not approved, recipient blocked, too large, …).Fix the cause; resending the same email won't help.
452More than 50 recipients in one email.Your SMTP client sends the remaining recipients in another email automatically.
450Temporary: daily limit reached or a problem on our side.Your SMTP client retries automatically.

Delivery

  • Asynchronous: 202 means 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. An email counts once, on the day it is accepted: also while it awaits your approval and if you reject it, but not again when you approve it later.

Bounces and spam complaints

To protect your sender reputation, obanox blocks addresses automatically:

EventBlocked for
Hard bounce: the address doesn't exist or permanently rejects mailThe newsletter the email was sent through
Spam complaint: the recipient marked an email as spamThe newsletter the email was sent through
Undeliverable: the recipient's mailbox is full, or delivery was retried for hours and gave up, e.g. because the recipient's domain doesn't resolve. This also applies when it happens to one of your newsletter emailsThe newsletter the email was sent through, for 7 days
Soft bounce: other temporary problems, e.g. an auto-replyNot 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. Blocks after an undeliverable email end on their own after 7 days. If an address was blocked by mistake (for example, the recipient has since fixed their mailbox), you can remove it under Suppressed emails in your account.

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 set reply_to if 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 request1 (API), 50 per email (SMTP)
Request size512 KB (API), 10 MB per email incl. attachments (SMTP)
AttachmentsNot supported over the API; supported over SMTP
Daily emailsAccording to your plan
SenderAddresses 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.