> ## Documentation Index
> Fetch the complete documentation index at: https://docs.r28.ai/charter/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Charter works for any HTTP API, including the user's own. The packs are examples of the result, not the limit: an API with no pack is declared the same way, following https://raw.githubusercontent.com/r28ai/charter/main/docs/.mintlify/skills/declaring-charter-tools/SKILL.md.
> Charter is for agents that act in customers' accounts: every call is checked field by field before it's sent, the app says whose account each call is for, and the same declarations list what each tool can reach. https://docs.r28.ai/charter/llms.txt says what it is and lists every page.

# Register a Microsoft Entra app

> The app your users connect their Outlook mailboxes through: the account types, the redirect URI, the client secret and the Graph permissions, with a screenshot for each screen.

Microsoft issues no API key for mail. Before your users can connect Outlook,
you need an app registered in Microsoft Entra ID, Microsoft's identity
platform: it holds your redirect URI, your client secret, and the Graph
permissions your tools ask for. A personal Microsoft account is enough to
register one, and it takes about five minutes.

Every Microsoft link below opens in a new tab, so this page stays where you left it.

**1. Start a new registration**

Open [App registrations](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)
in the Microsoft Entra admin center and click **New registration**.

![The App registrations page in the Microsoft Entra admin center, with New registration first in the toolbar and no applications owned yet.](https://mintcdn.com/r28-ai-inc/38sMUPhbPomQJ9Uz/charter/images/setup/microsoft/01-app-registrations.webp?fit=max\&auto=format\&n=38sMUPhbPomQJ9Uz\&q=85\&s=63abbacc75c33eb0f5eb6b0b07cb2cb7)

**2. Choose who can connect, and add your redirect URI**

The registration form has three fields:

* **Name**: what your users see on the consent screen.
* **Supported account types**: who can sign in. For a product, pick the option
  that includes **personal Microsoft accounts**, so both work or school
  mailboxes and Outlook.com mailboxes can connect. The app's overview then
  reads **All Microsoft account users**. Pick one organisation only, and the
  app serves that organisation alone, through a different endpoint: see
  [the server](https://docs.r28.ai/charter/charter/auth/providers/microsoft.md#the-server).
* **Redirect URI**: choose **Web** as the platform and enter your app's
  callback route, such as `https://app.example.com/oauth/microsoft/callback`.
  It has to use HTTPS unless it's `localhost`, and match the flow's
  `redirect_uri` character for character.

Choose **Web**, not **Single-page application**. Microsoft expires refresh
tokens sent to a single-page redirect after 24 hours, and a single-page app
can't use a client secret. Click **Register**.

**3. Copy the client ID**

The app opens on its **Overview**. Copy the **Application (client) ID**.

![The Overview of Example App: its application (client) ID, object ID and directory (tenant) ID, one web redirect URI, and supported account types All Microsoft account users.](https://mintcdn.com/r28-ai-inc/38sMUPhbPomQJ9Uz/charter/images/setup/microsoft/02-overview.webp?fit=max\&auto=format\&n=38sMUPhbPomQJ9Uz\&q=85\&s=f4b33a3141dc8405dcd3b5fb6ab13ff4)

```bash theme={null}
export MICROSOFT_CLIENT_ID=7c2e9b41-5d08-4f3a-a6e1-0b9d84c25f17
```

You don't need the **Object ID**. The **Directory (tenant) ID** matters only if
you chose a single organisation, because its endpoints include it.

**4. Create a client secret**

Under **Manage**, open **Certificates & secrets**. On the **Client secrets** tab,
click **New client secret**, give it a description, and pick an expiry.

![The Certificates & secrets page of Example App on its Client secrets tab, with New client secret above an empty list.](https://mintcdn.com/r28-ai-inc/38sMUPhbPomQJ9Uz/charter/images/setup/microsoft/03-client-secrets.webp?fit=max\&auto=format\&n=38sMUPhbPomQJ9Uz\&q=85\&s=bb60bdd6b9c4f8f3d3c78fa8c688a990)

Copy the new secret's **Value**, not its **Secret ID**. Entra shows the value
once, and only until you leave the page.

```bash theme={null}
export MICROSOFT_CLIENT_SECRET=...
```

A secret lasts at most 24 months, and Microsoft recommends less than 12. When it
expires, every token request fails until you create another, so put the date
somewhere you'll see it.

**5. Add the Graph permissions**

Under **Manage**, open **API permissions** and click **Add a permission** →
**Microsoft Graph** → **Delegated permissions**. Tick:

* `Mail.ReadWrite`, `Mail.Send` and `MailboxSettings.ReadWrite`
* `User.Read`, which Entra adds to a new registration by itself
* `offline_access`, which is how Microsoft issues a refresh token

Between them, they cover every tool in the [Outlook pack](https://docs.r28.ai/charter/charter/packs/outlook.md) but one.

![The API permissions page of Example App: five delegated Microsoft Graph permissions, Mail.ReadWrite, Mail.Send, MailboxSettings.ReadWrite, offline\_access and User.Read, none of which needs admin consent.](https://mintcdn.com/r28-ai-inc/38sMUPhbPomQJ9Uz/charter/images/setup/microsoft/04-api-permissions.webp?fit=max\&auto=format\&n=38sMUPhbPomQJ9Uz\&q=85\&s=06edac76d743449044e34ddaa78ec594)

The exception is `translate_exchange_ids`, which needs `User.ReadBasic.All`. Add
it too if you hand that tool out.

This list is what an administrator approves when they consent for a whole
organisation. Each user is asked for what your consent link requests, which
[`scopes_for`](https://docs.r28.ai/charter/charter/reference/oauth#scopes_for) builds from the tools you hand out:
[Scopes](https://docs.r28.ai/charter/charter/auth/providers/microsoft.md#scopes). None of these permissions needs an
administrator, as the **Admin consent required** column shows.

**6. Get verified, for other organisations' users**

Skip this if your users sign in with personal Microsoft accounts, or all belong
to the organisation the app is registered in.

Users in other organisations may not be allowed to consent to an app from an
**unverified publisher**. Since November 2020, Microsoft has blocked them from
consenting to a newly registered multitenant app that asks for more than
sign-in, wherever risk-based step-up consent is on. Many organisations also let
their users consent only to verified publishers. Either way, the user sees
**Need admin approval** instead of your consent screen, and until an
administrator consents for the organisation, they can't connect.

Publisher verification removes that block. It needs:

* An account in the [Microsoft AI Cloud Partner Program](https://partner.microsoft.com/membership) that has completed verification.
* An app registered with a **work or school account**. One registered with a
  personal Microsoft account can't be verified, so register the production app
  in your company's tenant.
* A publisher domain that isn't `*.onmicrosoft.com`, and that matches the email
  domain of the partner account.

The [publisher verification overview](https://learn.microsoft.com/en-us/entra/identity-platform/publisher-verification-overview)
has the rest. It costs nothing.

**7. Connect a mailbox**

Your app's "Connect Outlook" button opens the link
[`flow.authorize()`](https://docs.r28.ai/charter/charter/reference/oauth#oauth2flow-authorize) builds. The user
signs in, sees the permissions it asks for, and accepts. The server constant,
the scopes and the per-user client are on the
[Microsoft provider page](https://docs.r28.ai/charter/charter/auth/providers/microsoft.md).

## When it does not work

> **AADSTS50011: the redirect URI does not match**
>
> The flow sent a URI that isn't listed for the app, character for character.
> Check **Authentication** under **Manage**: the URI has to be there, under
> **Web**. A trailing slash is enough to break the match.

> **AADSTS50194: not configured as a multi-tenant application**
>
> The app was registered for one organisation, and the link went to the
> `common` endpoint. Use the tenant's own endpoints, or change
> **Supported account types**:
> [the server](https://docs.r28.ai/charter/charter/auth/providers/microsoft.md#the-server).

> **AADSTS7000222: the client secret keys are expired**
>
> Every token request fails, for every user. Create a new secret, deploy it,
> then delete the old one. Users don't need to connect again.

> **“Need admin approval”**
>
> The user's organisation doesn't let users consent to this app. An
> administrator can consent for the organisation, or the app can be
> publisher-verified: see the step above.

> **The exchange raises: no refresh\_token**
>
> The link didn't ask for `offline_access`. Add it to the scopes the flow
> authorizes, and have the user connect again.

## Related

* [Microsoft OAuth](https://docs.r28.ai/charter/charter/auth/providers/microsoft.md) — the server constant and the per-user client
* [Getting the grant](https://docs.r28.ai/charter/charter/auth/oauth-flow.md) — the two routes, `state` and PKCE, inside your app
* [Outlook](https://docs.r28.ai/charter/charter/packs/outlook.md) — the pack, and what each tool needs


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.