Explore Experience programs

Experience Programs are fundamental data structures that support various products and services. For example, they define data schemas that map program-specific feedback data into new tables, which Total Experience profiles then use to accelerate data processing. Experience Programs also support Query API applications by providing a referential data schema that allows automating subsequent feedback extraction.

Warning: The legacy schema metadata field programRecordSchemas has been deprecated. Program updates are no longer being synchronized or reflected on the programRecordSchemas field. Consequently, any data returned by this field is now stale and may be inaccurate. The programs field has been introduced as its permanent replacement. For information, see Transition from programRecordSchemas to programs.

Experience programs and their schemas are available in your instance, including both Enterprise and Ad Hoc types, through the programs operation.

Tip: Access to Ad Hoc type program metadata is controlled by the Edit Ad Hoc Surveys administrative permission. This permission can be customized, for example: to grant access to all Ad Hoc programs or to limit it to specific ones — and it aligns metadata access with the existing permissions for accessing feedback data in the API. For information, see Feedback.

Access to specific Ad Hoc records is determined by AppID Accounts data access.

Example: Exploring Experience programs

query experiencePrograms {
  programs(
    first: 3
  	   ){
    nodes {
      name
      id
      createdBy
      createdOn
      description
      status
      responsesCount
      type
    }
  }
}

Sample response

{
  "data": {
    "programs": {
      "nodes": [
        {
          "name": "Contact Center transactional agent interaction",
          "id": "6688cde1-3d7f-4486-b9ec-076c73d51364",
          "createdBy": "_medallia_system_test",
          "createdOn": "2021-07-23 04:57:02",
          "description": "Program: Contact Center transactional agent interaction. Created by Merlin Spell",
          "status": "ACTIVE",
          "responsesCount": 2447,
          "type": "ENTERPRISE"
        },
        {
          "name": "Retail Store e-receipt",
          "id": "9a3317f9-dc77-4430-bced-b35d976d1d31",
          "createdBy": "_medallia_system_test",
          "createdOn": "2021-07-23 04:56:07",
          "description": "Program: Retail Store e-receipt. Created by Merlin Spell",
          "status": "ACTIVE",
          "responsesCount": 73610,
          "type": "ENTERPRISE"
        },
        {
          "name": "Wealth Management Client Onboarding",
          "id": "abbb51a8-7792-4c41-b731-c873b492dd72",
          "createdBy": "_medallia_system_test",
          "createdOn": "2021-07-23 04:56:56",
          "description": "Program: Wealth Management Client Onboarding. Created by Merlin Spell",
          "status": "ACTIVE",
          "responsesCount": 890,
          "type": "ENTERPRISE"
        }
      ]
    }
  },
  "errors": null,
  "_links": null,
  "_allowed": [
    "POST"
  ]
}

Example: Exploring Experience program schemas using the fields operation

query experienceProgramSchemas {
   programs(
      first: 3
   ) {
      totalCount
      nodes {
         name
         id
         fields(first: 3) {
            totalCount
            nodes {
               id
               name
               dataType
            }
         }
      }
   }
}

Sample response

{
  "data": {
    "programs": {
      "nodes": [
        {
          "name": "B2B Onboarding program",
          "id": "ea891440-f715-43dd-a275-44cbd353dae9",
          "fields": {
            "totalCount": 57,
            "nodes": [
              {
                "id": "q_bp_b2b_ltr_scale",
                "name": "Likelihood to Recommend",
                "dataType": "ENUM"
              },
              {
                "id": "e_email",
                "name": "Email",
                "dataType": "EMAIL"
              },
              {
                "id": "e_bp_uniquerecordid_txt",
                "name": "Unique Record Id",
                "dataType": "STRING"
              }
            ]
          }
        },
        {
          "name": "B2B Onsite Service program",
          "id": "cdf759c8-3bef-4c13-afca-159fb8bcc750",
          "fields": {
            "totalCount": 42,
            "nodes": [
              {
                "id": "q_bp_svc_ltr_scale",
                "name": "Likelihood to Recommend Service",
                "dataType": "ENUM"
              },
              {
                "id": "e_phone",
                "name": "Phone",
                "dataType": "STRING"
              },
              {
                "id": "e_bp_uniquerecordid_txt",
                "name": "Unique Record Id",
                "dataType": "STRING"
              }
            ]
          }
        },
        {
          "name": "B2B Project program",
          "id": "3d69e34d-1eb6-458a-a726-53826937eab5",
          "fields": {
            "totalCount": 17,
            "nodes": [
              {
                "id": "q_bp_proj_ltr_scale",
                "name": "Likelihood to Recommend Project",
                "dataType": "ENUM"
              },
              {
                "id": "e_firstname",
                "name": "First name",
                "dataType": "STRING"
              },
              {
                "id": "e_bp_uniquerecordid_txt",
                "name": "Unique Record Id",
                "dataType": "STRING"
              }
            ]
          }
        }
      ]
    }
  },
  "errors": null,
  "_links": null,
  "_allowed": [
    "POST"
  ]
}

Filters and pagination for programs

Use a filter like the one shown below to get all data fields for a specific program. By defining the parameter first on the internal fields operation — and not on the programs — you get the data of all fields.

