# Common fields

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

When you send a call to Customer.io, we capture additional information from our libraries and information implicit in each call, like:

*   `context` for the source of your calls
*   the `ip` and `locale` of the person the call represents
*   timestamps that help you understand the chronology of your data

The added context these common fields provide can help you debug issues with your data or add special handling in actionsThe source event and data that triggers an API call to your destination. For example, an incoming `identify` event from your sources *adds or updates a person* in our Customer.io Journeys destination. for downstream applications.

## A full payload[](#a-full-payload)

Imagine you send the `track` call (using our [JavaScript client library](/integrations/data-in/connections/javascript)) below. The call itself simply contains the event `name` and a `properties` object:

```javascript
cioanalytics.track("Report Submitted", {
  reportType: "sales",
  reportFormat: "csv"
})
```

But, when you look at your call in Customer.io, you’ll see the complete payload below. Our libraries and API automatically capture the `context`, `integrations`, `messageId`, `receivedAt`, `sentAt`, `version`, `type` (which is implicit in the method/endpoint you call), and [timestamp properties](#timestamps).

```json
{
  "userId": "AiUGstSDIg",
  "event": "Report Submitted",
  "properties": {
    "reportType": "sales",
    "reportFormat": "csv"
  },
  "integrations": {
    "All": true
  },
  "messageId": "ajs-f8ca1e4de5024d9430b3928bd8ac6b96",
  "timestamp": "2015-12-12T19:11:01.249Z",
  "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": [
        "report"
      ]
    },
    "library": {
      "name": "analytics.js",
      "version": "2.11.1"
    }
  },
  "anonymousId": "23adfd82-aa0f-45a7-a756-24f2a7a4c895",
  "receivedAt": "2015-12-12T19:11:01.266Z",
  "sentAt": "2015-12-12T19:11:01.169Z",
  "type": "track",
  "originalTimestamp": "2015-12-12T19:11:01.152Z"
}
```

## The context object[](#the-context-object)

The `context` object contains useful information about the origin of a call, like the `page` the call originates from, or the `ip` address of the user the call represents.

You’ll notice slightly different context depending on whether you use a mobile SDK or another SDK. Our mobile libraries capture information about a `device` rather than a `page`.

If you use our [server libraries](/integrations/data-in/connections/servers), you’ll need to set this information yourself. Make sure that you use these properties for their originally-intended purpose; setting values that don’t make sense for the property can result in unexpected behaviors in downstream applications that rely on context.

### Automatically-collected fields[](#automatically-collected-fields)

Our [JavaScript](/integrations/data-in/connections/javascript), [mobile](/integrations/sdk/), and server libraries capture the information below.

For now, our mobile libraries collect very few fields but we’re working on changes that will increase the `context` they capture.

Our server-side libraries generally require you to send context and other common fields yourself. They’ll set the `context.library` property, but you should check with the appropriate documentation for the server library you use for help adding context to your calls.

Context Field

JavaScript (Web)

Mobile (iOS/Android)

Server

app.name

✅

app.version

✅

app.build

✅

campaign.name

✅

campaign.source

✅

campaign.medium

✅

campaign.term

✅

campaign.content

✅

device.type

✅

device.id

✅

device.advertisingId

✅

device.adTrackingEnabled

✅

device.manufacturer

✅

device.model

✅

device.name

✅

journeys.identifiers

✅

library.name

✅

✅

✅

library.version

✅

✅

✅

ip1

✅

✅

locale

✅

✅

network.bluetooth

network.carrier

✅

network.cellular

✅

network.wifi

✅

os.name

✅

os.version

✅

page.path

✅

page.referrer

✅

page.search

✅

page.title

✅

page.url

✅

screen.height

✅

screen.width

✅

traits

✅

userAgent

✅

✅

userAgentData2

✅

timezone

✅

1Our libraries don’t capture IP address. Our servers fill in this information when we receive calls from our JavaScript or mobile libraries.

2We only collect `userAgentData` when the [Client Hints API](https://developer.mozilla.org/en-US/Web/API/User-Agent_Client_Hints_API) is available in the browser.

## The integrations object[](#the-integrations-object)

When you connect a data source to an integration, we send all the data for which we have actionsThe source event and data that triggers an API call to your destination. For example, an incoming `identify` event from your sources *adds or updates a person* in our Customer.io Journeys destination. to that integrated service. But you can filter calls you make to Customer.io directly from your data source to a specific subset of downstream integrations using the `integrations` object.

In general, we recommend that you filter calls for each data-out integration using actionsThe source event and data that triggers an API call to your destination. For example, an incoming `identify` event from your sources *adds or updates a person* in our Customer.io Journeys destination., because they’re easier to change and manage than your source code. But you might want to modify the `integrations` object if:

*   You have an integration that bills you for incoming API calls and you want to limit traffic to that service.
*   if you know that information in the individual call is only useful in specific downstream integrations.

To limit a call to specific integrations, you need to set `"All": false` and set `true` for the integrations you want to send to.

Within the integrations object, you need to use the *integration name* exactly as we show it at the top of every data-out integration in [our integration directory](/integrations/catalog). For example, if you simply used `Mixpanel` below, we may not recognize the integration and send the call to your Mixpanel destination.

```json
{
    "integrations": {
        "All": false,
        "Actions Customerio": true,
        "Google Analytics 4 Cloud": true,
        "Mixpanel (Actions)": true
    }
}
```

[![find the integration name in our catalog pages](https://docs.customer.io/images/cdp-integration-name.png)](#1fc8a96d54840b8f3cd2c778d78775e3-lightbox)

## `messageId`: deduplicate calls[](#messageid-deduplicate-calls)

When you send a call to Customer.io, we generate a `messageId` for the call. This `messageId` is a value that uniquely identifies a call to Customer.io.

If you think you might send duplicate calls or events to Customer.io, you can generate your own `messageId` string and send it as a part of your calls.

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.

## Timestamps[](#timestamps)

Every call includes [ISO-8601](http://en.wikipedia.org/wiki/ISO_8601) timestamps, `originalTimestamp`, `timestamp`, `sentAt`, and `receivedAt`, each with different purposes.

When analyzing your data, we recommend that you use `receivedAt` when chronology doesn’t matter and `timestamp` when it does. This is because `receivedAt` is typically correct but not guaranteed to be in chronological order, but the formula we apply to `timestamp` ensures that it is always in chronological order.

Timestamp

Calculated

Description

`originalTimestamp`

The date-time on the client device when you invoked a call or a value that you pass manually from a server-side library.

Used to calculate `timestamp`.

`sentAt`

The date-time on client device when you invoked a call or a value that you set manually in your call.

Used to calculate `timestamp`.

`receivedAt`

The date-time when Customer.io received a call.

Used to calculate `timestamp` and used as sort key in data warehouse and database integrations.

`timestamp`

Calculated by Customer.io to correct client-device clock skew using the formula: `receivedAt` - (`sentAt` - `originalTimestamp`).

Used to send data to downstream integrationss and in data replays.

## Reserved traits and properties in Customer.io[](#reserved-traits-and-properties-in-customerio)

Some traits and properties in [semantic events](/integrations/data-in/semantic-events/cio-journeys/) have special meanings within Customer.io. You should only use these fields for their intended purposes when you send data into Customer.io.

Trait/Property

Purpose

Set by Customer.io

`id`

A synonym for `userId` acting as a unique identifier for people. If your `userId` isn’t an email address, we automatically set the `userId` value as a person’s `id`.

`email`

A person’s email address. In most cases, we use email as another way to identify people. If you pass an email address as a `userId`, we’ll automatically set it as a person’s `email` trait.

`cio_id`

A unique, immutable identifier set by Customer.io, set automatically when you add a person. You cannot set this value yourself.

✅

`created_at`

We recommend that you set this value when you identify someone for the first time so you can take advantage of timestamp operators in [segmentsA group of people who match a series of conditions. People enter and exit the segment automatically when they match or stop matching conditions.](/journeys/data-driven-segments/). It also helps you determine the real age of a person’s profile.

`_created_in_customerio_at`

The date-time when Customer.io recognizes a new person. This value can be different from `created_at`, especially if you backdate people you identify.

✅

`unsubscribed`

Determines whether a person is subscribed or unsubscribed from email, SMS, and push messages.

`cio_object_id`

A unique, immutable identifier for [objectsAn object is a non-person entity that you can associate with one or more people—like a company, account, or online course.](/journeys/objects/) set automatically by Customer.io.

✅

`object_id`

A unique identifier for objects (like accounts, companies, etc).

`objectId`

An analog for `object_id` in some Customer.io integrations.

`relationshipTraits`

Used to reference relationships to objects.

`relationship`

Used to reference relationships to objects.

`_relationship`

Used in relationship-triggered campaigns to reference audience members who did not trigger the campaign. Cannot be used as the name of a trait.