Every RudderStack API call shares the same common fields that define the core event data structure. The following table describes the common fields in every call.

Name
Data type
Description
anonymousId
Required
StringUnique identification for the user. This is the same as the deviceId.
channel
Required
StringIdentifies the source of the event. Permitted values are mobile, web, server.
context
Required
ObjectContains all the additional user information. The RudderStack SDKs populate this information automatically.
type
Required
StringCaptures the type of event. Values can be either track, screen, identify, page.
originalTimestamp
Required
TimestampRecords the actual time 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 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 the relevant information associated with the event.
Upon receving an event, RudderStack also sets receivedAt - the timestamp when the event is ingested (received). You need not set this field explicitly when sending the events to RudderStack.

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 deviceId, manufacturer, model, name and type.
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.
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.
os.version-YesYesVersion of the operating system.
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.
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--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.
timezone-YesYesInformation about the user's timezone.
  • 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:

{
"anonymousId": "78c53c15-32a1-4b65-adac-bec2d7bb8fab",
"channel": "web",
"context": {
"campaign": {
"name": "sales campaign",
"source": "google",
"medium": "medium",
"term": "event data",
"content": "Make sense of the modern data stack"
},
"library": {
"name": "RudderLabs JavaScript SDK",
"version": "2.9.1"
},
"locale": "en-US",
"page": {
"path": "/best-seller/1",
"initial_referrer": "https://www.google.com/search",
"initial_referring_domain": "google.com",
"referrer": "https://www.google.com/search?q=estore+bestseller",
"referring_domain": "google.com",
"search": "estore bestseller",
"title": "The best sellers offered by EStore",
"url": "https://www.estore.com/best-seller/1"
},
"screen": {
"density": 420,
"height": 1794,
"width": 1080,
"innerHeight": 200,
"innerWidth": 100
},
"userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)"
},
"event": "Product Reviewed",
"integrations": {
"All": true
},
"messageId": "1578564113557-af022c68-429e-4af4-b99b-2b9174056383",
"properties": {
"review_id": "review_id_1",
"product_id": "product_id_1",
"rating": 2.0,
"review_body": "Sample Review Body"
},
"originalTimestamp": "2020-01-09T10:01:53.558Z",
"type": "track",
"sentAt": "2020-01-09T10:02:03.257Z"
}
{
"anonymousId": "78c53c15-32a1-4b65-adac-bec2d7bb8fab",
"channel": "mobile",
"context": {
"app": {
"name": "RudderAndroidClient",
"version": "1.0",
"build": "1"
},
"device": {
"type": "android",
"id": "78c53c15-32a1-4b65-adac-bec2d7bb8fab",
"advertisingId":"435o4GRlm",
"manufacturer": "Google",
"model": "Android SDK built for x86",
"name": "generic_x86",
},
"library": {
"name": "com.rudderstack.android.sdk.core",
"version": "0.1.4"
},
"locale": "en-US",
"network": {
"bluetooth": false,
"carrier": "Android",
"cellular": true,
"wifi": true
},
"os": {
"name": "Android",
"version": "9"
},
"screen": {
"density": 420,
"height": 1794,
"width": 1080
},
"traits": {
"anonymousId": "78c53c15-32a1-4b65-adac-bec2d7bb8fab"
},
"timezone": "Asia/Mumbai",
"userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)"
},
"event": "Product Reviewed",
"integrations": {
"All": true
},
"messageId": "1578564113557-af022c68-429e-4af4-b99b-2b9174056383",
"properties": {
"review_id": "review_id_1",
"product_id": "product_id_1",
"rating": 2.0,
"review_body": "Sample Review Body"
},
"originalTimestamp": "2020-01-09T10:01:53.558Z",
"type": "track",
"sentAt": "2020-01-09T10:02:03.257Z"
}
{
"anonymousId": "78c53c15-32a1-4b65-adac-bec2d7bb8fab",
"channel": "mobile",
"context": {
"app": {
"name": "RudderSampleAppObjC",
"version": "1.0",
"build": "1"
},
"device": {
"type": "iOS",
"id": "78c53c15-32a1-4b65-adac-bec2d7bb8fab",
"advertisingId":"435o4GRlm",
"adTrackingEnabled": false,
"manufacturer": "Apple",
"model": "iPhone",
"name": "iPhone 12",
},
"library": {
"name": "rudder-ios-library",
"version": "1.5.0"
},
"locale": "en-US",
"network": {
"carrier": "unavailable",
"cellular": false,
"wifi": true
},
"os": {
"name": "iOS",
"version": "15.2"
},
"screen": {
"height": 1794,
"width": 1080
},
"traits": {
"anonymousId": "78c53c15-32a1-4b65-adac-bec2d7bb8fab"
},
"timezone": "Asia/Mumbai"
},
"event": "Product Reviewed",
"integrations": {
"All": true
},
"messageId": "1643629072-8ce81faf-7489-4508-b21b-659e81510991",
"properties": {
"review_id": "review_id_1",
"product_id": "product_id_1",
"rating": 2.0,
"review_body": "Sample Review Body"
},
"originalTimestamp": "2020-01-09T10:01:53.558Z",
"type": "track",
"sentAt": "2020-01-09T10:02:03.257Z"
}

How RudderStack collects IP address

RudderStack automatically collects the user's IP address in the request_ip property as a common field. You can see it in the event received at the destination but not in the Live Events tab. This is because RudderStack adds the IP in the backend while sending the event sent to the destination; it is not a part of the initial event data generated at the source.

You can also specify the ip field explicitly to anonymize the IP address, in which case it will be captured as a contextual field at the source itself.

Clock skew considerations

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

If not specified in the payload explicitly, RudderStack calculates timestamp based on originalTimestamp and sentAt to account for the client clock skew.

As mentioned in the above section:

FieldDescription
originalTimestampRecords the actual time when the event occurred at the source.
sentAtCaptures the time when the event was sent from the client to RudderStack.
receivedAtThe timestamp 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.
sentAt > originalTimestamp is always true. However, timestamp can be more or less than the originalTimestamp. Refer to the cases below for more details.

Case 1: originalTimestamp < receivedAt

The following table demonstrates an example of 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:44.834

In this case, timestamp will be greater than originalTimestamp.

Case 2: originalTimestamp > receivedAt

The following table demonstrates an example of originalTimestamp > receivedAt(when the client-side time is more 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:43.965

In this case, timestamp will be less than originalTimestamp.


Contact us

For more information on the topics covered on this page, email us or start a conversation in our Slack community.

On this page