Spec: Common Fields

In the Segment Spec all the API calls have a common structure, and a few common fields. However, not every integration accepts every specced field. If you have a question about what fields an integration will accept, you can refer to the integration’s docs page, or check out our open-source integration code on Github.

Structure

Every API call has the same core structure and fields. These fields describe user identity, timestamping and mechanical aides like API version.

Here’s an example of these common fields in raw JSON:

{
  "anonymousId": "507f191e810c19729de860ea",
  "context": {
    "active": true,
    "app": {
      "name": "InitechGlobal",
      "version": "545",
      "build": "3.0.1.545"
    },
    "campaign": {
      "name": "TPS Innovation Newsletter",
      "source": "Newsletter",
      "medium": "email",
      "term": "tps reports",
      "content": "image link"
    },
    "device": {
      "id": "B5372DB0-C21E-11E4-8DFC-AA07A5B093DB",
      "advertisingId": "7A3CBEA0-BDF5-11E4-8DFC-AA07A5B093DB",
      "adTrackingEnabled": true,
      "manufacturer": "Apple",
      "model": "iPhone7,2",
      "name": "maguro",
      "type": "ios",
      "token": "ff15bc0c20c4aa6cd50854ff165fd265c838e5405bfeb9571066395b8c9da449"
    },
    "ip": "8.8.8.8",
    "library": {
      "name": "analytics.js",
      "version": "2.11.1"
    },
    "locale": "nl-NL",
    "location": {
      "city": "San Francisco",
      "country": "United States",
      "latitude": 40.2964197,
      "longitude": -76.9411617,
      "speed": 0
    },
    "network": {
      "bluetooth": false,
      "carrier": "T-Mobile NL",
      "cellular": true,
      "wifi": false
    },
    "os": {
      "name": "iPhone OS",
      "version": "8.1.3"
    },
    "page": {
      "path": "/academy/",
      "referrer": "",
      "search": "",
      "title": "Analytics Academy",
      "url": "https://segment.com/academy/"
    },
    "referrer": {
      "id": "ABCD582CDEFFFF01919",
      "type": "dataxu"
    },
    "screen": {
      "width": 320,
      "height": 568,
      "density": 2
    },
    "timezone": "Europe/Amsterdam",
    "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
  },
  "integrations": {
    "All": true,
    "Mixpanel": false,
    "Salesforce": false
  },
  "messageId": "022bb90c-bbac-11e4-8dfc-aa07a5b093db",
  "receivedAt": "2015-12-10T04:08:31.909Z",
  "sentAt": "2015-12-10T04:08:31.581Z",
  "timestamp": "2015-12-10T04:08:31.905Z",
  "type": "track",
  "userId": "97980cfea0067",
  "version": 2
}

In more detail these common fields for every API call are:

w
FieldTypeDescription
anonymousId optionalStringA pseudo-unique substitute for a User ID, for cases when you don’t have an absolutely unique identifier

See the Identities docs for more detail

context optionalObjectDictionary of extra information that provides useful context about a message, but is not directly related to the API call like ip address or locale

See the Context field docs for more detail

integrations optionalObjectDictionary of integrations to either enable or disable

See the Integrations field docs for more detail

messageId implicitStringAutomatically collected by Segment, a unique identifier for each message that lets you find an individual message across the API
receivedAt implicitDateAutomatically set by Segment, the timestamp of when a message is received by Segment

It is an ISO-8601 date string. See the Timestamps fields docs for more detail

sentAt optionalDateTimestamp of when a message is sent to Segment, used for clock skew correction

It is set automatically by the Segment tracking libraries. It is an ISO-8601 date string. See the Timestamps fields docs for more detail.

timestamp optionalDateTimestamp when the message itself took place, defaulted to the current time by the Segment Tracking API

It is an ISO-8601 date string

If the event just happened, leave it out and we’ll use the server’s time. If you’re importing data from the past, make sure you to provide a timestamp.See the Timestamps fields docs for more detail.

type implicitStringType of message, corresponding to the API method: 'identify', 'group', 'track', 'page', 'screen' or 'alias'
userId requiredStringUnique identifier for the user in your database

A userId or anonymousId is required

See the Identities docs for more detail

version implicitNumberVersion of the Tracking API that received the message, automatically set by Segment

Beyond this common structure, each API call adds a few specialized top-level fields.

Context

Context is a dictionary of extra information that provides useful context about a datapoint, for example the user’s ip address or locale. Context is a complete and explicit specification, so properties outside the spec will be ignored. You should only use Context fields for their intended meaning.

