Add custom data to groups using schema extensions

In this tutorial, you learn how to use schema extensions.

Imagine you're a developer in a Learning Management Software company called Bellows College that builds training courses and materials for businesses. You use the collaborative experience of Microsoft 365 groups to deliver course content and record exercises among participants for both online courses and instructor-led courses. You want to make the Microsoft 365 groups used for training courses easily identifiable as training courses, which allows other developers to discover your groups and build rich experiences on top of your learning courses.

For this scenario, this article shows you how to:

  • Discover available schema extension definitions that you could use.
  • Register a schema extension definition that targets groups for training courses.
  • Create a new group with custom data based on the schema extension definition that you registered.
  • Add, update, or remove custom data in an existing group based on a schema extension definition.
  • Read a group and the extension data.
  • Delete the schema extension definition and the extension data.

Note

Apart from groups, schema extensions are also supported and can be managed for other resource types.

Prerequisites

To reproduce the steps in this article, you need the following privileges:

  • Sign in to an API client such as Graph Explorer.
  • Grant the app the Group.ReadWrite.All and Application.ReadWrite.All delegated permissions for the signed-in user.
  • Be the owner of an application that you assign ownership of the schema extension definition in this tutorial. In this tutorial, the application is named extensions-application and has appId d1e6f196-fca3-48ad-8cd3-1a98e3bd46d2.

Step 1. View available schema extensions

First, as a developer, you might want the app to reuse any existing schema extension definitions if they're fit for purpose. In the following example, you query schema extensions that are named (by the id) bellowscollege_courses. Assume that the response shows there are no schema extensions that are named bellowscollege_courses in your tenant.

Request

GET https://graph.microsoft.com/v1.0/schemaExtensions?$filter=id eq 'bellowscollege_courses'

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions",
    "@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET schemaExtensions?$select=description,owner",
    "value": []
}

You can also query by the id as a path parameter as follows: GET https://graph.microsoft.com/v1.0/schemaExtensions/bellowscollege_courses. If there are no schema extensions that match the ID, the response is 404 Not Found.

Step 2. Register a schema extension definition

You want to create and register a new extension definition for training courses on the group resource. Specify the following properties:

  • id: Provide a string for this property following one of two ways:
    • Option 1: Concatenate a verified vanity domain name for your tenant with a name for the schema extension. For example, if the domain is bellowscollege.com, and the name of the schema extension is courses, then you can use the id bellowscollege_courses.

    • Option 2: An alternative way is to provide only a schema name, such as courses, and let Microsoft Graph automatically generate the id for you by prefixing the provided name with a random alphanumeric string.

      This id becomes the name of the schema extension property on a group.

  • description
  • targetTypes: Specify the resource types that the schema extension can be applied to. In this example, the resource type is Group. You can add more resource types by updating the schema extension definition later.
  • properties: Specify the custom properties that make up the schema. In this example, specify the courseId, courseName and courseType custom properties and their types. Only additive changes are permitted after you create the schema extension definition.
  • owner: Specify the application that owns the schema extension definition. If you're running this example from an app that you're not assigned as owner, specify the appId of the application that you're assigned in the owner property.

Request

POST https://graph.microsoft.com/v1.0/schemaExtensions
Content-type: application/json

{
    "id": "bellowscollege_courses",
    "description": "Bellows College training courses extensions",
    "targetTypes": [
        "Group"
    ],
    "owner": "d1e6f196-fca3-48ad-8cd3-1a98e3bd46d2",
    "properties": [
        {
            "name": "courseId",
            "type": "Integer"
        },
        {
            "name": "courseName",
            "type": "String"
        },
        {
            "name": "courseType",
            "type": "String"
        }
    ]
}

Response

The following example shows the response.

In the response, the default initial status of the schema extension is InDevelopment. While you're developing the extension, you can keep it in this status, during which only the app that created it can update it with additive changes or delete it. When you're ready to share the extension for use by other apps, set status to Available.

HTTP/1.1 201 Created
Content-Type: application/json

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions/$entity",
    "id": "bellowscollege_courses",
    "description": "Bellows College training courses extensions",
    "targetTypes": [
        "Group"
    ],
    "status": "InDevelopment",
    "owner": "d1e6f196-fca3-48ad-8cd3-1a98e3bd46d2",
    "properties": [
        {
            "name": "courseId",
            "type": "Integer"
        },
        {
            "name": "courseName",
            "type": "String"
        },
        {
            "name": "courseType",
            "type": "String"
        }
    ]
}

