Timeline API Overview

The Timeline API allows integrators to create their own custom timeline events that will show up in the contact's timeline, like the follwing Example Webinar events:
icon-in-timeline.png

This walkthrough will step you through setting up Event Types and creating events for your customer's contacts.

Prerequisites

Check the prerequisites document for what you need to start using this API.

1. Creating an Event Type

Event Types describe a type of event that your app will add to a HubSpot contact's timeline. This should model a type of action that a specific contact can perform in your integration such as viewing a video, registering for a webinar, filling out a survey, etc. A single App can defined multiple event types. Each event type contains its own set of properties and templates. In list segmentation, users will be able to create list filters for a specific event types, such as: 'create a list of all contacts that have a Video Like where url is equal to ...' You must create an Event Type before you can create any events.

For this example, we'll create a new 'Example Webinar Registration' event type. For authentication we'll use your Developer HAPIKey.

curl -X POST -H "Content-Type: application/json" -d '
{ 
    "name" : "Example Webinar Registration", 
    "applicationId": <<appId>>
}' \
https://api.hubapi.com/integrations/v1/<<appId>>/timeline/event-types?hapikey=<<developerHapikey>>&userId=<<yourUserId>>

Be sure to replace <<appId>> with your App Id. Your App Id can be found both in the 'My Apps' list and in the application details screens. Also replace <<developerHapikey>> and <<yourUserId>> which you can find on the 'My Apps' screen in the 'Developer HAPIKey' section.

The properties headerTemplate and detailTemplate could also be provided here, see section 3. Defining Templates.

This POST request will return the full saved definition of the event-type. Be sure to note the id property in this response. This is the Event Type Id and it is needed in order to add properties to this event-type.

You can see all event-types defined for an app via this GET command:

curl -X GET https://api.hubapi.com/integrations/v1/<<appId>>/timeline/event-types?hapikey=<<developerHapikey>&userId=<<yourUserId>>

The GET request will also return the Event Type Ids.

2. Defining Event Properties

Once you've defined an Event Type it's likely that you'll want to define properties for the Event Type. Event Type properties allow you to attach custom data to events that can be displayed in the timeline or used for list-segmentation.

Using the Event Type Id from the Event Type created in the previous step, we'll add a couple properties to identify which webinar our contacts have registered for.

curl -X POST -H "Content-Type: application/json" -d '
{
    "name" : "webinarName",
    "label" : "Webinar Name",
    "propertyType": "String"
}' \
https://api.hubapi.com/integrations/v1/<<appId>/timeline/event-types/<<eventTypeId>>/properties?hapikey=<<developerHapikey>>&userId=<<yourUserId>>

curl -X POST -H "Content-Type: application/json" -d '
{
    "name" : "webinarId",
    "label" : "Webinar Id",
    "propertyType": "String"
}' \
https://api.hubapi.com/integrations/v1/<<appId>/timeline/event-types/<<eventTypeId>>/properties?hapikey=<<developerHapikey>>&userId=<<yourUserId>>

Similarly a GET will return all properties defined on an Event Type:

curl -X GET -H "Content-Type: application/json" https://api.hubapi.com/integrations/v1/<<appId>>/timeline/event-types/<<eventTypeId>>/properties?hapikey=<<developerHapikey>>&userId=<<yourUserId>>

The supported property types are:

  • String
  • Enumeration -- See the Property Options API for details on creating Enumeration properties.
  • Numeric
  • Date -- All dates must be in milliseconds in Unix time.

3. Defining Templates

Templates define how to display an event in a contact's timeline. The Timeline API allows you to specify Markdowndocuments with Handlebars templates. We accept two templates: the header template which should be just one line describing the event; and the details template which is the drill-down view of the event (examples below).

The event properties are passed as data to the templates. Using our example, you can reference the 'webinarName' property in the template by using {{webinarName}}.

The extraData of an event (discussed below in 'Understanding extraData') can only be referenced in the details template.

Templates can be defined on the event-type via the event-type API. For example we can add templates to our 'Example Webinar Registration' by modifying that event-type with a PUT:

