Common Fields

Understand the common fields that define the core RudderStack event data structure.

RudderStack defines some common fields (event type, timestamps, and more) across all API calls that make up the core event data structure.

This guide covers the common and contextual fields in detail.

Common fields

Name
Data type
Description
userId
Required, if anonymousId is absent.
StringUnique identification for the user in the database
anonymousId
Required, if userId is absent.
StringPseudo-identifier for the user in cases where userId is absent. This is the same as the device ID.
channel
Required
StringIdentifies the source of the event. Permitted values are mobile, web, server and sources.
context
Required
ObjectContains all additional user information. The RudderStack SDKs populate this information automatically.
type
Required
StringCaptures the type of event. Values can be either identify, track, screen, page, group, or alias.
originalTimestamp
Required
TimestampRecords the actual time (in UTC) when the event occurred. Make sure it conforms to the ISO 8601 date format yyyy-MM-ddTHH:mm:ss.SSSZ.

For e.g., 2022-02-01T19:14:18.381Z.
sentAt
Required
TimestampCaptures the time (in UTC) when the event was sent from the client to RudderStack. Make sure it conforms to the ISO 8601 date format yyyy-MM-ddTHH:mm:ss.SSSZ.

For e.g., 2022-02-01T19:14:18.381Z.
eventStringCaptures the user action that you want to record.
integrationsObjectYou can specify the destinations for which you want to enable/disable sending events.
messageIdStringUnique identification for the event.
propertiesObjectPasses all relevant information associated with the event.

RudderStack also sets the following fields automatically, so you do not have to set them explicitly:

NameData typeDescription
receivedAtTimestampTime in UTC when RudderStack ingests the event.
timestampTimestampRudderStack calculates this field to account for any client-side clock skew using the formula: timestamp = receivedAt - (sentAt - originalTimestamp). See Clock skew considerations for more information. Note that this time is in UTC.
request_ipStringUser’s IP address. RudderStack automatically collects and sets this property as a common field. See How RudderStack collects IP address for more information.

Contextual fields

Contextual fields give additional information about a particular event. The following table describes the available contextual fields.

Name
Data type
Description
appObjectGives detailed information related to your app, like build, name, namespace and version.
campaignObjectGives detailed information about campaigns, like name, source, medium, content and term.
deviceObjectInformation about the device from which you are capturing the event. It contains the device id, manufacturer, model, name and type.
ipStringUser’s IP address. See How RudderStack collects IP address for more information.
libraryObjectDetails about the RudderStack SDK you are using, like name and version.
localeStringCaptures the language of the device.
networkObjectContains information about the reachability of the device. Also, it gives you the status of the device’s bluetooth, wifi, cellular network and carrier name.
osObjectCaptures the operating system details of the device you are tracking.

Note: While the JavaScript SDK does not populate this information automatically, you can get it using the uaChTrackLevel load API option.
screenObjectGives you the screen dimensions of the device, i.e. height, width and the density.
timezoneStringCaptures the timezone of the user you are tracking.
traitsObjectCaptures any additional relevant information about the user. RudderStack fills in the anonymousId for you. You can also associate the traits from the previously-made identify call from the SDK.
userAgentStringThe user agent of the device that you are tracking.

Automatically collected contextual fields

The following table describes contextual fields that are automatically collected and populated by the RudderStack SDKs:

FieldJavaScriptAndroidiOSDescription
app.name-YesYesName of the application.
app.version-YesYesVersion of the application.
app.build-YesYesBuild of the application.
campaign.nameYes--Name of the campaign.
campaign.sourceYes--Source of the campaign.
campaign.mediumYes--Medium of the campaign.
campaign.termYes--Term of the campaign.
campaign.contentYes--Content of the campaign.
device.type-YesYesType of the device.
device.id-YesYesID of the device.
device.advertisingId-YesYesAdvertising ID of the device.
device.adTrackingEnabled--YesIf ad tracking is enabled on the device.
device.manufacturer-YesYesManufacturer of the device.
device.model-YesYesModel of the device.
device.name-YesYesName of the device.
library.nameYesYesYesName of the library.
library.versionYesYesYesVersion of the library.
localeYesYesYesLocale string of the user.
network.bluetooth-Yes*-Bluetooth information.
network.carrier-YesYesCarrier information about the network connection.
network.cellular-YesYesCellular information about the network connection.
network.wifi-YesYesWiFi information about the network connection.
os.name-YesYesName of the operating system.

For JavaScript SDK, you can get it using the uaChTrackLevel load API option.
os.version-YesYesVersion of the operating system.

