Skip to main content

Overview

The Applications API provides operations to manage Azure AD application registrations. Access through graphClient.Applications.

Request Builder

public ApplicationsRequestBuilder Applications { get; }
Accessed via: graphClient.Applications

Operations

List Applications

Retrieve all application registrations.
var applications = await graphClient.Applications.GetAsync();

foreach (var app in applications.Value)
{
    Console.WriteLine($"{app.DisplayName}");
    Console.WriteLine($"  App ID: {app.AppId}");
    Console.WriteLine($"  Object ID: {app.Id}");
}

// Filter applications
var filteredApps = await graphClient.Applications.GetAsync(config =>
{
    config.QueryParameters.Filter = "startsWith(displayName,'MyApp')";
    config.QueryParameters.Select = new[] { "id", "appId", "displayName" };
});
Query Parameters:
$select
string[]
Properties to return
$filter
string
Filter expression
$orderby
string[]
Sort order
$top
int
Number of applications to return
Search query (requires ConsistencyLevel header)

Get Application by ID

// By object ID
var app = await graphClient.Applications["object-id"].GetAsync();

// By app ID (alternate key)
var app = await graphClient.ApplicationsWithAppId("app-id").GetAsync();

Console.WriteLine($"Display Name: {app.DisplayName}");
Console.WriteLine($"App ID: {app.AppId}");
Console.WriteLine($"Sign-in audience: {app.SignInAudience}");

Create Application

var newApp = new Application
{
    DisplayName = "My Application",
    SignInAudience = "AzureADMyOrg",
    RequiredResourceAccess = new List<RequiredResourceAccess>
    {
        new RequiredResourceAccess
        {
            ResourceAppId = "00000003-0000-0000-c000-000000000000", // Microsoft Graph
            ResourceAccess = new List<ResourceAccess>
            {
                new ResourceAccess
                {
                    Id = Guid.Parse("e1fe6dd8-ba31-4d61-89e7-88639da4683d"), // User.Read
                    Type = "Scope"
                },
                new ResourceAccess
                {
                    Id = Guid.Parse("df021288-bdef-4463-88db-98f22de89214"), // User.Read.All
                    Type = "Role"
                }
            }
        }
    },
    Web = new WebApplication
    {
        RedirectUris = new List<string>
        {
            "https://localhost:5001/signin-oidc"
        },
        ImplicitGrantSettings = new ImplicitGrantSettings
        {
            EnableIdTokenIssuance = true
        }
    },
    Api = new ApiApplication
    {
        Oauth2PermissionScopes = new List<PermissionScope>
        {
            new PermissionScope
            {
                AdminConsentDescription = "Allow app to read data",
                AdminConsentDisplayName = "Read data",
                Id = Guid.NewGuid(),
                IsEnabled = true,
                Type = "User",
                UserConsentDescription = "Allow app to read your data",
                UserConsentDisplayName = "Read your data",
                Value = "Data.Read"
            }
        }
    }
};

var app = await graphClient.Applications.PostAsync(newApp);
Console.WriteLine($"Created app: {app.AppId}");

Update Application

var updateApp = new Application
{
    DisplayName = "Updated App Name",
    Tags = new[] { "WindowsAzureActiveDirectoryIntegratedApp" }
};

await graphClient.Applications["object-id"].PatchAsync(updateApp);

Delete Application

await graphClient.Applications["object-id"].DeleteAsync();

Owners

List Owners

var owners = await graphClient.Applications["object-id"].Owners.GetAsync();

foreach (var owner in owners.Value)
{
    if (owner is User user)
    {
        Console.WriteLine($"Owner: {user.DisplayName}");
    }
}

Add Owner

var ownerRef = new ReferenceCreate
{
    OdataId = $"https://graph.microsoft.com/v1.0/users/{userId}"
};

await graphClient.Applications["object-id"].Owners.Ref.PostAsync(ownerRef);

Remove Owner

await graphClient.Applications["object-id"].Owners["user-id"].Ref.DeleteAsync();

Certificates and Secrets

Add Password Credential (Client Secret)

var passwordCredential = new AddPasswordPostRequestBody
{
    PasswordCredential = new PasswordCredential
    {
        DisplayName = "My Client Secret",
        EndDateTime = DateTime.UtcNow.AddMonths(6)
    }
};

var credential = await graphClient.Applications["object-id"]
    .AddPassword
    .PostAsync(passwordCredential);

Console.WriteLine($"Secret: {credential.SecretText}");
Console.WriteLine($"Key ID: {credential.KeyId}");
// Store the secret securely - it's only shown once!

Remove Password Credential

var removePassword = new RemovePasswordPostRequestBody
{
    KeyId = Guid.Parse("key-id")
};

await graphClient.Applications["object-id"]
    .RemovePassword
    .PostAsync(removePassword);

Add Certificate

using System.Security.Cryptography.X509Certificates;

var certificate = new X509Certificate2("path/to/cert.pfx", "password");

