Organization connections
Register Google Workspace delegation or Microsoft 365 app-only access, then list the directory and add mailboxes as accounts.
Guides: Organization connections.
| Method | Path | Operation | Scope |
|---|---|---|---|
GET | /v1/org-connections | List organization connections | admin |
POST | /v1/org-connections | Register an organization connection | admin |
GET | /v1/org-connections/{connectionId} | Get an organization connection | admin |
PATCH | /v1/org-connections/{connectionId} | Update an organization connection | admin |
DELETE | /v1/org-connections/{connectionId} | Delete an organization connection | admin |
POST | /v1/org-connections/{connectionId}/consent | Start Microsoft admin consent | admin |
POST | /v1/org-connections/{connectionId}/test | Test an organization connection | admin |
GET | /v1/org-connections/{connectionId}/directory-entries | List the directory's mailboxes | admin |
POST | /v1/org-connections/{connectionId}/accounts | Add mailboxes as accounts | write |
Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Required scope: admin.
OK
application/json- response
items*array<>curl -X GET 'https://api.workwae.com/v1/org-connections'{ "items": [ { "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "kind": "google_delegation", "name": "string", "clientId": "string", "status": "pending_consent", "statusDetail": "string", "checkedAt": "2026-05-04T09:30:00.000Z", "google": { "domain": "string", "serviceAccountEmail": "string", "directoryAdmin": "string", "scopes": [ "string" ] }, "microsoft": { "cloud": "global", "credentialType": "platform", "directoryId": "string", "permissions": [ { "name": "string", "isRequired": true } ] }, "accounts": 0, "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z" } ]}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Google: the service account key is checked and sealed; authorize the returned clientId for the returned scopes in the Admin console, then test. Microsoft: a platform connection starts in pending_consent (POST .../consent); a tenant app with a directoryId starts unverified.
Required scope: admin.
application/json- body
kind*unknownname*string1 <= length <= 100serviceAccountKey*string2 <= length <= 20000domain*string3 <= length <= 253calendarEnabled?booleantruecontactsEnabled?booleanfalsedirectoryAdmin?stringemaillength <= 320OK
application/json- response
id*stringuuidkind*OrgConnectionKind"google_delegation""microsoft_app"name*stringclientId*stringstatus*OrgConnectionStatus"pending_consent""unverified""active""failing"statusDetail*string|nullcheckedAt*|nullgoogle*|nullmicrosoft*|nullaccounts*integercreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X POST 'https://api.workwae.com/v1/org-connections' \ -H 'Content-Type: application/json' \ -d '{ "kind": "google_delegation", "name": "string", "serviceAccountKey": "string", "domain": "string"}'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "kind": "google_delegation", "name": "string", "clientId": "string", "status": "pending_consent", "statusDetail": "string", "checkedAt": "2026-05-04T09:30:00.000Z", "google": { "domain": "string", "serviceAccountEmail": "string", "directoryAdmin": "string", "scopes": [ "string" ] }, "microsoft": { "cloud": "global", "credentialType": "platform", "directoryId": "string", "permissions": [ { "name": "string", "isRequired": true } ] }, "accounts": 0, "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Required scope: admin.
connectionId*stringuuidOK
application/json- response
id*stringuuidkind*OrgConnectionKind"google_delegation""microsoft_app"name*stringclientId*stringstatus*OrgConnectionStatus"pending_consent""unverified""active""failing"statusDetail*string|nullcheckedAt*|nullgoogle*|nullmicrosoft*|nullaccounts*integercreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X GET 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "kind": "google_delegation", "name": "string", "clientId": "string", "status": "pending_consent", "statusDetail": "string", "checkedAt": "2026-05-04T09:30:00.000Z", "google": { "domain": "string", "serviceAccountEmail": "string", "directoryAdmin": "string", "scopes": [ "string" ] }, "microsoft": { "cloud": "global", "credentialType": "platform", "directoryId": "string", "permissions": [ { "name": "string", "isRequired": true } ] }, "accounts": 0, "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Replacing a credential or the authorized scopes makes the connection unverified until the next test.
Required scope: admin.
connectionId*stringuuidapplication/json- body
name?string1 <= length <= 100serviceAccountKey?string2 <= length <= 20000calendarEnabled?booleancontactsEnabled?booleandirectoryAdmin?|nullclientSecret?string1 <= length <= 1024certificate?string1 <= length <= 20000privateKey?string1 <= length <= 20000directoryId?string1 <= length <= 100OK
application/json- response
id*stringuuidkind*OrgConnectionKind"google_delegation""microsoft_app"name*stringclientId*stringstatus*OrgConnectionStatus"pending_consent""unverified""active""failing"statusDetail*string|nullcheckedAt*|nullgoogle*|nullmicrosoft*|nullaccounts*integercreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X PATCH 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "kind": "google_delegation", "name": "string", "clientId": "string", "status": "pending_consent", "statusDetail": "string", "checkedAt": "2026-05-04T09:30:00.000Z", "google": { "domain": "string", "serviceAccountEmail": "string", "directoryAdmin": "string", "scopes": [ "string" ] }, "microsoft": { "cloud": "global", "credentialType": "platform", "directoryId": "string", "permissions": [ { "name": "string", "isRequired": true } ] }, "accounts": 0, "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Required scope: admin.
connectionId*stringuuidOK
application/json- response
curl -X DELETE 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab'nullRuns against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Returns the URL an administrator of the directory grants consent at. Afterwards the browser returns to redirectUri with status=success|error, connection_id, error and state; the connection records the consenting directory and is tested. A tenant app uses /adminconsent. The platform app is consented through a sign-in (authorize with prompt=admin_consent) and records the directory named by the sign-in's ID token; it can only be started from the console, and the console user who started it has to be signed in, in the browser that returns, for the directory to be recorded. Errors on return include access_denied, consent_failed, consent_unverified, directory_mismatch and directory_already_connected (another platform connection holds the directory).
Required scope: admin.
connectionId*stringuuidapplication/json- body
redirectUri*stringuristate?stringlength <= 1024OK
application/json- response
consentUrl*stringuricurl -X POST 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab/consent' \ -H 'Content-Type: application/json' \ -d '{ "redirectUri": "https://app.example.com/mail/connected"}'{ "consentUrl": "https://app.example.com/"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Requests a token the way accounts will and reports each check; the connection becomes active or failing. A passing test returns accounts that were moved to reauth_required to active. Google impersonates user (default: the directory admin).
Required scope: admin.
connectionId*stringuuidapplication/json- body
user?stringemaillength <= 320OK
application/json- response
connection*checks*array<>curl -X POST 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab/test' \ -H 'Content-Type: application/json' \ -d '{}'{ "connection": { "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "kind": "google_delegation", "name": "string", "clientId": "string", "status": "pending_consent", "statusDetail": "string", "checkedAt": "2026-05-04T09:30:00.000Z", "google": { "domain": "string", "serviceAccountEmail": "string", "directoryAdmin": "string", "scopes": [ "string" ] }, "microsoft": { "cloud": "global", "credentialType": "platform", "directoryId": "string", "permissions": [ { "name": "string", "isRequired": true } ] }, "accounts": 0, "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z" }, "checks": [ { "name": "string", "isOk": true, "isRequired": true, "detail": "string" } ]}Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Microsoft: Graph /users (needs User.Read.All). Google: the Admin SDK users.list as the directory admin (needs admin.directory.user.readonly). query matches the start of names and addresses. A nextCursor is good for an hour, on this connection only.
Required scope: admin.
connectionId*stringuuidcursor?string1 <= length <= 512limit?integer1 <= value <= 200100query?stringlength <= 100OK
application/json- response
items*array<>nextCursor*|nullcurl -X GET 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab/directory-entries'{ "items": [ { "id": "string", "email": "string", "displayName": "string", "accountId": "6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b" } ], "nextCursor": "eyJ0eG5pZCI6IjQyIiwiaWQiOjEwMDF9"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Each mailbox is checked through the connection before its account is created (Google: a delegated token for it; Microsoft: its inbox). items holds one result per mailbox, in request order. Per-mailbox failures are reported there with the reason the API would answer with, e.g. invalid_grant (no such user), consent_revoked (the scopes or permissions are not granted), provider_forbidden or provider_not_found (no mailbox access), plan_limit_accounts (the plan's account limit was reached part way through; the mailboxes before it are created).
Required scope: write.
connectionId*stringuuidapplication/json- body
mailboxes*array<>1 <= items <= 100settings?OK
application/json- response
items*array<>curl -X POST 'https://api.workwae.com/v1/org-connections/d2c1cc43-b491-4d08-8b29-11a5f88293ab/accounts' \ -H 'Content-Type: application/json' \ -d '{ "mailboxes": [ { "email": "ada@example.com" } ]}'{ "items": [ { "email": "string", "status": "created", "accountId": "6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b", "error": { "reason": "string", "message": "string" } } ]}