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 |
| Step record ID |
| Client that owns this record |
| Person who performed the step |
| Step name — e.g. |
| Primary name, excluding aliases |
| When the step occurred |
| When the request was received |
| Program this step belongs to |
| Campaign context (may be null) |
| Environment container — e.g. |
| Quality signal: |
|
|
|
|
| Whether this was the person's first site visit |
| Root event in the causal chain |
| Journey this step belongs to (may be null) |
| A/B test variant (may be null) |
|
|
| Operating system |
|
|
| 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 |
| Input record ID |
| Client that owns this record |
| Person associated with the event |
| Event name — e.g. |
| When the event occurred |
| When the request was received |
| Environment container |
| Locale at event time |
| API access method |
| Client-side user identifier (may be null) |
| Browser or client user-agent string (may be null) |
| Client IP address (may be null) |
| Device type |
| Operating system |
| Application type |
| Custom key-value payload from the client |
| 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 |
| Internal person ID |
| Email address |
| Lowercased, normalized email |
| First name |
| Last name |
| Preferred locale |
| External user ID from the client |
| Whether this person is blocked from participating |
| Custom person-level data |
| All steps recorded on this profile ( |
| All rewards linked to this profile ( |
| Referral links owned by this person ( |
| Journey participation records ( |
| Friends this person has referred ( |
| Advocates who referred this person ( |
| Audience segments this person belongs to |
| Recent device and geo snapshots ( |
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 |
| Step name |
| When the step occurred |
| When the record was persisted |
| Campaign context |
| Program label |
| Consumer event ID for this step |
| Root event ID |
| Quality signal |
| Numeric value attached to the step |
| Whether this step name is an alias |
| Environment container |
| Journey name |
| Step-level custom data |
PersonReward
One reward on the person's profile, accessible via person.rewards.
Field | Description |
| Platform reward ID |
| Reward slot name |
|
|
| Reward face value |
|
|
| Current reward state |
| When the reward was earned |
| Supplier ID |
| Campaign context |
| Program label |
| Expiry date (may be null) |
| Custom reward data |
PersonReferral
One referral relationship, accessible via person.recentAssociatedFriends or person.recentAssociatedAdvocates.
Field | Description |
| The other person in this referral pair |
| This person's role in the relationship |
| How the referral was established |
| When the referral was established |
| Whether this referral was replaced by a later one |
| Environment container |
RequestContext
One device and geo snapshot, accessible via person.recentRequestContexts.
Field | Description |
| Device fingerprint ID |
| When this snapshot was captured |
| IP address |
| Country ISO code |
| Country name |
| State ISO code |
| State name |
| City name |
| 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 |
| Campaign ID |
| Display name |
| URL-safe program slug |
| Program type |
| Campaign description |
|
|
| Scheduled start date |
| Scheduled stop date |
| When the campaign was last published |
| Campaign type |
| 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 |
| Campaign ID |
| Display name |
| URL-safe program slug |
| Current lifecycle state |
| When the campaign first went live |
| When the campaign was last stopped |
| When the campaign was last paused |
| When the campaign was last archived |
| 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 |
| Client ID |
| Full client name |
| Short identifier slug |
|
|
| Client's configured timezone |
| 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 |
| Platform reward ID |
| Person who earned the reward |
| Reward face value |
|
|
|
|
| Supplier that issued this reward |
| Campaign context |
| Program label |
| External reward identifier |
| Name of the step that triggered this reward |
| When the triggering step occurred |
| When the reward was earned |
| When the reward was fulfilled |
| When the reward was last sent |
| When the reward was redeemed |
| When the reward failed |
| When the reward was canceled |
| When the reward was revoked |
| Classification tags |
| 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 |
| Supplier ID |
| Display name |
|
|
| UI display type |
| Value type |
| Configured face value |
| How face value is calculated |
| 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 |
| CRM account ID |
| Internal Slack channel |
| Customer success manager email |
| CSM first name |
| CSM last name |
| 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 |
| Event ID |
| Event type discriminator |
| When the event occurred |
| When the request was received |
| Root event in the causal chain |
| The event that directly caused this one |
| Arbitrary event data |
| The full Person profile |
| Client ID at event time |
| Client short name |
| Application type |
| Client-side user ID |
| 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;