{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"redocly_category":"Products","product_name":"Integration Hub","type":"markdown"},"seo":{"title":"Tracking Sessions with Treasure AI Mobile SDKs","description":"Understand global and instance sessions in Treasure AI mobile SDKs: how td_session_id and td_session_event work, session timeouts, and which API to use.","siteUrl":"https://docs.treasure.ai","lang":"en-US","jsonLd":{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.treasure.ai/","name":"Treasure AI","url":"https://www.treasure.ai/","logo":"https://www.treasure.ai/hubfs/assets/images/logos/primary-logo.svg"},{"@type":"WebSite","@id":"https://docs.treasure.ai/#website","name":"Treasure AI Documentation","url":"https://docs.treasure.ai/","inLanguage":["en","ja"],"publisher":{"@id":"https://www.treasure.ai/"}}]},"llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"tracking-sessions-with-mobile-sdks","__idx":0},"children":["Tracking Sessions with Mobile SDKs"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A session groups the events your app sends into one period of user activity, so you can analyze behavior per visit: how long users stay, what they do in a single sitting, and in which visit a conversion happened. The Treasure AI mobile SDKs (Android, iOS, Unity, Cordova, and React Native) provide two session mechanisms — ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["instance sessions"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["global sessions"]}," — that differ in scope, in the columns they write, and in whether they record session start and end events. This page defines both mechanisms, shows what each writes to your tables, and helps you choose the right one. For installation and general event tracking, see the individual SDK pages linked in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#session-apis-by-sdk"},"children":["Session APIs by SDK"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"global-sessions-vs-instance-sessions","__idx":1},"children":["Global Sessions vs. Instance Sessions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["instance session"]}," is scoped to one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData"]}," instance. Starting it records an explicit start event, and ending it records an explicit end event, in a table you specify. A ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["global session"]}," is shared across every ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData"]}," instance in the app. It records no events of its own; instead, it stamps a shared ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]}," on every event tracked while it is active, and it can resume after a short interruption so that brief app switches count as one session."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"width":"30%","data-label":"Aspect"},"children":["Aspect "]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"35%","data-label":"Instance Session"},"children":["Instance Session "]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"35%","data-label":"Global Session"},"children":["Global Session "]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Scope"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["One ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData"]}," instance"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The whole app — shared across all ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData"]}," instances"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["How you start and end it"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Instance methods that take a table name, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession(\"demotbl\")"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession(\"demotbl\")"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Static (class-level) methods with no table argument, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.startSession(context)"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.endSession(context)"]}," on Android"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Records ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_event"]}," start and end events"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes — one record at start and one at end, in the table you specify"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No — a global session never writes any event by itself"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Adds ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]}," to tracked events"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes, while the session is active"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes, while the session is active. If both session types are active, the global session ID wins"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Designed for"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Explicit session boundaries with start and end records — for example, tracking a checkout flow as a unit"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Treating short interruptions (screen rotation, brief app switches) as one continuous session, using the session timeout"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"what-sessions-write-to-your-tables","__idx":2},"children":["What Sessions Write to Your Tables"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["There is no separate SDK-managed session table. Sessions add columns to the tables you already stream events into:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]}," — a UUID string identifying the session. The SDK adds it automatically to every event tracked while a session is active."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_event"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["start"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["end"]},". Written only by instance sessions: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]}," each add one record containing this column to the table you pass them."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For example, calling ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession(\"demotbl\")"]}," and later ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession(\"demotbl\")"]}," produces two records in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["demotbl"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"[\n  {\"td_session_id\": \"cad88260-67b4-0242-1329-2650772a66b1\", \"td_session_event\": \"start\", \"time\": 1418880000},\n  {\"td_session_id\": \"cad88260-67b4-0242-1329-2650772a66b1\", \"td_session_event\": \"end\", \"time\": 1418880123}\n]\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Any other event you track between those two calls carries the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]}," in whatever table you send it to. You can pass your main event table to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]}," so that boundaries and events live together, or use a dedicated table for the start and end records — either way, you analyze a session by grouping events on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},". Optional columns such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_uuid"]}," (device ID) appear alongside if you enable them; see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/about-mobile-tracking-and-mobile-sdks"},"children":["About Mobile Tracking and Mobile SDKs"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-the-global-session-timeout-works","__idx":3},"children":["How the Global Session Timeout Works"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A global session does not end immediately when you call the global ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]},". The session ID is retained for the length of the session timeout — 10 seconds by default. If your app calls the global ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession"]}," again within that window, the previous session resumes with the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},"; a new session is not created. After the window passes, the next ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession"]}," generates a new session ID. This is what lets a session survive an Android Activity being destroyed and recreated, or a user briefly switching away from the app."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Key behaviors:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["On Android and iOS, change the window with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.setSessionTimeoutMilli(...)"]}," before starting the session. On Unity, the resume window is 10 seconds."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["After the global ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]},", the global ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getSessionId"]}," returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},", even while the session can still resume."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["resetSessionId"]}," (Android and iOS) to generate a new global session ID immediately, so subsequent events are no longer associated with the previous session."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Session IDs are held in memory only. If the app process is killed, the current session ID is discarded and the next launch starts a new session, regardless of the timeout."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The SDKs never start or end sessions on their own, and a session does not expire from inactivity while the app stays in the foreground. A session ends only when your app calls ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]}," or the process terminates. Call the session APIs from your app lifecycle callbacks — for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onStart"]},"/",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onStop"]}," on Android, or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["applicationDidBecomeActive:"]},"/",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["applicationDidEnterBackground:"]}," on iOS."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A common convention in web and app analytics is a 30-minute inactivity window. To get that behavior, set the timeout to 30 minutes and start/end the global session when the app enters and leaves the foreground:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"// Android — in onCreate\nTreasureData.setSessionTimeoutMilli(30 * 60 * 1000); // 30 minutes\n\n// in onStart / when the app enters the foreground\nTreasureData.startSession(this);\n\n// in onStop / when the app leaves the foreground\nTreasureData.endSession(this);\nTreasureData.sharedInstance().uploadEvents();\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With this configuration, foreground visits separated by less than 30 minutes share one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},", and returning after 30 or more minutes (or after the process was killed) starts a new session."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recording-session_start-and-session_end-events","__idx":4},"children":["Recording session_start and session_end Events"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only instance sessions write ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_event"]}," records. The global ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]}," change which ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]}," is stamped on events, but they do not send any event — so if you track sessions only with the global API, your tables contain no explicit start or end records."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you manage sessions with the global API and also need boundary events — for example, to analyze session starts or to trigger downstream logic — record them yourself with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["addEvent"]}," at the same points where you start and end the session:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"// Android\nTreasureData.startSession(this);\nMap<String, Object> event = new HashMap<>();\nevent.put(\"event\", \"session_start\");\nTreasureData.sharedInstance().addEvent(\"demotbl\", event);\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Because the global session is active, the record automatically carries the current ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Note the interaction with the session timeout: if the user leaves and returns within the timeout window, each visit produces its own start and end records, but they all share one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},", because the SDK resumed the same session. This is expected — the records mark each foreground visit, and the shared ID groups those visits into one session. If you want every visit to be its own session instead, shorten the timeout or call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["resetSessionId"]}," before starting the new session."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"using-global-and-instance-sessions-together","__idx":5},"children":["Using Global and Instance Sessions Together"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Avoid running both session types at the same time. If an instance session and a global session are both active, the global session wins: every tracked event — including the start and end records written by the instance ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession"]}," — carries the global session's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},", and the instance session's ID is ignored. The SDK logs a warning when this happens. The two IDs are independent, differently generated values; the instance session's ID is simply never written while a global session is active."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pick one mechanism per app: the global session when you want one app-wide session that survives short interruptions, or instance sessions when you want explicit start and end records without extra code."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"session-apis-by-sdk","__idx":6},"children":["Session APIs by SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The method names differ by SDK. The Cordova and React Native plugins expose instance sessions only."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"width":"16%","data-label":"SDK"},"children":["SDK "]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"34%","data-label":"Instance Session"},"children":["Instance Session "]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"50%","data-label":"Global Session"},"children":["Global Session "]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/android"},"children":["Android"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession(table)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession(table)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getSessionId()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.startSession(context)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.endSession(context)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.getSessionId(context)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.setSessionTimeoutMilli(millis)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TreasureData.resetSessionId(context)"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/ios"},"children":["iOS"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession:"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession:"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getSessionId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[TreasureData startSession]"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[TreasureData endSession]"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[TreasureData getSessionId]"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[TreasureData setSessionTimeoutMilli:]"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[TreasureData resetSessionId]"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/int/unity-sdk"},"children":["Unity"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["StartSession(tableName)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["EndSession(tableName)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GetSessionId()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["StartGlobalSession()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["EndGlobalSession()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GetGlobalSessionId()"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/cordova/api"},"children":["Cordova"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession(sessionTable, sessionDatabase)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession(sessionTable, sessionDatabase)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not exposed by the plugin"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/react-native/api"},"children":["React Native"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession(sessionTable, sessionDatabase)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession(sessionTable, sessionDatabase)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not exposed by the plugin"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"frequently-asked-questions","__idx":7},"children":["Frequently Asked Questions"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-is-td_session_event-missing-from-my-events","__idx":8},"children":["Why Is td_session_event Missing from My Events?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Global sessions never write ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_event"]},". Only the instance ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startSession(table)"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endSession(table)"]}," methods record start and end events. If you use the global session API and need boundary records, add them yourself with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["addEvent"]}," — see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#recording-session_start-and-session_end-events"},"children":["Recording session_start and session_end Events"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"does-killing-the-app-reset-the-global-session-id","__idx":9},"children":["Does Killing the App Reset the Global Session ID?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Yes. Session IDs are held in memory only, so force-quitting the app (or the OS terminating the process) discards the current global session ID. The next launch starts a new session with a new ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},", even if it happens within the session timeout window."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"can-i-use-global-and-instance-sessions-at-the-same-time","__idx":10},"children":["Can I Use Global and Instance Sessions at the Same Time?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["They can technically both be active, but the SDK logs a warning and the instance session's ID is ignored: all events, including the instance session's own start and end records, carry the global ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["td_session_id"]},". Use one mechanism per app — see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#using-global-and-instance-sessions-together"},"children":["Using Global and Instance Sessions Together"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"which-session-type-should-i-use-for-mobile-in-app-messaging","__idx":11},"children":["Which Session Type Should I Use for Mobile In-App Messaging?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the mechanism that matches what you need recorded. If your in-app messaging logic triggers on explicit session start and end events, instance sessions provide them automatically; with the global session you must record boundary events yourself. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/marketing-cloud/engage-studio/channels/mobile-inapp"},"children":["Mobile In-App Messaging"]}," for how the trigger flow works."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"can-i-compute-sessions-in-sql-instead-of-in-the-app","__idx":12},"children":["Can I Compute Sessions in SQL Instead of in the App?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Yes. If your events already have timestamps and a user or device identifier, the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TD_SESSIONIZE_WINDOW"]}," window function assigns session IDs at query time using an inactivity timeout you choose. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/data-workbench/queries/sql-reference/td_trino_function_reference#td_sessionize_window"},"children":["TD_SESSIONIZE_WINDOW"]}," in the Trino function reference."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"next-steps","__idx":13},"children":["Next Steps"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/android"},"children":["Android SDK"]}," — full lifecycle code examples"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/ios"},"children":["iOS SDK"]}," — Objective-C and Swift examples"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/int/unity-sdk"},"children":["Unity SDK"]}," — global and instance session usage"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/customer-data-platform/integration-hub/streaming/mobile/about-mobile-tracking-and-mobile-sdks"},"children":["About Mobile Tracking and Mobile SDKs"]}," — SDK features and account setup"]}]}]},"headings":[{"value":"Tracking Sessions with Mobile SDKs","id":"tracking-sessions-with-mobile-sdks","depth":1},{"value":"Global Sessions vs. Instance Sessions","id":"global-sessions-vs-instance-sessions","depth":2},{"value":"What Sessions Write to Your Tables","id":"what-sessions-write-to-your-tables","depth":2},{"value":"How the Global Session Timeout Works","id":"how-the-global-session-timeout-works","depth":2},{"value":"Recording session_start and session_end Events","id":"recording-session_start-and-session_end-events","depth":2},{"value":"Using Global and Instance Sessions Together","id":"using-global-and-instance-sessions-together","depth":2},{"value":"Session APIs by SDK","id":"session-apis-by-sdk","depth":2},{"value":"Frequently Asked Questions","id":"frequently-asked-questions","depth":2},{"value":"Why Is td_session_event Missing from My Events?","id":"why-is-td_session_event-missing-from-my-events","depth":3},{"value":"Does Killing the App Reset the Global Session ID?","id":"does-killing-the-app-reset-the-global-session-id","depth":3},{"value":"Can I Use Global and Instance Sessions at the Same Time?","id":"can-i-use-global-and-instance-sessions-at-the-same-time","depth":3},{"value":"Which Session Type Should I Use for Mobile In-App Messaging?","id":"which-session-type-should-i-use-for-mobile-in-app-messaging","depth":3},{"value":"Can I Compute Sessions in SQL Instead of in the App?","id":"can-i-compute-sessions-in-sql-instead-of-in-the-app","depth":3},{"value":"Next Steps","id":"next-steps","depth":2}],"frontmatter":{"seo":{"title":"Tracking Sessions with Treasure AI Mobile SDKs","description":"Understand global and instance sessions in Treasure AI mobile SDKs: how td_session_id and td_session_event work, session timeouts, and which API to use."}},"lastModified":"2026-08-17T04:53:10.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/customer-data-platform/integration-hub/streaming/mobile/tracking-sessions-with-mobile-sdks","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}