curl -X PUT -H "Content-Type: application/json" -d '
{
    "id": 3,
    "applicationId": <<appId>>,
    "name": "Example Webinar Registration",
    "headerTemplate": "Registered for [{{webinarName}}](https://mywebinarsystem/webinar/{webinarId})",
    "detailTemplate": "Registration occurred at {{#formatDate timestamp}}{{/formatDate}}"
}' \
https://api.hubapi.com/integrations/v1/<<appId>>/timeline/event-types/<<eventTypeId>>?hapikey=<<developerHapikey>>&userId=<<yourUserId>>

Note the use of the #formatDate directive. This is a directive we have defined to allow for user-friendly date formatting.

Once an event is created for a Contact for this Event Type (see 'Creating an Event', below) the following will show up in that Contact's timeline:

example-event.png

Clicking on 'Show details' results in the details template being rendered:

example-event-details.png

The integration-icon.png is the default icon we show for integration events if the app has not specified a custom icon, see 'Setting up a Custom Icon' below.

The 'Example Webinars' text above is the name of the Application. In the contacts timeline, events are filterable by application.

4. Creating an Event

Now that an Event Type has been set up with properties and templates, we're ready to create Events for our customers' contacts. An example PUT to create an event is below:

curl -X PUT -H "Content-Type: application/json" \
-H "Authorization: Bearer CJSP5qf1KhICAQEYs-gDIIGOBii1hQIyGQAf3xBKmlwHjX7OIpuIFEavB2-qYAGQsF4" \
-d '
{
  "id": "001-001001",
  "eventTypeId": <<eventTypeId>>,
  "webinarName": "A Test Webinar",
  "webinarId": "001001",
  "email": "a.test.contact@email.com"
}' \
https://api.hubapi.com/integrations/v1/<<applicationId>>/timeline/event

This generates an event on a.test.contact@email.com's timeline like so (assuming the templates in 'Defining Templates' above):

test-webinar-example.png

Note that you can't use the developer hapikey to create events. This is because the developer hapikey is only for setting up event-types from your development portal. To create an event for a HubSpot portal, that portal will need to grant access to your application via OAuth. Using our OAuth flow you'll need to obtain an access token for a portal and use that to add events to that portal's contacts.

The Event Id

The id property in this request can be any string. This is meant to be generic enough to fit whatever ID scheme you use to keep track of these events in your system. This PUT requests are idempotent on this id so the same PUT to the same idwill not create a new event, but will update the existing event.

Setting the Event timestamp

By default, the timestamp of the event is the time that this PUT command is sent. You can customize the event time by providing it in the request body in a timestamp property like so:

curl -X PUT -H "Content-Type: application/json" \
-H "Authorization: Bearer CJSP5qf1KhICAQEYs-gDIIGOBii1hQIyGQAf3xBKmlwHjX7OIpuIFEavB2-qYAGQsF4" \
-d '
{
  "id": "001-001001",
  "eventTypeId": <<eventTypeId>>,
  "webinarName": "A Test Webinar",
  "webinarId": "001001",
  "email": "a.test.contact@email.com",
  "timestamp": 1388534400000
}' \
https://api.hubapi.com/integrations/v1/<<applicationId>>/timeline/event

This is prefered if you know the exact time an action occured. In this example, if we have the timestamp for this webinar registration, we should provide it in this PUT.

Times must be in milliseconds epoch time.

Associating to a Contact via Email

In order to create an Event you must be able to associate this event with a contact in the customer's portal.

In the examples above, we use email to associate the Event with a contact in the users portal. Because contacts in HubSpot are unique by email address, this is straightforward. If no contact exists under the email address you provide, a contact will be created. By default, this new contact will only have the email contact property provided. See the section below about 'Stamping Event Data onto Contact Properties' to see how to add additional data to Contact properties.

5. Stamping Event Data onto Contact Properties

In many cases, you'll want to modify the Contact properties for the Contacts to which you're adding events. This commonly happens in cases where adding the event will actually create a Contact--you'll likely want to update the first and last name properties on the Contact so that you don't just create a contact with only an email address and an event.

