Timeline API Overview

The Timeline API allows integrators to create their own custom timeline events that will show up in the timeline of contacts, companies, or deals, like the following Example Webinar events:
event_expanded.png

This walkthrough will step you through setting up event types and creating events.

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 the timeline of a contact, company, or deal record in HubSpot. This should model a type of action that can be performed in your integration such as viewing a video, registering for a webinar, filling out a survey, etc. A single App can define 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 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 event type", 
    "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.

By default, event types will be created for contacts, but it's possible to create event types for companies and deals as well. See creating a timeline event type for more details.

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
  • Numeric
  • Enumeration -- One of a set of options. See creating an event type property for details.
  • Date -- All dates must be in milliseconds in Unix time.

Note: Event properties cannot be named log or lookup. These tokens are reserved as helpers by the library used to render events in-app, Handlebars.js. For more information, check out the Handlebars.js docs here.

3. Defining Templates

Templates define how to display an event in a record's timeline. The Timeline API allows you to specify Markdown documents 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 event type",
    "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:

event_collapsed.png

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

event_expanded.png

To set the icon that is displayed next to the events, see 'Setting up a Custom Icon' below.

The 'Example App Name' text above is the name of the Application. In the CRM 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, companies, and deals. The examples below assume we're working with the contacts event type created above. 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):

event_collapsed.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. The PUT requests are idempotent on this id, so another PUT with the same id will 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 preferred if you know the exact time an action occurred. 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.

5. Associating the event with a CRM object

In order to create an event, you must be able to associate the event with a contact, company, or deal in the customer's portal.

In the examples above, we're working with an event type that has the objectType set to CONTACT, and we use email to associate the Event with a contact in the users portal. Email addresses must be unique for contacts in HubSpot, so if there is an existing contact with the provided email, that contact would be updated, but if no contact exists under the email address you provide, a new 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. The example data here uses email (as do the examples above this section):

{
"id": "001-001001",
"eventTypeId": <<eventTypeId>>,
"webinarName": "A Test Webinar",
"webinarId": "001001",
"email": "a.test.contact@email.com"
}

If you are working with known contacts, you can also use the contact vid to associate the event. In those cases, you would use objectId in the request json. Note that this must the be the vid of an existing contact, as you will not be able to create new contacts using objectId. This example uses the objectId instead of email:

{
"id": "001-001001",
"eventTypeId": <<eventTypeId>>,
"webinarName": "A Test Webinar",
"webinarId": "001001",
"objectId": 1234
}

You can also associate an event with a contact by usertoken, or utk. The usertoken is used by the HubSpot tracking code to track visitors, and is stored in the hubspotutk cookie. Use the utk parameter to associate an event with a contact by usertoken. Note: It is not possible to associate events with anonymous visitors using the usertoken, so if the event is associated using only the utk, and the provided usertoken is not already associated with a contact, no new contact would be created and the event would not be visible in HubSpot. However, the event would appear in the timeline if a new contact was associated with the usertoken through another means (usually through a form submission including the hutk, or through the identify method of the Tracking Code API). For this reason, we recommend including the email in addition to the utk to make sure that the event gets associated with a new or existing contact.

If you're working with an event type for contacts, it's possible to include multiple identification parameters with the event, so any combination of the email, objectId, and utk parameters may be included. If multiple parameters are included, the objectId (vid) will have the highest priority when determining which contact to associate with the event, followed by utk, with email being the lowest priority. This means that you can update the email address of an existing record by including a new email address in the email parameter with the vid of a known record in objectId. This example uses the email address and usertoken together:

{
"id": "001-001001",
"eventTypeId": <<eventTypeId>>,
"webinarName": "A Test Webinar",
"webinarId": "001001",
"email": "a.test.contact@email.com",
"utk": "89b5afb740d41f4cd6651ac5237edf09"
}

In addition to working with contacts, it's also possible to create event types for companies and deals. For those event types, you must use objectId to associate the event with the company or deal. For companies, the objectId must be set to the companyId of the company you want to associate the event with, and for deals you would set the objectId to the dealId of the deal record.

In the example below, assuming the event type was set to the COMPANY objectType, this event would be associate with the company record with companyId 528253914:

{
"id": "002-001002",
"eventTypeId": <<eventTypeId>>,
"webinarName": "A Test Webinar",
"webinarId": "001001",
"objectId": "528253914"
}

6. Timeline Extensions

The Timeline Extensions feature can be used to display data from an external system using an IFrame. When included, the event will display a link that will open a modal window displaying the IFrame contents when clicked. The details for the IFrame are set in the timelineIFrame field, which is an object containing the following fields:

  • linkLabel - The text used to display the link that will display the IFrame.
  • iframeLabel - The label of the modal window that displays the IFrame contents. 
  • iframeUri - The URI of the IFrame contents.
  • width - The width of the modal window.
  • height - The height of the modal window.

For example, using this data for an event:

{
"id": "1501696173424",
"eventTypeId": 18568,
"webinarName": "A Test Webinar",
"webinarId": "001001",
"email": "a.test.contact@email.com",
"timelineIFrame": {
"linkLabel": "View external data",
"iframeLabel": "Example iframe",
"iframeUri": "https://www.example.com",
"width": 800,
"height": 300
}
}

Would create this event, with the "View external data" link:

external_data_link.png

Clicking that link would open a modal window displaying the page set in iframeUri:

iframe_modal.png

7. Stamping Event Data onto CRM Object Properties

In many cases, you'll want to modify the properties for the contacts, companies, or deals 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 the associated object from an event by mapping your custom event properties to contact, company, or deal properties.

Consider this PUT command for defining a custom event property, note the objectProperty field:

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

This uses objectProperty 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'

set_property.png

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

8. 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 hierarchical breakdown to an integration event. This is where extraData comes 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.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.

9. 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 scroll down till you see the Event timeline assets section:

timeline_assets.png

Note: The grayscale icon is used for the events when displayed in a contact's timeline. The full color icon is used when setting up list or workflow filters.

Click the icon or links to open the file selection dialog. You can also drag and drop an image file directly onto the existing icons.

Once you set the icons, they will be shown next to all of the timeline events associated with this application:

timeline_icon.png

Docs for this section or API