# Track

## How it works[](#how-it-works)

The `track` method helps you record events: the things your users do on your site, in your app, and so on.

Each `track` call records a single event. Each event has a `name` and properties. For example, if you send a `track` call when someone starts a video on your website, the `name` of the event might be `Video Started`, and the properties might include the title of the video, the length of the video, and so on.

 See our API documentation for code samples

This page can help you better understand when and how to use this API method. But, if you already know how it works and are ready to get started, you can go straight to our [API documentation](/integrations/api/cdp) and start writing code.

## A typical call[](#a-typical-call)

A typical track call is relatively straightforward. It contains an event `name` and a `properties` object. The `name` is the name of the event you want to track, and the `properties` are custom values providing extra information about the event.

The call below is based on our JavaScript library, and doesn’t contain the `userId` or `anonymousId` of the person performing the event because our JavaScript library automatically captures that information for you. If you use our HTTP API or server libraries, you’ll need to include an identifier for the person performing the event in your request.

While this is the general shape of your call, our libraries actually capture much more information. See the [full payload below](#complete-payload). You can send additional objects in your call, overriding the information that our SDKs and libraries typically capture, but you’ll need to find documentation for your specific library for details.

```javascript
cioanalytics.track("Course Started", {
  course_in_series: 1,
  course_format: "pass/fail",
  title: "Intro to Customer.io"
});
```

## The full payload[](#complete-payload)

Our libraries capture much more information than you send with each call. This helps us provide context, not only for the person performing the event, but the source of the call.

Customer.io and our libraries typically populate `integrations` and timestamp values as shown in the payload below. If you use our JavaScript or mobile libraries, they’ll also populate `context` for you. If you use our server-side libraries, you’ll need to populate `context` yourself.

See [common fields](/integrations/data-in/source-spec/common-fields) for more information about context, integrations, and timestamps in source payloads.

```json
{
  "userId": "AiUGstSDIg",
  "type": "track",
  "event": "Course Started",
  "properties": {
    "course_in_series": 1,
    "course_format": "pass/fail",
    "title": "Intro to Customer.io"
  },
  "integrations": null,
  "messageId": "ajs-f8ca1e4de5024d9430b3928bd8ac6b96",
  "receivedAt": "2015-12-12T19:11:01.266Z",
  "sentAt": "2015-12-12T19:11:01.169Z",
  "timestamp": "2015-12-12T19:11:01.249Z",
  "version": 0,
  "context": {
    "active": true,
    "ip": "108.0.78.21",
    "locale": "string",
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML like Gecko) Chrome/46.0.2490.86 Safari/537.36",
    "channel": "browser",
    "campaign": {
      "name": "string",
      "source": "string",
      "medium": "string",
      "term": "string",
      "content": "string",
    },
    "page": {
      "name": "string",
      "path": "/",
      "referrer": null,
      "search": null,
      "title": "Customer.io Docs",
      "url": "https://customer.io",
      "keywords": [
        "string"
      ]
    },
    "library": {
      "name": "analytics.js",
      "version": "2.11.1"
    }
  },
  "anonymousId": "23adfd82-aa0f-45a7-a756-24f2a7a4c895",
  "originalTimestamp": "2015-12-12T19:11:01.152Z"
}
```

*   event string
    
    Required The name of the event
    
*   integrations object
    
    Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set `"All": false` to reverse this behavior.
    
    *   *Enabled/Disabled integrations\** boolean
        
*   messageId string
    
    A unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
    
*   properties object
    
    Additional properties for your event.
    
    *   *Event Properties\** any type
        
        Additional properties that you want to capture in the event. These can take any JSON shape.
        
*   receivedAt string  (date-time)
    
    The ISO-8601 timestamp when Data Pipelines receives an event.
    
*   sentAt string  (date-time)
    
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
    
*   timestamp string  (date-time)
    
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you’re not backfilling data, you can leave this field empty and we’ll use the current time or server time.
    
*   type string
    
    Required The event type. This is set automatically by the request method/endpoint.
    
    Accepted values:`track`
    
*   version number
    
    The version of the API that received the event, automatically set by Customer.io.
    

*   event string
    
    Required The name of the event
    
*   integrations object
    
    Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set `"All": false` to reverse this behavior.
    
    *   *Enabled/Disabled integrations\** boolean
        
*   messageId string
    
    A unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
    
*   properties object
    
    Additional properties for your event.
    
    *   *Event Properties\** any type
        
        Additional properties that you want to capture in the event. These can take any JSON shape.
        
*   receivedAt string  (date-time)
    
    The ISO-8601 timestamp when Data Pipelines receives an event.
    
*   sentAt string  (date-time)
    
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
    
*   timestamp string  (date-time)
    
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you’re not backfilling data, you can leave this field empty and we’ll use the current time or server time.
    
*   type string
    
    Required The event type. This is set automatically by the request method/endpoint.
    
    Accepted values:`track`
    
*   version number
    
    The version of the API that received the event, automatically set by Customer.io.
    

## Identifying the person who performed the event[](#identifying-the-person-who-performed-the-event)

If you use our JavaScript library, `track` calls automatically use the `userId` of the identified person or the `anonymousId` if you haven’t identified a user yet.

If you use our HTTP API or server libraries, you’ll need to include an identifier for the person performing the event in your request. You can use either a `userId` or an `anonymousId`. See the specific library documentation for more information about identifying people in requests.

See the [*Identify* page](/integrations/data-in/source-spec/identify-spec) for more information about User IDs and Anonymous IDs.

## Event names[](#event-names)

Every `track` call records a single event—something a person did on your website, in your app, and so on. The event must have a `name`. We recommend that you use human-readable names for events, so that everyone on your team knows what each event represents.

Don’t use nondescript names like **Event 12** or **TMDropd**. Instead, use unique but recognizable names like **Video Started** and **Order Completed**.

## Deduplicate events[](#deduplicate-events)

By default, we automatically assign a `messageId` to each call you make to Customer.io. But, you can set your own `messageId` if you need to deduplicate calls to Customer.io, ensuring that you don’t bog down your workspace with unnecessary traffic or trigger unnecessary downstream actions.

We’ll accept the first instance of any operation with a given `messageId` and ignore any operations with the same `messageId` **for the next 12 hours**. The `messageId` is can be any string value, but we recommend a hash of the event data or a UUID/ULID to ensure that you don’t inadvertently deduplicate events.

If you [backdate events](/integrations/data-in/importing-old-data/#advanced-backfilling-events), you’ll need to deduplicate them before you send them to Customer.io. We deduplicate the `messageId` for 12 hours after we receive the operation—not the timestamp on the event itself.

## Properties[](#properties)

Properties are information you want to record for the events you track. They can be anything that will be useful while analyzing the events later. We recommend that you send properties whenever possible because they give you a more complete picture of what your users do.

We’ve reserved some properties with semantic meanings in Customer.io, and handle them in special ways. For example, we always expect `revenue` to be a currency value that we send to your downstream integrations that handle revenue tracking.

You should **only use the following reserved properties for their intended meaning**.

**Property**

**Type**

**Description**

`revenue`

Number

Amount of revenue an event resulted in. This should be a decimal value, so a shirt worth $19.99 would result in a `revenue` of `19.99`.

`currency`

String

Currency of the revenue an event resulted in. This should be sent in the [ISO 4127 format](http://en.wikipedia.org/wiki/ISO_4217). If this isn’t set, we assume the revenue to be in US dollars.

`value`

Number

An abstract “value” to associate with an event. This is typically used in situations where the event doesn’t generate real-dollar revenue, but has an intrinsic value to a marketing team, like newsletter signups.

Different data-out integrations may use these special properties differently. For example, Mixpanel has a `track_charges` method for accepting revenue. Luckily, you don’t have to worry about those inconsistencies. Just pass along the reserved property (in this example,`revenue`) and **Customer.io will handle these conversions for you automatically.**