diff --git a/src/jsonobject.ts b/src/jsonobject.ts
index e86e589c9c..550718cfec 100644
--- a/src/jsonobject.ts
+++ b/src/jsonobject.ts
@@ -1714,7 +1714,7 @@ export class JsonObject {
     options?: ISaveToJSONOptions | boolean
   ): any {
     if (!obj || !obj.getType) return obj;
-    if (typeof obj.getData === "function") return obj.getData();
+    if (!obj.isSurvey && typeof obj.getData === "function") return obj.getData();
     var result = {};
     if (property != null && !property.className) {
       (<any>result)[JsonObject.typePropertyName] = property.getObjType(
diff --git a/src/survey-element.ts b/src/survey-element.ts
index 1b6022b55c..af39aa0f0b 100644
--- a/src/survey-element.ts
+++ b/src/survey-element.ts
@@ -36,6 +36,26 @@ export abstract class SurveyElementCore extends Base implements ILocalizableOwne
   protected createLocTitleProperty(): LocalizableString {
     return this.createLocalizableString("title", this, true);
   }
+  /**
+   * Returns `true` if the survey element is a page.
+   * @see Base.getType
+   */
+  public get isPage(): boolean { return false; }
+  /**
+   * Returns `true` if the survey element is a panel.
+   * @see Base.getType
+   */
+  public get isPanel(): boolean { return false; }
+  /**
+   * Returns `true` if the survey element is a question.
+   * @see Base.getType
+   */
+  public get isQuestion(): boolean { return false; }
+  /**
+   * Returns `true` if the element is a survey.
+   * @see Base.getType
+   */
+  public get isSurvey(): boolean { return false; }
   /**
    * A title for the survey element. If `title` is undefined, the `name` property value is displayed instead.
    *
@@ -670,27 +690,6 @@ export class SurveyElement<E = any> extends SurveyElementCore implements ISurvey
   public setVisibleIndex(index: number): number {
     return 0;
   }
-  /**
-   * Returns `true` if the survey element is a page.
-   * @see Base.getType
-   */
-  public get isPage(): boolean {
-    return false;
-  }
-  /**
-   * Returns `true` if the survey element is a panel.
-   * @see Base.getType
-   */
-  public get isPanel(): boolean {
-    return false;
-  }
-  /**
-   * Returns `true` if the survey element is a question.
-   * @see Base.getType
-   */
-  public get isQuestion(): boolean {
-    return false;
-  }
   public delete(doDispose: boolean): void { }
   //ILocalizableOwner
   locOwner: ILocalizableOwner;
diff --git a/src/survey.ts b/src/survey.ts
index f9e35fedcb..5931895545 100644
--- a/src/survey.ts
+++ b/src/survey.ts
@@ -2912,6 +2912,25 @@ export class SurveyModel extends SurveyElementCore
     this.runConditions();
     this.updateAllQuestionsValue(clearData);
   }
+  public get isSurvey(): boolean { return true; }
+  /**
+   * Returns an object with survey results.
+   *
+   * If you want to get a survey results object that mirrors the survey structure, call the `getData()` method with an object that has the `includePages` and `includePanels` properties enabled. Without this object, the `getData()` method returns the [`data`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#data) property value.
+   *
+   * ```js
+   * import { Model } from "survey-core";
+   *
+   * const surveyJson = { ... };
+   * const survey = new Model(surveyJson);
+   * survey.getData({ includePages: true, includePanels: true });
+   * ```
+   */
+  public getData(options?: { includePages?: boolean, includePanels?: boolean }): any {
+    const opt = options || { includePages: false, includePanels: false };
+    if(!opt.includePages && !opt.includePanels) return this.data;
+    return this.getStructuredData(!!opt.includePages, !opt.includePanels ? (opt.includePages ? 1 : 0) : -1);
+  }
   public getStructuredData(includePages: boolean = true, level: number = -1): any {
     if (level === 0) return this.data;
     const data: any = {};
diff --git a/tests/surveytests.ts b/tests/surveytests.ts
index 9d27e805e7..2a646f8dec 100644
--- a/tests/surveytests.ts
+++ b/tests/surveytests.ts
@@ -17956,6 +17956,30 @@ QUnit.test("getStructuredData function", function (assert) {
   }, "includePages: false, level: 3");
 
 });
+QUnit.test("getData function", function (assert) {
+  const survey = new SurveyModel(structedDataSurveyJSON);
+  survey.setValue("q1", 100);
+  survey.setValue("q2", 200);
+  survey.setValue("q3", 300);
+  survey.setValue("q21", 2100);
+  survey.setValue("q22", 2200);
+  const data = survey.data;
+  assert.deepEqual(survey.getData(), data, "survey.getData()");
+  assert.deepEqual(survey.getData({}), data, "survey.getData({})");
+  assert.deepEqual(survey.getData({ includePages: false, includePanels: false }), data, "survey.getData({ includePages: false, includePanels: false })");
+  assert.deepEqual(survey.getData({ includePages: true, includePanels: false }), {
+    page1: { q1: 100, q2: 200, q3: 300 },
+    page2: { q21: 2100, q22: 2200 },
+  }, "survey.getData({ includePages: true, includePanels: false })");
+  assert.deepEqual(survey.getData({ includePages: true, includePanels: true }), {
+    page1: { q1: 100, panel1: { q2: 200, panel2: { q3: 300 } } },
+    page2: { q21: 2100, panel21: { q22: 2200 } },
+  }, "survey.getData({ includePages: true, includePanels: true })");
+  assert.deepEqual(survey.getData({ includePages: false, includePanels: true }), {
+    q1: 100, panel1: { q2: 200, panel2: { q3: 300 } },
+    q21: 2100, panel21: { q22: 2200 },
+  }, "survey.getData({ includePages: true, includePanels: true })");
+});
 QUnit.test("setStructuredData function", function (assert) {
   const survey = new SurveyModel(structedDataSurveyJSON);
   survey.setStructuredData({