Why Schema Design Matters More Than You Think
XDM (Experience Data Model) schemas are the foundation of everything in Adobe Experience Platform. Every dataset, every identity graph, every segment, and every journey depends on the schema being right. Change a schema later and you’re dealing with dataset migrations, broken queries, and downstream tools (Target, CJA, AJO) that reference fields that no longer exist.
The cost of a bad schema decision is not immediately visible. It shows up six months later when someone tries to build a cross-channel report and discovers that web events and CRM events used different field paths for the same concept, or when a critical identity field was stored as a string instead of an identity map.
The Two Schema Classes
AEP schemas fall into two classes:
XDM ExperienceEvent
Time-series data. Every record represents something that happened at a specific point in time. This is where most of your data lives:
- Web page views and interactions (via Web SDK)
- Mobile app events
- Email sends, opens, clicks
- Purchase transactions
- Call center interactions
- Any other timestamped customer activity
ExperienceEvent schemas always require a timestamp field and benefit from an identityMap for linking events to people.
XDM Individual Profile
Entity data. Each record represents the current state of a person. This is your customer attributes:
- Name, email, account type
- Loyalty tier, LTV segment
- Consent preferences
- Computed attributes (last purchase date, total spend)
Profile schemas support merge policies, which determine how AEP resolves conflicting data from multiple sources. For example, if your CRM says a customer’s email is X and your web form says it’s Y, the merge policy decides which wins.
Field Groups: Build or Borrow
Field groups are reusable bundles of fields. They’re how you add structure to a schema without defining everything from scratch.
Adobe-Provided Field Groups
Start here. Adobe provides field groups for common data patterns:
- Web Details —
web.webPageDetails,web.webReferrer, etc. Automatically populated by Web SDK. - Commerce —
productListItems,commerce.purchases,commerce.order. Standard e-commerce event structure. - Channel Details — Marketing channel classification fields.
- Profile Person Details — Name, birth date, gender, etc.
- Profile Personal Contact Details — Email, phone, address.
Using standard field groups means Target, CJA, and AJO know where to find data without custom mapping. If you put page names in web.webPageDetails.name, CJA auto-discovers it. If you put it in a custom field, you have to map it manually everywhere.
Custom Field Groups
Create custom field groups for data that doesn’t fit Adobe’s standard models. Common examples:
- Business-specific attributes — Account type, subscription tier, internal segment codes
- Custom event properties — Fields specific to your product (game level, article category, plan type)
- Integration identifiers — IDs from third-party systems (Salesforce ID, Marketo lead ID, internal CRM key)
When creating custom field groups, put them under your tenant namespace (_yourorgid). This prevents naming collisions with Adobe’s standard fields and other organizations.
Identity Configuration
Identity is the most consequential schema decision. Get it wrong and your identity graph becomes a mess.
Primary vs. Secondary Identities
Each schema can have one primary identity and multiple secondary identities:
- Primary identity — The main identifier for this data source. For web data, this is usually ECID. For CRM data, it’s your customer ID.
- Secondary identities — Additional identifiers that AEP uses for identity stitching. Authenticated user ID on web data is a secondary identity that links anonymous ECID sessions to known profiles.
Identity Namespaces
Define namespaces before designing schemas:
- ECID (standard) — Automatically assigned by Web SDK. Device-scoped, first-party cookie.
- Email (standard) — Use the hashed email namespace if you’re stitching by email.
- CRM ID (custom) — Create a custom namespace for your internal customer identifier.
- Loyalty ID (custom) — If separate from CRM ID.
The rule of thumb: every system that assigns its own user ID should have its own namespace. Don’t reuse namespaces across systems — it creates false identity merges.
The Identity Map
For ExperienceEvent schemas, use the identityMap field instead of marking individual fields as identities. The identity map is an object where each key is a namespace and the value is an array of IDs:
{
"identityMap": {
"ECID": [{ "id": "12345", "primary": true }],
"CRM_ID": [{ "id": "CUST-789", "primary": false }]
}
}
This approach is more flexible than field-level identity marking because a single event can carry multiple identities without schema changes.
Schema Architecture Patterns
Pattern 1: One Schema Per Channel
The simplest approach. Create separate ExperienceEvent schemas for web, mobile, CRM, and email data:
Web Interaction Event— Uses Web Details, Commerce, and your custom field groupsMobile App Event— Uses Mobile SDK fields and custom event propertiesCRM Interaction Event— Uses custom field groups for offline touchpoints
Pros: Clean separation, easy to understand, each team owns their schema. Cons: If you need to add a field that applies to multiple channels, you create a shared field group or duplicate it.
Pattern 2: Unified Event Schema
One ExperienceEvent schema for all channels with channel-specific field groups attached:
Pros: One schema to manage, guaranteed field consistency across channels. Cons: Large schema with many fields that are null for most events. Can be confusing for teams that only work with one channel.
Recommendation
Start with Pattern 1 (one schema per channel). It’s easier to reason about, easier to govern, and you can always create shared field groups that get attached to multiple schemas. A unified schema sounds elegant in theory but becomes unwieldy once you have 200+ fields and 5 different teams adding to it.
Common Design Mistakes
- Storing computed values — Don’t put “total lifetime spend” in an event schema. Compute it in CJA or use AEP computed attributes. Event schemas should capture what happened, not derived metrics.
- Flat field structures — Don’t create
customField1,customField2, etc. Use nested objects with meaningful names._tenant.subscription.planTypeis searchable and self-documenting;_tenant.cf7is not. - Ignoring data types — Use the correct XDM data type. Dates should be
dateTime, not strings. Currencies should use thecurrencyCode+amountpattern, not a plain number. IDs should be in the identity map, not free-text strings. - Over-engineering — Don’t model every possible future requirement. Design for the data you’re ingesting today and the reports you need this quarter. Schemas can be extended (fields added) without breaking existing data. They cannot be narrowed (fields removed from existing records) without migration.
A well-designed XDM schema is boring. It maps cleanly to the source data, uses standard field groups where possible, has clear identity configuration, and doesn’t try to be clever. Clever schemas are the ones that cause problems six months later.