Skip to main content

Analytics

Analytics events are captured for a wide range of card activity and user actions. There are four ways to extract these analytics from Atomic:

  1. Batched data
  2. Recent data
  3. Workbench
  4. Webhooks

Atomic provides the ability to download analytic events from the previous 30 days directly in the Workbench. We also provide two API endpoints which allow analytics events to be retrieved from the Atomic Platform.

Overview of Atomic API options for retrieving analytics

Backup and storage

Analytics are stored in Atomic for the amount of time defined in an organization's data retention settings.

warning

Atomic is not a long-term storage solution. If you wish to store Analytic data for a long-term (i.e. longer than a year) then you should use the APIs as documented in this page to retrieve the data and store it in your own solution. The recommended pattern is to poll the batched analytics API to download and copy analytics out.

Batched data analytics via API

See Atomic's public API specification for more specific details about the analytics/batched endpoint.

Analytics data is processed in hourly batches, and available for retrieval as CSV, newline-delimited JSON or Parquet from the Atomic API. Batches are available at most one hour after their period ends. The default format is newline-delimited JSON, if none is specified.

Custom events aren't included in batch exports

Batches contain Atomic analytics events only. Your custom events are not included, in any of the three formats. To retrieve them, use recent analytics via API, a webhook, or the analytics debugger.

A time range may be specified via the from and to parameters, which are timestamps in ISO8601 format. Note that data is processed hourly, so it isn't possible to retrieve a partial hour. When creating the date range, the from parameter is rounded down to the nearest hour, and to is rounded up. The maximum allowed date range is 30 days.

GET /v1/:environmentId/analytics/batched?from=<timestamp>&to=<timestamp>&format=<ndjson | parquet | csv>

The API response contains an array of pre-signed urls pointing to the data files for the specified period, these URLS expire after 15 minutes. The files are grouped by hour ended in UTC, using the format YYYY-MM-DDTHH - for example, the batch for March 27 2020, 1-2am will be under 2020-03-27T02. Note the file array for an hour will only appear here once it is finished processing. If the file array is empty, it means there were no analytics events for that period.

For example, to retrieve all analytics data for the 27th of March 2020:

GET /v1/:environmentId/analytics/batched?from=2020-03-27T00:00:00Z&to=2020-03-28T00:00:00Z&format=parquet

Response:

{
"data": {
"2020-03-27T01": ["https://data.atomic.io/path-to/file.parquet?signature=..."],
"2020-03-27T02": ["https://data.atomic.io/path-to/file.parquet?signature=..."],
...
"2020-03-28T00": ["https://data.atomic.io/path-to/file.parquet?signature=..."],
}
}

Note that url parameters may be localized, but the response format will always use UTC.

Newline-delimited JSON format

Files contain one analytics object, in json format matching the schema, per line. For example

{"id": "...", "analyticsEvent": "card-published", "endUserId": "...", "timestamp": "...", "eventContext": { ... }, ...}
{"id": "...", "analyticsEvent": "card-published", "endUserId": "...", "timestamp": "...", "eventContext": { ... }, ...}
{"id": "...", "analyticsEvent": "card-published", "endUserId": "...", "timestamp": "...", "eventContext": { ... }, ...}

Parquet format

Each record in the parquet file has the keys in the schema flattened.

Recent analytics via API

See Atomic's public API specification for more specific details about the analytics endpoint.

Another endpoint is available to retrieve non-batched analytics. Data for the last 7 days may be retrieved in JSON format, with the oldest data returned first. The from and to parameters are timestamps in ISO8601 format. The analytics in the API response can be further filtered with the following query parameters:

  • cardTemplateId
  • eventName (can be a single event or comma separated list i.e. card-completed or card-completed,card-snoozed)
  • endUserId
  • flowConfigId
  • flowInvocationId
  • desc (order newest to oldest, providing any value in this parameter will enable this)
  • limit (default 1000, max 5000)
warning

Analytic events are written to Atomic's datastore from a queue based system. As such, at times of high usage there may be a delay in writing analytic events and therefore also a delay in retrieving them from this endpoint. Typically such a delay would not be more than a few minutes. Due to this, we recommend, if polling this endpoint, to leave a buffer between the current time and the time you are querying for of at-least a few minutes.

