Skip to main content
The surveys module lets you collect user feedback through in-app surveys. Surveys can trigger automatically based on events or be presented manually from your code.

Present a Survey Manually

val presented = AppDNA.surveys.present("nps_q1_2026", activity)

if (!presented) {
    println("Survey not found or already completed")
}
Returns false if the survey is not available (not found, already completed, or config not loaded).

Module Access

val surveys = AppDNA.surveys

Module Methods

MethodSignatureDescription
presentpresent(surveyId: String, activity: Activity): BooleanPresent a survey manually
promptReviewpromptReview(activity: Activity)Start the smart review prompting flow
setDelegatesetDelegate(delegate: SurveyDelegate?)Set a delegate for survey callbacks

8 Question Types

TypeDisplayResponse
nps0-10 numeric scaleInteger 0-10
csat1-5 satisfaction scaleInteger 1-5
ratingStar ratingInteger 1-5
emoji_scaleEmoji optionsSelected emoji value
yes_noBinary choiceBoolean
single_choiceRadio button optionsSelected option string
multi_choiceCheckbox optionsList of selected strings
free_textText input fieldFree-form string

Smart Review Prompting

A two-step flow that routes happy users to the Play Store review dialog and unhappy users to a feedback form:
  1. In-app question: “Do you enjoy using [app]?”
  2. Positive response — shows the Google In-App Review API dialog
  3. Negative response — shows a free-text feedback form
AppDNA.surveys.promptReview(activity)
Smart review prompting is rate-limited: maximum 3 times per year, at least 90 days apart. The SDK enforces these limits automatically.

SurveyDelegate

AppDNA.surveys.delegate = object : SurveyDelegate {
    override fun onSurveyPresented(surveyId: String) {
        println("Survey shown: $surveyId")
    }

    override fun onSurveyResponseSubmitted(surveyId: String, responses: List<SurveyAnswer>) {
        for (answer in responses) {
            when (answer.questionType) {
                "nps" -> {
                    val score = answer.numericValue ?: 0
                    if (score >= 9) showReferralPrompt()
                    else if (score <= 6) showSupportLink()
                }
                "free_text" -> {
                    answer.stringValue?.let { println("Feedback: $it") }
                }
            }
        }
    }

    override fun onSurveyDismissed(surveyId: String) {
        println("Survey dismissed: $surveyId")
    }
}

SurveyAnswer

PropertyTypeDescription
questionIdStringIdentifier for the question
questionTypeStringQuestion type (e.g., "nps", "free_text")
stringValueString?Text response
numericValueInt?Numeric response
arrayValueList<String>?Multi-select response
boolValueBoolean?Boolean response

Rich Media

Survey questions support rich media content configured in the Console:
  • Header images — add images above survey questions
  • Icons in options — use icon references in choice options (Lucide, Material, or emoji)
  • Thank-you animations — Lottie or confetti effects on survey completion
  • Haptic feedback — triggered on option selection and submission
See the Rich Media guide for details on supported formats.

Auto-Tracked Events

EventTrigger
survey_presentedA survey is displayed
survey_response_submittedUser submits a survey response
survey_dismissedSurvey is closed without completing

Full Example

import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.SurveyDelegate
import ai.appdna.sdk.SurveyAnswer

class FeedbackManager(private val activity: Activity) : SurveyDelegate {
    init {
        AppDNA.surveys.delegate = this
    }

    fun askForFeedback() {
        AppDNA.surveys.present("nps_q1_2026", activity)
    }

    fun promptForReview() {
        AppDNA.surveys.promptReview(activity)
    }

    override fun onSurveyPresented(surveyId: String) { }

    override fun onSurveyResponseSubmitted(surveyId: String, responses: List<SurveyAnswer>) {
        val nps = responses.firstOrNull { it.questionType == "nps" }
        val score = nps?.numericValue ?: return

        when {
            score >= 9 -> showReferralPrompt()
            score <= 6 -> showSupportLink()
        }
    }

    override fun onSurveyDismissed(surveyId: String) { }
}
Surveys are created in the Console under Feedback > Surveys. Trigger-based surveys appear automatically — manual presentation with present() is for precise control over timing.