Appearance
Instant API
TIP
Access to our APIs is evaluated on a case-by-case basis. To find out if your use case is one that we support feel free to get in touch with the details of your project. partners@litmus.com
Why the Instant API?
The Instant API is ideal for integration within email editing tools that have an iterative workflow which can be enhanced with real, rather than approximated, previews.
Our Instant API is the easiest and fastest way to get super speedy email client screenshots into your service. In fact, it's what Litmus uses to power its email client previews within Builder. If you haven't checked that out already, we'd recommend giving it a try to see the API in action.
In our editor, a user makes a change to their email and saves. The screenshots on the right automatically refresh within seconds.
How does it work?
When a user makes a change to their email, or tests it for the first time, you create a new Instant test by creating a POST request with details of the email. There's no need to send an email to us, simply POST the HTML and other details, along with a list of the email clients you'd like us to screenshot. We'll return a unique email id (email_guid
) to you.
And that's it!
To show the screenshots to the user, all you need to do is set the src
attribute of an img
:
html
<img alt="Outlook 2003"
src="https://instant-api.litmus.com/v1/emails/{email_guid}/previews/OL2003/full"/>
Litmus will handle the rest. For more granular control, you can specify fallback images to show in case there was a problem or timeout, or request the image server-side. We've covered all those specifics and more below, but even with the simplest implementation, we're sure you'll be thrilled with the ease of integration and the reliable performance.
How fast is fast?
Pretty damn fast. Where previews have traditionally taken many minutes to complete, Litmus' previews return within seconds without any accuracy cost---it's still real screenshots of real email clients. In the table below, we've included a sample of average completion times seen when using the Instant API. In all cases, you should expect previews to return in around 10 seconds or less.
Typically, creating an Instant Preview test will take 600ms to generate an email_guid
. If your images are larger or take longer to download, you may see this step take a little longer.
Email client | Average speed via the Instant API |
---|---|
Outlooks | 3s - 7s |
iPhones & iPads | 7s |
Android & Gmail apps | 7s - 10s |
Gmail & Google apps | 5s - 8s |
Yahoo, AOL, & Outlook.com | 5s - 11s |
Apple Mails | 5s |
Lotus Notes | 6s |
Overview
Previews can be obtained in only two steps:
POST an email
Describe its content and attributes in JSON. In response, the API will provide you with anemail_guid
.GET each preview required
Specify theemail_guid
and the desiredclient
.
The GET request does not require authentication, so it can be used directly as the source for an image within an end user's browser.
Requiring that the email source is POSTed via HTTP, rather than waiting on email delivery, is one of the methods used to obtain the fast responses.
To capture the most reflective previews, please ensure that the email source provided has been through any transformation that would be applied by the Email Service Provider before being sent on to the mail transfer agent.
Base URI
The base URI of the API is https://instant-api.litmus.com/v1
.
SSL/TLS
All API endpoints are only available via HTTPS.
Content types
By default all data is sent and received as application/json
, exceptions to this are marked in the documentation.
CORS, JSONP
Neither CORS nor JSONP are currently supported. If you have a use case that would benefit from either, please let us know.
Authentication
The Instant API support authentication with either:
- HTTP Basic Authentication - use an API key to make calls on behalf of your own account; or:
- OAuth Bearer tokens - act on behalf of Litmus users with usage against their account
HTTP Basic Authentication
For each Instant API application, you'll be issued an API key. The API key should be provided in the Auth Basic username field. The password field can be left blank.
For the cURL examples shown below, either export your key to the API_KEY environment variable, e.g.
sh
$ export API_KEY="XeyNuXp_NdVtTREH1iaJ78vjFqlBGQfaJOur"
or replace $API_KEY
in each example with your key directly. Note that the trailing colon will hint cURL to send the required empty password, rather than prompting you for it, e.g.
sh
curl -X "POST" "https://instant-api.litmus.com/v1/emails"\
-H "Content-Type: application/json"\
-u "$API_KEY:"\
-d "{\"plain_text\":\"Hello World\"}" -v
OAuth Bearer Tokens
OAuth is useful when you wish to access the API on behalf of Litmus users, typically when you want to bring Litmus features to your own web application, but leverage the Litmus subscriptions that your users may already have.
Obtaining tokens requires implementing the OAuth2 flow within your application which involves sending each end user to litmus.com to authorize you to act on their behalf after which they're returned. See our guide on implementing the OAuth2 flow for detailed integration details.
To authorize an API request with a Bearer token, provide an HTTP Authorization
header of Bearer $TOKEN
(replacing $TOKEN appropriately), e.g.
sh
$ curl -X "POST" "https://instant-api.litmus.com/v1/emails"\
-H "Content-Type: application/json"\
-H "Authorization: Bearer a66841f0a212c0afb6344c6377df4dde0389922511540d9e3c1d11e2ab811a2e"\
-d "{\"plain_text\":\"Hello World\"}" -v
> POST /v1/emails HTTP/1.1
> Host: instant-api.litmus.com
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Authorization: Bearer a66841f0a212c0afb6344c6377df4dde0389922511540d9e3c1d11e2ab811a2e
> Content-Length: 28
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 21 Jun 2016 20:10:06 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 58
< Connection: keep-alive
< Strict-Transport-Security: max-age=3600; includeSubdomains; preload
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
<
{
"email_guid": "113bdfdf-6d54-4cbe-8d38-dd66157e1751"
}
Lifetimes
Emails
Uploaded emails are available to request new captures against for up to 48 hours. After this time, attempting to capture a new preview may yield a 404 Not Found
when using the corresponding email_guid
.
If access to unrequested previews is likely outside the 48 hour window, you can:
- Pre-request previews if you know expected capture configurations; or:
- Repost the email and obtain a fresh
email_guid
then capture a new preview using this
Previews
The image data following a successful capture will be available for 180 days. However, the storage location during this time may change. Once time has passed since a capture, a request to either the Instant API previews endpoint or a litmuscdn URL returned by the API will handle these changes in location gracefully—they will return a 404 Not Found
when a capture is no longer available. Later requests to other locations, like the result of the redirection when the initial capture was made, may result in failure when a capture is still available.
If access to previews is likely outside the 180 day window, you can:
- Download the previews when first captured and host them elsewhere
Example
To make our example less verbose, first download an example HTML email encoded in to the html_text
property of a JSON object:
sh
$ wget https://docs.litmus.com/html-test-email.json
Next describe an email, providing your application's API key. This step is intended to be conducted server to server. Do not share the API key with your end users.
sh
$ curl -X "POST" "https://instant-api.litmus.com/v1/emails"\
-H "Content-Type: application/json"\
-u "$API_KEY:"\
-d @html-test-email.json -v
> POST /v1/emails HTTP/1.1
> Authorization: Basic XXXXXXXXXXXXXXXXXXXXXX
> User-Agent: curl/7.37.1
> Host: instant-api.litmus.com
> Accept: */*
> Content-Type: application/json
> Content-Length: 59740
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Server: nginx
< Date: Fri, 12 Jun 2015 16:58:38 GMT
< Content-Type: application/json
< Content-Length: 58
< Connection: keep-alive
< Strict-Transport-Security: max-age=3600;
<
{
"email_guid": "87bf47f2-600e-40eb-8ccb-c9649f17644d"
}
Then simply construct a GET request for each capture you require, using the email_guid
you just received and a code for the client you want (OL2015
in this example):
sh
$ curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2015/full" -v
> GET /v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2015/full HTTP/1.1
> User-Agent: curl/7.37.1
> Host: instant-api.litmus.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Fri, 12 Jun 2015 17:37:40 GMT
< Content-Type: application/json
< Content-Length: 0
< Connection: keep-alive
< Location: https://ol2015.capture.litmuscdn.com/87bf47f2-600e-40eb-8ccb-c9649f17644d/results/ol2015-vertical-allowed.png
< Strict-Transport-Security: max-age=3600;
<
Behind the scenes a lot of work is going on between the GET being received and the response being provided—the capture of the preview is only initiated once the first request for it is received. While capture is occurring the HTTP connection remains open, once complete the response is sent and then the connection closed. Typically this will take around 6 seconds.
The GET URL can be embedded directly in an HTML image tag:
html
<html>
<body>
<img src="https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2015/full">
</body>
Create an email
POST
https://instant-api.litmus.com/v1/emails
This method expects to receive a JSON object describing an email's content and metadata and, in exchange, returns an email_guid
required to capture previews of it.
We intend these objects to be treated as lightweight. Once uploaded, emails can't be modified. Obtain a new email_guid
each time changes need to be reflected.
The uploaded email has a limited lifespan. As a result, a new email_guid
should be obtained before requesting new previews if more than a day has passed since the last upload.
At least one of html_text
, plain_text
, raw_source
must be provided.
Body parameters | Description |
---|---|
html_text | string Quotes within the HTML must be escaped appropriately |
plain_text | string |
subject | string |
from_address | string |
from_display_name | string |
raw_source | string This field provides an alternative approach to defining the email and so is only valid in the absence of all the fields above |
end_user_id | string A unique identifier for your end users. When provided, we use this to partition your usage data. See Identifying End Users |
configurations | array of objects An array of capture capture configurations as JSON objects. This allows pre-requesting previews that should be captured as soon as possible. This can be a useful performance optimisation. See the dedicated pre-request method for further detail on format |
Errors |
---|
400 Bad Request |
401 Unauthorized |
JSON response body attributes | Description |
---|---|
email_guid | A unique identifier for the uploaded email required to requests captures |
end_user_id | optional Confirmation if an end_user_id was provided in the request |
configurations | optional Confirmation if configurations was provided in the request |
Examples
sh
curl -X "POST" "https://instant-api.litmus.com/v1/emails"\
-H "Content-Type: application/json"\
-u "$API_KEY:"\
-d "{\"plain_text\":\"Hello World\"}" -v
sh
$ curl -X "POST" "https://instant-api.litmus.com/v1/emails" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN"\
-d "{\"plain_text\":\"Hello World\"}" -v
ruby
Litmus::Instant.api_key = ENV["API_KEY"]
Litmus::Instant.create_email(plain_text: "Hello World")
# => {"email_guid"=>"ce6ba90f-cf28-4772-ab09-30a1d48a5e12"}
ruby
api_client = Litmus::Instant::Client.new(oauth_token: user_oauth_token)
api_client.create_email(plain_text: "Hello World")
# => {"email_guid"=>"ce6ba90f-cf28-4772-ab09-30a1d48a5e12"}
Result Format
200 OK
json
{
"email_guid": "ce6ba90f-cf28-4772-ab09-30a1d48a5e12"
}
List supported email clients
GET
https://instant-api.litmus.com/v1/clients
Returns a JSON array of email client names.
Examples
sh
curl -X "GET" "https://instant-api.litmus.com/v1/clients"
ruby
Litmus::Instant.clients
# => ["ANDROID4",
# "ANDROIDGMAILAPP",
# "AOLONLINE",
# "APPMAIL8",
# ...clipped...
Result Format
200 OK
json
[
"OL2000",
"OL2002",
"OL2003",
"OL2007",
"OL2010",
...clipped...
"NOTES9",
"OFFICE365",
"FFOFFICE365",
"CHROMEOFFICE365",
"ANDROIDGMAILAPP"
]
List supported email client configurations
GET
https://instant-api.litmus.com/v1/clients/configurations
Returns a JSON hash detailing available options for each client.
Examples
sh
curl -X "GET" "https://instant-api.litmus.com/v1/clients/configurations"
ruby
> Litmus::Instant.client_configurations
# => {"OL2000"=>{"orientation_options"=>["vertical"], "images_options"=>["allowed"]},
# "OL2002"=>{"orientation_options"=>["vertical"], "images_options"=>["allowed"]},
# "OL2003"=>{"orientation_options"=>["vertical"], "images_options"=>["allowed", "blocked"]},
# ... clipped ...
Result Format
200 OK
json
{
"OL2000": {
"orientation_options": [
"vertical"
],
"images_options": [
"allowed"
],
"name": "Outlook 2000",
"group": "Desktop",
"platform": "Windows 7",
"status": "normal"
},
"OL2002": {
"orientation_options": [
"vertical"
],
"images_options": [
"allowed"
],
"name": "Outlook 2002",
"group": "Desktop",
"platform": "Windows 7",
"status": "normal"
},
"OL2003": {
"orientation_options": [
"vertical"
],
"images_options": [
"allowed",
"blocked"
],
"name": "Outlook 2003",
"group": "Desktop",
"platform": "Windows 7",
"status": "normal"
}
... clipped ...
}
Request a preview
GET
https://instant-api.litmus.com/v1/emails/:email_guid/previews/:client
This triggers the capture of a preview. Once the capture is complete, the content of the JSON response body will contain URLs for each of the image sizes available. A second request will be needed to obtain actual image data.
WARNING
This method typically blocks for about 6 seconds when a new preview must be captured.
The URLs returned will be on subdomains of litmuscdn.com
e.g. https://ol2015.capture.litmuscdn.com/87bf47f2-600e-40eb-8ccb-c9649f17644d/results/ol2015-vertical-allowed.png
. GET requests to these URLs will return redirects to the current location of the image asset.
Subsequent requests for a capture that's previously been made will result in a redirect to the cached result of the previous capture. To trigger a new capture a new email_guid
must be obtained. Only the initial capture is a billable event, not GETs of the cached preview.
Path parameters | Description |
---|---|
email_guid | REQUIRED string Provided on email creation |
client | REQUIRED string An identifier present in available clients |
Query parameters | Description |
---|---|
images | Default allowed string One of allowed , blocked . Refer to configurations to determine what's valid for for each client |
orientation | Default vertical string One of vertical , horizontal . Refer to configurations to determine what's valid for for each client |
Different configurations of the same client are considered as separate captures and billed as such. For instance the following would be considered three separate captures:
sh
$ curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/IPAD?images=allowed&orientation=vertical"
$ curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/IPAD?images=blocked&orientation=vertical"
$ curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/IPAD?images=blocked&orientation=horizontal"
Errors |
---|
400 Bad Request |
404 Not Found - when the email_guid is not found. This can occur when email assets or stored captures have expired having exceeded their lifetime |
500 Internal Server Error - in particular when email clients fail unexpectedly |
503 Service Unavailable |
504 Timeout - this can occur when an email client takes too long to respond |
Examples
sh
curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019" -v
ruby
Litmus::Instant.get_preview("7179b074-2b1e-455e-bf48-8068eb42d7ca", "OL2010", images: "blocked")
# => {"full_url"=>"https://ol2010.capture.litmuscdn.com/7179b074-2b1e-455e-bf48-8068eb42d7ca/results/ol2010-vertical-blocked-1366.png",
# "thumb_url"=>"https://ol2010.capture.litmuscdn.com/7179b074-2b1e-455e-bf48-8068eb42d7ca/results/ol2010-vertical-blocked-1366-thumb.png",
# "thumb450_url"=>"https://ol2010.capture.litmuscdn.com/7179b074-2b1e-455e-bf48-068eb42d7ca/results/ol2010-vertical-blocked-1366-thumb450.png"}
Result Format
200 OK
json
{
"full_url": "https://OL2019.capture.litmuscdn.com/87bf47f2-600e-40eb-8ccb-c9649f17644d/results/ol2019-vertical-allowed-1366.png",
"thumb_url": "https://OL2019.capture.litmuscdn.com/87bf47f2-600e-40eb-8ccb-c9649f17644d/results/ol2019-vertical-allowed-1366-thumb.png",
"thumb450_url": "https://OL2019.capture.litmuscdn.com/87bf47f2-600e-40eb-8ccb-c9649f17644d/results/ol2019-vertical-allowed-1366-thumb450.png"
}
Directly request a preview image
GET
https://instant-api.litmus.com/v1/emails/:email_guid/previews/:client/:capture_size
This method returns a redirect to the preview image or an (optional) redirect to a fallback image. In all other respects it behaves identically to requesting a preview above.
This makes requesting and displaying a capture in your user interface as simple as including any other remote image. For example, for a web application, you would place the constructed URL in the src
attribute of an <img>
tag (see example).
It can also be used as a convenience when downloading captures by simply configuring your HTTP client to follow redirects, cutting out the need to parse JSON and make a second request.
WARNING
This method typically blocks for about 6 seconds when a new preview must be captured.
Path parameters | Description |
---|---|
email_guid | REQUIRED string Provided on email creation |
client | REQUIRED string An identifier present in available clients |
capture_size | REQUIRED string One of full , thumb450 , thumb |
Query parameters | Description |
---|---|
images | Default allowed string One of allowed , blocked . Refer to configurations to determine what's valid for for each client |
orientation | Default vertical string One of vertical , horizontal . Refer to configurations to determine what's valid for for each client |
fallback | Default true boolean When fallback is enabled capture errors result in a redirect to a fallback image rather than in a failed response. An error is indicated by the presence of the custom header X-Litmus-Error . Errors relating to the request (i.e. 400 errors) are returned normally and do not result in the fallback redirect |
fallback_url | Defaults to the following fallback images: full, thumb450, thumb string A custom fallback image to display in case of errors. This must be an absolute URL, URL encoded and have a recognizable image extension. Query parameters are not supported. The image should be accessible publicly without the need for authentication |
Errors |
---|
400 Bad Request |
404 Not Found - when the email_guid is not found. This can occur when email assets or stored captures have expired having exceeded their lifetime |
500 Internal Server Error - in particular when email clients fail unexpectedly |
503 Service Unavailable |
504 Timeout - this can occur when an email client takes too long to respond |
WARNING
Some failure cases can take significantly longer to return than the typical 6 seconds for a successful case.
Examples
html
<img src="https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full">
sh
curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full" -v
* Trying 216.126.40.158...
* Connected to instant-api.litmus.com (216.126.40.158) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: instant-api.litmus.com
* Server certificate: RapidSSL SHA256 CA - G4
* Server certificate: GeoTrust Primary Certification Authority - G3
> GET /v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full HTTP/1.1
> Host: instant-api.litmus.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Tue, 16 Feb 2016 09:53:39 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 0
< Connection: keep-alive
< Location: https://OL2019.capture.litmuscdn.com/87bf47f2-600e-40eb-8ccb-c9649f17644d/results/ol2019-vertical-allowed-1366.png
< Strict-Transport-Security: max-age=3600; includeSubdomains; preload
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
<
sh
# failure with default fallback behaviour
curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full" -v
* Trying 216.126.40.158...
* Connected to instant-api.litmus.com (216.126.40.158) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: instant-api.litmus.com
* Server certificate: RapidSSL SHA256 CA - G4
* Server certificate: GeoTrust Primary Certification Authority - G3
> GET /v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full HTTP/1.1
> Host: instant-api.litmus.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: nginx
< Date: Tue, 16 Feb 2016 09:57:24 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 0
< Connection: keep-alive
< X-Litmus-Error: 500 Server error
< Location: https://instant-api.litmuscdn.com/images/placeholder-full.png
< Strict-Transport-Security: max-age=3600; includeSubdomains; preload
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
<
sh
# failure with fallback disabled
curl -X "GET" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full?fallback=false" -v
* Trying 216.126.40.158...
* Connected to instant-api.litmus.com (216.126.40.158) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: instant-api.litmus.com
* Server certificate: RapidSSL SHA256 CA - G4
* Server certificate: GeoTrust Primary Certification Authority - G3
> GET /v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/OL2019/full?fallback=false HTTP/1.1
> Host: instant-api.litmus.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Server: nginx
< Date: Tue, 16 Feb 2016 10:02:09 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 496
< Connection: keep-alive
<
{
"status": 500,
"title": "Server error",
"description": "An unknown error occurred. We know this is frustrating, but we ran into a problem and we don’t yet have a way to categorize and report it to you as this type of error hasn’t occurred before. This type of error is logged on our end, but if you see this while in development, please do reach out to us at resellers@litmus.com with details of your request and we’ll have a Support Engineer get back to you as soon as possible."
}
ruby
@preview_url = Litmus::Instant.preview_image_url(email_guid, "OL2010")
# => "https://OL2010.instant-api.litmus.com/v1/emails/755d1f9f-ad28-460f-8e45-632e0eceab32/previews/OL2010/full"
# Which could be used in a view template eg
# <%= image_tag @preview_url %>
Delete an email and its previews
DELETE
https://instant-api.litmus.com/v1/emails
This method allows deleting a batch of emails and any previews associated with them.
The request is accepted if well formed, but the response itself provides no indication of the state of the emails before or after the request. An email may already have been deleted, or have never existed, and the request would still be Accepted.
Deletion is scheduled shortly after an accepted request (usually completing within seconds).
Confirmation of deletion requires attempted requests to the original resource URLs.
Body parameters | Description |
---|---|
email_guids | array of strings An array of up to 1,000 email_guid s provided by the API at email creation time |
Errors |
---|
400 Bad Request |
401 Unauthorized |
Examples
sh
curl -X "DELETE" "https://instant-api.litmus.com/v1/emails" \
-H "Content-Type: application/json" \
-u "$API_KEY:" \
-d "{\"email_guids\":[\"3fefaeb4-8c99-4779-8594-8d441ab07a1e\"]}"
Result Format
202 Accepted
json
{
"status": "Accepted",
"email_guids": [
"3fefaeb4-8c99-4779-8594-8d441ab07a1e"
]
}
Pre-request previews before download
POST
https://instant-api.litmus.com/v1/emails/:email_guid/previews/prefetch
This method is provided as an optional performance enhancement, typically useful before embedding a set of previews within a browser, where connection limits might otherwise delay the start of capture of some previews. For more detail on when this might be useful see performance.
The method does not block while capture occurs, a 202 Accepted
response is returned immediately.
Note that should capture failure occur for a preview, it will only be discovered when the preview is later requested. Request errors, for instance attempting to prefetch an invalid client, will result in a 400 Bad Request
however.
Path parameters | Description |
---|---|
email_guid | REQUIRED string Provided on email creation |
Body parameters | Description |
---|---|
configurations | REQUIRED array of objects An array of capture configurations as JSON objects, see table below |
Capture configuration | Description |
---|---|
client | REQUIRED An identifier present in available clients |
images | optional One of allowed (default), blocked . Refer to configurations to determine what's valid for for each client |
orientation | optional One of vertical (default), horizontal . Refer to configurations to determine what's valid for for each client |
Errors |
---|
400 Bad Request - if the request body is malformed, or if any requested capture configuration is invalid |
404 Not Found - when the email_guid is not found. This can occur when email assets or stored captures have expired having exceeded their lifetime |
JSON response body attributes | Description |
---|---|
configurations | Confirmation of capture configurations that will be prefetched |
Examples
sh
curl -X "POST" "https://instant-api.litmus.com/v1/emails/87bf47f2-600e-40eb-8ccb-c9649f17644d/previews/prefetch"\
-H "Content-Type: application/json" -v\
-d '{"configurations":[
{"client":"OL2010"},
{"client":"OL2010", "images":"blocked"},
{"client":"IPAD"}
]}'
ruby
Litmus::Instant.prefetch_previews(
email_guid, [
{ client: "OL2010" },
{ client: "OL2013", images: "blocked" }
]
)
# => {"configurations"=>
# [{"orientation"=>"vertical", "images"=>"allowed", "client"=>"OL2010"},
# {"orientation"=>"vertical", "images"=>"blocked", "client"=>"OL2013"}]}
Result Format
202 Accepted
json
{
"configurations": [
{
"orientation": "vertical",
"images": "allowed",
"client": "OL2010"
},
{
"orientation": "vertical",
"images": "blocked",
"client": "OL2010"
},
{
"orientation": "vertical",
"images": "allowed",
"client": "IPAD"
}
]
}
Identifying End Users
INFO
In earlier API versions "End User Identifier" was referred to as "User GUID".
You may find it useful to partition your API usage data by your end users. If you are offering an unlimited previews facility to your users, we need to be able to identify the number of unique users of your application.
To do this, you can associate emails (and, as a consequence, any previews), with a unique identifier of your choosing—an end_user_id.
WARNING
The identifier used must be unique to that user. The identifier should be stored in a unique field within your database and should not change for the life of that user's account.
This information is never shared with anyone, not even your user. It will only be shown in your billing reports and confirmed in the response to a POST request that provides it.
Do not use a hash of your user's details unless you can ensure that this will remain unchanged and unique for that user. You'll want to refrain from hashing user details because, by doing so, a hash of their email address could change over time and cause them to be identified twice in one month.
Standard UUIDs make a good choice for this field, but any uniquely identifying string of 64 characters or less may be used.
sh
# An example of identifying an end user when POSTing a new email
$ curl -X "POST" "https://instant-api.litmus.com/v1/emails" \
-H "Content-Type: application/json" \
-u "$API_KEY:" \
-d "{\"plain_text\":\"Hello World\",\"end_user_id\":\"a5725576-07d5-4e28-9e6c-2f1851825c14\"}" -v
> POST /v1/emails HTTP/1.1
> User-Agent: curl/7.37.1
> Host: instant-api.litmus.com
> Accept: */* > Content-Type: application/json
> Authorization: Basic XXXXXXXXXXXXXXXXXXXXXX
> Content-Length: 28
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Thu, 16 Jul 2015 12:35:02 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 58
< Connection: keep-alive
< Strict-Transport-Security: max-age=3600;
<
{ "email_guid": "ce6ba90f-cf28-4772-ab09-30a1d48a5e12", "end_user_id": "a5725576-07d5-4e28-9e6c-2f1851825c14"}
Performance
Working with long running requests
To avoid complexity, the first request for a new preview blocks for a number of seconds until the capture has completed. However, this introduces some complications.
Captures are only initiated when a request for a preview has been made. If you make your requests in serial and wait for responses before proceeding, then they'll stack behind each other. This will multiply your overall load time.
Requesting multiple previews in parallel can be used to initiate capture for all desired configurations at once. In this case, your load time will be limited to the longest running query. Alternatively, you could choose to show those ready earlier as soon as they're available.
At scale, this could lead to a large number of open waiting connections if these requests are made server-side. We can also run into client-side connection limits in the browser.
Working with browser connection limits
Requesting a single preview or two in parallel
If you're only requesting a single preview or two in parallel, then you can skip this section on working with browser connection limitations. All common browsers allow this to occur unrestricted.
Requesting 3-6 images in parallel
You can safely ignore this unless you're concerned about the performance of your web application in legacy browsers where per-host connection limits will impact users.
However, if you're concerned about the following browsers, we have a solution:
- IE6 or IE7 – Maximum connections per host is 2
- Opera 9.x – Maximum connections per host is 4
- Safari 3 and 4 – Maximum connections per host is 4
To remedy this, we allow access to the API assets using domain sharding.
Requesting 7-10 images in parallel
At 7 concurrent connections many browsers start to reach per host limits. As above, see domain sharding.
Requesting 10+ images in parallel
When we reach 10 concurrent connections we start to hit all-host connection limits, particularly in Chrome. Domain sharding doesn't stop our 11th request being queued, so it's best to pre-request any images required before embedding.
Domain sharding
We allow GET requests against the API at custom subdomains, which allows you to circumvent browser per-host connections limits at the small cost of additional DNS lookups.
For instance, if the following hit a per-host connection limit:
html
<img src="https://instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2000/thumb">
<img src="https://instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2002/thumb">
<img src="https://instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2003/thumb">
<img src="https://instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2007/thumb">
<img src="https://instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2010/thumb">
<img src="https://instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/NOTES9/thumb">
The limit could be circumvented with:
html
<img src="https://OL2000.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2000/thumb">
<img src="https://OL2002.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2002/thumb">
<img src="https://OL2003.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2003/thumb">
<img src="https://OL2007.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2007/thumb">
<img src="https://OL2010.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2010/thumb">
<img src="https://NOTES9.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/NOTES9/thumb">
Note that the choice of subdomain is arbitrary. You only need to ensure that they are distinct. You could equally use:
html
<img src="https://1.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2000/thumb">
<img src="https://2.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2002/thumb">
<img src="https://3.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2003/thumb">
<img src="https://4.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2007/thumb">
<img src="https://5.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/OL2010/thumb">
<img src="https://6.instant-api.litmus.com/emails/ce6ba90f-cf28-4772-ab09-30a1d48a5e12/previews/NOTES9/thumb">
Pre-request
Pre-requesting allows for requesting that a capture (or set of captures) is initiated for specified configurations with an immediate (non-blocking) response.
Because the API guards against duplicate captures, this means that any requests queued due to browser connection limits will yield the preview as soon as the pre-requested capture has completed, rather than initiating then waiting the full duration of capture.
See the API method for further information.
Managing server-side connections
Downloading large volumes of raw image data or holding large numbers of open connections server-side could place unwanted burden on your infrastructure.
The simple solution to alleviate these concerns is to ensure capture requests are only made in-browser or in-app. This will distribute the bulk of the network and bandwidth strain.
If your use case doesn't allow for this approach, the bandwidth requirements are difficult to avoid. However, the number of open connections can be reduced by employing a pre-request along with a delay before attempting download of the captured previews.