This guest post comes from Chris Gutierrez, an Engineer at apartment hunting app RadPad.

At RadPad, we recently rolled out a messaging system for renters to communicate with landlords within our mobile and web apps. As a mobile centric rental marketplace, we wanted communication on RadPad to be as simple and familiar as sending a text message.

On top of being able to send messages through our apps, we wanted users to be able to read and respond to messages via email. One detail we wanted to include in messaging is read receipts, a small response after a recipient has read a message letting you know it’s been read. It’s a small feature but great for letting you know someone is on the other end. Doing this was made trivial by the SendGrid Event Webhook.

With the Event Webhook, SendGrid will post a JSON payload to a URL you specify anytime a user opens or clicks a link in your email (there are nine types of email events). When RadPad sends out a message notification, we attach an X-SMTPAPI header to the email with additional data we use to identify the thread. SendGrid includes the data from the X-SMTPAPI header in the JSON payload sent to your webhook URL.

RadPad is a Rails app so we use ActionMailer to send email through SendGrid and attach the X-SMTPAPI header.

class MessageMailer < ActionMailer::Base
  def notification(recipient, thread)
    headers 'X-SMTPAPI' => {
      category: ['messages'],
      unique_args: {
        thread_hash: thread.thread_hash

    mail(, reply_to: "#{thread.thread_hash}", subject: 'New Message')

The controller we have set up to receive the webhook requests looks like this:

class Api::EmailsController < ApplicationController
  def track
    payload = params[:_json]
    payload = [params[:_json]] unless payload.kind_of?(Array)
    payload.each { |event| handle_payload(event) }
    render status: 200, json: true

  def handle_payload(event)
    if event['event'] == 'open'
      user = User.find_by_email(event['email'])
      thread = MessageThread.find_by_thread_hash(event['thread_hash'])
      thread.mark_as_read(user) if user && thread

Once a thread is marked as read from the email being opened, we then send out push notifications and events through Urbanairship and Pusher to update the UI of our apps in real time.

In addition to notifying users when their messages have been read, SendGrid also enables us to handle replying to messages through email using the Parse Webhook. The SendGrid Parse Webhook sends requests to an endpoint on our API with data from the email. To handle replies on RadPad, we use the Griddler gem which simplifies dealing with incoming messages from SendGrid.

Thanks to SendGrid, we were able to hit the ground running on some pretty complex email features with a relatively small development effort. Their webhook architecture is super simple to work with and great for delivering any data you could possibly need for email processing.

To learn how to set up the Parse Webhook, check out our docs article, Setting Up the Inbound Parse Webhook

Expert advice and insight about all things email including best practices tips, examples, and advice for marketers, developers, and everyone in between.