How should in-app event names be defined?
Fix names, parameters, and firing timing in one source of truth the whole team reads.
Related resources
Fix names, parameters, and firing timing in one source of truth the whole team reads.
Related resources
The event spec that defines your core business funnel as a single source of truth (SSOT). It underpins network optimization signals, cohort analysis, and LTV validation — name, parameters, and firing timing are all standardized.
This taxonomy compresses a 7-stage funnel (Install → Activate → Convert → Retain → Refer → Monetize → Reactivate) into 12 Tier-1 events. Every event enforces snake_case naming, lowercase English, and a verb+noun or noun+state structure. Tier-1 events feed network optimization signals (UAC/AAP/ASA tCPA) and SKAN Conversion Value mapping — changing them arbitrarily discards campaign learning data and forces retraining.
addToCart (✗) → add_to_cart (✓). No mixing camel/Pascal/kebab caseproduct_view over view_product (GA4-standard alignment)session_start, first_open, in_app_purchase and other Adjust/Firebase reserved names can't be self-defined. Send revenue through a purchase event so Adjust's in_app_purchase maps automaticallyClick a column header to sort. Tier-1 events are the core signals used for network optimization.
| Event Name | Funnel Stage | Trigger | Required Params | Tier | Source |
|---|---|---|---|---|---|
| session_start | Lifecycle | App enters foreground | platform, app_version, network_type | Tier-1 | auto |
| sign_up | Acquisition | Signup completed | method(email|kakao|apple), user_grade | Tier-1 | manual |
| login | Lifecycle | Returning user login | method, days_since_last_login | Tier-2 | manual |
| onboarding_complete | Activation | Last onboarding step finished | duration_sec, skipped(bool) | Tier-1 | manual |
| product_view | Funnel | Product detail viewed | product_id, category, price, currency | Tier-2 | manual |
| add_to_cart | Funnel | Added to cart | product_id, quantity, price | Tier-1 | manual |
| begin_checkout | Funnel | Checkout screen entered | cart_value, item_count | Tier-1 | manual |
| purchase | Revenue | Payment completed (transaction) | transaction_id, revenue, currency, payment_method | Tier-1 | manual |
| subscribe | Revenue | Subscription started (incl. trial) | plan_id, trial(bool), revenue | Tier-1 | manual |
| refund | Revenue | Refund processed | transaction_id, refund_amount | Tier-2 | server |
| share | Engagement | External share action | channel(km|fb|link), content_type | Tier-3 | manual |
| push_open | Re-engagement | Push notification opened | campaign_id, segment | Tier-2 | manual |
| Parameter | Type | Example | Required | Description |
|---|---|---|---|---|
| transaction_id | string | tx_20260525_a91b3 | Yes (purchase) | Unique payment transaction ID. Dedup key against duplicate sends |
| revenue | decimal(10,2) | 29900.00 | Yes (purchase) | Revenue incl. VAT. Negative values only for refunds |
| currency | string(3) | KRW | Yes (purchase) | ISO 4217 currency code |
| product_id | string | sku_88421 | Yes (commerce) | Internal SKU. Catalog matching key |
| category | string | outerwear | No | L1 category. Slash-separated down to L2 allowed |
| quantity | integer | 2 | Yes (cart) | Quantity. Integer ≥ 1 |
| price | decimal(10,2) | 14950.00 | Yes (cart) | Unit price. revenue = price × quantity |
| payment_method | string | card_visa | Yes (purchase) | card_* / kakaopay / naverpay / applepay / googlepay |
| user_grade | string | vip | No | 4 levels: guest / new / regular / vip |
| screen | string | home_main | No | Screen name at firing time. Screen names managed in a separate dictionary |
All client SDKs serialize into the JSON structure below and map it onto Adjust's ADJEvent / AdjustEvent. Server-side sends deliver the same payload to the S2S endpoint.
{
"event_token": "p4q7zx",
"event_name": "purchase",
"timestamp_ms": 1779360000000,
"user": {
"user_id_hashed": "sha256:8a7d...e1c2",
"user_grade": "regular",
"is_logged_in": true
},
"params": {
"transaction_id": "tx_20260525_a91b3",
"revenue": 29900.00,
"currency": "KRW",
"payment_method": "kakaopay",
"item_count": 2,
"products": [
{ "product_id": "sku_88421", "category": "outerwear", "price": 14950.00, "quantity": 2 }
],
"screen": "checkout_complete"
},
"context": {
"platform": "android",
"app_version": "4.12.0",
"network_type": "wifi",
"ab_variant": "ckt_v3_B"
}
}
fun trackPurchase(tx: Transaction) {
val event = AdjustEvent("p4q7zx").apply {
setRevenue(tx.revenue, tx.currency)
setOrderId(tx.id) // dedup key
addCallbackParameter("payment_method", tx.method)
addCallbackParameter("item_count", tx.items.size.toString())
addPartnerParameter("ab_variant", tx.abVariant)
}
Adjust.trackEvent(event)
}
1) currency missing before the setRevenue call. 2) The event token isn't checked as a Revenue Event in the Adjust dashboard. 3) FX conversion missing when client currency and network reporting currency differ. Recommend unifying every network's reporting currency to a single KRW or USD.
StoreKit/Play Billing payment callbacks retry and re-send the same transaction. Force-map transaction_id to Adjust's orderId and delegate dedup to the SDK. Also gate the client so the event only fires after server-side receipt validation completes.
With fewer than ~30 Tier-1 event firings per week, machine learning can't converge. If volume is short, temporarily switch the conversion definition to an upper-funnel event (purchase → add_to_cart or begin_checkout) to build learning volume, then switch back.
Emails/phone numbers sneak into product_id, or free-text lands in search_keyword. Before release, scan Adjust raw exports with regex filters (@, 010, +). If found, hash or remove the parameter immediately and start the network-side data deletion process.