Entities and Context Available in Extole's Configurable Reporting System

Reference for the entities and fields available in Extole's configurable reporting system, and how to access them in report mappings.

Overview

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.

FieldDescription
idStep record ID
clientIdClient that owns this record
personIdPerson who performed the step
nameStep name — e.g. converted, shared, signup
primaryStepNamePrimary name, excluding aliases
eventTimeWhen the step occurred
requestTimeWhen the request was received
programLabelProgram this step belongs to
campaignIdCampaign context (may be null)
containerEnvironment container — e.g. production
qualityQuality signal: HIGH, LOW, etc.
visitTypeNEW_TO_CLIENT, EXISTING_CLIENT, NORMAL, etc.
attributionALL, REFERRED, NOT_REFERRED, etc.
firstSiteVisitWhether this was the person's first site visit
rootEventIdRoot event in the causal chain
journeyNameJourney this step belongs to (may be null)
variantA/B test variant (may be null)
deviceTypeMobile, Desktop, Other
deviceOsOperating system
appTypeWEB, MOBILE, etc.
dataCustom 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.

FieldDescription
idInput record ID
clientIdClient that owns this record
personIdPerson associated with the event
nameEvent name — e.g. purchase, signup
eventTimeWhen the event occurred
requestTimeWhen the request was received
containerEnvironment container
localeLocale at event time
apiTypeAPI access method
userIdClient-side user identifier (may be null)
userAgentBrowser or client user-agent string (may be null)
ipAddressClient IP address (may be null)
deviceTypeDevice type
deviceOsOperating system
appTypeApplication type
dataCustom key-value payload from the client
httpHeadersHTTP 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.

FieldDescription
idInternal person ID
emailEmail address
normalizedEmailLowercased, normalized email
firstNameFirst name
lastNameLast name
localePreferred locale
partnerUserIdExternal user ID from the client
blockedWhether this person is blocked from participating
dataCustom person-level data
stepsAll steps recorded on this profile (PersonStep[])
rewardsAll rewards linked to this profile (PersonReward[])
shareablesReferral links owned by this person (Shareable[])
journeysJourney participation records (PersonJourney[])
recentAssociatedFriendsFriends this person has referred (PersonReferral[])
recentAssociatedAdvocatesAdvocates who referred this person (PersonReferral[])
audienceMembershipsAudience segments this person belongs to
recentRequestContextsRecent 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.

FieldDescription
stepNameStep name
eventDateWhen the step occurred
createdDateWhen the record was persisted
campaignIdCampaign context
programLabelProgram label
eventIdConsumer event ID for this step
rootEventIdRoot event ID
qualityQuality signal
valueNumeric value attached to the step
aliasNameWhether this step name is an alias
containerEnvironment container
journeyNameJourney name
dataStep-level custom data

PersonReward

One reward on the person's profile, accessible via person.rewards.

FieldDescription
rewardIdPlatform reward ID
nameReward slot name
personRoleadvocate, friend, etc.
faceValueReward face value
faceValueTypePOINTS, CREDIT, COUPON_CODE, etc.
stateCurrent reward state
dateEarnedWhen the reward was earned
rewardSupplierIdSupplier ID
campaignIdCampaign context
programLabelProgram label
expiryDateExpiry date (may be null)
dataCustom reward data

PersonReferral

One referral relationship, accessible via person.recentAssociatedFriends or person.recentAssociatedAdvocates.

FieldDescription
otherPersonIdThe other person in this referral pair
mySideThis person's role in the relationship
reasonHow the referral was established
createdDateWhen the referral was established
displacedWhether this referral was replaced by a later one
containerEnvironment container

RequestContext

One device and geo snapshot, accessible via person.recentRequestContexts.

FieldDescription
deviceIdDevice fingerprint ID
createdAtWhen this snapshot was captured
geoIp.ipAddressIP address
geoIp.country.isoCodeCountry ISO code
geoIp.country.nameCountry name
geoIp.state.isoCodeState ISO code
geoIp.state.nameState name
geoIp.city.nameCity name
geoIp.zipCodePostal 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.

FieldDescription
campaignIdCampaign ID
campaignNameDisplay name
programLabelURL-safe program slug
programTypeProgram type
descriptionCampaign description
currentStateLIVE, PAUSED, STOPPED, ARCHIVED, ENDED, DRAFT
startDateScheduled start date
stopDateScheduled stop date
lastPublishedDateWhen the campaign was last published
campaignTypeCampaign type
tagsClassification 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.

FieldDescription
campaignIdCampaign ID
campaignNameDisplay name
programLabelURL-safe program slug
currentStateCurrent lifecycle state
firstLaunchDateWhen the campaign first went live
lastStoppedDateWhen the campaign was last stopped
lastPausedDateWhen the campaign was last paused
lastArchivedDateWhen the campaign was last archived
tagsClassification 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.

FieldDescription
idClient ID
nameFull client name
shortNameShort identifier slug
clientTypeCUSTOMER, INTERNAL, etc.
timezoneClient's configured timezone
identityKeyIdentity 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.

FieldDescription
rewardIdPlatform reward ID
personIdPerson who earned the reward
faceValueReward face value
faceValueTypePOINTS, CREDIT, COUPON_CODE, etc.
currentStateEARNED, FULFILLED, SENT, REDEEMED, FAILED, CANCELED, REVOKED
rewardSupplierIdSupplier that issued this reward
campaignIdCampaign context
programProgram label
partnerRewardIdExternal reward identifier
earnedStepEventContext.nameName of the step that triggered this reward
earnedStepEventContext.eventTimeWhen the triggering step occurred
rewardEarnedDateWhen the reward was earned
rewardFulfilledDateWhen the reward was fulfilled
rewardSentDateWhen the reward was last sent
rewardRedeemedDateWhen the reward was redeemed
rewardFailedDateWhen the reward failed
rewardCanceledDateWhen the reward was canceled
rewardRevokedDateWhen the reward was revoked
tagsClassification tags
dataCustom 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.

