Skip to main content
Event properties allow you to add structured, typed data to your events. Properties must match your dashboard schema exactly, or the event will be rejected.

Supported Types

EventProperties can contain the following types:
TypeKotlin/Java TypeExample
BooleanBooleantrue, false
IntegerInt, Long42, 1000L
StringString"Technology"
FloatFloat, Double99.99, 3.14f
DateTimejava.util.DateDate()
Nested ObjectEventPropertiesNested properties
ListList<T>List of any supported type

Nullable Values

The API accepts nullable types. Properties with null values will be automatically filtered and not sent with the event.
EventProperties.from(
    "optional_field" to null  // This will be filtered out automatically
)

Creating Event Properties

import com.permutive.android.EventProperties

val properties = EventProperties.from(
    "article_id" to 12345,
    "title" to "Breaking News",
    "category" to "Technology",
    "price" to 9.99,
    "is_premium" to true,
    "published_at" to Date(),
    "tags" to listOf("tech", "mobile", "android")
)

Nested Properties

Use nested EventProperties to represent hierarchical data structures:
val properties = EventProperties.from(
    "article_id" to 12345,
    "user" to EventProperties.from(
        "type" to "premium",        // user.type
        "premium" to true,           // user.premium
        "subscription_tier" to "gold" // user.subscription_tier
    ),
    "metadata" to EventProperties.from(
        "source" to "mobile_app",
        "version" to "2.1.0"
    )
)

Complete Example

Here’s a complete example matching a typical Pageview event schema:

Schema Definition

NameType
idLong
descriptionString
tagsList of String
published_atDateTime
user.typeString
user.premiumBoolean
private fun pageProperties(
    id: Long,
    description: String,
    tags: List<String>,
    published: Date,
    userType: String,
    userIsPremium: Boolean
): EventProperties =
    EventProperties.from(
        "isp_info" to EventProperties.ISP_INFO,
        "geo_info" to EventProperties.GEO_INFO,
        "id" to id,
        "description" to description,
        "tags" to tags,
        "published_at" to published,
        "user" to EventProperties.from(
            "type" to userType,      // user.type
            "premium" to userIsPremium // user.premium
        )
    )

// Usage
val properties = pageProperties(
    id = 12345L,
    description = "Article about Android development",
    tags = listOf("android", "mobile", "development"),
    published = Date(),
    userType = "subscriber",
    userIsPremium = true
)

pageTracker = permutive.trackPage(
    title = "Article Title",
    url = Uri.parse("https://example.com/article"),
    eventProperties = properties
)

Event Enrichment

Events can be enriched with additional information automatically by using special constants.

Location and ISP Enrichment

Add location and ISP data to events using these constants:
EventProperties.from(
    "isp_info" to EventProperties.ISP_INFO,        // ISP information
    "geo_info" to EventProperties.GEO_INFO,        // Geographic location
    "ip_address" to EventProperties.IP_ADDRESS_HASH // Hashed IP address
)
This enriches events with:
  • ISP_INFO: Internet Service Provider details
  • GEO_INFO: Geographic location (country, region, city)
  • IP_ADDRESS_HASH: Hashed IP address for privacy
Contact Technical Services for configuration details.

Watson NLP Enrichment

Add IBM Watson Natural Language Understanding data:
EventProperties.from(
    "watson_concepts" to EventProperties.ALCHEMY_CONCEPTS,
    "watson_entities" to EventProperties.ALCHEMY_ENTITIES,
    "watson_keywords" to EventProperties.ALCHEMY_KEYWORDS,
    "watson_taxonomy" to EventProperties.ALCHEMY_TAXONOMY,
    "watson_emotion" to EventProperties.ALCHEMY_DOCUMENT_EMOTION,
    "watson_sentiment" to EventProperties.ALCHEMY_DOCUMENT_SENTIMENT,
    "watson_taxonomy_labels" to EventProperties.ALCHEMY_TAXONOMY_LABELS,
    "watson_entity_names" to EventProperties.ALCHEMY_ENTITY_NAMES
)
See IBM Watson Integration for details.

Complete Enrichment Example

pageTracker = permutive.trackPage(
    eventProperties = EventProperties.from(
        "isp_info" to EventProperties.ISP_INFO,
        "geo_info" to EventProperties.GEO_INFO,
        "ip_address" to EventProperties.IP_ADDRESS_HASH,
        "article_id" to 12345,
        "category" to "technology"
    ),
    title = "Tech Article",
    url = Uri.parse("https://www.example.com/article"),
    referrer = Uri.parse("https://www.example.com/home")
)

Type-Specific Methods (Java)