var keyCredential = new AddKeyPostRequestBody
{
    KeyCredential = new KeyCredential
    {
        Type = "AsymmetricX509Cert",
        Usage = "Verify",
        Key = certificate.RawData,
        DisplayName = "My Certificate"
    },
    PasswordCredential = null,
    Proof = "proof-token" // Required for key verification
};

var key = await graphClient.Applications["object-id"]
    .AddKey
    .PostAsync(keyCredential);

Remove Certificate

var removeKey = new RemoveKeyPostRequestBody
{
    KeyId = Guid.Parse("key-id"),
    Proof = "proof-token"
};

await graphClient.Applications["object-id"]
    .RemoveKey
    .PostAsync(removeKey);

Extension Properties

List Extension Properties

var extensions = await graphClient.Applications["object-id"]
    .ExtensionProperties
    .GetAsync();

foreach (var ext in extensions.Value)
{
    Console.WriteLine($"{ext.Name}: {ext.DataType}");
}

Create Extension Property

var extensionProperty = new ExtensionProperty
{
    Name = "customAttribute",
    DataType = "String",
    TargetObjects = new[] { "User" }
};

var ext = await graphClient.Applications["object-id"]
    .ExtensionProperties
    .PostAsync(extensionProperty);

Federated Identity Credentials

List Federated Credentials

var credentials = await graphClient.Applications["object-id"]
    .FederatedIdentityCredentials
    .GetAsync();

Create Federated Credential

var federatedCred = new FederatedIdentityCredential
{
    Name = "GitHubActions",
    Issuer = "https://token.actions.githubusercontent.com",
    Subject = "repo:organization/repository:environment:production",
    Description = "GitHub Actions deployment",
    Audiences = new[] { "api://AzureADTokenExchange" }
};

await graphClient.Applications["object-id"]
    .FederatedIdentityCredentials
    .PostAsync(federatedCred);
using var logoStream = File.OpenRead("logo.png");

await graphClient.Applications["object-id"]
    .Logo
    .PutAsync(logoStream);
var logoStream = await graphClient.Applications["object-id"]
    .Logo
    .GetAsync();

using var fileStream = File.Create("downloaded-logo.png");
await logoStream.CopyToAsync(fileStream);

Token Issuance Policies

List Token Issuance Policies

var policies = await graphClient.Applications["object-id"]
    .TokenIssuancePolicies
    .GetAsync();

Token Lifetime Policies

List Token Lifetime Policies

var policies = await graphClient.Applications["object-id"]
    .TokenLifetimePolicies
    .GetAsync();

Common Scenarios

Create Web Application with Redirect URIs

var webApp = new Application
{
    DisplayName = "My Web App",
    SignInAudience = "AzureADMultipleOrgs",
    Web = new WebApplication
    {
        RedirectUris = new List<string>
        {
            "https://myapp.com/signin-oidc",
            "https://myapp.com/signout-callback-oidc"
        },
        LogoutUrl = "https://myapp.com/signout-oidc"
    }
};

var app = await graphClient.Applications.PostAsync(webApp);

Create SPA Application

var spaApp = new Application
{
    DisplayName = "My SPA",
    SignInAudience = "AzureADandPersonalMicrosoftAccount",
    Spa = new SpaApplication
    {
        RedirectUris = new List<string>
        {
            "http://localhost:3000",
            "https://myspa.com"
        }
    },
    RequiredResourceAccess = new List<RequiredResourceAccess>
    {
        new RequiredResourceAccess
        {
            ResourceAppId = "00000003-0000-0000-c000-000000000000",
            ResourceAccess = new List<ResourceAccess>
            {
                new ResourceAccess
                {
                    Id = Guid.Parse("e1fe6dd8-ba31-4d61-89e7-88639da4683d"),
                    Type = "Scope"
                }
            }
        }
    }
};

Create Native/Mobile Application

var nativeApp = new Application
{
    DisplayName = "My Mobile App",
    SignInAudience = "AzureADandPersonalMicrosoftAccount",
    PublicClient = new PublicClientApplication
    {
        RedirectUris = new List<string>
        {
            "msauth.com.mycompany.myapp://auth",
            "http://localhost"
        }
    },
    IsFallbackPublicClient = true
};

Delta Query

var delta = await graphClient.Applications.Delta.GetAsync();

foreach (var app in delta.Value)
{
    Console.WriteLine($"Changed: {app.DisplayName}");
}

var deltaLink = delta.OdataDeltaLink;

Error Handling

using Microsoft.Graph.Models.ODataErrors;

try
{
    var app = await graphClient.Applications["object-id"].GetAsync();
}
catch (ODataError error)
{
    if (error.Error.Code == "Request_ResourceNotFound")
    {
        Console.WriteLine("Application not found");
    }
    else if (error.Error.Code == "Authorization_RequestDenied")
    {
        Console.WriteLine("Insufficient permissions");
    }
    else
    {
        Console.WriteLine($"Error: {error.Error.Message}");
    }
}

See Also

Application Model

Application properties

Service Principals

Service principal management

OAuth2 Permission Grants

Permission grants

App Registrations

Azure AD documentation

Build docs developers (and LLMs) love