HTTP Submission API
- Table of Contents
- Overview
- Example
- Compression
- Request Document
- Request for Multiple Messages
- Throttling Message Acceptance
Overview
GreenArrow Engine provides an HTTP message submission API.
The information is provided to the API as a POST or PUT request of JSON content. (The header of content-type: application/json
must be provided.)
The API provides a response of JSON content with a content type of application/json
.
The uploaded information can be compressed using gzip
or deflate
compression. The header of Content-Encoding: gzip
or Content-Encoding: deflate
must be provided when doing this.
There is a 10MB size limit per submission. This limit is applied before a compressed payload is uncompressed, so if, for example, a 25MB payload compresses down to 8MB, you can submit it, but if it compresses down to 11MB, you cannot.
Authentication is performed by providing a username/password for an Email User in the JSON document.
The API is provided at /api/v1/send.json
on your GreenArrow server’s HTTP service.
Example
Example JSON document:
{
"username":"[email protected]",
"password":"test",
"message":{
"html":"html content goes <b>here</b>",
"text":"text content goes here",
"subject":"this is the subject",
"to":[
{
"email":"[email protected]",
"name":"John Doe"
}
],
"from_email":"[email protected]",
"from_name":"Your Company"
}
}
Example JSON reply for success:
{"success":1,"message_id":"[email protected]"}
Example JSON reply for failure:
{"success":0,"error":"no data in POST or PUT payload"}
or:
{"success":0,"error":"incorrect username\/password"}
Submitting this request with curl
:
cat <<'EOT' > post_body.txt
{
"username":"[email protected]",
"password":"test",
"message":{
"html":"html content goes <b>here</b>",
"text":"text content goes here",
"subject":"this is the subject",
"to":[
{
"email":"[email protected]",
"name":"John Doe"
}
],
"from_email":"[email protected]",
"from_name":"Your Company",
"mailclass":"trans",
"headers":{
"X-foo":"bar"
}
}
}
EOT
curl -X POST -H "Content-Type: application/json" --data-binary @post_body.txt http://127.0.0.1/api/v1/send.json
The API can also be accessed through SSL:
(Remove the --insecure
option if you have a valid SSL certificate.)
curl -X POST -H "Content-Type: application/json" --data-binary @post_body.txt --insecure https://127.0.0.1/api/v1/send.json
Compression
The content can be gzip
or deflate
compressed. This allows payloads with lots of messages to be reduced in size.
This requires the Content-Encoding: gzip
or Content-Encoding: deflate
header on the HTTP request.
Example:
cat <<'EOT' | gzip -c -9 > post_body.txt.gz
{
"username":"[email protected]",
"password":"test",
"message":{
"html":"html content goes <b>here</b>",
"text":"text content goes here",
"subject":"this is the subject",
"to":[
{
"email":"[email protected]",
"name":"John Doe"
}
],
"from_email":"[email protected]",
"from_name":"Your Company",
"mailclass":"trans",
"headers":{
"X-foo":"bar"
}
}
}
EOT
curl -X POST -H "Content-Type: application/json" -H "Content-Encoding: gzip" --data-binary @post_body.txt.gz http://127.0.0.1/api/v1/send.json
Request Document
-
username
- email address of an email user (NOT the username of GreenArrow web-interface login) -
password
- password of above user -
message
- Object containing the following fields:
id
string /optional |
Extra identifier for the message. This value is returned in the response in order to assist in mapping specific messages to responses. It is not otherwise used. It is not the same as the |
||||
html
string |
HTML version of content for email message. Either the |
||||
text
string |
Text version of content for email message Either the |
||||
subject
string /required |
|
||||
to
hash /required List of recipients of email. Each entry in the list is an object consisting of:
|
|||||
from_email
string /required |
Email address to use in |
||||
from_name
string /optional |
Name to use in |
||||
return_path
string /optional |
Return-Path to use. This is also known as the bounce address and envelope sender. Note that this gets overwritten if SimpleMH is configured to set the Return-Path for you. |
||||
mailclass
string /default: The default Mail Class |
Name of the SimpleMH Mail Class to use. This key has the same effect as the |
||||
message_id_domain
string /optional |
Fully qualified domain name to use in the domain portion of the |
||||
headers
hash /optional |
Additional headers to add to the email. The key is the header name and the value is the raw text of the value of the header. (For example, to set the Message ID of the email, specify |
Request for Multiple Messages
Up to 500 messages may be submitted per API request.
To submit multiple messages in a single request, provide a document like this:
{
"username":"[email protected]",
"password":"test",
"messages":[
{
"html":"html content goes <b>here</b>",
"text":"text content goes here",
"subject":"this is the subject",
"to":[
{
"email":"[email protected]",
"name":"John Doe"
}
],
"from_email":"[email protected]",
"from_name":"Your Company"
},
{
"html":"html content goes <b>here</b>",
"text":"text content goes here",
"subject":"this is the subject",
"to":[
{
"email":"[email protected]",
"name":"Bob Smith"
}
],
"from_email":"[email protected]",
"from_name":"Your Company"
}
]
}
The JSON document most be an object with the following keys:
Key | Description |
---|---|
username |
Same as single message document |
password |
Same as single message document |
messages |
A list containing one or more objects which contain the same information as the message key in a single message document. |
The output can be in two formats.
(1) An error that applies globally to the entire request:
{"success":0,"error":"incorrect username\/password"}
(2) Or the overall request succeeded and a specific success value is provided for each message:
{
"success":1,
"messages":[
{
"success":1,
"message_id":"[email protected]",
"attempted":1,
"id":"1"
},
{
"success":1,
"message_id":"[email protected]",
"attempted":1,
"id":"2"
}
]
}
If there is an internal error, then the subsequent messages in the request will not be attempted. For example:
{
"success":1,
"messages":[
{
"success":1,
"message_id":"[email protected]",
"attempted":1,
"id":"1"
},
{
"success":0,
"error":"internal error: unable to make socket connection (Connection refused)",
"attempted":1,
"id":"2"
},
{
"success":0,
"error":"not attempting due to previous internal errors",
"attempted":0,
"id":"3"
}
]
}
In this request of three messages, the second message encountered an internal error so the third message was not even attempted. The attempted
key provides data on if the message was even attempted.
It is very important to handle error conditions and retry messages appropriately.
If the attempted
value is 0
for a message, this lets you know that you should retry it.
Here are the two error messages that cause messages to not be attempted:
-
not attempting due to previous internal errors
– a previous message encountered an internal error, so the rest of the messages in the batch are not attempted and return this error message. Please retry these messages in a different batch. -
not attempting because previous messages have taken too long
– this happens when the system is not able to pre-process messages as fast as you are trying to send them to this API (see “Throttling” below). Only the messages that can be accepted within about 30 seconds will be accepted, and the rest of the messages in the batch will not be attempted and return this error. This is put in place so that an HTTP timeout does not prevent you from getting any answer to the HTTP request.
Throttling Message Acceptance
GreenArrow throttles how fast messages will be accepted through the HTTP API so that they can not be injected faster than the messages can be pre-processed (specifically performing click/open tracking, DKIM signing, and adding them to the MTA’s ram-queue).
If message acceptance is currently being throttled, the size of the Simplemh pre-processing queue
in the hvmail_status status
output will be above 90%. Here is an example:
Simplemh pre-processing queue: 98% used (1960/2000)