Understanding Our Module Structure

If you plan on interacting with our templates programmatically, you are going to need to understand their basic structure. All of our templates require a JSON object we refer to as a context to be built. The context contain 4 top level sections and are used to set values for everything pertaining to an email. The 4 sections are rid, settings, custom, and components.

Recipient ID

The recipient ID (RID) is a string value that needs to be either unique per user or a merge tag for your email service provider (ESP) that is unique per user. We take this RID value and append it to a number of items in the email that are used for reporting our analytics. A great example value here would be email address.
Note: This field is not needed if you plan on using the /emails endpoint, if you use that endpoint our system will generate a universally unique id to use. This will make sure that if you send the same email address two separate transactional emails in one campaign the reporting will be separated.

Settings

The settings section is used to set global variables such as language, title or preheader, and to set styles for the container object in the email. The container is the table that wraps all the code in the email. The font styles set here are inherited by other elements wrapped by this container, making this the default value for the email.

Note: The specifics of our style structure will be covered in more detail as part of the component section.

Custom

The custom section of the context allows you to add some custom CSS and custom HTML above and below your module. There are 3 key values included here they are context.custom.css for CSS that will be wrapped in <style> tags in the <head> of the HTML, context.custom.header for HTML above the module, and context.custom.footer for HTML below the module.

Components

The components section is where you include all the information related to the module that you are sending. The section is an array, currently we only support one item in the array but we are working to get our customers the ability to add as many modules as needed in that array. Each component contains 3 sections, they are body, styles, and fallback.

Body

The body section contains all the content and settings that go into a specific module. This will include things like images, copy, and true/false switches to enable and disable certain features in the module. As an example let’s take a look at the body section of the Gallery module.

“body”: {
  "id":"test1",
  "images":[
    {
      "src":htttp://www.url.com/image1.jpg",
      "href":"htttp://www.url.com/1/"
    },
    {
      "src":htttp://www.url.com/image2.jpg",
      "href":"htttp://www.url.com/2/"
    },
    {
      "src":htttp://www.url.com/image3.jpg",
      "href":"htttp://www.url.com/3/"
    },
    {
      "src":htttp://www.url.com/image4.jpg",
      "href":"htttp://www.url.com/4/"
    }
  ],
  "tooltip":"Click thumbnails to view gallery",
  "hasArrows":true
}

Keep in mind the data covered in this section is content only. The structure for the gallery is fairly straightforward. There is an id, make sure that this is unique within the request if you are using more than one module. The images array contains all of the information needed to populate the gallery images. The number of items in the array corresponds to the number of images in the gallery and the order will be the order they are shown in the email (top down). Lastly included there are a few stand alone settings to include, they turn on and off whether or not the gallery has arrows for navigating and allow you to change the copy of a tooltip that appears letting users know what to do.

The body.tooltip value is a good example of key concept we employ in our API, when setting the value for a piece of content an empty string will set that value to false. So instead of having two keys, one toggling if the content appears or not and one setting the value, we allow the empty string to represent a false value. So setting:

…
“tooltip”: “”,
…

Will result in no tooltip being displayed.

Styles

We strive to give our users as much control over their templates as they like, you can get down into the nitty-gritty of a template and adjust the tiniest details. And while we love when our customers take the styling of our emails seriously, we do stress that as is true for Spiderman is true for our customers. With great power comes great responsibility. That is to say, we want you to style to your heart's content, but make sure that you are testing thoroughly. We do not set any limits on what you can set a value to, but at certain points your choices can break the layouts of our emails.

Our styles follow a consistent structure, and if you are familiar with CSS you will find more than a few stolen concepts. That isn’t by accident, with our API you should feel like you are working with normal CSS, we will handle all the hard bits of making it uniform on all the various email clients.

Take a look at an example style block here:

"width":"300",
"height":"300",
"background":{
  "color":"#f69513"
},
"border": {
  "color": "",
  "width": "",
  "style":"",
  "radius": ""
},
"padding":{
  "top":"5",
  "right":"5",
  "bottom":"5",
  "left":"5"
},
"margin":{
  "top":"5",
  "right":"5",
  "bottom":"5",
  "left":"5"
},
"boxShadow": {
  "horizontalOffset": "",
  "verticalOffset": "",
  "blur": "",
  "spread": "",
  "color": ""
},
"font": {
  "color": "#fff",
  "decoration":"",
  "family":"",
  "style":"",
  "weight":"",
  "size": "16",
  "align":"center"
}

A couple notes on the style block above and what you can expect going forward:

  • Most styles are logically nested allowing you granular control. E.G. Setting a padding-top: 10px; becomes setting a value at padding.top
  • For fonts and box-shadows this rule breaks slightly. For instance, when you want to set a text-decoration: normal; you would be placing the value at font.decoration this is to avoid having two sibling elements that control styles of one object.
  • Styles that are inheritable will inherit as normal. For example, setting the font.family on a wrapping container will apply that choice to nested items like a button. Unless it is specifically overridden by setting the font.family on that element.
  • There is no need to append units to any number values, when trying to set padding-top: 10px you only need to include the value as 10, our system will append the needed unit.
  • As with content, anytime that you leave a value empty the system will not include the CSS rule for that element.
  • And lastly, while you will be given complete control over almost every element with our API, from time to time a value will be omitted by the template, often times these are things like height or width that need to be set to auto. In these cases while you will not get an error from our API we will ignore the value when rendering the template in favor of displaying a working layout. See the individual module documentation for examples of this.
    This style block structure is also used to apply styles for pseudo states, e.g. hover, selected, and focus. Only certain elements will have these pseudo states, they are there for things like inputs, thumbnails and buttons. For elements that have a pseudo state, there is a nested object at styledObject.hover, it will accept the exact same values as a normal style block.

Fallback

The last section available is for setting the fallback object. The fallback is our term for what will be displayed on email clients that cannot support interactivity. We offer up three options.

  • ”fallback.type”: “none”: means that nothing will display in it’s place.
  • ”fallback.type”: “custom-html”: means that you can add any html you would like to be displayed.
  • ”fallback.type”: “multi-image”: means you can include an array of images and links that are displayed one on top of the other.

Next Steps

That covers all of the basics that you need to get started building our modules programmatically. For next steps we would suggest checking out the documentation for the modules you’d like to send. And reach out with any questions.