Direct API Integration

In this article, you’ll learn how to get your customer data flowing into our system: your list of users, their properties, and information about events (activities) they’re performing inside your app.

When you sign up for a new Userlist account, your list of users is blank. User profiles will start appearing there once you start pushing data for each individual user. When that happens depends on how your developer implements the integration. For example, the Rails library has an import task that gets all users into the system at once (more about that below).

Alternatively, Segment users can set up their integration in a few clicks. View this guide for instructions on Segment.

Start planning your campaigns as early as possible — this way you'll know what properties and events to track. Download these free worksheets to speed up the process.

How behavior tracking works

You can track user behavior by sending us user data as well as events.

User data (properties) represents the current state of the user and doesn’t have a temporal aspect — we only store the latest version. One of the properties might have changed in the past, but you cannot tell just by looking at it. User properties include things like their name, company role, their current payment plan, and anything else you prefer to track — like total number of created tasks (in a project management app for example).

Events are composed of an event name, a timestamp to describe when the event occurred, a set of additional properties (specific to the event type), and a user that triggered that event. Events are important activities performed by the user inside your application. E.g. in a project management app, events might include things like completed a task, created a new project, etc.

In addition to custom events you send us from your application, Userlist automatically records events that happen inside our system (like when users open a message, click a link, join a segment, etc.). So you don’t have to worry about tracking these things yourself.

Setting up the integration

Integrating Userlist into your application is done by sending user data and events into the system via our HTTP JSON API or via our Segment integration. We also offer libraries for some frameworks and languages that help with the integration:

Language / Framework GitHub
Ruby https://github.com/userlist/userlist-ruby
Ruby on Rails https://github.com/userlist/userlist-rails
JavaScript https://github.com/userlist/userlist-javascript
PHP https://github.com/userlist/userlist-php

Request payloads and responses

The Push API expects payloads as JSON as well as responds with JSON. It’s recommended to set the Accept and Content-Type accordingly.

1
2
Accept: application/json
Content-Type: application/json; charset=utf-8

Timestamps are expected to be strings formatted according to ISO 8601: YYYY-MM-DDTHH:MM:SS+HH:MM. If no time zone is given, we’ll assume UTC.

Object keys, as well as event names, will be normalized to snake_case. You’re free to use any format you like for these, just be aware that we’ll store it in snake_case way.

Userlist will automatically recognize custom properties as timestamps when the value is formatted according to ISO 8601.

Limits

The Push API has a rate limit of 1000 requests per minute per account. Additionally, there is also a 100KB request size limit.

Authentication

To start sending data into Userlist, you first have to get your Push API Key. It is used to authenticate your requests to the Push API and connect the data with your account. Keep this Push API Key secure, or an attacker will be able to mess with your data and automation.

All requests to our Push API need to have the Push API Key in the Authorization header in this format:

1
Authorization: Push your-push-api-key-here

Errors

When things go wrong, the Push API will respond with appropriate HTTP status codes. Status codes in the 2xx range can be considered as successful. Status codes in the 4xx range indicate a problem with the initial request. Status codes in the 5xx range indicate errors on the server.

The Push API will also respond with a JSON body describing the error in more detail.

1
2
3
4
{
  "status": 422,
  "errors": ["User must exist"]
}

Tracking user data

User data can be tracked by sending POST requests to https://push.userlist.com/users. The identifier is a unique identifier for that user within your application. This can either be the user’s primary key in your database, a generated tracking identifier or their email address (we don’t recommend using email address though, because it’s less reliable). Whatever you choose, please keep in mind that it’ll be the way Userlist identifies this user moving forward.

You can also send marketing leads to Userlist without an identifier, as long as you include an email.

The signed_up_at parameter accepts timestamps in ISO 8601 format.

The custom properties can be any format you like, and their type will be inferred.

Parameter Required
identifier No1
email No1
signed_up_at No
properties No
relationships2 No
company2 No
companies2 No

1 Either an identifier or an email address is required.
2 These parameters are mutually exclusive. Please only provide one of them.