When building properties in Java, use type-specific methods for lists:
EventProperties properties = new EventProperties.Builder()
    .withStrings("tags", Arrays.asList("tech", "mobile"))     // List<String>
    .withIntegers("scores", Arrays.asList(1, 2, 3))           // List<Integer>
    .withLongs("ids", Arrays.asList(100L, 200L))              // List<Long>
    .withBooleans("flags", Arrays.asList(true, false))        // List<Boolean>
    .withDoubles("prices", Arrays.asList(9.99, 19.99))        // List<Double>
    .build();

Common Patterns

val purchaseProperties = EventProperties.from(
    "order_id" to "ORD-12345",
    "total_amount" to 149.99,
    "currency" to "USD",
    "item_count" to 3,
    "items" to listOf(
        EventProperties.from(
            "product_id" to "PROD-001",
            "name" to "Widget",
            "price" to 49.99,
            "quantity" to 1
        ),
        EventProperties.from(
            "product_id" to "PROD-002",
            "name" to "Gadget",
            "price" to 99.99,
            "quantity" to 2
        )
    ),
    "payment_method" to "credit_card",
    "shipping_method" to "express"
)
val contentProperties = EventProperties.from(
    "article_id" to 12345,
    "title" to "Article Title",
    "author" to "John Doe",
    "category" to "Technology",
    "subcategories" to listOf("Mobile", "Android"),
    "word_count" to 1500,
    "published_at" to Date(),
    "is_premium" to true,
    "tags" to listOf("android", "sdk", "mobile"),
    "isp_info" to EventProperties.ISP_INFO,
    "geo_info" to EventProperties.GEO_INFO
)
val userContextProperties = EventProperties.from(
    "user" to EventProperties.from(
        "id" to "user_12345",
        "type" to "premium",
        "subscription_tier" to "gold",
        "is_logged_in" to true,
        "account_age_days" to 365
    ),
    "session" to EventProperties.from(
        "id" to "session_abc123",
        "duration_seconds" to 120,
        "page_views" to 5
    )
)

Validation and Errors

Schema Validation

Properties are validated against your event schema in the Permutive dashboard: ✅ Valid:
  • Property names match exactly (case-sensitive)
  • Property types match schema
  • All required properties included
❌ Invalid:
  • Misspelled property names
  • Wrong property types
  • Missing required properties

Common Validation Errors

Problem: Event rejected with “Schema validation failed” Causes:
  1. Property name doesn’t match dashboard (case-sensitive)
  2. Property type doesn’t match schema
  3. Required property missing
Solutions:
  1. Verify property names in dashboard
  2. Check property types match
  3. Include all required properties
Example of incorrect types:
// ❌ WRONG - Sending string where number expected
EventProperties.from(
    "article_id" to "12345"  // Schema expects Long, got String
)

// ✅ CORRECT
EventProperties.from(
    "article_id" to 12345L   // Matches schema
)

Best Practices

  • Match property names and types exactly with your schema
  • Use enrichment constants when available
  • Create reusable property builder functions
  • Use nested properties for related data
  • Include relevant context properties
  • Validate against your schema before deploying
Never send unhashed PII:
// ❌ WRONG - Sending raw email
EventProperties.from("email" to "[email protected]")

// ✅ CORRECT - Hash before sending
EventProperties.from("email_sha256" to hashSHA256("[email protected]"))

Troubleshooting

Solutions:
  1. Check property names match schema exactly
  2. Verify property types are correct
  3. Ensure event is being accepted (check logs)
  4. Confirm properties are defined in dashboard schema
Cause: Incompatible type passed to builder.Solution: Ensure types match:
// ❌ WRONG
EventProperties.from("count" to "10")  // String instead of number

// ✅ CORRECT
EventProperties.from("count" to 10)    // Number
Solution: Ensure nested properties are defined in your dashboard schema:
user.type
user.premium
user.subscription_tier

API Reference

For complete API documentation, see the Javadocs.

EventProperties Class

Kotlin:
  • EventProperties.from(vararg pairs: Pair<String, Any?>) - Create from pairs
Java:
  • EventProperties.Builder() - Create builder
  • builder.with(key: String, value: Any) - Add property
  • builder.withStrings(key: String, values: List<String>) - Add string list
  • builder.withIntegers(key: String, values: List<Int>) - Add integer list
  • builder.withLongs(key: String, values: List<Long>) - Add long list
  • builder.withBooleans(key: String, values: List<Boolean>) - Add boolean list
  • builder.withDoubles(key: String, values: List<Double>) - Add double list
  • builder.build() - Build EventProperties

Enrichment Constants

  • EventProperties.ISP_INFO - ISP enrichment
  • EventProperties.GEO_INFO - Geographic enrichment
  • EventProperties.IP_ADDRESS_HASH - IP address hash
  • EventProperties.ALCHEMY_* - Watson NLP enrichment constants