FieldTypeDescription
activeBooleanWhether a user is active

This is usually used to flag an .identify() call to just update the traits but not “last seen.”

appObjectdictionary of information about the current application, containing name, version and build.

This is collected automatically from our mobile libraries when possible.

campaignObjectDictionary of information about the campaign that resulted in the API call, containing name, source, medium, term and content

This maps directly to the common UTM campaign parameters.

deviceObjectDictionary of information about the device, containing id, manufacturer, model, name, type and version
ipStringCurrent user’s IP address
libraryObjectDictionary of information about the library making the requests to the API, containing name and version
localeStringLocale string for the current user, for example en-US
locationObjectDictionary of information about the user’s current location, containing city, country, latitude, longitude, region and speed
networkObjectDictionary of information about the current network connection, containing bluetooth, carrier, cellular and wifi
osObjectDictionary of information about the operating system, containing name and version
pageObjectDictionary of information about the current page in the browser, containing hash, path, referrer, search, title and url

Automatically collected by Analytics.js.

referrerObjectDictionary of information about the way the user was referred to the website or app, containing type, name, url and link
screenObjectDictionary of information about the device’s screen, containing density, height and width
timezoneStringTimezones are sent as tzdata strings to add user timezone information which might be stripped from the timestamp

Ex: America/New_York

traitsObjectDictionary of traits of the current user

This is useful in cases where you need to track an event, but also associate information from a previous identify call

userAgentStringUser agent of the device making the request

Context Fields Automatically Collected

Below is a chart that shows you which context variables are populated automatically by our iOS, Android and analytics.js libraries.

Other libraries only collect context.library, any other context variables must be sent manually.

Context FieldAnalytics.jsAnalytics-iosAnalytics-android
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
hash
library.name
library.version
ip*
locale
location.latitude
location.longitude
location.speed
network.bluetooth
network.carrier
network.cellular
network.wifi
os.name
os.version
page.path
page.search
page.title
page.url
referrer.id
referrer.type
screen.density
screen.height
screen.width
search
title
traits
userAgent
url
timezone
  • IP Address is not collected by our libraries, but instead filled in by our servers when it receives a message for client side events only.
  • Our Android library collects screen.density with this method.

Integrations

A dictionary of integration names that the message should be sent to. 'All' is a special key that applies when no key for a specific integration is found.

Integrations defaults to the following:

{
  All: true,
  Salesforce: false,
  Marketo: false
}

This is because the Salesforce and Marketo integrations have strict limits on API calls, and we don’t want to run over your limits by accident.

Sending data to the rest of our integrations is opt-out so if you don’t specify the integration as false in this object, it will be sent to rest of the integrations that can accept it.

Timestamps

Every API call has three timestamps, timestamp, sentAt and receivedAt.

They’re used for very different purposes.

If you’re receiving data from Segment, you only need to care about timestamp: the true time the datapoint occurred.

If you’re sending data to Segment (e.g. from a library), you need to include both sentAt and timestamp. Internally, we add receivedAt and make clock skew corrections to timestamp using the difference between receivedAt and sentAt.

All timestamps are ISO-8601 date strings.

timestamp

This is important to use for importing historical data to the API.

The timestamp timestamp specifies when the datapoint occurred. If you’re receiving data from Segment, this is the only timestamp you care about. For track calls it’s the exact time when the user performed an action. Or, for identify calls, this would be when you saw the user.

The timestamp field is settable from our server-side libs or if passing info directly to the HTTP endpoints.

sentAt

The sentAt timestamp specifies the clock time for the client’s device when the network request was made to the Segment API. For libraries and systems that send batched requests, there can be a long gap between a datapoint’s timestamp and sentAt. Combined with receivedAt, we can use sentAt to correct the original timestamp in situations where a user’s device clock cannot be trusted (mobile phones and browsers). The sentAt and receivedAt timestamps are assumed to occur at the same time (maximum a few hundred milliseconds), and therefore the difference is the user’s device clock skew, which can be applied back to correct the timestamp.

Note: The sentAt timestamp is only applicable to upstream data sources. If you’re receiving data from Segment it’s not useful for any analysis since it’s tainted by user’s clock skew.

receivedAt

The receivedAt timestamp is added to incoming messages as soon as they hit our API. It’s used in combination with sentAt to correct clock skew, and also to aid with debugging libraries and systems that deliver events in batches.

The receivedAt timestamp is most important as the sort key in our Warehouses product. Use this for max query speed when retrieving data from your Warehouse!


If you have any questions or see anywhere we can improve our documentation, please let us know or kick off a conversation in the Segment Community!