For JavaScript SDK, you can get it using the uaChTrackLevel load API option.
page.pathYes--Path of the current page in the browser.
page.initial_referrerYes--Initial referrer of the current page in the browser.
page.initial_referring_domainYes--Initial referring domain of the current page in the browser.
page.referrerYes--Referrer of the current page in the browser. This value generally contains the page’s origin (for example, https://www.google.com) but is dependent on the referrer policy set on the previous page.
page.referring_domainYes--Referring domain of the current page in the browser.
page.searchYes--Search of the current page in the browser.
page.titleYes--Title of the current page in the browser.
page.urlYes--The canonical URL of the page (if present).

Otherwise, the URL of the current page in the browser.
page.tab_urlYes--URL of the current page in the browser.
screen.densityYesYesYesDensity of the device’s screen.
screen.heightYesYesYesHeight of the device’s screen.
screen.widthYesYesYesWidth of the device’s screen.
screen.innerWidthYes--Inner width of the device’s screen.
screen.innerHeightYes--Inner height of the device’s screen.
traits-YesYesTraits of the user.
userAgentYesYes-User agent of the device making the request.
timezoneYesYesYesInformation about the user’s timezone.
info
  • For Android SDK v1.6.0 and above, the Bluetooth status is collected in the network.bluetooth field only if the Bluetooth permission is present in the app.
  • For iOS SDK v1.6.3 and above, the Bluetooth status is not collected in the network.bluetooth field as it is a run-time permission.

Sample payload with contextual fields

The following sample payload highlights the usage of the common and contextual fields in web and mobile modes:

How RudderStack collects IP address

RudderStack automatically collects the user’s IP address in the request_ip property as a common field.

Note that you can see the request_ip field in the final event received at the destination but not in the Live Events. This is because RudderStack adds the IP address in the backend while sending the event to the destination - it is not a part of the initial event data generated at the source.

You can also set a custom IP address or anonymize it in your events. To do so, set the ip parameter in the source-level context object. RudderStack uses the provided IP address instead of automatically capturing it in the backend.

An example of how to do this using the identify API of the JavaScript SDK is shown:

rudderanalytics.identify(
  "1hKOmRA4el9Zt1WSfVJIVo4GRlm", {
    firstName: "Alex",
    lastName: "Keener",
    email: "alex@example.com",
    phone: "+1-202-555-0146"
  }, {
    ip: "192.0.2.0"
  },
  () => {
    console.log("Identify event successfully submitted to the RudderStack SDK.");
  }
);

Clock skew considerations

RudderStack considers the time at its end to be absolute and assumes any differences are on the client-side. Thus, the client clock skew is relative.

FieldDescription
originalTimestampTime, client-side, when the event occurred at the source.
sentAtTime, client-side, when the event was sent from the client to RudderStack.
receivedAtTime when the event is received(ingested) by the RudderStack server.
timestampCalculated by RudderStack to account for the client clock skew, if the user does not explicitly specify it in the payload.
info
All the above timestamps are in UTC.
warning

Important considerations for using timestamps in analysis

originalTimestamp and sentAt should not be used for analysis because they both reflect client-side clock skew.

Likewise, receivedAt does not guarantee preservation of the chronological order of events, and should not be used for analysis where chronological order is needed.

When importing historical events, timestamp should be used to preserve chronological order.

SDK sources

If you do not specify the timestamp field in the payload for SDK sources, RudderStack calculates it based on the originalTimestamp and sentAt to account for the client clock skew.

sentAt > originalTimestamp is always true. However, timestamp can be greater or less than the originalTimestamp:

Case 1: originalTimestamp < receivedAt

When the client-side time is less than the time registered by RudderStack:

originalTimestampsentAtreceivedAttimestamp = receivedAt - (sentAt - originalTimestamp)
2020-04-26 07:00:43.4002020-04-26 07:00:45.1242020-04-26 07:00:45.5582020-04-26 07:00:43.834

In this case, timestamp will be greater than originalTimestamp.

Case 2: originalTimestamp > receivedAt

When the client-side time is greater than the time registered by RudderStack:

originalTimestampsentAtreceivedAttimestamp = receivedAt - (sentAt - originalTimestamp)
2020-04-26 07:00:45.5582020-04-26 07:00:46.1242020-04-26 07:00:43.4002020-04-26 07:00:42.834

In this case, timestamp will be less than originalTimestamp.

HTTP/Webhook-based sources

RudderStack does not consider any clock skew for HTTP/Webhook-based sources and uses the timestamp passed in the timestamp payload field.

Case 1: When the client-side time is less than the time registered by RudderStack:

originalTimestampsentAtreceivedAttimestamp = receivedAt - (sentAt - originalTimestamp)timestamp (payload field)
NANA2020-04-26 07:00:49.400NA2020-04-26 07:00:46.400

Case 2: When the client-side time is greater than the time registered by RudderStack:

originalTimestampsentAtreceivedAttimestamp = receivedAt - (sentAt - originalTimestamp)timestamp (payload field)
NANA2020-04-26 07:00:43.400NA2020-04-26 07:00:47.400

In the above cases, timestamp is the same as specified in the payload. RudderStack sets the originalTimestamp as the currentTime. You can add a transformation to correct the clock skew.

Case 3: If none of the originalTimestamp, sentAt, receivedAt, and timestamp fields are passed in the payload:

originalTimestampsentAtreceivedAttimestamp = receivedAt - (sentAt - originalTimestamp)timestamp (payload field)
Set as current timeSet as current timecurrent timecurrent timeNA

RudderStack sets the originalTimestamp and sentAt fields to the current time and calculates timestamp (same as receivedAt/current time).

Destinations

RudderStack gives priority to the timestamp field over originalTimestamp. Refer to the destination documentation for more details.

Timestamp mapping for Reverse ETL sources

When you map your warehouse columns to destination fields using JSON mapper, RudderStack prefers the timestamp to be set in the following event traits/properties (in the exact preference order):

Event typeJSON key for timestamp
trackproperties.timestamp
identify
  1. context.timestamp
  2. context.traits.timestamp
  3. traits.timestamp
  4. timestamp
  5. originalTimestamp
info

Note that:

  • If the timestamp is not present in any of the outermost timestamp fields, RudderStack takes the timestamp value from the originalTimestamp field (at the outermost level in the event payload).
  • RudderStack generates the root level timestamp field and it changes every time a full sync is triggered.

Questions? Contact us by email or on Slack