Stitchflow
Notion logo

Notion User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 5, 2026

Summary and recommendation

Notion's REST API (base URL: `https://api.notion.com/v1`, stable version header `2022-06-28`) supports read operations on workspace users via `GET /v1/users` and `GET /v1/users/{user_id}`. Authentication uses either an internal integration Bearer token (`secret_*`) or OAuth 2.0 for public integrations.

There is no API endpoint to create, update, or delete workspace users - user lifecycle management requires SCIM (Enterprise only) or manual admin action.

The API enforces a rate limit of 3 requests per second per integration token. HTTP 429 responses include a `Retry-After` header; the `X-RateLimit-*` header family is not documented. Pagination is cursor-based via `start_cursor`; max page size is 100.

Always check `has_more` before terminating a pagination loop.

API quick reference

Has user APIYes
Auth methodBearer token (internal integration secret) or OAuth 2.0 (public integrations)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise

Authentication

Auth method: Bearer token (internal integration secret) or OAuth 2.0 (public integrations)

Setup steps

  1. Go to https://www.notion.so/my-integrations and create a new integration.
  2. Copy the Internal Integration Secret (starts with 'secret_') for server-to-server use.
  3. For OAuth 2.0 public integrations, configure redirect URIs and use the authorization code flow at https://api.notion.com/v1/oauth/authorize.
  4. Share the target Notion workspace pages/databases with the integration to grant access.
  5. Pass the token in the Authorization header: 'Authorization: Bearer ' and set 'Notion-Version: 2022-06-28'.

Required scopes

Scope Description Required for
read_user Read user objects (name, email, avatar) for workspace members. List users, Retrieve user
read_content Read pages and databases; indirectly needed to resolve user references in content. Resolving user mentions in page content

User object / data model

Field Type Description On create On update Notes
object string Always 'user'. system-set immutable
id string (UUID) Unique identifier for the user. system-set immutable
type string 'person' or 'bot'. system-set immutable Bot users represent integrations.
name string Display name of the user. user-set user-managed May be null for bots without a name.
avatar_url string (URL) | null URL of the user's profile photo. user-set user-managed Nullable.
person.email string Email address of a person-type user. user-set user-managed Only present when the integration has user email capability enabled and the user has granted access.
bot.owner object Owner info for bot-type users; contains 'type' ('workspace' or 'user') and optionally a user object. system-set immutable Only present on bot-type users.
bot.workspace_name string | null Workspace name for workspace-owned bots. system-set immutable Only present on workspace-owned bots.

Core endpoints

List all users

  • Method: GET
  • URL: https://api.notion.com/v1/users
  • Watch out for: Requires the integration to be added to the workspace by an admin. Returns all workspace members visible to the integration.

Request example

GET /v1/users?page_size=100
Authorization: Bearer secret_xxx
Notion-Version: 2022-06-28

Response example

{
  "object": "list",
  "results": [{"object":"user","id":"uuid","type":"person","name":"Alice"}],
  "next_cursor": "cursor_abc",
  "has_more": true
}

Retrieve a user

  • Method: GET
  • URL: https://api.notion.com/v1/users/{user_id}
  • Watch out for: Email is only returned if the integration has the 'Read user information including email addresses' capability enabled.

Request example

GET /v1/users/abc123
Authorization: Bearer secret_xxx
Notion-Version: 2022-06-28

Response example

{
  "object": "user",
  "id": "abc123",
  "type": "person",
  "name": "Alice",
  "avatar_url": "https://...",
  "person": {"email": "alice@example.com"}
}

Retrieve the bot (token owner) user

  • Method: GET
  • URL: https://api.notion.com/v1/users/me
  • Watch out for: Returns the bot user associated with the integration token, not a human user.

Request example

GET /v1/users/me
Authorization: Bearer secret_xxx
Notion-Version: 2022-06-28

Response example

{
  "object": "user",
  "id": "bot-uuid",
  "type": "bot",
  "name": "My Integration",
  "bot": {"owner":{"type":"workspace"},"workspace_name":"Acme"}
}

Search (find pages/databases, resolves user mentions)

  • Method: POST
  • URL: https://api.notion.com/v1/search
  • Watch out for: Not a direct user search endpoint; user objects appear as nested references in page/database results.

Request example

POST /v1/search
Content-Type: application/json

{"query": "Alice", "filter": {"value":"page","property":"object"}}

Response example

{
  "object": "list",
  "results": [{"object":"page","id":"page-uuid","created_by":{"object":"user","id":"abc123"}}]
}

Rate limits, pagination, and events

  • Rate limits: Notion enforces an average rate limit of 3 requests per second per integration token. Bursting above this threshold returns HTTP 429.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: On HTTP 429, Notion returns a 'Retry-After' header indicating seconds to wait. The header 'X-RateLimit-*' family is not documented; rely on 429 + Retry-After.
  • Pagination method: cursor
  • Default page size: 100
  • Max page size: 100
  • Pagination pointer: start_cursor