Atomic does not recommend polling this endpoint to retrieve all of your analytic events, the batched analytics endpoint is more fault tolerant and recommended.

GET /v1/:environmentId/analytics?from=<timestamp>&to=<timestamp>

The additional query parameters listed above are optional, they can be used like so:

GET /v1/:environmentId/analytics?from=<timestamp>&to=<timestamp>&cardTemplateId=<your-card-template>&limit=3000

Response format:

{
"data": {
"events": [
{ ... },
{ ... },
...
],
"count": 100, // number of events returned in this payload
"cursor": "..." // used for pagination
}
}

Pagination

When you make a request to get events a cursor property is returned. To get the next page of results, use the cursor query parameter with the value returned from your last request to get the next page i.e. cursor={cursor from previous request}.

Workbench download

Batches are available in JSON, CSV, or Parquet format.

Note that CSV exported content is sanitized as per OWASP guidance.

Locate them in your Workbench: Tools > Operations > Analytics exporter.

This area of the Workbench is updated a few minutes after the hour, to include the preceding hour’s analytics. The Timestamp field indicates when the hour period began. The amount of analytic events in each batch is limited. If the number of analytic events emitted within an hour is greater than the limit, multiple batches are created and saved into multiple files available for download.

A description of all of the available analytics events are available in the Analytics Reference.

Batches are only available for the past 30 days. If you require analytics data from prior to this date, please use our API Endpoints.

Webhooks

Another pattern we support is to subscribe a URL to card status-change event. Atomic will then send an update for the event (e.g. card-dismissed) with the payload data to your URL.

Docs on configuring webhooks are found here: Webhooks

Analytics export settings

Workbench members with access to the 'Environments' resource can configure the analytics data content returned by Atomic.

Test cards and request payloads are included in analytics data by default. Card response data is not included by default.

The settings are all configured at the environment level.

info

Environment analytics data preferences affect API responses, but not webhooks. Webhooks get the full payload by default, but by using our mapping capability, you can configure webhook data to match your desired output.

Change environment analytics export settings

To change your environment analytics export settings:

  1. Go to Configuration > Webhooks > Analytics Export Settings.
  2. Toggle the preferences to your desired settings, and select ‘Save’.
info

With batched analytics, the settings are applied at the time the batch is generated. This means that no historical batches will be changed.

Setting the preferences

The analytics export settings that can be configured on or off:

PreferenceDescriptionDefault setting
Include test cardsTest cards that are manually triggered from within the Workbench are included. These are tagged as Test within the Workbench card log.on
Include request payloadPayload data is included, and captured in the platformContext.eventDetail object e.g. within a card-completed analytics event.on
Include card responseResponses from customers are included, and captured in the properties.values object e.g. within a card-displayed, notification-sent, or notification-received analytics event.off
Card response data analytics

The card response data payload is only available via the analytics API endpoints. The workbench analytics debugger screen will not include any card response data. This is done to prevent potential customer personally identifiable information (PII) being exposed in the workbench.

Custom events

It is possible to send your own analytic events to the Atomic platforms via the Atomic API or SDKs.

After a custom event has been sent to Atomic once it can be used to:

  • Create Webhooks that trigger when instances of that event are received.
  • Create user segments; users associated with the event will get the profile analytics fields last_[your-custom-event-name]_at & first_[your-custom-event-name]_at populated. This allows you to build segments based on custom events.
  • In the future Action Flows will be able to be configured to start or resume when custom analytics occur with particular properties.

Known custom events and their properties can be seen at Configuration > Webhooks > Custom events. Each time a new custom event type is sent to Atomic it is automatically added to this page.

Instances of custom events are listed in the analytics debugger tool, are returned by recent analytics via API, and can trigger webhooks. They are not included in the hourly batch exports, in any of the three formats.

Sending custom events via API

A credential role of events is required to utilize the Analytics API.

You can interact with the Analytics API using Insomnia (follow the Insomnia instructions) or curl. When using curl, you'll need to set up your Authentication first.