FieldDescription
rewardSupplierIdSupplier ID
nameDisplay name
typeCOUPON, TANGO, PAYPAL_PAYOUTS, SALESFORCE_COUPON, CUSTOM, etc.
displayTypeUI display type
faceValueTypeValue type
faceValueConfigured face value
faceValueAlgorithmTypeHow face value is calculated
partnerRewardSupplierIdExternal 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.

FieldDescription
salesforceAccountIdCRM account ID
slackChannelNameInternal Slack channel
csmEmailCustomer success manager email
csmFirstNameCSM first name
csmLastNameCSM last name
supportEmailSupport 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.

FieldDescription
idEvent ID
typeEvent type discriminator
eventTimeWhen the event occurred
requestTimeWhen the request was received
rootEventIdRoot event in the causal chain
causeEventIdThe event that directly caused this one
dataArbitrary event data
personThe full Person profile
clientContext.clientIdClient ID at event time
clientContext.clientShortNameClient short name
eventContext.appTypeApplication type
eventContext.userIdClient-side user ID
sandbox.containerEnvironment 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;

AudienceMembershipRecord

Used in: Audience Memberships, Audience Memberships Metrics reports · Access: event.* (no join function — only reachable as the primary record of these two report types)

One audience membership change event: a person entering, updating, or leaving an audience segment.

FieldDescription
typeEvent type — AUDIENCE_MEMBERSHIP_CREATED, AUDIENCE_MEMBERSHIP_UPDATED, or AUDIENCE_MEMBERSHIP_DELETED
idEvent ID
clientIdClient that owns this record
eventTimeWhen the membership change occurred
requestTimeWhen the request was received
deviceProfileIdAssociated device profile (may be null)
identityProfileIdAssociated identity profile (may be null)
personIdPerson this membership belongs to
containerEnvironment container
dataCustom key-value event data
appDataApplication-level event data
audienceIdAudience segment ID
audienceNameAudience segment display name

MessageSummary

Used in: Message Metrics reports · Access: event.* (no join function — only reachable as the primary record of this report type)

One outbound message (typically email) triggered by a campaign, with delivery and suppression outcome.

FieldDescription
clientIdClient that owns this record
messageIdMessage ID
zoneNameZone/campaign zone that triggered the message
programLabelProgram label (may be null)
campaignIdParent campaign ID (may be null)
containerEnvironment container (may be null)
optoutListOpt-out list name if the message was suppressed (may be null)
normalizedEmailFromNormalized sender email (may be null)
normalizedEmailSentAsNormalized "sent as" email (may be null)
normalizedEmailToNormalized recipient email (may be null)
emailToRecipient email, original form (may be null)
emailSubjectEmail subject line (may be null)
doNotSendReasonReason the message was not sent, if applicable (may be null)
statusMessage status — e.g. SENT, FAILED, NOT_SENT
dataCustom message data
triggeredDateWhen the message was triggered
sentDateWhen the message was sent (may be null)
recipientIdRecipient identifier, if known (may be null)

WebhookEvent

Used in: Webhook Events, Webhook Event Metrics reports · Access: event.* (no join function — only reachable as the primary record of these two report types)

One webhook trigger event — the event that queues a webhook dispatch, before the dispatch attempt itself.

FieldDescription
eventIdWebhook event ID
clientIdClient that owns this record
eventTimeWhen the webhook event was generated
webhookIdWebhook definition ID
causeEventIdID of the event that triggered this webhook
rootEventIdRoot event in the causal chain
causeEventSequenceSequence position of the cause event
dataWebhook event payload (custom data)

WebhookDispatchResultEvent

Used in: Webhook Dispatch Results, Webhook Dispatch Result Metrics reports · Access: event.* (no join function — only reachable as the primary record of these two report types)

The outcome of one webhook dispatch attempt — the HTTP request Extole sent and the response received.

FieldDescription
clientIdClient that owns this record
webhookIdWebhook definition ID
urlTarget webhook URL (may be null)
eventTimeWhen the dispatch attempt occurred
attemptCountNumber of retry attempts made
configuredRetriesCountMaximum configured retries
methodHTTP method used — e.g. POST (may be null)
requestBodyRequest body sent to the webhook endpoint (may be null)
requestHeadersHTTP request headers sent
responseStatusCodeHTTP response status code received (may be null)
responseBodyResponse body received (may be null)
responseHeadersHTTP response headers received
logMessagesDispatch attempt log messages
tagsTags/labels assigned to this dispatch result

ClientEvent

Used in: Client Event Metrics reports · Access: event.* (no join function — only reachable as the primary record of this report type)

An operational or business event logged against a client account (e.g. a platform notice or account-level occurrence), distinct from a person's referral-program steps.

FieldDescription
eventIdEvent ID
eventTypeEvent type classification
clientIdClient this event is logged against
eventTimeWhen the event occurred
nameEvent name
tagsClassification tags — e.g. TECHNICAL, BUSINESS_OPERATIONS
messageHuman-readable event message
dataStructured event data — each value has value, type (STRING or ATTACHMENT), and scope
levelSeverity level — INFO, WARN, or ERROR
userIdUser identifier, if applicable (may be null)
scopeVisibility scope of the event

Did this page help you?