Plan Limit Concurrent
All plans (per integration) 3 requests/second average 0
  • Webhooks available: No
  • Webhook notes: Notion does not offer native webhooks as of the current API version (2022-06-28). There is no event-push mechanism for user creation, deletion, or updates.
  • Alternative event strategy: Poll GET /v1/users on a schedule to detect membership changes, or use SCIM provisioning events via your IdP (Okta, Entra ID) for user lifecycle events.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise

  • Endpoint: https://www.notion.so/scim/v2

  • Supported operations: GET /Users – list users, GET /Users/{id} – retrieve user, POST /Users – provision user, PUT /Users/{id} – replace user, PATCH /Users/{id} – update user attributes, DELETE /Users/{id} – deprovision user, GET /Groups – list groups, GET /Groups/{id} – retrieve group, POST /Groups – create group, PUT /Groups/{id} – replace group, PATCH /Groups/{id} – update group members, DELETE /Groups/{id} – delete group

Limitations:

  • Requires Enterprise plan; not available on Free, Plus, or Business plans.
  • SAML SSO must be configured before enabling SCIM.
  • SCIM token is generated in workspace Settings > Identity & Provisioning; only workspace owners can generate it.
  • Supported IdPs with documented setup: Okta, Microsoft Entra ID (Azure AD), OneLogin, Google Workspace.
  • SCIM Groups map to Notion workspace groups; group membership changes are reflected in workspace permissions.
  • Deprovisioning via SCIM removes workspace access but does not delete user-created content.
  • Email address is used as the unique identifier for matching existing Notion accounts.

Common scenarios

For identity graph construction, GET /v1/users is the primary enumeration endpoint. Each person-type user object exposes id (UUID), name, and `person.

email- but email is only returned if the integration has the 'Read user information including email addresses' capability explicitly enabled in integration settings. Bot-type users appear in the same endpoint response and must be filtered bytype` field to avoid polluting identity records.

For automated provisioning and deprovisioning, the SCIM 2.0 API (https://www.notion.so/scim/v2) is the correct surface. It supports full user and group lifecycle: POST /Users, PATCH /Users/{id}, DELETE /Users/{id}, and group management via /Groups. SCIM Groups map directly to Notion workspace groups, making group-based access control automatable from an IdP. Supported IdPs with documented setup include Okta, Microsoft Entra ID, OneLogin, and Google Workspace.

For token introspection, GET /v1/users/me returns the bot user associated with the integration token. To resolve the authorizing human for OAuth integrations, inspect bot.owner.user - the top-level response is always the bot, not the human who created the integration.

Sync workspace member list to an external directory

  1. Authenticate with an internal integration token (Bearer secret_xxx).
  2. Call GET /v1/users?page_size=100 with Notion-Version: 2022-06-28.
  3. Iterate through 'results'; if 'has_more' is true, repeat with 'start_cursor' set to 'next_cursor' value.
  4. For each user of type 'person', store id, name, and person.email (requires email capability enabled).
  5. Schedule polling (e.g., every 15 minutes) since no webhooks are available.

Watch out for: Email is absent unless the integration's 'Read user information including email addresses' capability is enabled in the Notion integration settings.

Provision and deprovision users via SCIM (Enterprise)

  1. Ensure the workspace is on the Enterprise plan with SAML SSO configured.
  2. Navigate to Settings > Identity & Provisioning and generate a SCIM token.
  3. Configure your IdP (e.g., Okta) with base URL https://www.notion.so/scim/v2 and the SCIM token as Bearer auth.
  4. Map IdP user attributes to SCIM schema: userName (email), name.givenName, name.familyName, active.
  5. Assign users/groups in the IdP; provisioning events trigger POST /Users or PATCH /Users/{id} calls to Notion.
  6. Deprovisioning (removing from IdP) triggers DELETE /Users/{id}, revoking workspace access.

Watch out for: Deprovisioning removes access but does not delete content created by the user. Group membership via SCIM Groups maps to Notion workspace groups.

Identify the bot user associated with an integration token

  1. Call GET /v1/users/me with the integration's Bearer token.
  2. Inspect the returned 'bot.owner' field: type 'workspace' means a workspace-level integration; type 'user' means a user-authorized OAuth integration.
  3. Use the returned bot 'id' to filter out bot activity from audit logs or page-created-by fields.

Watch out for: GET /v1/users/me returns the bot user, not the human who created the integration. To get the authorizing human user for OAuth integrations, inspect 'bot.owner.user'.

Why building this yourself is a trap

The most significant architectural caveat: Notion has no native webhooks as of API version 2022-06-28. There is no event-push mechanism for user creation, deletion, or role changes.

Any identity graph that depends on real-time membership state must poll GET /v1/users on a schedule and diff results - or rely on IdP-side SCIM events for lifecycle signals, which are only available on Enterprise.

Internal integrations cannot self-discover workspace content; they must be manually added to pages or databases by a workspace member. This means an integration scoped for user enumeration still requires an admin to explicitly authorize it within the workspace.

Combined with the email capability gate, it is straightforward to build an integration that silently returns incomplete user records - person.email will be absent with no error, only an empty field, if the capability is not enabled.

Automate Notion workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 5, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen