Skip to content
Dashboard

OAuth 2.1 User-Delegated Access

API keys authenticate an integration as a machine member of your organization. OAuth 2.1 user-delegated access is the alternative: it lets a third-party application — or an AI assistant such as a Model Context Protocol (MCP) client — act on a specific person’s behalf, using only the permissions that person actually has.

When a user connects an app this way, they see a SuiteOp consent screen, choose which organization to grant access to, and review the permissions the app is requesting. The app then receives an access token tied to that user, that organization, and the approved permissions.


API keyOAuth 2.1 access token
Acts asA machine member of the orgThe person who authorized the app
Best forYour own server-to-server scripts and integrationsApps used by many different SuiteOp users, and AI assistants
PermissionsThe scopes you choose when creating the keyThe granted scopes intersected with the user’s live permissions
User involvementNone — you create the key yourselfThe user signs in and approves a consent screen
Token formatsk_live_… / sk_test_…, shown onceOpaque access token issued by the authorization server

Reach for OAuth whenever an app needs to do things as the user — so that what it can do is automatically bounded by what that user is allowed to do, and revoking the user’s access also revokes the app’s.


SuiteOp hosts a standard OAuth 2.1 authorization server. Clients discover it, register, send the user through an authorization request, and exchange the resulting code for an access token.

  1. Discover the server. Fetch the authorization-server and protected-resource metadata from your region’s API root:

    GET https://api-<region>.suiteop.com/.well-known/oauth-authorization-server
    GET https://api-<region>.suiteop.com/.well-known/oauth-protected-resource

    The metadata returns the authorization, token, and registration endpoints to use. Replace <region> with us, eu, or apac (see Base URLs).

  2. Register the client. SuiteOp supports Dynamic Client Registration, so a client can register itself at the registration endpoint and receive a client_id. Registration is open but rate-limited, and registered redirect URIs must use HTTPS (with a loopback exception for localhost during development).

  3. Send the user to authorize. Redirect the user to the authorization endpoint with PKCE (the S256 code challenge method is required). The user signs in to SuiteOp if they aren’t already, then lands on the consent screen.

  4. The user authorizes. Once they approve, SuiteOp redirects back to your registered redirect URI with an authorization code.

  5. Exchange the code for a token. Call the token endpoint with the authorization code and your PKCE verifier to receive an access token.


The consent screen is what the person authorizing the app sees. It always appears — an app can never obtain a user-delegated token without the user explicitly approving it.

On the screen the user:

  • Reviews the app. The requesting application’s name is shown at the top (“<App> is requesting access to your SuiteOp account”).
  • Chooses an organization. If the user belongs to more than one organization in the region, they pick exactly one to grant access to. The token is bound to that single organization. (Users who belong to only one org have it preselected.)
  • Reviews requested permissions. The screen lists the specific permissions the app asked for, in plain language (for example View tasks, Manage reservations).
  • Authorizes or cancels. Clicking Authorize completes the flow; Cancel denies it and returns the user to the app empty-handed.

The permissions an OAuth token actually carries are the scopes granted at consent intersected with the user’s live permissions in the chosen organization — and this is recomputed on every request.

This has two important consequences:

  • An app can never do more than the user can. If the app was granted tasks:write but the user only has read access to tasks, the token cannot write tasks.
  • Permissions stay in sync automatically. If the user’s role changes — or they’re removed from the organization — the token’s effective permissions shrink (or disappear) on the very next request, with no need to re-issue or revoke anything manually.

A request that needs a permission the token’s effective set doesn’t include returns 403 authorization_error, exactly like API keys.


Access ends in any of these ways:

  • The user re-authorizes the app. Going through consent again replaces the previous grant and revokes the app’s outstanding tokens for that user and organization.
  • The user’s permissions change. Because effective permissions are recomputed per request, losing a role or being removed from the organization immediately narrows or nullifies what the token can do.
  • Standard token expiry. Access tokens are short-lived; clients refresh them through the normal OAuth flow.

SuiteOp exposes a hosted Model Context Protocol server at /mcp so AI assistants can call the same operations as the REST API. OAuth 2.1 is how a user connects such an assistant to their account.

Point the MCP client at your region’s endpoint:

https://api-<region>.suiteop.com/mcp

When the client first connects, it discovers the authorization server (an unauthenticated request to /mcp advertises it), registers, and walks the user through the same authorization flow and consent screen described above. From then on the assistant acts within that user’s permissions in the chosen organization.