This reference catalogs the standard (global) attributes available on the Narrative platform. These attributes are available to all organizations and represent commonly used data concepts.
Identity attributes
Attributes for identifying individuals across datasets.
| Attribute | Type | Description |
|---|
unique_identifier | object | Universal identifier supporting multiple ID types |
narrative_id | string | Narrative-encoded pseudonymous identifier for privacy-safe collaboration |
email_sha256 | string | SHA-256 hash of lowercase, trimmed email address |
phone_sha256 | string | SHA-256 hash of E.164 formatted phone number |
idfa | string | Apple Identifier for Advertisers |
gaid | string | Google Advertising ID |
cookie_id | string | Browser cookie identifier |
unique_identifier
A flexible object for representing various identifier types.
Structure:
{
"id": 100,
"name": "unique_identifier",
"type": "object",
"description": "Universal identifier supporting multiple ID types",
"properties": {
"type": {
"type": "string"
},
"value": {
"type": "string"
},
"context": {
"type": "string"
}
},
"required": ["type", "value"]
}
Common type/context combinations:
| type | context | Description |
|---|
email_sha256 | hashed_email | SHA-256 hashed email |
phone_sha256 | hashed_phone | SHA-256 hashed phone |
idfa | mobile_advertising | Apple IDFA |
gaid | mobile_advertising | Google Advertising ID |
cookie | web | Browser cookie |
customer_id | internal | Internal customer identifier |
Mapping example:
STRUCT(
'email_sha256' AS type,
LOWER(email_hash) AS value,
'hashed_email' AS context
)
narrative_id
A Narrative-encoded pseudonymous identifier that enables privacy-safe data collaboration. Unlike standard hashes, Narrative IDs are encoded per-partner, meaning the same underlying identifier produces different Narrative IDs for different partners.
Definition:
{
"id": 103,
"name": "narrative_id",
"type": "string",
"is_join_key": true,
"description": "Narrative-encoded pseudonymous identifier"
}
Mapping example:
-- Encode a hashed email into a Narrative ID
NARRATIVE_ID_ENCODE(email_sha256, 'your_encoding_key_id')
-- Encode a raw email (normalize first)
NARRATIVE_ID_ENCODE(LOWER(TRIM(email)), 'your_encoding_key_id')
Narrative IDs exist within encoding spaces. To match across partners, use NARRATIVE_ID_TRANSLATE to convert between encoding spaces.
Related: Narrative ID Concepts, Using Narrative ID
email_sha256
SHA-256 hash of an email address. The source email should be lowercased and trimmed before hashing.
Definition:
{
"id": 101,
"name": "email_sha256",
"type": "string",
"is_join_key": true,
"validations": ["min_length:64", "max_length:64", "pattern:^[a-f0-9]{64}$"]
}
Mapping example:
-- If already hashed
LOWER(email_hash)
-- If raw email (not recommended - hash before upload)
SHA256(LOWER(TRIM(email)))
phone_sha256
SHA-256 hash of a phone number in E.164 format (e.g., +15551234567).
Definition:
{
"id": 102,
"name": "phone_sha256",
"type": "string",
"is_join_key": true,
"validations": ["min_length:64", "max_length:64", "pattern:^[a-f0-9]{64}$"]
}
Demographic attributes
Attributes describing individual characteristics.
| Attribute | Type | Description |
|---|
hl7_gender | string (enum) | Gender using HL7 administrative codes |
age | long | Age in years |
birth_year | long | Year of birth |
birth_date | timestamptz | Full date of birth |
household_income | string (enum) | Income bracket |
education_level | string (enum) | Highest education attained |
hl7_gender
Gender using HL7 FHIR administrative gender codes.
Definition:
{
"id": 200,
"name": "hl7_gender",
"type": "string",
"enum": ["male", "female", "other", "unknown"],
"description": "Gender using HL7 administrative gender codes"
}
Mapping example:
CASE UPPER(gender_col)
WHEN 'M' THEN 'male'
WHEN 'MALE' THEN 'male'
WHEN 'F' THEN 'female'
WHEN 'FEMALE' THEN 'female'
WHEN 'NB' THEN 'other'
WHEN 'NON-BINARY' THEN 'other'
WHEN 'O' THEN 'other'
ELSE 'unknown'
END
age
Age in whole years.
Definition:
{
"id": 201,
"name": "age",
"type": "long",
"validations": ["min:0", "max:150"]
}
Mapping example:
-- From birth year
YEAR(CURRENT_DATE) - birth_year
-- From birth date
DATE_DIFF('year', birth_date, CURRENT_DATE)
birth_year
Four-digit year of birth.
Definition:
{
"id": 202,
"name": "birth_year",
"type": "long",
"validations": ["min:1900", "max:2025"]
}
household_income
Household income bracket.
Definition:
{
"id": 203,
"name": "household_income",
"type": "string",
"enum": ["under_25k", "25k_50k", "50k_75k", "75k_100k", "100k_150k", "150k_200k", "over_200k", "unknown"]
}
Timestamp attributes
Attributes for temporal data.
| Attribute | Type | Description |
|---|
event_timestamp | timestamptz | When an event occurred |
nio_created_at | timestamptz | When the record was created in Narrative |
nio_last_modified | timestamptz | When the record was last updated |
event_timestamp
The timestamp when the event or observation occurred. Stored in UTC.
Definition:
{
"id": 300,
"name": "event_timestamp",
"type": "timestamptz",
"description": "When the event occurred"
}
Format: ISO 8601 (YYYY-MM-DDTHH:MM:SSZ)
Mapping examples:
-- From ISO 8601 string
TO_TIMESTAMP(ts_col, 'YYYY-MM-DD"T"HH24:MI:SS')
-- From Unix epoch (seconds)
TO_TIMESTAMP(epoch_seconds)
-- From Unix epoch (milliseconds)
TO_TIMESTAMP(epoch_ms / 1000)
-- From various date formats
TO_TIMESTAMP(date_col, 'MM/DD/YYYY HH24:MI:SS')
nio_created_at / nio_last_modified
System-managed timestamps. These are set automatically by the platform and should not be mapped manually.
Geographic attributes
Attributes for location data.
| Attribute | Type | Description |
|---|
country_code | string | ISO 3166-1 alpha-2 country code |
postal_code | string | Postal/ZIP code |
geo_coordinates | object | Latitude and longitude |
region | string | State, province, or region |
city | string | City name |
dma_code | string | Designated Market Area code (US) |
country_code
Two-letter ISO 3166-1 alpha-2 country code.
Definition:
{
"id": 400,
"name": "country_code",
"type": "string",
"validations": ["min_length:2", "max_length:2", "pattern:^[A-Z]{2}$"]
}
Examples: US, GB, DE, JP
Mapping example:
geo_coordinates
Geographic coordinates.
Definition:
{
"id": 401,
"name": "geo_coordinates",
"type": "object",
"properties": {
"latitude": {
"type": "double"
},
"longitude": {
"type": "double"
},
"accuracy_meters": {
"type": "double"
}
},
"required": ["latitude", "longitude"]
}
Mapping example:
STRUCT(
CAST(lat AS DOUBLE) AS latitude,
CAST(lon AS DOUBLE) AS longitude,
CAST(accuracy AS DOUBLE) AS accuracy_meters
)
postal_code
Postal or ZIP code. Format varies by country.
Definition:
{
"id": 402,
"name": "postal_code",
"type": "string"
}
Mapping example:
-- US ZIP codes: normalize to 5 digits
SUBSTRING(zip_code, 1, 5)
-- Include +4 if available
CASE
WHEN LENGTH(zip_code) >= 9 THEN CONCAT(SUBSTRING(zip_code, 1, 5), '-', SUBSTRING(zip_code, 6, 4))
ELSE SUBSTRING(zip_code, 1, 5)
END
Event attributes
Attributes for describing events and actions.
| Attribute | Type | Description |
|---|
event_type | string | Category or type of event |
event_properties | object | Key-value properties associated with the event |
session_id | string | Session identifier |
page_url | string | URL of the page where event occurred |
event_type
A string categorizing the type of event.
Definition:
{
"id": 500,
"name": "event_type",
"type": "string",
"description": "Category or type of event"
}
Common values: page_view, click, purchase, signup, login
event_properties
Flexible key-value pairs for event metadata.
Mapping example:
-- From JSON
JSON_PARSE(properties_json)
-- Building from columns
STRUCT(
campaign_id AS campaign_id,
source AS source,
medium AS medium
)
Marketing attributes
Attributes for marketing and campaign data.
| Attribute | Type | Description |
|---|
campaign_id | string | Marketing campaign identifier |
utm_source | string | UTM source parameter |
utm_medium | string | UTM medium parameter |
utm_campaign | string | UTM campaign parameter |
conversion_timestamp | timestamptz | When a conversion occurred |
conversion_value | double | Monetary value of conversion |
Extending with organization attributes
When global attributes don’t fit your needs, create organization-specific attributes.
When to create organization attributes
- You have domain-specific concepts not covered by global attributes
- You need stricter validations than global attributes provide
- You want to enforce organization-specific standards
Creating an organization attribute
Via API:
curl -X POST "https://api.narrative.io/v1/attributes" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "internal_segment_id",
"type": "string",
"description": "Internal customer segmentation identifier",
"validations": ["pattern:^SEG-[A-Z]{3}-[0-9]{4}$"]
}'
Requesting new global attributes
If you believe an attribute would benefit the broader community:
- Contact Narrative support with the proposed attribute
- Include: name, type, description, use case, and any relevant standards
- Narrative will review and potentially add it to the global catalog
Related content