Step 3. Extend a group with custom data

You can extend a group with custom data either during group creation or by updating an existing group.

Option 1: Create a new group with extended data

The following request creates a new group and uses the bellowscollege_courses schema extension to extend the group with custom data. If you have an existing group, you can also extend it with custom data by updating the group with the extension data.

The response doesn't mirror back any data extensions. You need to explicitly $select the extension by name using a GET /group/{id} operation.

Request

POST https://graph.microsoft.com/v1.0/groups
Content-type: application/json

{
    "displayName": "New Managers March 2024",
    "description": "New Managers training course for March 2024",
    "groupTypes": [
        "Unified"
    ],
    "mailEnabled": true,
    "mailNickname": "newMan202403",
    "securityEnabled": false,
    "bellowscollege_courses": {
        "courseId": "123",
        "courseName": "New Managers",
        "courseType": "Online"
    }
}

Response

The following example shows the response. The response doesn't include the new extension. You need to explicitly $select the extension by name using a GET /group/{id} operation.

Note: The response object shown here might be shortened for readability.

HTTP/1.1 201 Created
Content-Type: application/json

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups/$entity",
    "id": "8fb45944-4085-449f-b95d-f7dd74a1b081",
    "createdDateTime": "2024-01-24T09:09:03Z",
    "description": "New Managers training course for March 2024",
    "displayName": "New Managers March 2024",
    "groupTypes": [
        "Unified"
    ],
    "mail": "newMan202403@bellowscollege.com",
    "mailEnabled": true,
    "mailNickname": "newMan202403"
}

Option 2: Update an existing group with extended data

If you have an existing group, you can also extend it with custom data as follows. The request returns a 204 No Content response.

PATCH https://graph.microsoft.com/v1.0/groups/dfc8016f-db97-4c47-a582-49cb8f849355
Content-type: application/json

{
    "bellowscollege_courses": {
        "courseId": "123",
        "courseName": "New Managers",
        "courseType": "Online"
    }
}

Step 4. Update custom data in a group

The following request updates the courseType property in the bellowscollege_courses extension for the group to Hybrid. Though you want to update only the courseType property, you must include the other properties and their existing values in the request body as well. Otherwise, Microsoft Graph sets them to null and removes their data.

The following request returns a 204 No Content response.

PATCH https://graph.microsoft.com/v1.0/groups/dfc8016f-db97-4c47-a582-49cb8f849355
Content-type: application/json

{
    "bellowscollege_courses": {
        "courseId": "123",
        "courseName": "New Managers",
        "courseType": "Hybrid"
    }
}

Step 5. Get a group and its extension data

To get the custom data in a group, use $select to include the extension by name.

Apart from filtering by the id of the schema extension, you can also filter by the extension property values. The following example looks for the group that has the bellowscollege_courses extension with a courseId property value matching 123, and gets the extension data and the displayName, id, and description properties of the group.

Request

GET https://graph.microsoft.com/v1.0/groups?$filter=bellowscollege_courses/courseId eq '123'&$select=displayName,id,description,bellowscollege_courses

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups(displayName,id,description,bellowscollege_courses)",
    "value": [
        {
            "displayName": "New Managers March 2024",
            "id": "8fb45944-4085-449f-b95d-f7dd74a1b081",
            "description": "New Managers training course for March 2024",
            "bellowscollege_courses": {
                "@odata.type": "#microsoft.graph.ComplexExtensionValue",
                "courseType": "Hybrid",
                "courseName": "New Managers",
                "courseId": 123
            }
        }
    ]
}

Step 6: Delete extension data and schema extension definition

You can delete a schema extension definition if you no longer need it. If resource instances have the extension property applied, deleting the schema extension definition doesn't delete the extension data in the resource instances. Instead, the extension data is available but no longer accessible. You can recreate the schema extension definition with the same configuration - if you used the verified domain for the schema extension id - to be able to delete the extension data.

The following request deletes the bellowscollege_courses schema extension property and its associated data from the group. The request returns a 204 No Content response.

PATCH https://graph.microsoft.com/v1.0/groups/8fb45944-4085-449f-b95d-f7dd74a1b081

{
    "bellowscollege_courses": null
}

The following request deletes the bellowscollege_courses schema extension definition. The request returns a 204 No Content response.

DELETE https://graph.microsoft.com/v1.0/schemaExtensions/bellowscollege_courses