# Stop Spamming Your Users: Create Microsoft 365 Groups Without Welcome Emails

- Date: 2026-02-14
- Author: Jeppe Spanggaard
- Description: Learn how to create Microsoft 365 groups programmatically with the Graph SDK in C# without sending a welcome email flood to every member.
- URL: https://jeppe-spanggaard.dk/blogs/graph-sdk-create-group-without-welcome-email/
- Tags: SharePoint, csharp, Microsoft Graph, Provisioning

## TL;DR

Add `WelcomeEmailDisabled` to `resourceBehaviorOptions` via `AdditionalData` when creating the group. It can **only** be set at creation time — not patched afterward.

```cs
AdditionalData = new Dictionary<string, object>
{
    { "resourceBehaviorOptions", new List<string> { "WelcomeEmailDisabled" } }
}
```

Want the full example with owners and members included? Read on. 👇


## The Problem

When building automated site provisioning, every Microsoft 365 group creation triggers a welcome email to each member by default. In an automated scenario where multiple groups are created at once, that quickly turns into a flood of emails your users didn't ask for — and they're going to call it spam.

Microsoft [documents](https://learn.microsoft.com/en-us/graph/group-set-options) `WelcomeEmailDisabled` as a supported option, but doesn't show you how to actually set it from the Graph SDK in C#. That's what this post is about.

## The Weird Part: AdditionalData

If you look at the typed `Group` object in the SDK, you won't find a `ResourceBehaviorOptions` property anywhere. It has to be set through `AdditionalData` — a catch-all dictionary for properties that exist in the Graph API but aren't modeled as first-class typed properties in the SDK.

It works fine, but it does mean you lose IntelliSense and compile-time safety. The same pattern applies to `owners@odata.bind` and `members@odata.bind`, which let you assign owners and members at creation time without separate follow-up calls.

## The Solution

Here's the complete group creation request with welcome emails disabled, owners set, and members added — all in a single API call:

```cs
var ownerId = $"https://graph.microsoft.com/v1.0/users/{ownerObjectId}";
var groupMembers = new List<string>
{
    $"https://graph.microsoft.com/v1.0/users/{memberObjectId1}",
    $"https://graph.microsoft.com/v1.0/users/{memberObjectId2}"
};

Group requestBody = new()
{
    Description = description,
    DisplayName = displayName,
    GroupTypes = ["Unified"],
    MailEnabled = false,
    MailNickname = siteName,
    SecurityEnabled = true,
    AdditionalData = new Dictionary<string, object>
    {
        { "resourceBehaviorOptions", new List<string> { "WelcomeEmailDisabled" } },
        { "owners@odata.bind", new List<string> { ownerId } },
        { "members@odata.bind", groupMembers }
    }
};

Group? group = await _graphClient.Groups.PostAsync(requestBody);
```

### resourceBehaviorOptions

`resourceBehaviorOptions` controls specific group behaviors at creation. `WelcomeEmailDisabled` simply stops Microsoft 365 from sending the welcome email to members.

You can also combine multiple options in the same list if needed:

```cs
{ "resourceBehaviorOptions", new List<string> { "WelcomeEmailDisabled", "HideGroupInOutlook" } }
```

Other supported values are documented [here](https://learn.microsoft.com/en-us/graph/group-set-options).

### owners@odata.bind and members@odata.bind

The `@odata.bind` syntax binds users to the group by their full resource URL at creation time, so you don't need separate `POST /groups/{id}/members` calls afterward. The URL format must be the full Graph v1.0 path:

```
https://graph.microsoft.com/v1.0/users/{objectId}
```