Detailed specs and examples can be found in the Atomic API spec for the Analytics endpoint.

ENDPOINT="https://$ORG_ID.customer-api.atomic.io/v1/$ENVIRONMENT_ID/analytics"

PAYLOAD='{
"data": [
{
"id": "6a1e92d3-fa0d-56da-a2d7-bc616ade57d1",
"eventName": "my-custom-event",
"eventType": "custom",
"endUserId": "an-end-user",
"timestamp": "2022-04-25T02:47:46.977Z",
"properties": {
"stringProperty": "string",
"boolProperty": true,
"numberProperty": 42,
"objectProperty": {},
"arrayProperty": []
},
"platformContext": {
"flowInstanceId": "dec19d46-241d-47e9-906b-6361ac49903a"
}
}
]
}'

# send request to Atomic
curl -X POST "$ENDPOINT" \
--header "Content-Type:application/json" \
--header "Authorization: Bearer $TOKEN" \
--data "$PAYLOAD"

Request information

The required fields are:

  • eventName
  • eventType
  • endUserId
  • timestamp

Atomic will populate the id field with a UUID if it is not provided in the event. You may optionally specify a custom id in the event, but it must be a valid UUID.

The fields in properties are entirely custom, they should be used to add any metadata associated with your custom event that is useful to you. If the data within properties changes between instances of an event then they are updated in the Configuration > Webhooks > Custom events screen - this screen will always reflect the latest instance's properties.

A platformContext object including flowInstanceId is required if a custom event is used to resume an Action Flow.

If the custom event is in-use on a card-scoped webhook then cardContext must be included in order for that webhook to trigger.

  "cardContext": {
"cardTemplateId": "a-card-template-id",
"cardInstanceId": "a-card-instance-id"
},

Marking a custom event as a test to start draft Action Flows

By default, a custom event is treated as a live event. If it starts an Action Flow via an event trigger, it can only start the published version of that flow, and can target live customers.

To use a custom event to start a draft Action Flow while you're testing, before it's published, mark the event as a test by adding isTestFlow: true to the platformContext object:

  "platformContext": {
"isTestFlow": true
}

Test events behave the same way as tests sent from the Workbench: they can start draft Action Flow versions, and will only target test customers. This is a safeguard to prevent draft flows from being sent to live customers.

Sending custom events via SDK

It is also possible to send custom events via SDK:

Analytics events examples

See the examples for each of the analytic events page for payload examples. The response payloads in your environment might look different, depending on your analytics settings.

Analytics event schema

Schema properties

The JSON schema below describes the full analytics event payload and may not be included in certain export formats, such as Parquet.