Here’s what an example request might look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /users HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "identifier": "3d70d1d4-484a-4e72-8857-916ee525214e",
  "email": "delaney.jones@example.net",
  "properties": {
    "first_name": "Delaney",
    "last_name": "Jones"
  },
  "relationships": [
    {
      "company": "eb66093e-62be-47fb-82bc-64da1bd120b0",
      "properties": {
        "role": "owner"
      }
    }
  ]
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the data and it’ll show up inside Userlist within a few moments.

Deleting users

You can remove user data by sending a DELETE request to https://push.userlist.com/users. The body of the request is the same as for creating or updating users. We’ll process your deletion request within a few of moments and remove the user, all their events, as well as all their messages. All campaigns will immediately be stopped. If you send any data or event with this property after requesting a deletion, we’ll treat it as fresh and create a new user.

Here’s what an example request might look like:

1
2
3
4
5
6
7
8
DELETE /users HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "identifier": "3d70d1d4-484a-4e72-8857-916ee525214e"
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the request and the user will be removed from Userlist within a few moments.

Tracking company data

Company data can be tracked by sending POST requests to https://push.userlist.com/companies. The only required parameter is identifier which is a unique identifier for that company within your application. This can either be the company's primary key in your database, or some kind of generated tracking identifier. Whatever you choose, make please keep in mind that it’ll be the way Userlist identifies this company moving forward.

Parameter Required
identifier Yes
name No
signed_up_at No
properties No
relationships1 No
user1 No
users1 No

1 These parameters are mutually exclusive. Please only provide one of them.

Here’s what an example request might look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
POST /companies HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "identifier": "eb66093e-62be-47fb-82bc-64da1bd120b0",
  "name": "Example, Inc.",
  "properties": {
    "industry": "Testing",
    "billing_plan": "enterprise"
  },
  "relationships": [
    {
      "user": {
        "identifier": "3d70d1d4-484a-4e72-8857-916ee525214e",
        "email": "delaney.jones@example.net",
        "properties": {
          "first_name": "Delaney",
          "last_name": "Jones"
        }
      }
      "properties": {
        "role": "owner"
      }
    }
  ]
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the data and it’ll show up inside Userlist within a few moments.

Deleting companies

You can remove company data by sending a DELETE request to https://push.userlist.com/companies. The body of the request is similar to the one you sent when sending the company data initially. We’ll process your deletion request within a few of moments and remove the company, all its events, as well as all relationships to users. The users that were part of that company are not deleted automatically. If you send any data or event with this company after requesting a deletion, we’ll treat it as fresh and create a new company record.

Here’s what an example request might look like:

1
2
3
4
5
6
7
8
DELETE /companies HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "identifier": "eb66093e-62be-47fb-82bc-64da1bd120b0"
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the request and the company will be removed from Userlist within a few moments.

Tracking relationships

Userlist allows you to track relationships between users and companies. It's possible to track many-to-many relationships between users and companies. Creating a relationship needs at least two pieces of information: a user and a company. Both the user and company properties can be either an identifier or a user or company object with a structure like the one described above.

Parameter Required
user Yes
company Yes
properties No

Here's what an example request might look like:

1
2
3
4
5
6
7
8
9
10
11
12
POST /relationships HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "user": "3d70d1d4-484a-4e72-8857-916ee525214e",
  "company": "eb66093e-62be-47fb-82bc-64da1bd120b0",
  "properties": {
    "role": "admin"
  }
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the data and it’ll show up inside Userlist within a few moments.

Deleting relationships

You can remove relationship data by sending a DELETE request to https://push.userlist.com/relationships. We’ll process your deletion request within a few of moments and remove the relationship between this user and this company. Both the associated user and company are not deleted automatically.

Here’s what an example request might look like:

1
2
3
4
5
6
7
8
9
DELETE /relationships HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "user": "3d70d1d4-484a-4e72-8857-916ee525214e",
  "company": "eb66093e-62be-47fb-82bc-64da1bd120b0"
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the request and the relationship will be removed from Userlist within a few moments.

