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:
- Authenticate with your REST Email API credentials.
- Submit a JSON request to send or schedule a plain-text email message.
- Store the 64-bit message ID returned by the API.
- Use the message ID to retrieve message details when needed.
- 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:
- You have REST Email API credentials.
- Your server IP address is authorised if IP allowlisting is enabled.
- Your email message includes
from,to,subject, andbody. - Scheduled send times are provided as RFC3339 timestamps.
- Your requests use HTTPS and JSON encoding.
First successful request path
For most implementations, the fastest way to validate connectivity and configuration is:
- Authenticate using your REST Email API credentials.
- Submit a simple POST request to
/messagewithfrom,to,subject, andbody. - Confirm the
201 Createdresponse and store the returned message ID. - 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.bodyimport 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.bodyimport 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.