You can stamp data onto a Contact from an event by mapping your custom event properties to contact properties.

Consider this PUT command for defining a custom event property:

curl -X POST -H "Content-Type: application/json" -d '
{
    "name" : "companyName",
    "label" : "Company Name",
    "propertyType": "String",
    "contactProperty": "company"
}' \
https://api.hubapi.com/integrations/v1/<<applicationId>>/timeline/event-types/<<eventTypeId>>/properties?hapikey=<<developerHapikey>>&userId=<<yourUserId>>

This uses contactProperty to map this custom event property to the 'company' contact property. This means that when we create a new event that specifies a 'companyName', the 'company' property of the associated contact will also be set.

For example, creating an event like this:

curl -X PUT -H "Content-Type: application/json" \
-H "Authorization: Bearer CJSP5qf1KhICAQEYs-gDIIGOBii1hQIyGQAf3xBKmlwHjX7OIpuIFEavB2-qYAGQsF4" \
-d '
{
  "id": "001-001002",
  "eventTypeId": <<eventTypeId>>,
  "webinarName": "A Test Webinar With Company",
  "webinarId": "001001",
  "companyName": "TestCo",
  "email": "a.test.contact@email.com"
}' \
https://api.hubapi.com/integrations/v1/<<applicationId>>/timeline/event

Causes the 'company' property to be set on the Contact with the email address 'a.test.contact@email.com'

contact-with-company.png

Note: To ensure compatibility with all portals, you can only stamp to standard contact properties which will always be available in all portals.

6. Understanding extraData

You may need to add detail data to an event that doesn't fit the simple property-value structure used by the Event Type properties. You may need to add a list or some heirarchical breakdown to an integration event. This is where extraDatacomes in.

You can add a extraData attribute to an events json body. The value of this extraData can be any valid JSON. For example:

curl -X PUT -H "Content-Type: application/json" \
-H "Authorization: Bearer CJSP5qf1KhICAQEYs-gDIIGOBii1hQIyGQAf3xBKmlwHjX7OIpuIFEavB2-qYAGQsF4" \
-d '
{
    "id": "001-001002",
    "eventTypeId": <<eventTypeId>>,
    "webinarName": "A Test Webinar With Extra Data",
    "webinarId": "001001",
    "email": "a.test.contact@email.com",
    "extraData": {
      "pollData": [
        { "question": "How excited are you for this webinar?", "answer":"Quite!" },
        { "question": "How frequently do you use our product?", "answer":"Daily" }
      ],
      "coWorkers": [
        { "name": "Joe Coworker", "email":"jmcoworker@testco.com" },
        { "name": "Jane Coworker", "email":"jcoworker@testco.com" }
      ]
  }
}' \
https://api.hubapi.com/integrations/v1/<<applicationId>>/timeline/event

An example of using extraData in a details template:

Registration occurred at {{#formatDate timestamp}}{{/formatDate}}

#### Poll Questions
{{#each extraData.pollData}}
  **{{question}}**: {{answer}}
{{/each}}

#### Co-Workers
{{#each extraData.coWorkers}}
  * {{name}}
{{/each}}

Which will result in a timeline event that looks like:

extra-data-example.png

Note: The extraData attribute can only be referenced in the details template for an event. It cannot be used in either the header template or in list segmentation.

7. Setting Up a Custom Icon

To add visual appeal to your timeline items, you'll want to add a custom icon. This image file for this icon should have:

  • square dimensions
  • a transparent background
  • centered content
  • be able to size down to 15x15 pixels

For example:

Box_Green.png

Custom icons are added at the application level. So in the developers app, go to the application details page for your application and click on the grey placeholder icon next to the application name:

placeholder-icon-1.png

This will open up a file dialog where you can select the image file for your icon. After the icon has been uploaded it will replace the grey placeholder icon:

applied-icon.png

And this icon will now show next to all of the timeline events associated with this application:

icon-in-timeline_1.png

Docs for this section or API