Giftbit blog image.png

Enter email to get news and updates

Email open tracking – why and how to do it

Finding out whether or not an email has been read by your recipients is a great way to gather insight about your email.

It can also indicate (although see important caveats below) whether or not your emails are reaching users’ inboxes or are getting caught in a spam filter, as very few people open emails in their spam folder.

At Giftbit, email deliverability of gifts is core to our business, and open tracking is one of many statistics we collect and analyze to improve our product. It is also a metric we make available to our customers as part of their gift card orders.

How to do it

Email open tracking is a simple concept and implementation:

  1. Create a standard webapp driven URL in your product that accepts your tracking information via the URL or in parameters, but always return an image content type and corresponding binary image data (such as ‘image/gif’, and usually a 1×1 pixel transparent .gif).
  2. Embed the URL as the src of a tag in all outgoing emails you wish to track, adding appropriate information to the URL to identify the email and information you wish to track. Because the returned content type is an image, it will render properly as an image.
  3. Done! Whenever an email is opened and that tiny invisible image is rendered, your URL will be called. Capture and store the information to your database, etc.

Working example

All code samples are written in Groovy/Grails, but can easily be applied to any web framework / language.

Step 1 - create your controller

Your controller has two jobs:

Accept tracking information and do something with it. This example shows an image tracking controller that accepts a URL that looks like an image (, rather than a standard dynamic page ( The reason for doing it this way is to avoid it being identified as a web bug and stripped out by email clients and email scanning programs.

Return the actual binary data of the image and set the appropriate content type of the response.

In this example, we are tracking opens of gift emails. To track additional emails, I would add additional methods (which in grails are exposed as URL paths). This avoids a long single controller method with conditionals for different tracking types.

class OpenController {
     def openTrackingService

     def giftinstance() {
     String giftcode ='.gif', '')
     if (giftcode) {

     //add additional tracking as needed.
     //def someOtherEmail() {}

     public void sendTrackingImageToResponse() {
     response.contentType = 'image/gif'
     response.outputStream << openTrackingService.get1pixelTrackingImageAsBytes()

Here is the source for the service. While very simple, resist the urge to put your database interaction into your controller. Good encapsulation is fundamental to code health and maintainability.

Of note is the definition of the 1×1 pixel image data. Given that it is such a tiny amount of data, I chose to simply store the byte array from a 1×1 pixel transparent gif for performance and simplicity, rather than go and actually load the image data from a file/URL/Classpath every time I need it.

class OpenTrackingService {
   private final byte[] singlePixelTransparentShimBytes = [71, 73, 70, 56, 57, 97, 1, 0, 1, 0, -128, 0, 0, -1, -1, -1, 0, 0, 0, 33, -7, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59]

     public byte[] get1pixelTrackingImageAsBytes() {
     return singlePixelTransparentShimBytes

     public void trackGiftInstanceEmailOpen(String giftCode) {
     //update your tracking database/datastore accordingly.
     GiftInstance giftInstance = giftCode ? GiftInstance.findByGiftcode(giftCode) : null;
     if (giftInstance) {
          giftInstance.lastOpened = new Date()


     //public void trackSomeOtheStuff(def data) {}

Step 2 - add your image tag to your emails

For any email you want to track, simply add an tag to call your controller as part of the email source. Usually this is done as part of the footer.

<img src="" alt="">

This would result in the giftcode ‘GIFTCODE123′ being tracked every time the email is opened.

Important caveats

  • Your email must be sent as HTML (not plaintext), even if it is otherwise text, otherwise the tag will not function.
  • In order for open tracking to work, the recipient must render images in their email reader. If your email is text heavy, it is possible it may be opened and read without the user ever choosing to ‘display images.’ This solution works best with media rich email, in which your recipient will almost definitely choose to display images if they wish to read it.
  • Many email readers cache images, so while you can rely on your URL being called for the first open, it should not be relied on to be called every subsequent time the person reads or displays the email.
  • If you use a third party mail provider / mailing list tool, it is likely they have something similar to this already built in. Don’t roll your own if you can use something you already have available to you.

A quick word on click throughs

If your email is actionable, click throughs (the act of a user following a link from the email) are a great statistic to measure rather than, or in addition to, opens.

They work with plaintext emails and are easy to measure by adding a parameter to your destination in the links in the email ( or handling all your email links through a central tracking controller that does statistics recording and then sends the user to the real destination (

The advantage of the latter approach is that you don’t need your tracking business logic scattered throughout your application if there are many destinations.

Click throughs are often considered a ‘better’ metric because they show actual engagement and aren’t skewed by potential technical or user behaviour limitations that prevent images in emails from being rendered.