Microsoft Graph provides a single API endpoint to access rich people-centric data and insights through resources such as user and message. You can also extend Microsoft Graph by adding custom properties to resource instances without requiring an external data store.
In this article, we'll discuss how Microsoft Graph supports extending its resources, the options available to add custom properties and when to use them.
Important
Do not use extensions to store sensitive personally identifiable information, such as account credentials, government identification numbers, cardholder data, financial account data, healthcare information, or sensitive background information.
As an ISV developer, you might decide to keep your app lightweight and store app-specific user profile data in Microsoft Graph by extending the user resource.
Alternatively, you might want to retain your app's existing user profile store, and add an app-specific identifier to the user resource.
As an enterprise developer, the in-house applications that you build might rely on your organization's HR-specific data. Integration within multiple applications can be simplified by storing this custom data in Microsoft Graph.
Custom data options in Microsoft Graph
Microsoft Graph offers four types of extensions for adding custom data.
Extension attributes
Directory (Azure AD) extensions
Schema extensions
Open extensions
Extension attributes
Azure AD offers a set of 15 extension attributes with predefined names on the user and device resources. These properties were initially custom attributes provided in on-premises Active Directory (AD) and Microsoft Exchange. However, they can now be used for more than syncing on-premises AD and Microsoft Exchange data to Azure AD through Microsoft Graph.
Developer experience
You can use the 15 extension attributes to store String values on user or device resource instances, through the onPremisesExtensionAttributes and extensionAttributes properties respectively. The values may be assigned when creating a new resource instance or when updating an existing resource instance. You can also filter by the values.
Add or update data in extension attributes
The following example shows how to store data in extensionAttribute1 and delete existing data from extensionAttribute13 through an update operation with a PATCH method.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new User
{
OnPremisesExtensionAttributes = new OnPremisesExtensionAttributes
{
ExtensionAttribute1 = "skypeId.adeleVance",
ExtensionAttribute13 = null,
},
};
var result = await graphClient.Users["{user-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new User();
$onPremisesExtensionAttributes = new OnPremisesExtensionAttributes();
$onPremisesExtensionAttributes->setExtensionAttribute1('skypeId.adeleVance');
$OnPremisesExtensionAttributes->setExtensionAttribute13(null);
$requestBody->setOnPremisesExtensionAttributes($onPremisesExtensionAttributes);
$result = $graphServiceClient->users()->byUserId('user-id')->patch($requestBody);
GET https://graph.microsoft.com/v1.0/users?$select=id,displayName,onPremisesExtensionAttributes
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "id","displayName","onPremisesExtensionAttributes" };
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new UsersRequestBuilderGetRequestConfiguration();
$queryParameters = UsersRequestBuilderGetRequestConfiguration::createQueryParameters();
$queryParameters->select = ["id","displayName","onPremisesExtensionAttributes"];
$requestConfiguration->queryParameters = $queryParameters;
$result = $graphServiceClient->users()->get($requestConfiguration);
Considerations for using extension attribute properties
The onPremisesExtensionAttributes object can be updated only for objects that aren't synced from on-premises AD.
The 15 extension attributes are already predefined in Microsoft Graph and their property names can't be changed. Therefore, you can't use custom names such as SkypeId for the extension attributes. This requires you and the organization to be aware of the extension attribute properties that are in use so that the values aren't inadvertently overwritten by other apps.
Directory (Azure AD) extensions
Directory extensions provide developers with a strongly typed, discoverable and filterable extension experience for directory objects.
Directory extensions are first registered on an application through the Create extensionProperty operation and must be explicitly targeted to specific and supported directory objects. After the application has been consented to by a user or an admin, the extension properties become immediately accessible in the tenant. All authorized applications in the tenant can read and write data on any extension properties defined on an instance of the target directory object.
For the list of resource types that can be specified as target objects for a directory extension, see Comparison of extension types.
Developer experience
Directory extension definitions are managed through the extensionProperty resource and its associated methods. The data is managed through the REST API requests that you use to manage the resource instance.
Define the directory extension
Before you can add a directory extension to a resource instance, you must first define the directory extension.
Request
In the following request, 30a5435a-1871-485c-8c7b-65f69e287e7b is the object ID of the application that owns the directory extension. On the beta endpoint, you can create directory extensions that store a collection of values.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new ExtensionProperty
{
Name = "jobGroupTracker",
DataType = "String",
TargetObjects = new List<string>
{
"User",
},
};
var result = await graphClient.Applications["{application-id}"].ExtensionProperties.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new ExtensionProperty();
$requestBody->setName('jobGroupTracker');
$requestBody->setDataType('String');
$requestBody->setTargetObjects(['User', ]);
$result = $graphServiceClient->applications()->byApplicationId('application-id')->extensionProperties()->post($requestBody);
A directory extension property named extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker is created with an extension name that follows the following naming convention: extension_{appId-without-hyphens}_{extensionProperty-name}.
Add a directory extension property to a target object
After defining the directory extension, you can now add it to an instance of a target object type. You can store data in the directory extension when creating a new instance of the target object or when updating an existing object. The following example shows how to store data in the directory extension when creating a new user object.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new User
{
AccountEnabled = true,
DisplayName = "Adele Vance",
MailNickname = "AdeleV",
UserPrincipalName = "AdeleV@contoso.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = false,
Password = "xWwvJ]6NMw+bWH-d",
},
AdditionalData = new Dictionary<string, object>
{
{
"extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker" , "JobGroupN"
},
},
};
var result = await graphClient.Users.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new User();
$requestBody->setAccountEnabled(true);
$requestBody->setDisplayName('Adele Vance');
$requestBody->setMailNickname('AdeleV');
$requestBody->setUserPrincipalName('AdeleV@contoso.com');
$passwordProfile = new PasswordProfile();
$passwordProfile->setForceChangePasswordNextSignIn(false);
$passwordProfile->setPassword('xWwvJ]6NMw+bWH-d');
$requestBody->setPasswordProfile($passwordProfile);
$additionalData = [
'extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker' => 'JobGroupN',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->post($requestBody);
The request returns a 201 Created response code and a user object in the response body.
Retrieve a directory extension
The following example shows how the directory extensions and associated data are presented on a resource instance. The extension property will be returned by default through the beta endpoint, but only on $select through the v1.0 endpoint.
GET https://graph.microsoft.com/beta/users?$select=id,displayName,extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker,extension_b7d8e648520f41d3b9c0fdeb91768a0a_permanent_pensionable
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "id","displayName","extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker","extension_b7d8e648520f41d3b9c0fdeb91768a0a_permanent_pensionable" };
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new UsersRequestBuilderGetRequestConfiguration();
$queryParameters = UsersRequestBuilderGetRequestConfiguration::createQueryParameters();
$queryParameters->select = ["id","displayName","extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker","extension_b7d8e648520f41d3b9c0fdeb91768a0a_permanent_pensionable"];
$requestConfiguration->queryParameters = $queryParameters;
$result = $graphServiceClient->users()->get($requestConfiguration);
To update or delete the value of the directory extension for a resource instance, use the PATCH method. To delete the extension property and its associated value, set its value to null.
The following request updates the value of one directory extension and deletes another extension property.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new User
{
AdditionalData = new Dictionary<string, object>
{
{
"extension_b7d8e648520f41d3b9c0fdeb91768a0a_permanent_pensionable" , null
},
{
"extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker" , "E4"
},
},
};
var result = await graphClient.Users["{user-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new User();
$additionalData = [
'extension_b7d8e648520f41d3b9c0fdeb91768a0a_permanent_pensionable' => null,
'extension_b7d8e648520f41d3b9c0fdeb91768a0a_jobGroupTracker' => 'E4',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->byUserId('user-id')->patch($requestBody);
The request returns a 204 No Content response code.
Considerations for using directory extensions
If you accidentally delete a directory extension definition, any data that's stored in the associated property becomes undiscoverable. To resolve this, create a new directory extension definition on the same owner app and with exactly the same name as the deleted definition.
When a definition object is deleted before the corresponding extension property is updated to null, the property will still count against the 100-limit for the object.
When the definition is deleted before data in the associated extension property is deleted, there's no way to know the existence of the extension property via Microsoft Graph - even though the undiscoverable property counts against the 100-limit.
Deleting an owner app in the home tenant makes the associated directory extensions and their data undiscoverable. Restoring an owner app restores the directory extension definitions but doesn't make the directory extension properties or their data immediately discoverable. This is because restoring an app doesn't automatically restore the associated service principal in the tenant. To make the directory extension properties and their data discoverable, either create a new service principal or restore the deleted service principal. NO changes are made to other tenants where the app has been consented to.
Schema extensions
Microsoft Graph schema extensions are conceptually similar to directory extensions. First, you define your schema extension. Then, use it to extend supported resource instances with strongly typed custom properties. In addition, you can control the status of your schema extension and let it be discoverable by other apps.
When creating a schema extension definition, you must provide a unique name for its id. There are two naming options:
If you already have a vanity .com,.net, .gov, .edu or a .org domain that you've verified with your tenant, you can use the domain name along with the schema name to define a unique name, in this format {domainName}_{schemaName}. For example, if your vanity domain is contoso.com, you can define an id of contoso_mySchema. This option is highly recommended.
Alternatively, you can set the id to a schema name (without a domain name prefix). For example, mySchema. Microsoft Graph will assign a string ID for you based on the supplied name, in this format: ext{8-random-alphanumeric-chars}_{schema-name}. For example, extkvbmkofy_mySchema.
The id will be the name of the complex type that will store your data on the extended resource instance.
Once you register a schema extension, it's available to be used by all applications in the same tenant as the associated owner application (when in the InDevelopment state) or by all applications in any tenant (when in the Available state). Like directory extensions, authorized apps have the ability to read and write data on any extensions defined on the target object.
You manage the schema extension definitions and the data in the corresponding schema extension property using separate sets of API operations. To manage the schema extension data on the extended resource instance, use the same REST request that you use to manage the resource instance.
Use POST to store data in the schema extension property when you're creating a new user.
Use PATCH to either store data in the schema extension property or update or delete the stored data.
To delete data from a property, set its value to null.
To delete data from all properties, set its value to null. If all properties are null, the schema extension object is also deleted.
To update any property, you must specify all properties in the request body. Otherwise, Microsoft Graph will update the unspecified properties to null.
Use GET to read the schema extension properties for all users or individual users in the tenant.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new SchemaExtension
{
Id = "graphLearnCourses",
Description = "Graph Learn training courses extensions",
TargetTypes = new List<string>
{
"user",
},
Properties = new List<ExtensionSchemaProperty>
{
new ExtensionSchemaProperty
{
Name = "courseId",
Type = "Integer",
},
new ExtensionSchemaProperty
{
Name = "courseName",
Type = "String",
},
new ExtensionSchemaProperty
{
Name = "courseType",
Type = "String",
},
},
};
var result = await graphClient.SchemaExtensions.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new SchemaExtension();
$requestBody->setId('graphLearnCourses');
$requestBody->setDescription('Graph Learn training courses extensions');
$requestBody->setTargetTypes(['user', ]);
$propertiesExtensionSchemaProperty1 = new ExtensionSchemaProperty();
$propertiesExtensionSchemaProperty1->setName('courseId');
$propertiesExtensionSchemaProperty1->setType('Integer');
$propertiesArray []= $propertiesExtensionSchemaProperty1;
$propertiesExtensionSchemaProperty2 = new ExtensionSchemaProperty();
$propertiesExtensionSchemaProperty2->setName('courseName');
$propertiesExtensionSchemaProperty2->setType('String');
$propertiesArray []= $propertiesExtensionSchemaProperty2;
$propertiesExtensionSchemaProperty3 = new ExtensionSchemaProperty();
$propertiesExtensionSchemaProperty3->setName('courseType');
$propertiesExtensionSchemaProperty3->setType('String');
$propertiesArray []= $propertiesExtensionSchemaProperty3;
$requestBody->setProperties($propertiesArray);
$result = $graphServiceClient->schemaExtensions()->post($requestBody);
After defining the schema extension, you can now add the extension property to an instance of a target object type. You can store data in the schema extension when creating a new instance of the target object or when updating an existing object. The following example shows how to store data in the schema extension property when creating a new user object.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new User
{
AccountEnabled = true,
DisplayName = "Adele Vance",
MailNickname = "AdeleV",
UserPrincipalName = "AdeleV@m365x72712789.onmicrosoft.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = false,
Password = "xWwvJ]6NMw+bWH-d",
},
AdditionalData = new Dictionary<string, object>
{
{
"extkmpdyld2_graphLearnCourses" , new
{
CourseId = 100,
CourseName = "Explore Microsoft Graph",
CourseType = "Online",
}
},
},
};
var result = await graphClient.Users.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new User();
$requestBody->setAccountEnabled(true);
$requestBody->setDisplayName('Adele Vance');
$requestBody->setMailNickname('AdeleV');
$requestBody->setUserPrincipalName('AdeleV@m365x72712789.onmicrosoft.com');
$passwordProfile = new PasswordProfile();
$passwordProfile->setForceChangePasswordNextSignIn(false);
$passwordProfile->setPassword('xWwvJ]6NMw+bWH-d');
$requestBody->setPasswordProfile($passwordProfile);
$additionalData = [
'extkmpdyld2_graphLearnCourses' => $requestBody = new Extkmpdyld2_graphLearnCourses();
$requestBody->setCourseId(100);
$ requestBody->setCourseName('Explore Microsoft Graph');
$ requestBody->setCourseType('Online');
$requestBody->setExtkmpdyld2_graphLearnCourses($extkmpdyld2_graphLearnCourses);
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->post($requestBody);
The request returns a 201 Created response code and a schemaExtension object in the response body
Update or delete a schema extension property
Use the PATCH operation to update a schema extension or delete an existing schema extension. To delete the extension property and its associated value from the resource instance, set its value to null.
The following example deletes the value of the courseId property and updates the courseType property. To delete the extkmpdyld2_graphLearnCourses extension property in its entirety, set its value to null.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new User
{
AdditionalData = new Dictionary<string, object>
{
{
"extkmpdyld2_graphLearnCourses" , new
{
CourseType = "Instructor-led",
CourseId = null,
}
},
},
};
var result = await graphClient.Users["{user-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new User();
$additionalData = [
'extkmpdyld2_graphLearnCourses' => $requestBody = new Extkmpdyld2_graphLearnCourses();
$ requestBody->setCourseType('Instructor-led');
$requestBody->setCourseId(null);
$requestBody->setExtkmpdyld2_graphLearnCourses($extkmpdyld2_graphLearnCourses);
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->byUserId('user-id')->patch($requestBody);
GET https://graph.microsoft.com/beta/users/0668e673-908b-44ea-861d-0661297e1a3e?$select=id,displayName,extkmpdyld2_graphLearnCourses
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users["{user-id}"].GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "id","displayName","extkmpdyld2_graphLearnCourses" };
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new UserRequestBuilderGetRequestConfiguration();
$queryParameters = UserRequestBuilderGetRequestConfiguration::createQueryParameters();
$queryParameters->select = ["id","displayName","extkmpdyld2_graphLearnCourses"];
$requestConfiguration->queryParameters = $queryParameters;
$result = $graphServiceClient->users()->byUserId('user-id')->get($requestConfiguration);
A schema extension must have an owner app. Ownership of the schema extension can't be reassigned to another app.
Deleting a schema extension definition without setting the schema extension to null makes the property and its associated user data undiscoverable.
Deleting an owner app in the home tenant doesn't delete the associated schema extension definition or the property and the data it stores. The schema extension property can still be read, deleted, or updated for users. However, the schema extension definition can't be updated.
Open extensions
Microsoft Graph open extensions are open types that offer a simple and flexible way to add untyped data directly to a resource instance. These extensions aren't strongly typed, discoverable, or filterable.
Open extensions, together with their data, are accessible through the extensions navigation property of the resource instance. They allow you to group related properties for easier access and management.
You define and manage open extensions on the fly on resource instances. They're considered unique for each object, and it's not required to apply a universally consistent pattern for all objects. For example, in the same tenant:
The user object for Adele can have an open extension named socialSettings that has three properties: linkedInProfile, skypeId, and xboxGamertag.
The user object for Bruno can have no open extension property.
The user object for Alex can have an open extension named socialSettings with five properties: theme, color, language, font, and fontSize.
Create an open extension
The following example shows an open extension definition with three properties and how the custom properties and associated data are presented on a resource instance.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Extension
{
OdataType = "#microsoft.graph.openTypeExtension",
Id = "com.contoso.socialSettings",
AdditionalData = new Dictionary<string, object>
{
{
"extensionName" , "com.contoso.socialSettings"
},
{
"skypeId" , "skypeId.AdeleV"
},
{
"linkedInProfile" , "www.linkedin.com/in/testlinkedinprofile"
},
{
"xboxGamerTag" , "AwesomeAdele"
},
},
};
var result = await graphClient.Users["{user-id}"].Extensions.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new Extension();
$requestBody->set@odatatype('#microsoft.graph.openTypeExtension');
$requestBody->setId('com.contoso.socialSettings');
$additionalData = [
'extensionName' => 'com.contoso.socialSettings',
'skypeId' => 'skypeId.AdeleV',
'linkedInProfile' => 'www.linkedin.com/in/testlinkedinprofile',
'xboxGamerTag' => 'AwesomeAdele',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->byUserId('user-id')->extensions()->post($requestBody);
The request returns a 201 Created response code and an openTypeExtension object in the response body.
Update an existing open extension
To update an open extension, you must specify all its properties in the request body. Otherwise, the unspecified properties will be updated to null and deleted from the open extension.
The following request specifies only the linkedInProfile and xboxGamerTag properties. The value of the xboxGamerTag property is being updated while the linkedInProfile property remains the same. This request also deletes the unspecified skypeId property.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Extension
{
AdditionalData = new Dictionary<string, object>
{
{
"xboxGamerTag" , "FierceAdele"
},
{
"linkedInProfile" , "www.linkedin.com/in/testlinkedinprofile"
},
},
};
var result = await graphClient.Users["{user-id}"].Extensions["{extension-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new Extension();
$additionalData = [
'xboxGamerTag' => 'FierceAdele',
'linkedInProfile' => 'www.linkedin.com/in/testlinkedinprofile',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->byUserId('user-id')->extensions()->byExtensionId('extension-id')->patch($requestBody);
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.Users.Item.Extensions.Item.Extension
{
AdditionalData = new Dictionary<string, object>
{
{
"@odata.context" , "https://graph.microsoft.com/beta/$metadata#users('3fbd929d-8c56-4462-851e-0eb9a7b3a2a5')/extensions/$entity"
},
{
"@odata.type" , "#microsoft.graph.openTypeExtension"
},
{
"xboxGamerTag" , "FierceAdele"
},
{
"linkedInProfile" , "www.linkedin.com/in/testlinkedinprofile"
},
{
"id" , "com.contoso.socialSettings"
},
},
};
var result = await graphClient.Users["{user-id}"].Extensions["{extension-id}"].GetAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new Extension();
$additionalData = [
'@odata.context' => 'https://graph.microsoft.com/beta/$metadata#users(\'3fbd929d-8c56-4462-851e-0eb9a7b3a2a5\')/extensions/$entity',
'@odata.type' => '#microsoft.graph.openTypeExtension',
'xboxGamerTag' => 'FierceAdele',
'linkedInProfile' => 'www.linkedin.com/in/testlinkedinprofile',
'id' => 'com.contoso.socialSettings',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->users()->byUserId('user-id')->extensions()->byExtensionId('extension-id')->get($requestBody);
15 predefined attributes per user or device resource instance
100 extension values per resource instance
Maximum of five definitions per owner app
100 extension values per resource instance (directory objects only)
Two open extensions per creator app per resource instance3
Max. of 2 Kb per open extension3
For Outlook resources, each open extension is stored in a MAPI named property4
Note
1 Due to an existing service limitation, delegates cannot create open extension-appended events in shared mailbox calendars. Attempts to do so will result in an ErrorAccessDenied response.
2 Only available in public preview for directory extensions.
3 These limits on open extensions apply to the following directory resources: user, group, device, and organization.
4 Each open extension is stored in a MAPI named property, which are a limited resource in a user's mailbox. This limit applies to the following Outlook resources: message, event, and contact
You can manage all extensions when you're signed in with a work or school account. Additionally, you can manage open extensions for the following resources when signed-in with a personal Microsoft account: event, post, group, message, contact, and user.
Permissions and privileges
The same privileges that your app requires to read from or write to a resource instance are also required to manage any extensions data on that resource instance. For example, for an app to update any user's profile with custom app data, the app must have been granted the User.ReadWrite.All Microsoft Graph permission.
Known limitations
For known limitations using extensions, see the extensions section in the known issues article.