Tracking events

Similar to tracking user or company data, tracking events works by sending POST requests to https://push.userlist.com/events. Tracking an event requires at least two pieces of information: a name, and a user or company identifier. Other parameters are optional.

Parameter Required
name Yes
user Yes (unless there's a company)
company Yes (unless there's a user)
occurred_at No
properties No

Here’s what an example request might look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /events HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "name": "product_purchased",
  "user": "3d70d1d4-484a-4e72-8857-916ee525214e",
  "properties": {
    "product": "Flowers",
    "price": "$12.99"
  }
}

When successful, the Push API will respond with 202 Accepted and an empty body. Afterwards, we’ll process the data and it’ll show up inside Userlist within a few moments.

Referencing and embedding resources

In all payload that allow referencing another resources by their identifier (like an event that references the user that performed the event) it's also possible to embed the resource in place.

The following example shows a payload that references a user by their identifier.

1
2
3
{
  "user": "3d70d1d4-484a-4e72-8857-916ee525214e"
}

This is equivalent to the following expanded payload.

1
2
3
4
5
{
  "user": {
    "identifier": "3d70d1d4-484a-4e72-8857-916ee525214e"
  }
}

This allows complex updates of multiple related resources in the same transaction. The following example shows how to update a nested user resource within the parent payload.

1
2
3
4
5
6
7
8
9
{
  "user": {
    "identifier": "3d70d1d4-484a-4e72-8857-916ee525214e",
    "properties": {
      "first_name": "Delaney",
      "last_name": "Jones"
    }
  }
}

Nested properties

Nested properties will help structure your data, especially if you're managing multiple products in one Userlist account.

E.g. a billing plan property for Product A will look like this: user.product_a.billing_plan.

Here's an example payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /users HTTP/1.1
Accept: application/json
Authorization: Push your-push-api-key-here
Content-Type: application/json; charset=utf-8

{
  "identifier": "3d70d1d4-484a-4e72-8857-916ee525214e",
  "properties": {
    "product_a": {
      "billing_plan": "pro"
    },
    "product_b": {
      "billing_plan": "free"
    }
  }
}

However, we currently don't support namespacing for event names. You can send product_a.project_created, but we'd normalize that to product_a_project_created.

Client-side tracking

In addition to server-side tracking, Userlist also allows client-side tracking — via the same tracking script that powers in-app messages. See these articles for details:

Best practices for a successful integration

A successful integration isn’t just a matter of technical setup. It’s equally important to be strategic and consistent in your user tracking — so that the data reflects your business goals and makes sense to all team members down the road.

Before you start the integration process, you need to make the following decisions:

  1. Figure out what properties and events need to be tracked. What properties and events reflect user progress the best, and describe the milestones in your typical user journey?
  2. Choose a naming convention and use it to document these properties and events before you implement them in code.

For further reading, we recommend this article on naming conventions published by the team at Segment.

Here are some of our recommendations:

  • Use a framework for naming events (e.g. Object-Action framework)
  • Track time instead of boolean — this will enable you to segment more meaningfully and send better communications, since you know when the user performed a certain event last time (as opposed to a boolean)
  • For dates without time we recommend to use an _on suffix (e.g. next_billing_on), and for dates with time an _at suffix (e.g. trial_expires_at)
  • Be consistent with vocabulary and phrase structure. Our recommendation for event names is resource name + verb in past tense, e.g. message_sent, template_created
  • Be consistent with capitalization and characters between words — e.g., created-project vs created_project (this isn't mission-critical as we normalize it anyways, but still a good practice)

What exactly should I track?

You don't need to reinvent the wheel. Sure, many properties are specific to your industry, but many of them are similar to most SaaS companies. To help you with planning, we created a set of free planning worksheets (12 pages, printable PDF) to use as a baseline.

Book your discovery demo

Let's see how Userlist fits into the bigger picture of your SaaS business. You'll learn about our automation features, integrations, proven lifecycle frameworks, and how we can help you hit your SaaS growth targets.