{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"title": "Atomic Analytics Schema",
"description": "The root schema comprises the entire JSON document.",
"required": ["id", "timestamp"],
"anyOf": [
{"required": ["analyticsEvent"]},
{"required": ["eventName"]}
],
"properties": {
"id": {
"type": "string",
"title": "Event id",
"description": "A GUID used for deduping"
},
"endUserId": {
"type": "string",
"title": "End user id",
"description": "The end user (customer) identifier known to Atomic. Absent on events which are not scoped to a user, such as 'action-flow-trigger-request-failed', and an empty string on 'action-flow-not-started' when the flow failed before a user was resolved.",
"examples": ["019mr8mf4r"]
},
"analyticsEvent": {
"type": "string",
"enum": [
"card-cancelled",
"card-published",
"card-embargoed",
"card-dismissed",
"card-error",
"card-completed",
"card-snoozed",
"card-unsnoozed",
"card-expired",
"notification-sent",
"notifications-not-sent",
"smart-badge-notification-sent",
"smart-badge-notifications-not-sent",
"stream-displayed",
"card-displayed",
"card-subview-displayed",
"card-subview-exited",
"user-redirected",
"runtime-vars-updated",
"notification-received",
"card-voted-up",
"card-voted-down",
"snooze-options-displayed",
"snooze-options-canceled",
"request-failed",
"sdk-initialized",
"segment-entered",
"segment-exited",
"video-played",
"video-completed",
"user-file-uploads-started",
"user-file-uploads-completed",
"user-file-uploads-failed",
"user-registered-for-notifications",
"user-deregistered-for-notifications",
"action-flow-started",
"action-flow-step-completed",
"action-flow-step-failed",
"action-flow-completed",
"action-flow-failed",
"action-flow-error-handler-triggered",
"action-flow-wait-completed",
"action-flow-cancelled",
"card-not-sent",
"action-flow-not-started",
"card-first-displayed",
"card-first-snoozed",
"user-first-redirected",
"card-first-voted",
"action-flow-trigger-successful",
"action-flow-trigger-request-failed",
"file-scan-completed",
"file-scan-failed",
"marketo-callback-invoked",
"<a-custom-event>"
],
"title": "Analytics event name",
"description": "Name of the analytics event. Not present on custom events, which carry 'eventName' only.",
"examples": ["card-published"]
},
"eventName": {
"type": "string",
"title": "Event name",
"description": "Mirror of 'analyticsEvent', present on every event. Custom events carry this field only.",
"examples": ["card-published"]
},
"timestamp": {
"type": "string",
"format": "date-time",
"title": "Timestamp",
"description": "UTC timestamp of when the event occurred.",
"examples": ["2012-12-02T00:30:12.984Z"]
},
"properties": {
"type": "object",
"title": "Properties schema",
"description": "An object containing extra content detail about this particular event.",
"properties": {
"notificationScenario": {
"type": "string",
"title": "Notification scenario",
"enum": ["newCard", "unsnoozedCard"],
"description": "Used for the 'notification-sent' event to indicate whether the notification was sent for a new or snoozed card"
},
"rescheduledBasedOnEndUserPrefs": {
"type": "boolean",
"title": "Rescheduled based on end user prefs",
"description": "Used for the 'notification-sent' event to indicate if the notification was rescheduled due to user delivery preferences"
},
"atomicPushId": {
"type": "string",
"title": "Atomic push id",
"description": "Identifies a single notification across the events describing it, on the notification and 'notification-received' events"
},
"isDataOnlyNotification": {
"type": "boolean",
"title": "Is data only notification",
"description": "Used for the 'notification-sent' event to indicate the notification carried no user-visible content"
},
"badgeCount": {
"type": "integer",
"title": "Badge count",
"description": "Used for the notification events to report the badge count sent with the notification"
},
"subviewId": {
"type": "string",
"title": "Subview id",
"description": "Used for the 'card-subview-displayed' and 'card-subview-exited' events to identify the relevant subview"
},
"subviewTitle": {
"type": "string",
"title": "Subview title",
"description": "Used for the 'card-subview-displayed' and 'card-subview-exited' events"
},
"subviewLevel": {
"type": "integer",
"title": "Subview level",
"description": "Used for the 'card-subview-displayed' and 'card-subview-exited' events to identify the subview level. Reported as 0 for an event raised from the top view of a card."
},
"linkMethod": {
"type": "string",
"title": "Link method",
"enum": ["url", "payload"],
"description": "Used for the 'user-redirected' event to identify the link method used."
},
"url": {
"type": "string",
"title": "URL",
"description": "Used for the 'user-redirected' event, when the url method is used, to indicate the URL that was launched."
},
"payload": {
"type": "object",
"title": "Payload",
"description": "Used for the 'user-redirected' event, when the payload method is used, to indicate the payload that was sent to the SDK. Contains whatever the card's custom action payload was configured with."
},
"detail": {
"type": "string",
"title": "Detail",
"description": "Used for the 'user-redirected' event to identify what the user interacted with, for example 'image', 'textLink', 'linkButton' or 'submitButton'."
},
"displayMode": {
"type": "string",
"title": "Display mode",
"enum": ["stream", "single"],
"description": "Sent by the Web SDK on the 'stream-displayed' event to indicate whether the card feed rendered as a stream or a single card. The container's own display mode is reported separately as streamContext.displayMode."
},
"resolvedVariables": {
"type": "object",
"title": "Resolved variables",
"description": "Used for the 'runtime-vars-updated' event to express which runtime variables were updated and their new values."
},
"source": {
"type": "string",
"title": "The source of a card action",
"description": "Used for the 'card-voted-down/card-voted-up' event to identify the source of the vote.",
"enum": ["overflow-menu", "card-button"]
},
"reason": {
"type": "string",
"title": "Downvote reason",
"enum": ["not-relevant", "too-often", "other"],
"description": "Used for the 'card-voted-down' event to identify the reason for the vote."
},
"message": {
"type": "string",
"title": "Message",
"description": "Used for the 'card-voted-down' event to carry a message from the user, and for the 'notifications-not-sent' events to carry the reason the notification was not sent."
},
"messages": {
"type": "array",
"items": {
"type": "string"
},
"title": "Messages",
"description": "Used for the 'notifications-not-sent' events when more than one reason applies."
},
"snoozePeriod": {
"type": ["string", "null"],
"title": "Snooze period",
"description": "Used for the 'card-snoozed' event, specifies how long the card was snoozed for as an ISO8601 time interval"
},
"values": {
"type": ["object", "string"],
"title": "Card response values",
"description": "Contains response values for the 'card-completed' event. Replaced with the string '[redacted]' when the environment's analytics settings exclude card responses."
},
"errors": {
"type": "array",
"items": {
"type": "string"
},
"title": "Errors",
"description": "The reasons a failure occurred, on the 'card-error', 'card-not-sent', 'action-flow-step-failed', 'action-flow-failed', 'action-flow-error-handler-triggered', 'action-flow-not-started' and 'action-flow-trigger-request-failed' events."
},
"expires": {
"type": "string",
"title": "Expires",
"description": "Used for the 'card-not-sent' event when the card was not sent because it had already expired."
},
"path": {
"type": "string",
"title": "Path",
"description": "Used for the 'request-failed' event to indicate the request path which failed."
},
"statusCode": {
"type": "integer",
"title": "Status code",
"description": "Used for the 'request-failed' event to indicate the HTTP status returned."
},
"videoUrl": {
"type": "string",
"title": "Video URL",
"description": "Used for the 'video-played' and 'video-completed' events by the iOS and Android SDKs to indicate the video the user played. The Web SDK reports the same value as 'mediaURL'."
},
"mediaURL": {
"type": "string",
"title": "Media URL",
"description": "Used for the 'video-played' and 'video-completed' events by the Web SDK to indicate the video the user played. The iOS and Android SDKs report the same value as 'videoUrl'."
},
"waitUntil": {
"type": "string",
"title": "Wait until",
"description": "Used for the 'action-flow-wait-completed' event to indicate the absolute time the flow was waiting until."
},
"resumptionCompleted": {
"type": "boolean",
"title": "Resumption completed",
"description": "Used for the 'action-flow-wait-completed' event to indicate the flow had already resumed because the wait time was in the past."
},
"goalValueMeasure": {
"type": "string",
"title": "Goal value measure",
"enum": ["points", "currency", "time", "none"],
"description": "Used for the 'action-flow-step-completed' event to designate the type of the accompanying goal value."
},
"goalValue": {
"type": "number",
"title": "Goal value",
"description": "Used for the 'action-flow-step-completed' event to carry a value used to generate aggregated statistics. Absent when goalValueMeasure is 'none'."
},
"segmentId": {
"type": "string",
"title": "Segment id",
"description": "Used for the 'segment-entered' and 'segment-exited' events to identify the segment."
},
"segmentName": {
"type": "string",
"title": "Segment name",
"description": "Used for the 'segment-entered' and 'segment-exited' events."
},
"fileKey": {
"type": "string",
"title": "File key",
"description": "Used for the 'file-scan-completed' and 'file-scan-failed' events to identify the scanned file."
},
"targetBucket": {
"type": "string",
"title": "Target bucket",
"description": "Used for the 'file-scan-completed' event to identify the bucket holding the scanned file."
},
"bucketAndKey": {
"type": "string",
"title": "Bucket and key",
"description": "Used for the 'file-scan-completed' event, the target bucket and file key joined for convenience."
}
}
},
"eventContext": {
"type": "object",
"title": "The eventContext Schema",
"description": "An object containing metadata about this particular event.",
"properties": {
"ip": {
"type": "string",
"title": "IP",
"description": "The IP address associated with the end user if available"
},
"actionSource": {
"type": "string",
"title": "Action Source",
"enum": ["user", "customer", "internal"],
"description": "The source of the action"
},
"userLocalTimestamp": {
"type": "string",
"title": "User Local Timestamp",
"description": "The local timestamp associated with the user device"
}
}
},
"sdkContext": {
"type": "object",
"title": "The sdkContext Schema",
"description": "Info about the SDK related to this event.",
"properties": {
"platform": {
"type": ["string", "null"],
"title": "Platform",
"enum": ["Web", "iOS", "Android", null],
"description": "The customer platform"
},
"sdkVersion": {
"type": ["string", "null"],
"title": "SDK Version",
"description": "The version of the Atomic SDK"
},
"sdkClientAppVersion": {
"type": ["string", "null"],
"title": "SDK Client App Version",
"description": "The version of the Client Application using the Atomic SDK"
},
"sdkDevice": {
"type": ["string", "null"],
"title": "SDK sdkDevice",
"description": "The customer Device"
},
"sdkTimezone": {
"type": ["string", "null"],
"title": "SDK sdkTimezone",
"description": "The timezone on the customer device"
},
"containerId": {
"type": ["string", "null"],
"title": "Container Id",
"description": "The ID of the container that was in context when the event occurred"
},
"containerIds": {
"type": ["array", "null"],
"items": {
"type": "string"
},
"title": "Container Ids",
"description": "The containers the event is relevant to, when it relates to more than one"
},
"isDNDActive": {
"type": ["boolean", "null"],
"title": "Is Do Not Disturb Active",
"description": "Whether DnD was active at the time the event occurred"
}
}
},
"streamContext": {
"type": "object",
"title": "The streamContext Schema",
"description": "Details of the stream at the time the event occurred.",
"properties": {
"streamId": {
"type": ["string", "null"],
"title": "Stream Id",
"description": "The identifier for the stream with which the event is associated"
},
"streamName": {
"type": "string",
"title": "Stream Name",
"description": "The name of the stream"
},
"streamLength": {
"type": "integer",
"title": "Stream Length",
"description": "The length of the stream"
},
"streamLengthVisible": {
"type": "integer",
"title": "Stream Length Visible",
"description": "The visible length of the stream"
},
"cardPositionInStream": {
"type": "integer",
"title": "Card Position In Stream",
"description": "The card position in the stream, indexed at 1"
},
"displayMode": {
"type": "string",
"title": "Display Mode",
"enum": [
"stream",
"single",
"horizontal",
"horizon",
"modal",
"launcher"
],
"description": "The display mode of the container the event occurred in. The iOS SDK reports a horizontal container as 'horizon' where the Web SDK reports 'horizontal', and 'launcher' is reported by the Web SDK only."
}
}
},
"cardContext": {
"type": "object",
"title": "The cardContext Schema",
"description": "Details of the card in the context of this event",
"properties": {
"cardInstanceId": {
"type": "string",
"title": "Card Instance Id",
"description": "The card instance id"
},
"cardPriority": {
"type": ["number", "null"],
"title": "Card Priority",
"description": "The priority assigned to the card",
"enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, null]
},
"cardInstanceStatus": {
"type": "string",
"title": "Card Instance Status",
"enum": [
"pending",
"embargoed",
"active",
"snoozed",
"dismissed",
"completed",
"expired",
"cancelled",
"suppressed",
""
],
"description": "The current status of the card. Reported as an empty string on SDK-sourced events when the SDK did not hold a status for the card."
},
"previousStatus": {
"type": "string",
"title": "Previous status",
"enum": [
"pending",
"embargoed",
"active",
"snoozed",
"dismissed",
"completed",
"expired",
"cancelled",
"suppressed"
],
"description": "Used with any status change event to indicate the previous status of the card"
},
"cardViewState": {
"type": "string",
"title": "Card View State",
"enum": ["topview", "subview"],
"description": "The current active view of the card at the time of the event"
},
"cardTemplateSettings": {
"type": "object",
"title": "Card Template Settings",
"description": "The card template settings",
"properties": {
"sendNotifications": {
"type": "boolean",
"title": "Send Notifications",
"description": "Whether notifications are on or off for the card template"
}
}
},
"cardTemplateId": {
"type": "string",
"title": "Card Template Id",
"description": "The card template id"
},
"cardTemplateName": {
"type": "string",
"title": "Card Template Name",
"description": "The card template name"
},
"cardTemplateVersion": {
"type": "integer",
"title": "Card Template Version",
"description": "The card template version"
},
"cardPresentation": {
"type": "string",
"title": "Card Presentation",
"enum": ["bundle", "individual"],
"description": "The card presentation mode"
},
"cardInstanceLinked": {
"type": "boolean",
"title": "Card Instance Linked",
"description": "Whether the card instance is linked to another card instance"
},
"publishedAt": {
"type": ["string", "null"],
"format": "date-time",
"title": "Published At",
"description": "The time when the card's status first transitioned to \"active\". Null on the 'card-not-sent' event, where no card was published."
}
}
},
"platformContext": {
"type": "object",
"title": "The platformContext Schema",
"description": "Details of the platform in the the context of this event.",
"properties": {
"eventDetail": {
"type": ["object", "string"],
"title": "Event Detail",
"description": "The event data. Replaced with the string '[redacted]' when the environment's analytics settings exclude event detail."
},
"targetStreamIds": {
"type": ["array", "null"],
"title": "Target stream IDs",
"description": "The target streams for a card instance",
"items": {
"type": "string"
},
"uniqueItems": true,
"default": []
},
"targetPlatforms": {
"type": ["array", "null"],
"title": "Target platforms",
"description": "The target platforms for a card instance",
"items": {
"type": "string"
},
"uniqueItems": true,
"default": []
},
"eventNotificationDetail": {
"type": "object",
"title": "Event Notification Detail",
"description": "The event notification data"
},
"metadata": {
"type": "object",
"title": "Metadata",
"description": "Arbitrary metadata passed through from the API call which triggered the flow or card"
},
"lifecycleId": {
"type": "string",
"title": "Lifecycle Id",
"description": "The event lifecycleId"
},
"triggerEventSource": {
"type": ["string", "null"],
"title": "Trigger Event Source",
"enum": ["live", "test", null],
"description": "The trigger event source"
},
"flowInstanceId": {
"type": "string",
"title": "Flow Instance Id",
"description": "The instance Id for the Action Flow that triggered this event"
},
"flowInvocationId": {
"type": "string",
"title": "Flow Invocation Id",
"description": "The invocation Id for the Action Flow that triggered this event"
},
"flowConfigId": {
"type": "string",
"title": "Flow Config Id",
"description": "The config id for the Action Flow that triggered this event"
},
"flowVersion": {
"type": "number",
"title": "Flow Version",
"description": "The version of the Action Flow that triggered this event"
},
"stepId": {
"type": "string",
"title": "Step Id",
"description": "The ID of the Action Flow step which generated, or is causally tied to, this event"
},
"stepType": {
"type": "string",
"title": "Step Type",
"description": "The type of the Action Flow step which generated, or is causally tied to, this event, for example 'create-card' or 'condition'"
},
"stepName": {
"type": "string",
"title": "Step Name",
"description": "The name of the Action Flow step which generated, or is causally tied to, this event"
},
"cardCreationStepId": {
"type": "string",
"title": "Card Creation Step Id",
"description": "For card-centric events, the Id of the Action Flow step which created the card"
},
"sourceTriggerId": {
"type": "string",
"title": "Source Trigger Id",
"description": "The ID of the trigger that started the Action Flow: 'api', 'api-csv-bulk', 'segment-publish' or a unique identifier"
},
"workbenchFolderIds": {
"type": "array",
"title": "Workbench Folder Ids",
"description": "The IDs of the folder(s) the Action Flow belonged to at the time it was triggered",
"items": {
"type": "string"
}
}
}
},
"hostContext": {
"type": "object",
"title": "The hostContext Schema",
"description": "Reserved for host-supplied properties. Currently always an empty object."
}
}
}

