All data in Appuri is loaded and manipulated through events. This allows time-series analytics such as "give me a list of users with attribute X who did Y but not Z". This also allows Appuri to load data from vastly different sources such as web logs, databases and external services.

🚧

Use UTF-8

All events need to be in JSON format encoded in UTF-8. The ordering of the keys is unimportant. UTF-8 characters greater than 4 bytes will be replaced by "?".

Event Keys

Entity Type (entype)

In order to handle events associated with different entities such as users, devices, anonymous sessions and so forth, events can have a entype key with a string representing what entity this event is associated with.

Here the type identifies the user, device, session respectively:

{ "entype": "user", "enid": "be652872", ... }
{ "entype": "device", "enid": "01f7582b", ... }
{ "entype": "session", "enid": "112014f0", ... }

Note: Entity Types are limited to 20 characters.

Note: If there is no entype field, the string "user" will be used as the default.

{ "enid": "12334298", ... } # Defaults to type "user"

If you are not sure, set entype to user.

Entity ID (enid) and User ID (user_id)

In order to uniquely identify the entity that is associated with this event, every event must have an enid key with a string. If you are sending an event with entype=user, you can just set the user_id field directly and there is no need to specify an enid.

{ "enid": "be652872", ... }
{ "enid": "01f7582b", ... }
{ "enid": "112014f0", ... }

Note: enid must be a string.

{ "enid": "12334298", ... }

Note: enid is case-sensitive.

{ "enid": "abc", ... }
is not the same entity as:
{ "enid": "ABC", ... }

Note: Entity ID is limited to 40 characters.

Event Name

Every event must have an evname key with a string representing what event it is:

{ "evname": "signed_in", "entype": "user", "user_id": "be652872" }
{ "evname": "app_launched", "entype": "device", "enid": "01f7582b" }
{ "evname": "started", "entype": "session", "enid": "112014f0" }

🚧

Limits on event names

Event names are limited to 40 characters. After processing and loading into the data warehouse, events may become SQL names (used in tables and columns) so it is recommended to use snake_case with all lowercase letters and underscores to separate words.

👍

How to pick evname and entype

Because the evname and entype tuple are distinct, Appuri will combine these to create event tables.

You should name events like this:

{ "evname": "started", "entype": "session", ... }

and not like this:

{ "evname": "session_started", "entype": "session", ... }

Timestamp

The client can provide an optional ISO 8601 Timestamp to the event in the 'ts' key.

❗️

All timestamps must be in 8601 Date and Time Representation

Make sure to include the 'T' delineator between the year and time. See Combining Date and Time Representations.

{ "ts": "2013-10-24T13:15:30Z", "evname": "signed_in", "entype": "user", "enid": "be652872" }
{ "ts": "2014-03-01T09:56:44.682Z", "evname": "app_launched", "entype": "device", "enid": "01f7582b" }
{ "ts": "2014-03-31T23:16:47.999Z", "evname": "started", "entype": "session", "enid": "112014f0" }

The ts can include milliseconds as fractions of a second up to 3 decimals of precision. Extra precision will be truncated.

📘

What happens if you don't provide a timestamp?

If there is no ts key in the event, the server will generate one at the time it received the event.

🚧

What time zone are timestamps stored in the warehouse?

Timestamps are stored as UTC timezone in the warehouse.

Body

Events can have metadata associated with them by passing in a body object. The body is a JSON object that represents data for an event. The values but must be JSON basic types (boolean, string, number, array) or an ISO-8601 timestamp.

{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 57, "price": 123.45 } }
{ "ts": "2014-03-01T09:56:44.682Z", "evname": "app_launched", "entype": "device", "enid": "01f7582b", \
"body": { "os": "ios 6.2", "firmware": "v1.2.3" } }
{ "ts": "2014-03-31T23:16:47.999Z", "evname": "started", "entype": "session", "enid": "112014f0", \
"body": { "user_agent": "safari", "utm_campaign": "Website Campaign 7", "referral_id": "website2"} }

📘

Limits on body

  • Nested JSON documents are not supported at this time.
  • Strings must be in UTF-8 format and are limited to 64000 bytes.
  • SQL reserved words are not allowed in JSON keys.

Transactions and De-Duplication

Events are idempotent in that you can resend the same event more than once but it will only show up in the data warehouse once.

For example, sending both of these will result in only one event being added in the data warehouse:

{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 57, "price": 123.45 } }
{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 57, "price": 123.45 } }
{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 57, "price": 123.45 } }

Note: Only one event will be added.

There may be times when you need to send the same event more than once and have distinct lines in the data warehouse (for example, several purchase transactions of the same item as the same timestamp).

You can do this by generating unique keys in the body.

{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 57, "price": 123.45, "tx": "f4677" } }
{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 57, "price": 123.45, "tx": "085ff" } }
{ "ts": "2013-10-24T13:15:30Z", "evname": "purchased", "entype": "user", "enid": "be652872", \
"body": { "item": 58, "price": 234.56, "tx": "085ff" } }

Note: Three events will be added as each event is distinct.