Entities and Context Available in Extole's Configurable Reporting System
Use this document alongside Custom Data Queries using Extole Reports, which covers expression syntax and functions.
In a report mapping, the primary row record is accessed as event.*. Which entity that is depends on the report type.
StepRecord
Used in: Events, Metrics reports · Access: event.*
One step in the referral lifecycle recorded on a person's profile. Examples: a share, a click, a conversion, a reward earned. Steps carry quality signals, attribution, and device context on top of the raw event data.
Field
Description
id
Step record ID
clientId
Client that owns this record
personId
Person who performed the step
name
Step name — e.g. converted, shared, signup
primaryStepName
Primary name, excluding aliases
eventTime
When the step occurred
requestTime
When the request was received
programLabel
Program this step belongs to
campaignId
Campaign context (may be null)
container
Environment container — e.g. production
quality
Quality signal: HIGH, LOW, etc.
visitType
NEW_TO_CLIENT, EXISTING_CLIENT, NORMAL, etc.
attribution
ALL, REFERRED, NOT_REFERRED, etc.
firstSiteVisit
Whether this was the person's first site visit
rootEventId
Root event in the causal chain
journeyName
Journey this step belongs to (may be null)
variant
A/B test variant (may be null)
deviceType
Mobile, Desktop, Other
deviceOs
Operating system
appType
WEB, MOBILE, etc.
data
Custom key-value data on the step
Common data keys: amount, source, channel, locale, country, partner_user_id, api_type.
Mapping examples:# Basic fields Id=event.id; Person=event.personId; Step=event.name; Amount=event.data.amount; # Keys that contain dots must be quoted Share Message=event.data."share.message"; # Null-safe data field Amount=default(event.data.amount, value:"0"); # Filter to high-quality referred conversions # (in Filters parameter) event.quality=="HIGH";event.visitType=="NEW_TO_CLIENT"
In a Metrics report, step_name scopes the aggregation to a specific step:Unique Converters=group_count_distinct(event.personId, step_name:"converted"); Total Revenue=group_sum(event.data.amount, step_name:"converted", quality:"HIGH");
InputRecord
Used in: Input Records, Input Record Metrics reports · Access: event.*
A raw inbound event from a client integration, before it is processed into a step. Captures the original payload and the device and network context at request time.
Field
Description
id
Input record ID
clientId
Client that owns this record
personId
Person associated with the event
name
Event name — e.g. purchase, signup
eventTime
When the event occurred
requestTime
When the request was received
container
Environment container
locale
Locale at event time
apiType
API access method
userId
Client-side user identifier (may be null)
userAgent
Browser or client user-agent string (may be null)
ipAddress
Client IP address (may be null)
deviceType
Device type
deviceOs
Operating system
appType
Application type
data
Custom key-value payload from the client
httpHeaders
HTTP headers from the inbound request
Mapping examples:# Basic fields Event Name=event.name; API Type=event.apiType; Device=device_type(user_agent:event.userAgent); OS=device_type(user_agent:event.userAgent, mode:"OS_TYPE"); # Count all input events by name in an Input Record Metrics report name=event.name; api_type=event.apiType; count=group_count_distinct(event.id, name:"all"); # Count a specific event per person per day day=end_date(event.eventTime, period:"DAY"); person_id=person(event.personId).id; count=group_count_distinct(event.id, name:"purchase");
Person
Function: person(personId) · e.g. person(event.personId).email
The full profile for one participant. A person accumulates steps, rewards, and referral relationships over time. Use the PERSON_COLLECTION function to filter and aggregate data from the collection fields.
Field
Description
id
Internal person ID
Email address
normalizedEmail
Lowercased, normalized email
firstName
First name
lastName
Last name
locale
Preferred locale
partnerUserId
External user ID from the client
blocked
Whether this person is blocked from participating
data
Custom person-level data
steps
All steps recorded on this profile (PersonStep[])
rewards
All rewards linked to this profile (PersonReward[])
shareables
Referral links owned by this person (Shareable[])
journeys
Journey participation records (PersonJourney[])
recentAssociatedFriends
Friends this person has referred (PersonReferral[])
recentAssociatedAdvocates
Advocates who referred this person (PersonReferral[])
audienceMemberships
Audience segments this person belongs to
recentRequestContexts
Recent device and geo snapshots (RequestContext[])
Mapping examples:# Basic person fields Email=person(event.personId).email; First Name=person(event.personId).firstName; Last Name=person(event.personId).lastName; Partner ID=person(event.personId).partnerUserId; # Custom person data Tier=person(event.personId).data.tier;
Use person_collection to aggregate from profile collections. It is more memory-efficient than collection for large profiles.# Count converted steps on the profile Conversions=person_collection(person(event.personId).id, collection:"steps", filter:stepName=="converted", extracting:eventId, reduce:"count"); # Sum high-quality conversion values Total Value=person_collection(person(event.personId).id, collection:"steps", filter:stepName=="converted" and quality=="HIGH", extracting:value, reduce:"sum"); # Count primary (non-alias) steps only Primary Steps=person_collection(person(event.personId).id, collection:"steps", filter:aliasName=="false", extracting:eventId, reduce:"count");
Use FIRST or LAST with sortBy to extract a single step:# Campaign of the person's first application step hidden(first_app)=FIRST(COLLECTION(PERSON(event.personId).steps, filter:stepName=="application_started"), sortBy:"createdDate"); First App Campaign=campaign(property(first_app).campaignId).campaignName;
PersonStep
One step on the person's timeline, accessible via person.steps.
Field
Description
stepName
Step name
eventDate
When the step occurred
createdDate
When the record was persisted
campaignId
Campaign context
programLabel
Program label
eventId
Consumer event ID for this step
rootEventId
Root event ID
quality
Quality signal
value
Numeric value attached to the step
aliasName
Whether this step name is an alias
container
Environment container
journeyName
Journey name
data
Step-level custom data
PersonReward
One reward on the person's profile, accessible via person.rewards.
Field
Description
rewardId
Platform reward ID
name
Reward slot name
personRole
advocate, friend, etc.
faceValue
Reward face value
faceValueType
POINTS, CREDIT, COUPON_CODE, etc.
state
Current reward state
dateEarned
When the reward was earned
rewardSupplierId
Supplier ID
campaignId
Campaign context
programLabel
Program label
expiryDate
Expiry date (may be null)
data
Custom reward data
PersonReferral
One referral relationship, accessible via person.recentAssociatedFriends or person.recentAssociatedAdvocates.
Field
Description
otherPersonId
The other person in this referral pair
mySide
This person's role in the relationship
reason
How the referral was established
createdDate
When the referral was established
displaced
Whether this referral was replaced by a later one
container
Environment container
RequestContext
One device and geo snapshot, accessible via person.recentRequestContexts.
Field
Description
deviceId
Device fingerprint ID
createdAt
When this snapshot was captured
geoIp.ipAddress
IP address
geoIp.country.isoCode
Country ISO code
geoIp.country.name
Country name
geoIp.state.isoCode
State ISO code
geoIp.state.name
State name
geoIp.city.name
City name
geoIp.zipCode
Postal code
Mapping example:# Last known zip code and city for the person Zip=LAST(COLLECTION(PERSON(event.personId).recentRequestContexts), sortBy:createdAt).geoIp.zip_code; City=LAST(COLLECTION(PERSON(event.personId).recentRequestContexts), sortBy:createdAt).geoIp.city.name;
BuiltCampaign
Function: campaign(campaignId) · e.g. campaign(event.campaignId).campaignName
The latest published state of a campaign. Use this when you need the current name, state, or dates as of the most recent publish.
Field
Description
campaignId
Campaign ID
campaignName
Display name
programLabel
URL-safe program slug
programType
Program type
description
Campaign description
currentState
LIVE, PAUSED, STOPPED, ARCHIVED, ENDED, DRAFT
startDate
Scheduled start date
stopDate
Scheduled stop date
lastPublishedDate
When the campaign was last published
campaignType
Campaign type
tags
Classification tags
**Mapping examples:**Campaign Name=campaign(event.campaignId).campaignName; Program=campaign(event.campaignId).programLabel; State=campaign(event.campaignId).currentState;
Use a hidden() column when you need multiple fields from the same campaign to avoid resolving it twice:hidden(camp)=campaign(event.campaignId); Campaign Name=camp.campaignName; Campaign State=camp.currentState;
CampaignSummary
Function: campaign_summary(campaignId) · e.g. campaign_summary(event.campaignId).firstLaunchDate
An aggregated view built from all known campaign state-change events. Use this instead of campaign() when you need historical milestone dates rather than the current snapshot.
Field
Description
campaignId
Campaign ID
campaignName
Display name
programLabel
URL-safe program slug
currentState
Current lifecycle state
firstLaunchDate
When the campaign first went live
lastStoppedDate
When the campaign was last stopped
lastPausedDate
When the campaign was last paused
lastArchivedDate
When the campaign was last archived
tags
Classification tags
Mapping examples:# When you need when a campaign first launched, not just its current state First Launch=campaign_summary(event.campaignId).firstLaunchDate; Last Stopped=campaign_summary(event.campaignId).lastStoppedDate;
Client
Function: client(clientId) or client() (uses the event's client) · e.g. client(event.clientId).shortName
The brand account on the platform.
Field
Description
id
Client ID
name
Full client name
shortName
Short identifier slug
clientType
CUSTOMER, INTERNAL, etc.
timezone
Client's configured timezone
identityKey
Identity key type used for this client
Arbitrary client configuration values are accessed via client_properties() (no argument):client_properties().vertical
**Mapping examples:**Client=client(event.clientId).shortName; Timezone=client(event.clientId).timezone; Vertical=client_properties().vertical;
client() with no argument resolves to the event's own client, so both forms are equivalent in single-client reports:Type=client().clientType;
When running a cross-client report from the Extole account, filter to real customers:# Filters parameter client(event.clientId).clientType=="CUSTOMER"
RewardSummary
Function: reward(rewardId) · e.g. reward(event.data.reward_id).currentState
The full lifecycle of one reward instance, built from all known reward state-change events.
Field
Description
rewardId
Platform reward ID
personId
Person who earned the reward
faceValue
Reward face value
faceValueType
POINTS, CREDIT, COUPON_CODE, etc.
currentState
EARNED, FULFILLED, SENT, REDEEMED, FAILED, CANCELED, REVOKED
rewardSupplierId
Supplier that issued this reward
campaignId
Campaign context
program
Program label
partnerRewardId
External reward identifier
earnedStepEventContext.name
Name of the step that triggered this reward
earnedStepEventContext.eventTime
When the triggering step occurred
rewardEarnedDate
When the reward was earned
rewardFulfilledDate
When the reward was fulfilled
rewardSentDate
When the reward was last sent
rewardRedeemedDate
When the reward was redeemed
rewardFailedDate
When the reward failed
rewardCanceledDate
When the reward was canceled
rewardRevokedDate
When the reward was revoked
tags
Classification tags
data
Custom reward data
Mapping examples:# From a Rewards report — reward_id is on the event data State=reward(event.data.reward_id).currentState; Face Value=reward(event.data.reward_id).faceValue; Value Type=reward(event.data.reward_id).faceValueType; Earned On=reward(event.data.reward_id).rewardEarnedDate; Earning Step=reward(event.data.reward_id).earnedStepEventContext.name;
To sum total reward value issued across a step in a Metrics report:Total Reward Value=group_sum(reward(event.data.reward_id).faceValue, step_name:"advocate_reward_earned");
RewardSupplier
Function: reward_supplier(rewardSupplierId) · e.g. reward_supplier(event.rewardSupplierId).displayType
The configuration for how rewards are structured and issued.
Field
Description
rewardSupplierId
Supplier ID
name
Display name
type
COUPON, TANGO, PAYPAL_PAYOUTS, SALESFORCE_COUPON, CUSTOM, etc.
displayType
UI display type
faceValueType
Value type
faceValue
Configured face value
faceValueAlgorithmType
How face value is calculated
partnerRewardSupplierId
External supplier identifier
**Mapping example:**Supplier Name=reward_supplier(event.rewardSupplierId).name; Supplier Type=reward_supplier(event.rewardSupplierId).type; Display Type=reward_supplier(event.rewardSupplierId).displayType;
SupportSummary
Function: support() · e.g. support().salesforceAccountId
Account-level support and CRM metadata for the current client. No argument is required.
Field
Description
salesforceAccountId
CRM account ID
slackChannelName
Internal Slack channel
csmEmail
Customer success manager email
csmFirstName
CSM first name
csmLastName
CSM last name
supportEmail
Support representative email
**Mapping example:**Salesforce ID=support().salesforceAccountId; CSM=concatenate(support().csmFirstName, " ", support().csmLastName);
ConsumerEvent
Function: event(eventId) · e.g. event(event.rootEventId).type
The raw event object. Most reports use StepRecord or InputRecord as the primary row record; load the raw event when you need the full person sub-object or properties not available on the record.
Field
Description
id
Event ID
type
Event type discriminator
eventTime
When the event occurred
requestTime
When the request was received
rootEventId
Root event in the causal chain
causeEventId
The event that directly caused this one
data
Arbitrary event data
person
The full Person profile
clientContext.clientId
Client ID at event time
clientContext.clientShortName
Client short name
eventContext.appType
Application type
eventContext.userId
Client-side user ID
sandbox.container
Environment container
StepConsumerEvent adds: name, aliases, firstSiteVisit, duplicate, partnerEventId, referralContext, selectedCampaignContext.
InputConsumerEvent adds: name, url, referrer, sourceIps, httpHeaders, httpCookies, labels, locale.
Mapping examples:# Load the root event to get its type or name Root Event Type=event(event.rootEventId).type; Root Event Name=event(event.rootEventId).name; # Access the person sub-object via the raw event Person Email=event(event.id).person.email;
Two common cross-entity lookups worth knowing:
From a step event, load the originating input record (gives you apiType, userAgent, etc.):API Type=input_record(event.rootEventId, event_time_name:event.eventTime).apiType; User Agent=input_record(event.rootEventId, event_time_name:event.eventTime).userAgent;
From a reward event, load the step record that earned the reward (gives you visitType, quality, etc.):Visit Type=step_record(event.earnedStepEventContext.id, step_name:event.earnedStepEventContext.name, event_time_name:event.earnedStepEventContext.eventTime).visitType;