query experienceProgramSchema {
  programs(
     ids: "51c1a508-cf61-4be7-901c-87f3989ab7e1"
  ) {
    nodes {
      name
      id
      fields(
        first: 300
        after: null,
      ) {
        nodes {
          id
          name
          type
        }
        pageInfo {
          endCursor
          hasNextPage
        }
        totalCount
      }
    }
  }
}

The endCursor returned in the previous response should be added as part of the pagination of the fields in the next query. For example, if the response contains the following pagination information:

[...]
"pageInfo": {
        "hasNextPage": true,
        "endCursor": "xWSJSCIGh9+8WBydu4cOW5xdK9Q"
      }
[...]

The programs query to get the next set of data looks like this:

query experienceProgramSchema {
  programs(
     ids: "51c1a508-cf61-4be7-901c-87f3989ab7e1"
  ) {
    nodes {
      name
      id
      fields(
        first: 300
        after: "xWSJSCIGh9+8WBydu4cOW5xdK9Q",
      ) {
        nodes {
          id
          name
          type
        }
        pageInfo {
          endCursor
          hasNextPage
        }
        totalCount
      }
    }
  }
}

The query below is used to get the first 50 Experience programs and the first 50 fields for each program.

query experienceProgramSchemas {
   programs(
      first: 50,
      after: null
   ) {
      totalCount
      pageInfo {
          endCursor
          hasNextPage
      }
      nodes {
         name
         id
         fields(
             first: 50,
             after: null
         ) {
            totalCount
            nodes {
               id
               name
               dataType
            }
         }
      }
   }
}

The next query below has additional pagination elements, it fetches the first 50 Experience programs and the first 100 fields for each program.

query experienceProgramSchemas {
   programs(
      first: 50,
      after: null
   ) {
      totalCount
      pageInfo {
          endCursor
          hasNextPage
      }
      nodes {
         name
         id
         fields(
             first: 100,
             after: null
         ) {
            totalCount
            nodes {
               id
               name
               dataType
            }
         }
      }
   }
}

Additionally, use the programIds filter while querying feedback records to get all data fields for specific programs. For information, see Filter programs.

Transition from programRecordSchemas to programs

Warning: All clients must update their GraphQL queries and response-parsing logic immediately to prevent data inconsistencies or integration failures in production environments.

While the new programs field offers equivalent capabilities, there are structural changes to the schema fields and node attributes that you must account for in your data models and parsers.

Deprecated component in programRecordSchemasNew component in programsDescription
Root field: programRecordSchemasRoot field: programsPrimary entry point for fetching program metadata.
Nested connection: attributesNested connection: fieldsConnection field containing the data fields of a given program.
Leaf node property: keyLeaf node property: idUnique identifier for a specific data field.
Leaf node argument: keysLeaf node argument: idsUnique identifier for a specific data field.
Leaf node property: nameLeaf node property: nameHuman-readable display name (remains unchanged).
Leaf node property: typeLeaf node property: dataTypeData type of the data field.
Leaf node property: containsPiiUnsupported in programsAttribute indicating if data fields store personally identifying information. Not supported in the programs field.
Leaf node property: mainScoreAttributeUnsupported in programsThis attribute is not supported in the programs field.
Note: The new programs field supports additional nodes and arguments beyond those detailed here. We encourage you to explore the full schema by introspecting the Query API GraphQL schema.

Follow these instructions to migrate your integrations from the deprecated programRecordSchemas query field to the programs field:

  1. Codebase audit — Search your application codebase, configuration files, and API client tools for any references to the programRecordSchemas operation. Identify all queries, fragments, and data access layers interacting with this field.

  2. Update GraphQL queries — Update your GraphQL definition strings or file templates to match the new structure:

    1. Replace the root query field programRecordSchemas(...) with programs(...).

    2. Inside the program node, change the nested attributes(...) connection to fields(...).

    3. Inside the nested nodes list, replace key with id.

    4. Inside the nested nodes list, remove containsPii and mainScoreAttribute.

  3. Update feedback filters — Search your codebase for any queries utilizing the schemaIds filter within the feedback operation. Replace these with the new programIds filter to align with the updated program identification logic. For information, see Filter programs.

  4. Update response parsing and data models — Because the JSON payload response structure changes to mirror the query schema, you must update your deserialization logic, TypeScript interfaces, or internal data transfer objects:

    1. JSON path change — Change access paths from response.data.programRecordSchemas to response.data.programs.

    2. Nested array change — Update references from node.attributes.nodes to node.fields.nodes.

    3. Property access change — If your code relies on the key property of an attribute (e.g., attribute.key), update it to read the id property from the field object instead (e.g., field.id). If your code references the containsPii or mainScoreAttribute attribute properties, make sure to remove these from your expected inputs.

  5. Review API role permissions — Review your existing API user role and permissions. Ensure that the AppID account utilized for your integrations has the necessary "Edit Ad Hoc Surveys" administrative permission if your application requires access to AD_HOC program metadata. This ensures your integration maintains access to Ad Hoc programs under the new programs field. For information, see Feedback.

  6. Test environments — Deploy the updated queries to your staging or development environment. Verify that:

    1. Pagination (pageInfo, endCursor, hasNextPage) and other fields continue to function without changes.

    2. The program metadata matches expected active values and is not returning stale results.