REST Email API

When to choose REST Email

Choose REST Email when you need a simple plain-text email channel for transactional messages that should follow the same gateway-style request, scheduling, retrieval, and DLR callback patterns as your messaging integrations; choose REST v2 when handset delivery, SMS delivery receipts, or mobile-originated replies are required.

Overview

Our REST API has been extended to allow the scheduling and sending of basic, plain text Email messages. It is intended as a supplement to the REST API for SMS, as an alternative delivery channel for SMS type (transactional) messages.

While this API is similar to the REST API, it is separate, please note this API has a separate endpoint for email requests.

Emails will be plain text only, there is no provision for HTML, rich text or attachments.

HTTPS use is mandatory, all attempts to use plain-text HTTP will be redirected to HTTPS. Request and response data requires JSON encoding. Only HTTP GET and POST methods are required.

What the API can do

  • Send plain-text email messages to a single recipient
  • Schedule email messages for future delivery
  • Set sender, reply-to, and reference values
  • Retrieve submitted email message details
  • Receive DLR callbacks when the message has been sent by the email transport

How it works

In practice, the API follows a simple workflow:

  1. Authenticate with your REST Email API credentials.
  2. Submit a JSON request to send or schedule a plain-text email message.
  3. Store the 64-bit message ID returned by the API.
  4. Use the message ID to retrieve message details when needed.
  5. Configure a DLR callback URL if your application needs sent-status events.

When to use REST Email API

Use REST Email API when your application needs to send simple transactional email through the gateway using a REST pattern similar to the SMS APIs. It is useful when the message content is plain text, the recipient is an email address, and your system needs predictable request and callback behavior.

REST Email API is not a rich email marketing or template platform. It does not support HTML, rich text, or attachments, and email status is limited compared with SMS delivery status.

Before you start

Before making your first request, confirm the following:

  1. You have REST Email API credentials.
  2. Your server IP address is authorised if IP allowlisting is enabled.
  3. Your email message includes from, to, subject, and body.
  4. Scheduled send times are provided as RFC3339 timestamps.
  5. Your requests use HTTPS and JSON encoding.

First successful request path

For most implementations, the fastest way to validate connectivity and configuration is:

  1. Authenticate using your REST Email API credentials.
  2. Submit a simple POST request to /message with from, to, subject, and body.
  3. Confirm the 201 Created response and store the returned message ID.
  4. Retrieve the message with GET /message/{message_id}/.

Authentication

HTTP Basic Authentication is used for all requests. If you access the API without having the correct credentials OR permission to access the API, you will get a HTTP 401 response.

Your gateway application credentials (‘application name’ and password) are available in the iAds Biz platform, under Mobile Gateway API, Rest Email API.

You will need a login email and password to retrieve these. If you do not have these details, please contact support@modicagroup.com.

Authorised IP Addresses

Allow-list your servers’ IPs or IP ranges using the ‘Add IP Address’ button under “Authorised IP Addresses”

Note: once one or more IP addresses or IP ranges have been added, REST Email API connections from all other IP addresses will be rejected. Any attempt from an IP not in the list will receive an Authentication error.

Base URL

All API access is over HTTPS, and accessed from:

https://api.modicagroup.com/rest/email/v1

Versions

The REST Email API version is currently v1. The media type can just be set to:

Accept: application/json

Error Codes

The following errors can occur:

Code Description
400 Could not queue message due to an unknown error
400 Invalid JSON data in the request body
400 Invalid attribute value
400 Invalid To email address
400 Invalid From email address
400 Invalid scheduled timestamp (must be RFC3339)
422 Invalid scheduled timestamp (must not be in the past)
602 Missing a required attribute

Sending an Email Message

To send an email message to a single destination, submit a POST request:

POST /message
 
{
  "from": str:name@domain.com,
  "to": str:name@domain.com,
  "subject": str:subject line for email,
  "body": str:message content
}

Optional Attributes

{
  "scheduled": str: 2017-05-05T10:00:00+12:00,
  "reply_to": str:name@domain.com,
  "reference": str:alt-reference,
  "sender": str:name@domain.com, 
}

Scheduled Date Limitation: The upper maximum for scheduled messages is 60 days ahead.

On Success

HTTP/1.1 201 Created
 
Content-Type: application/json
 
int:integer($int64):message-id

Note: All message IDs will be returned as 64bit Signed Integers

On Validation Error

HTTP/1.1 400 Bad Request

{
  "code": int:error-code
  "message": str:error-desc
}

Scheduled Date Validation Error

{
  "error-desc": "Invalid scheduled timestamp (must be less than 60 days)",
  "error": "invalid_attrib"
}

Send Email Message Example