Parquet schema

The Parquet files flatten the keys of the schema above into columns. Every row represents an Atomic analytic event. Custom events aren't included in batch exports.

The id, analyticsEvent, and timestamp columns are are always present. endUserId is optional, because some events such as action-flow-trigger-request-failed have no associated end user. Every other column is nullable, and only the columns relevant to a given row's analyticsEvent type are populated.

ColumnTypeOptionalRepeated
idUTF8
endUserIdUTF8
analyticsEventUTF8
timestampUTF8
properties.displayModeUTF8
properties.linkMethodUTF8
properties.messageUTF8
properties.notificationScenarioUTF8
properties.payloadJSON
properties.valuesJSON
properties.previousStatusJSON
properties.reasonUTF8
properties.rescheduledBasedOnEndUserPrefsBOOLEAN
properties.resolvedVariablesJSON
properties.sourceUTF8
properties.subviewIdUTF8
properties.subviewLevelINT32
properties.subviewTitleUTF8
properties.urlUTF8
properties.snoozePeriodUTF8
eventContext.actionSourceUTF8
eventContext.ipUTF8
eventContext.userLocalTimestampUTF8
sdkContext.platformUTF8
sdkContext.sdkVersionUTF8
sdkContext.sdkClientAppVersionUTF8
sdkContext.sdkDeviceUTF8
sdkContext.sdkTimezoneUTF8
sdkContext.containerIdUTF8
sdkContext.isDNDActiveBOOLEAN
streamContext.streamIdUTF8
streamContext.streamNameUTF8
streamContext.streamLengthINT32
streamContext.streamLengthVisibleINT32
streamContext.cardPositionInStreamINT32
streamContext.displayModeUTF8
cardContext.publishedAtUTF8
cardContext.cardInstanceIdUTF8
cardContext.cardInstanceStatusUTF8
cardContext.cardViewStateUTF8
cardContext.cardPresentationUTF8
cardContext.cardTemplateIdUTF8
cardContext.cardTemplateNameUTF8
cardContext.cardTemplateVersionINT32
cardContext.cardTemplateSettings.sendNotificationsBOOLEAN
cardContext.cardPriorityINT32
platformContext.eventDetailJSON
platformContext.eventNotificationDetailJSON
platformContext.lifecycleIdUTF8
platformContext.triggerEventSourceUTF8
platformContext.targetStreamIdsUTF8
platformContext.targetPlatformsUTF8
platformContext.flowInstanceIdUTF8
platformContext.flowInvocationIdUTF8
platformContext.flowConfigIdUTF8
platformContext.flowVersionINT32

