Custom endpoint tabs

A custom endpoint tab gets its locations from an HTTP endpoint you build, for example an Azure Logic App. MailConnect calls it as the person using it, with their delegated tokens, so the endpoint can look things up in SharePoint or Microsoft Graph as them.

Only you and Pinksky set these tabs up, on the customer’s Settings tab: Tabs in the add-in → Add tab → Custom endpoint… (🤝). The address and the tokens can carry keys, so the customer’s Admins can rename, move and star an endpoint tab, but not change or remove it. See Setting up customers for the card.

What goes in the dialog

FieldWhat to enter
Name in OutlookThe tab’s name. Required, and under 60 characters.
AddressThe endpoint’s full https:// address, called with GET. For a Logic App, that’s its invoke URL including its signature (sp, sv, sig). Anyone with the address can call the endpoint, so treat it as a secret. Once saved, it’s shown shortened: type a new one to replace it.
App IDThe app registration in the customer’s Microsoft 365 that MailConnect gets each person’s tokens from. See The app registration.
Tokens sentA SharePoint token, in X-SP-Access-Token (MailConnect’s default), or Choose the tokens. See Tokens.
Hide locations people can’t openMailConnect checks each location’s site for the person, and leaves out the ones they can’t open. Usually unnecessary: the endpoint already runs as the person.

Tokens

An access token is only valid for one API: a SharePoint token can’t be used against Microsoft Graph, or the other way round. An endpoint that calls both needs a token for each. With Choose the tokens, select Add token for each:

FieldWhat to enter
TypeSharePoint (the customer’s SharePoint, found automatically), Graph (Microsoft Graph), or Custom (your own API).
HeaderThe request header the token is sent in, for example X-SP-Access-Token or X-Graph-Access-Token. Not Authorization.
PrefixOptional: text in front of the token, for example Bearer . Without it, the bare token is sent.
ScopesFor Custom only: the scopes to ask for, separated by spaces, for example api://contoso-projects/.default.
  • Each token goes in its own header, never Authorization. A Logic App refuses a request that carries both its signature and an Authorization header.
  • A token that’s set up wrongly isn’t sent: no header, Authorization as the header, or a Custom token without scopes. The others still are, and the card warns about it.
  • One app registration for all of them. Every token comes through the App ID, so its delegated permissions are the limit of what your endpoint can do as the person. For SharePoint and Graph tokens, those are Microsoft Graph delegated permissions, for example Sites.Read.All.
  • At most one sign-in prompt. MailConnect gets the tokens one at a time: after the first, the rest come silently.

Using the tokens in a Logic App

  • Read each token from its trigger header, and call the matching API with Authorization: Bearer <token>. For example, X-SP-Access-Token for https://{tenant}.sharepoint.com/_api/search/postquery, and X-Graph-Access-Token for https://graph.microsoft.com/v1.0/search/query.
  • Keep the Logic App protected by the signature in its address. Don’t add a Microsoft Entra authorization policy: SharePoint tokens fail standard JWT validation, and only SharePoint itself accepts them. A token that isn’t valid simply gets a 401 from the API you call.
  • Getting a 401 from Graph? You’re probably sending the SharePoint token. Add a Graph token under Tokens sent, and use its header.

Calls from the browser

MailConnect calls the endpoint from the browser, with the token headers, so the endpoint must accept cross-origin requests (CORS) from MailConnect’s origin, https://mailconnect.tenantapps.cloud, including the preflight request. Until MailConnect’s old address retires, also allow https://mailconnect.pinksky.dk: customers who haven’t installed the new manifest still run from there.

What the endpoint returns

A JSON array, one entry per location:

[
  {
    "id": "1",
    "parentId": null,
    "title": "Project A",
    "subTitle": "Consulting",
    "webUrl": "https://tenant.sharepoint.com/sites/ProjectA",
    "filterValues": ["2024", "Active", "High Priority"]
  }
]
FieldDescription
idUnique ID of the location.
parentIdAccepted, but not used: MailConnect shows every location at the top level.
title / subTitleShown on the location’s card.
webUrlThe SharePoint site the location opens, for browsing and archiving.
filterValuesOptional. More text the tab’s search box matches, besides title and subTitle.

A response that isn’t an array, or an error status, shows the tab’s This tab couldn’t load message with Retry.

Checking it

In Outlook: save, then open MailConnect as someone at the customer and pick the tab. Its locations come straight from the endpoint. No locations means the endpoint refused the tokens, or didn’t answer with a list.

In the Admin Center: Check the endpoint…, in the pane next to the tabs, shows what the endpoint returns, without opening Outlook. It’s there when you’re signed in to the customer’s Microsoft 365.

  • It asks first: it sends a SharePoint token for your account to the endpoint’s host, and with it the endpoint can read SharePoint as you for up to an hour.
  • It’s logged before anything is sent: your account and the host, never the address or the token.
  • Only SharePoint tokens are sent, in the headers of the tab’s SharePoint tokens (or X-SP-Access-Token). Graph and Custom tokens aren’t sent from the Admin Center.
  • The token comes from MailConnect’s own app, not from the tab’s App ID. An endpoint that only accepts tokens from its own app refuses the check (401 or 403), even when the tab works in Outlook.
  • The endpoint must accept calls from any site (Access-Control-Allow-Origin: *): the check runs from a sandboxed page.

The pane then shows the first 50 locations returned. What the customer’s IT sees of this is under What the Admin Center can do in your tenant.

The app registration

The app registration behind App ID, in the customer’s Microsoft Entra ID:

Authentication: add these Single-page application (SPA) redirect URIs:

  • brk-multihub://mailconnect.tenantapps.cloud
  • https://mailconnect.tenantapps.cloud

Keep brk-multihub://mailconnect.pinksky.dk and https://mailconnect.pinksky.dk as well until the old address retires.

API permissions: Microsoft Graph delegated permissions (for example Sites.Read.All), not the SharePoint API’s AllSites.* permissions.

Expose an API: under Authorized client applications, add the client ID ea5a67f6-b6f3-4338-b240-c655ddc3cc8e.

That’s Microsoft’s well-known client ID that lets Office call your API on the signed-in person’s behalf. It’s the same for every add-in and every tenant, not something specific to MailConnect or to your app registration. See Microsoft’s Register an Office Add-in that uses SSO for background.

Authorize it for the access_as_user scope. In the app’s manifest:

"oauth2PermissionScopes": [
    {
        "adminConsentDescription": "App can act as the user",
        "adminConsentDisplayName": "App can act as the user",
        "id": "c92ac36c-da0c-4812-a119-592394406fde",
        "isEnabled": true,
        "type": "User",
        "userConsentDescription": null,
        "userConsentDisplayName": "App can act as the user",
        "value": "access_as_user"
    }
],
"preAuthorizedApplications": [
    {
        "appId": "ea5a67f6-b6f3-4338-b240-c655ddc3cc8e",
        "delegatedPermissionIds": [
            "c92ac36c-da0c-4812-a119-592394406fde"
        ]
    }
]

MailConnect uses cookies to improve your experience. You decide what we're allowed to use. Learn more in our cookie policy.