Browse the docs

Organization connections

Google Workspace domain-wide delegation, Microsoft 365 app-only access and shared mailboxes.

Access methods

An organization connection lets a Google Workspace or Microsoft 365 administrator authorize Workwae once. You list the directory, add mailboxes by address, and each one becomes an account with the same mail, calendar and contacts API as an account a user connected. Microsoft 365 shared mailboxes open through the grant of a user who can already open them.

MethodHow it works
Google Workspace delegationgoogle_delegation: a Workspace admin authorizes the service account's client id for the connection's scopes under Security, API controls, Domain-wide delegation. Scopes: gmail.modify always, calendar by default, contacts when you choose, and admin.directory.user.readonly with a directory admin.
Microsoft 365 app-onlymicrosoft_app: a directory administrator grants admin consent to Workwae's app for the cloud, or to your own app registration with a client secret or a certificate. Required: Mail.ReadWrite, Mail.Send. Optional: Calendars.ReadWrite, MailboxSettings.Read, Contacts.ReadWrite, User.Read.All.
Microsoft 365 shared mailboxA user who can open the mailbox connects with options.sharedMailboxesEnabled; the shared mailbox uses that grant over Graph or Exchange IMAP. Gmail has no delegated shared mailboxes: use domain-wide delegation there.

A connection is pending_consent until a Microsoft directory consents, unverified after a credential or scope change, then active or failing with the failed check as its detail. A missing optional permission limits only calendar, contacts or the directory; mail keeps syncing. For Google, the admin must authorize every scope the connection lists, or no token is issued.

Google Workspace delegation

Register the service account key; Workwae checks and seals it and returns the client id and scopes, in the Admin console's order, for the admin to authorize. Then test the connection. Without a directory admin, add mailboxes by address; tests then impersonate the user you name.

const connection = await workwae.orgConnections.create({
  kind: "google_delegation",
  name: "Acme Workspace",
  domain: "acme.com",
  serviceAccountKey, // the JSON key file
  calendarEnabled: true,
  contactsEnabled: true,
  directoryAdmin: "[email protected]",
});
// For the admin: Security > API controls > Domain-wide delegation
showAdmin(connection.clientId, connection.google?.scopes);

const result = await workwae.orgConnections.test({ connectionId: connection.id });
for (const check of result.checks) {
  if (!check.isOk) console.warn(check.name, check.detail);
}

Microsoft 365 app-only access

A Microsoft connection names its cloud: global (worldwide, including GCC), gcc-high, dod or china (21Vianet). Sign-in and Graph calls stay in that cloud. In 21Vianet, Graph has no message delta yet, so app-only mail sync does not run there; those mailboxes use IMAP and SMTP with a user's Microsoft sign-in.

Consent to Workwae's own app is started from the console, so the directory is taken from the administrator who actually signed in. With your own app registration, start consent through the API and get the administrator back to your app with status, connection_id, error and your state.

const connection = await workwae.orgConnections.create({
  kind: "microsoft_app",
  name: "Contoso (GCC High)",
  cloud: "gcc-high",
  credential: { type: "client_secret", clientId, clientSecret },
});

const { consentUrl } = await workwae.orgConnections.consent({
  connectionId: connection.id,
  redirectUri: "https://app.example.com/admin/consent-done",
  state: tenantRef,
});
// Send the administrator to consentUrl

Adding mailboxes

Page through the directory (up to 200 entries a page, matching the start of names and addresses); each entry shows the account already added for it. Add up to 100 addresses per call. Each mailbox is checked through the connection first, and every address gets its own result, in request order: created, exists or failed with the reason.

import { paginate } from "@workwae/sdk";

const mailboxes = [];
for await (const entry of paginate(workwae.orgConnections.directoryEntries, {
  connectionId,
  query: "support",
})) {
  if (entry.accountId) continue; // already an account
  mailboxes.push({ email: entry.email, externalRef: entry.id });
}

const { items } = await workwae.orgConnections.addAccounts({ connectionId, mailboxes });
for (const added of items) {
  if (added.status === "failed") console.warn(added.email, added.error?.reason);
}

Shared mailboxes

Open a Microsoft 365 shared mailbox as an account of its own through the grant of an account whose user can open it. That account must have been connected with options.sharedMailboxesEnabled, which asks for Mail.ReadWrite.Shared and Mail.Send.Shared (plus the shared calendar and contacts permissions). Shared mailboxes need the shared mailboxes module in the tenant's plan.

const billing = await workwae.sharedMailboxes.create({
  accountId: userAccountId,
  email: "[email protected]",
});

If the delegating account is deleted, the shared mailbox moves to reauth_required with delegate_missing.

When access changes

  • When an administrator withdraws authorization, the affected accounts move to reauth_required with consent_revoked and account.reauth_required is sent.
  • Once access is restored, a passing test returns them to active and sends account.connected with reauthorized: true.
  • Accounts added through a connection belong to it: a user sign-in cannot take them over. Fix the connection, then test it.
  • A connection cannot be deleted while live accounts use it (connection_in_use). Delete its accounts first.

Every route is in the Organization connections and Shared mailboxes references.