These examples send a plain-text email message using the REST Email API.

curl -v \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -u '<USERNAME>:<PASSWORD>' \
  -d '{"from": "sender@example.com", "to": "recipient@example.com", "subject": "Hello world", "body": "Hello world!"}' \
  https://{apiDomainName}/rest/email/v1/message
const credentials = btoa("gw_username:abcde12345");

const response = await fetch("https://{apiDomainName}/rest/email/v1/message", {
  method: "POST",
  headers: {
    "Accept": "application/json",
    "Authorization": `Basic ${credentials}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    from: "sender@example.com",
    to: "recipient@example.com",
    subject: "Hello world",
    body: "Hello world!"
  })
});

const messageId = await response.json();
import requests
import json
from base64 import b64encode

uri = 'https://{apiDomainName}/rest/email/v1/message'
username = "gw_username"
password = "abcde12345"

# Authorization token
def basic_auth(username, password):
    token = b64encode(f"{username}:{password}".encode('utf-8')).decode("ascii")
    return f'Basic {token}'

headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': basic_auth(username, password)
}

json_payload = json.dumps({
    "from": "sender@example.com",
    "to": "recipient@example.com",
    "subject": "Hello world",
    "body": "Hello world!"
})

response = requests.post(uri, headers=headers, data=json_payload)

if response.status_code == 201:
    print(response.json())
else:
    print("Error:", response.status_code, response.text)
<?php

    $uri = "https://{apiDomainName}/rest/email/v1/message";

    $json_payload = json_encode([
        "from" => "sender@example.com",
        "to" => "recipient@example.com",
        "subject" => "Hello world",
        "body" => "Hello world!",
    ]);

    $request = curl_init($uri);
    curl_setopt($request, CURLOPT_POST, true);
    curl_setopt($request, CURLOPT_USERPWD, "user:password");
    curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($request, CURLOPT_HTTPHEADER, ["Content-Type: application/json", "Accept: application/json"]);
    curl_setopt($request, CURLOPT_POSTFIELDS, $json_payload);
    $response = curl_exec($request);

    $http_status = curl_getinfo($request, CURLINFO_HTTP_CODE);

    echo "HTTP ".$http_status."\n".$response."\n";

    curl_close($request);
?>
require 'net/http'
require 'json'

uri = URI.parse('https://{apiDomainName}/rest/email/v1/message')
json_payload = {
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Hello world',
  body: 'Hello world!'
}.to_json

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request.basic_auth('username', 'password')
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
request.body = json_payload
response = http.request(request)

puts 'HTTP %s' % response.code
puts response.body
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

String token = Base64.getEncoder()
    .encodeToString("gw_username:abcde12345".getBytes(StandardCharsets.UTF_8));

String payload = """
{
  "from": "sender@example.com",
  "to": "recipient@example.com",
  "subject": "Hello world",
  "body": "Hello world!"
}
""";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://{apiDomainName}/rest/email/v1/message"))
    .header("Accept", "application/json")
    .header("Authorization", "Basic " + token)
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(payload))
    .build();

HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient();
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes("gw_username:abcde12345"));

var request = new HttpRequestMessage(
    HttpMethod.Post,
    "https://{apiDomainName}/rest/email/v1/message");
request.Headers.Accept.ParseAdd("application/json");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);
request.Content = new StringContent(
    """{"from":"sender@example.com","to":"recipient@example.com","subject":"Hello world","body":"Hello world!"}""",
    Encoding.UTF8,
    "application/json");

var response = await client.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync();
use strict;
use warnings;
use JSON;
use LWP::UserAgent;

#
# Alter these to your supplied credentials
#
my $username = 'username';
my $password = 'password';

my $message = {
    from    => 'sender@example.com',
    to      => 'recipient@example.com',
    subject => 'Hello world',
    body    => 'Hello world!'
};

my $json_payload = to_json($message);

my $URI = 'https://{apiDomainName}/rest/email/v1/message';
my $request = HTTP::Request->new('POST', $URI);

$request->authorization_basic($username, $password);
$request->header('Content-Type' => 'application/json');
$request->header('Accept' => 'application/json');
$request->content($json_payload);

my $ua = LWP::UserAgent->new();
my $response = $ua->request($request);

printf("HTTP %s\n", $response->code);
print $response->content . "\n";

Output:

HTTP 201
[message_id]

Retrieving a Message

To retrieve a message submit a GET request:

GET /message/id/

If a match is found:

HTTP/1.1 200 OK
 
Location: https://api.modicagroup.com/rest/email/v1/message/int:message-id
 
{
  "id": int:integer($int64):message-id,
  "from": str:name@domain.com,
  "to": str:name@domain.com,
  "subject": str:subject line for email,
  "body": str:message content
}

Note: All message IDs will be returned as 64bit Signed Integers

Additional Attributes

{ 
  "scheduled": str: RFC3339 date,
  "reply_to": str:name@domain.com,
  "reference": str:alt-reference,
  "sender": str:name@domain.com,
}

If not found:

HTTP/1.1 400 Bad Request

Get Email Message Example

These examples retrieve an email message using the REST Email API.

curl -v \
  -H 'Accept: application/json' \
  -u '<USERNAME>:<PASSWORD>' \
  https://{apiDomainName}/rest/email/v1/message/message_id/
const credentials = btoa("gw_username:abcde12345");

const response = await fetch("https://{apiDomainName}/rest/email/v1/message/message_id/", {
  method: "GET",
  headers: {
    "Accept": "application/json",
    "Authorization": `Basic ${credentials}`
  }
});

const message = await response.json();
import requests
from base64 import b64encode

uri = 'https://{apiDomainName}/rest/email/v1/message/message_id/'
username = "gw_username"
password = "abcde12345"

# Authorization token
def basic_auth(username, password):
    token = b64encode(f"{username}:{password}".encode('utf-8')).decode("ascii")
    return f'Basic {token}'

headers = {
    'Accept': 'application/json',
    'Authorization': basic_auth(username, password)
}

response = requests.get(uri, headers=headers)

if response.status_code == 200:
    print(response.json())
else:
    print("Error:", response.status_code, response.text)
<?php

    $uri = "https://{apiDomainName}/rest/email/v1/message/message_id/";
    $request = curl_init($uri);
    curl_setopt($request, CURLOPT_USERPWD, "user:password");
    curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($request, CURLOPT_HTTPHEADER, ["Accept: application/json"]);
    $response = curl_exec($request);

    $http_status = curl_getinfo($request, CURLINFO_HTTP_CODE);

    echo "HTTP ".$http_status."\n".$response."\n";

    curl_close($request);
?>
require 'net/http'

uri = URI.parse('https://{apiDomainName}/rest/email/v1/message/message_id/')

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
request.basic_auth('username', 'password')
request['Accept'] = 'application/json'
response = http.request(request)

puts 'HTTP %s' % response.code
puts response.body
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

String token = Base64.getEncoder()
    .encodeToString("gw_username:abcde12345".getBytes(StandardCharsets.UTF_8));

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://{apiDomainName}/rest/email/v1/message/message_id/"))
    .header("Accept", "application/json")
    .header("Authorization", "Basic " + token)
    .GET()
    .build();

HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient();
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes("gw_username:abcde12345"));

var request = new HttpRequestMessage(
    HttpMethod.Get,
    "https://{apiDomainName}/rest/email/v1/message/message_id/");
request.Headers.Accept.ParseAdd("application/json");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);

var response = await client.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync();
use strict;
use warnings;
use LWP::UserAgent;

my $uri = 'https://{apiDomainName}/rest/email/v1/message/message_id/';

my $request = HTTP::Request->new('GET', $uri);

$request->authorization_basic('username', 'password');
$request->header('Accept' => 'application/json');

my $ua = LWP::UserAgent->new();
my $response = $ua->request($request);

printf("HTTP %s\n", $response->code);
print $response->content . "\n";

Output:

HTTP 200
{
  "id": message_id,
  "from": "sender@example.com",
  "to": "recipient@example.com",
  "subject": "Hello world",
  "body": "Hello world!"
}

DLR Callback

You will only receive DLR Status messages if you have supplied a DLR Status in iAds Biz platform REST EMAIL page under Mobile Gateway (API).

NOTE: The security cert must match the domain name being used; self-signed certs will not verify and will generate errors.

The final DLR status for emails only indicate the message was SENT.

No status is available after that point, and read receipts are not supported.

When a DLR message is received for you a POST request is made to the DLR callback URL, this callback will include the DLR Status detail as a JSON object in the body of the POST request.

POST callback-url
 
{
  "message_id": integer($int64):message-id,
  "status": str:dlr-status
}

Note: All message IDs will be returned as 64bit Signed Integers

In the case that the MT message contained a reference, an additional “reference” attribute is added:

{ 
  "reference": str:alt-reference
}

Message Status

The following are the status codes that our message gateway supports for email.

Status Description
submitted Message successfully submitted to the recipient for delivery
sent Message has been sent by the email transport
failed Message delivery has failed because the email cannot be sent

Help

Having trouble integrating with any of our services? Visit our helpdesk at https://indosatooredoo.modicagroup.com/docs/ or contact support@modicagroup.com and we’ll help you sort it out.