Events are used for tracking meaningful user interactions (such as purchase, add to cart, form completion, rating a product, or anything you want), and have many purposes:
- Use for behavioral targeting in campaigns.
- Build audience groups, either long or short-term.
- Set as the primary or secondary metrics in campaigns.
- Events are also a data source for our recommendations engine, both for 'crowd-sourced' strategies such as Most Popular and Bought Together, and for personalized strategies and the Affinity Profile.
Request from:
In the US:
server-side: https://dy-api.com/v2/collect/user/event
client-side: https://direct-collect.dy-api.com/v2/collect/user/event (supports CORS)
In the EU:
server-side: https://dy-api.eu/v2/collect/user/event
client-side: https://direct-collect.dy-api.eu/v2/collect/user/event
See also API Reference: Reporting Events
Types of events
Events are broadly divided into two kinds: predefined and custom events.
Predefined events
These events have a standard schema for their properties, and the properties passed with the event are used by our backend for various purposes. Let's dive right in with an example of reporting the predefined Add to Cart event:
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": {
"dyid": "-4350463893986789401",
"dyid_server": "-4350463893986789401"
},
"session": { "dy": "ohyr6v42l9zd4bpinnvp7urjjx9lrssw" },
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Add to Cart",
"properties": {
"dyType": "add-to-cart-v1",
"value": 39.95,
"currency": "GBP",
"productId": "item-34454ga",
"quantity": 1
}
}
]
}'
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": { "id": "yaexono4ohphania" },
"session": { "custom": "iquahngaishe2koh" },
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Add to Cart",
"properties": {
"dyType": "add-to-cart-v1",
"value": 39.95,
"currency": "GBP",
"productId": "item-34454ga",
"quantity": 1
}
}
]
}'
There are several things to note:
- You can batch multiple events together, and thus, events is always an array. This can be used for batching events from the client-side (but don't hold 'em in your belly for too long) or reporting events en-masse from your server.
- Each event has a required name, and an optional properties object. The name is used for display purposes. It does not designate whether this is a predefined event or its schema.
- The type (scheme name) of a predefined event is set in properties.dyType (see List of predefined events for the full list of types). All attributes, either required by the schema or custom, are also included within the properties object.
- value can actually be passed with any event, including custom events, if the event has a monetary value. Without the optional currency argument, the value is taken to be in your site's currency, as defined in the site settings. You can, however, specify a different currency code, and the value would then be converted into the site's currency. It is a float number in the format of dollars[.cents], or its equivalent in other currencies.
The predefined add-to-cart-v1 type in the previous example requires two mandatory properties:
- productId that must exactly match an SKU in the product feed.
- quantity of the added product.
Note the following:
- Ensure you don't have ever-so-slightly differing variations on the SKU format between your feed, the events you report, and the context of pageviews you report. While SKUs may look deceptively simple, there are sometimes prefixes and suffixes which are only used in specific parts of your system. Typically, the component which generates the product feed is a whole other service, possibly written in a different language, from the code that reports client events.
- It's good practice to use a single meaningful display name for each predefined type. For a purchase event with the purchase-v1 schema, you may decide on either "Purchase", or any synonym, a translation of that term, or whatever term makes sense in your use case. However, stick to that single term in order not to confuse users of the Admin UI.
Events identifying users across channels
Some predefined events also serve to associate a given user ID to a customer ID. A user ID is unique to a device and may represent an anonymous user. It is the primary identifier in API endpoints. On the other hand, the optional Customer ID is a fixed identifier for a person that is the same across channels (web apps, mobile apps, e-mail) and is usually available only for registered users. In this way, multiple channels can be linked together across devices.
The Customer ID (or CUID for short) can be any unique string, however, we recommend using the customer's email address as the unique identifier. This enables the email personalization features. Email addresses are, in almost all cases, not passed as plain-text. Rather, you should lower-case the email string and then hash it in SHA256 format. The lower-case step helps to ensure consistency between all identifying events for the same user reported from multiple sources, and with any first-party data that you upload. Note that hashed email addresses are then further encrypted when stored in our servers.
Dynamic Yield does not in any way mandate that you pass a Customer ID. However, if you decide to use identifying events (see the list below), passing the Customer ID is required in some events, and optional in others.
Here are two examples of identification events. With these event types, passing a hashed email is mandatory. Without it, the event demarcates a login which might be a primary metric for some campaign but does not tie the user ID to any customer ID.
Login events
{
"user": {
"dyid": "7282320792394869879",
"dyid_server": "7282320792394869879"
},
"session": { "dy": "e3xi77qrxbsxxxmi18d8kxek6tdd12qj" },
"events": [
{
"name": "Login",
"properties": {
"dyType": "login-v1",
"hashedEmail": "62eccc43b550b012b7ea7fb07e64baafb1508d8b715a55148ccf0f3322eab1a1"
}
}
]
}'
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": { "id": "yaexono4ohphania" },
"session": { "custom": "iquahngaishe2koh" },
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Login",
"properties": {
"dyType": "login-v1",
"hashedEmail": "43e62d636651bc44edcd528a510d57ce69126cd875c..."
}
}
]
}'
{
"user": {
"dyid": "7282320792394869879",
"dyid_server": "7282320792394869879"
},
"session": { "dy": "e3xi77qrxbsxxxmi18d8kxek6tdd12qj" },
"events": [
{
"name": "Login",
"properties": {
"dyType": "login-v1",
"cuidType": "clientId", //You can use any type you want to
"cuid": "62eccc43b550b012b7ea7fb07e64baafb1508d8b715a55148ccf0f3322eab1a1"
}
}
]
}'
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": { "id": "yaexono4ohphania" },
"session": { "custom": "iquahngaishe2koh" },
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Login",
"properties": {
"dyType": "login-v1",
"cuidType": "clientId", //You can use any type you want to
"cuid": "62eccc43b550b012b7ea7fb07e64baafb1508d8b715a55148ccf0f3322eab1a1"
}
}
]
}'
Identify user events
{
"user": {
"dyid": "7282320792394869879",
"dyid_server": "7282320792394869879"
},
"session": { "dy": "e3xi77qrxbsxxxmi18d8kxek6tdd12qj" },
"events": [
{
"name": "Identify User",
"properties": {
"dyType": "identify-v1",
"hashedEmail": "62eccc43b550b012b7ea7fb07e64baafb1508d8b715a55148ccf0f3322eab1a1"
}
}
]
}'
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": { "id": "yaexono4ohphania" },
"session": { "custom": "iquahngaishe2koh" },
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Identify User",
"properties": {
"dyType": "identify-v1",
"hashedEmail": "43e62d636651bc44edcd528a510d57ce69126cd875c..."
}
}
]
}'
{
"user": {
"dyid": "7282320792394869879",
"dyid_server": "7282320792394869879"
},
"session": { "dy": "e3xi77qrxbsxxxmi18d8kxek6tdd12qj" },
"events": [
{
"name": "Identify User",
"properties": {
"dyType": "identify-v1",
"cuidType": "clientId", //You can use any type you want to
"cuid": "62eccc43b550b012b7ea7fb07e64baafb1508d8b715a55148ccf0f3322eab1a1"
}
}
]
}'
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": { "id": "yaexono4ohphania" },
"session": { "custom": "iquahngaishe2koh" },
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Identify User",
"properties": {
"dyType": "identify-v1",
"cuidType": "clientId", //You can use any type you want to
"cuid": "62eccc43b550b012b7ea7fb07e64baafb1508d8b715a55148ccf0f3322eab1a1"
}
}
]
}'
Custom events
Here's where you get to report any event that doesn't carry a meaning for Dynamic Yield, but does have one for your business.
A custom event:
- Must have a name for display, but does not have a dyType.
- Can have a monetary value, with or without the optional currency designation.
- Can have zero or more extra properties: strings, numbers, and boolean values. Note that we don't support nested properties when creating targeting rules over custom events.
Here's a simple example:
{
"user": {
"dyid": "7282320792394869879",
"dyid_server": "7282320792394869879"
},
"session": { "dy": "e3xi77qrxbsxxxmi18d8kxek6tdd12qj" },
"events": [
{
"name": "ExampleEvent1",
"properties": {
"isVIP": "true"
}
},
{
"name": "exampleEvent2"
}
]
}'
curl --request POST \
--url https://dy-api.com/v2/collect/user/event \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": { "id": "yaexono4ohphania" },
"sessionId": "iquahngaishe2koh",
"context": { "device": {"ip": "54.100.200.255" }},
"events": [
{
"name": "Filled Post-Purchase Survey",
"properties": {
"customerRole": "VP of Staplers",
"experienceRating": 4,
"likesSpecialOffers": true
}
}
]
}'
HTTP response codes
Code | Meaning |
---|---|
204 | Request succeeded. No body is returned |
400 | Error parsing request |
401 | Invalid or missing API key |
403 | Access denied for a valid API key |
405 | Wrong HTTP method (not POST, in this case) |
422 | Request body did not match schema |
429 | Too many requests received |
451 | Wrong key type was used (server-side key used from client-side or client-side key used from server-side) |
500 | Unspecified internal error |
List of predefined events
Add to Cart
Required for e-commerce sites.
Notes:
- Ensure that productId matches a SKU in the product feed.
- Optionally, you can pass the full updated cart with the newly added product to ensure that the cart state as known to Dynamic Yield is fully in sync with your system. This is mainly needed for triggered email and push notifications.
Property | Description | Type |
---|---|---|
dyType | Must be "add-to-cart-v1". | String |
value |
Add to Cart events must always have the total value of the added product. Value must be non-negative. |
Float |
currency (optional) |
String |
|
productId | SKU as in the feed. | String |
quantity | Product quantity added, must be non-negative. | Number |
cart | New cart state, including newly added item. | Array of objects. Properties of each object:
|
{
name: "Add to Cart",
properties: {
dyType: "add-to-cart-v1",
value: 198.00,
productId: "p-tv78615a",
quantity: 2,
cart: [
{
productId: "p-cr91275g",
quantity: 1,
itemPrice: 49.95
},
{
productId: "p-tv78615a",
quantity: 2,
itemPrice: 99.00,
}
]
}
}
Remove from Cart
The Remove from Cart event uses the same schema as Add to Cart, except for its dyType property value. Unlike Add to Cart, it isn't mandatory to implement this event unless you're using features that rely on Dynamic Yield holding the most up-to-date cart state (currently only triggered emails and push notifications).
Property | Description | Type |
---|---|---|
dyType | Must be "remove-from-cart-v1". | String |
value |
Remove from Cart events must always have the total value of the removed product. Value must be non-negative. |
Float |
currency (optional) |
String |
|
productId | SKU as in the feed. | String |
quantity | Product quantity removed, must be non-negative. | Number |
cart | New cart state, after the item is removed. | Array of objects. Properties of each object:
|
Sync Cart
- This optional event can be fired on any change to the cart that does not fall under adding or removing a specific product from cart.
- It updates the current cart state.
- Like the Remove from Cart event, this event is only needed for specific optional features.
- It's mandatory for the Exclude items currently in cart filter; for this filter, it must be implemented on every page load.
Property | Description | Type |
---|---|---|
dyType | Must be "sync-cart-v1". | String |
cart | New cart state, including adjusted items. | Array of objects. Properties of each object:
|
Purchase
Required for e-commerce sites.
Notes:
- Ensure that the productId property of each product matches a SKU in the product feed.
- In this event, unlike adding/removing from cart, the cart parameter is mandatory and describes all products purchased, rather than the new cart state post-purchase (which is usually empty).
- The value parameter should be the total value of the cart purchased.
- The uniqueTransactionId property is optional but strongly recommended, for data validation / de-duping any duplicate events over the same purchase.
Property | Description | Type |
---|---|---|
dyType | Must be "purchase-v1". | String |
value |
Purchase events should always have the total value of the whole cart. |
Float |
currency (optional) |
String |
|
uniqueTransactionId | If you pass this value, Dynamic Yield ensures that only one purchase is recorded for that transaction ID, even if duplicate events are reported. | String, maximum 64 characters |
cart | The products purchased. | Array of objects. Properties of each object:
|
{
name: "Purchase",
properties: {
dyType: "purchase-v1",
value: 349.80,
uniqueTransactionId: "exampleTransactionId",
cart: [
{
productId: "p-tv78615a",
quantity: 1,
itemPrice: 249.90,
},
{
productId: "p-cr91275g",
quantity: 2,
itemPrice: 49.95
}
]
}
}
Add to Wishlist
Optional. Use if your users can add items to a wish list, and you want to track this behavior.
Property | Description | Type |
---|---|---|
dyType | Must be "add-to-wishlist-v1". | String |
productId | SKU as in the feed. | String |
Login
Optionally identifies a customer.
Use this event type to report a login by an existing registered user. For a new account sign up, use the Sign Up event instead.
Make sure to read the section Events Identifying a Customer Across Channels. This event can be used with or without passing any registered customer ID (CUID). That CUID can be either a hashed email or any custom type.
You have several choices of what to include when sending this event:
- Report the event without any extra identifier to only track the action of the login itself.
- Report the event with a hashed email, enabling you to use email features (and onboarding of first-party data, for which the primary key is typically hashed email).
- Report the event with a non-email CUID type. In this case, you can specify the type by also setting the cuidType property. For example, pass crmId to designate identifiers created internally in your CRM. If cuidType is not set, a default type named id is used.
Property | Description | Type |
---|---|---|
dyType | Must be "login-v1". | String |
hashedEmail (optional) | SKU as in the feed. | String |
cuidType (optional) cuid (optional) |
Instead of a hashed email, you can pass a custom-type name into cuidType, and the actual ID in cuid. If only cuid is set, the type is set by default to id. |
String |
{
"name": "Login",
"properties": {
"dyType": "login-v1",
"hashedEmail": "43e62d636651bc44edcd528a510d57ce69126cd875c..."
}
}
Sign Up
Optionally identifies a customer.
Report this event when a user has completed the sign-up process and has become a registered customer. Optionally, you can also pass a hashed email or another customer ID type to associate the user ID with that registered customer ID.
Use this event the same way as the Login Event, with the dyType of "signup-v1".
Newsletter Subscription
Identifies a customer.
Report this event to track subscriptions (regardless of whether the user has an account) and associate the anonymous user ID with the hashed email entered by the user. This event does not accept custom customer ID types, and its main use is for enabling personalized email features.
Property | Description | Type |
---|---|---|
dyType | Must be "newsletter-subscription-v1". | String |
hashedEmail | SHA-256 encoding of the lowercase email. | String |
Video Watch
Report this event to track a video watch in media sites and applications.
Property | Description | Type |
---|---|---|
dyType | Must be "video-watch-v1". | String |
itemId | Mandatory string ID matching an identified present in the Content Feed. | String |
autoPlay (optional) | Indicates whether video played automatically or because of an explicit user action. | Boolean, false by default |
progress (optional) |
One of the following values:
|
String |
progressPercent | Only relevant if the progress value is VIDEO_PROGRESS. | Number |
{
"name": "Video Pre-roll Ended",
"properties": {
"dyType": "video-watch-v1",
"itemId":v-g67811a-people-watching-got-finale",
"autoplay": true,
"progress": "PREROLL_FINISHED"
}
}
Keyword Search
The user has run a free-style keyword search.
Property | Description | Type |
---|---|---|
dyType | Must be "keyword-search-v1". | String |
keywords | The search string, as is. | String |