Example Parquet record as JSON

{
"id": "6ed520b7-c313-5e98-afba-8cea41fc15b1",
"endUserId": "f7c75a4f-55f5-40a1-b55c-9783d9823fe6",
"analyticsEvent": "card-published",
"timestamp": "2020-07-24T02:50:28.526Z",
"eventContext.actionSource": "internal",
"sdkContext.isDNDActive": false,
"streamContext.streamId": "TspKk",
"streamContext.streamName": "Slurm Soda Co",
"cardContext.cardInstanceId": "leaveRequest|live|647a444a-43a3-484d-968d-c310686f6f01|8",
"cardContext.cardInstanceStatus": "active",
"cardContext.cardTemplateId": "8Xlss",
"cardContext.cardTemplateName": "Leave request",
"cardContext.cardTemplateVersion": 1,
"cardContext.cardTemplateSettings.sendNotifications": false,
"platformContext.eventDetail": "eyJhIjoiZXhhbXBsZSJ9",
"platformContext.lifecycleId": "647a444a-43a3-484d-968d-c310686f6f01",
"platformContext.triggerEventSource": "live",
"platformContext.flowInstanceId": "bb9c4ed5-d97c-49e7-be4c-97f9d88cbb9f",
"platformContext.flowInvocationId": "caaa170d-0521-4dfa-903a-19f410480402",
"platformContext.flowConfigId": "A9WBVx"
}