Portal Community

When to Use

Configuration

Authentication

FieldRequiredDescription
AuthenticationMethodRequired"ApiToken" or "OAuth2".
ApiTokenRequiredNotion Internal Integration Token starting with secret_.
ClientIdOAuth2OAuth2 client ID.
ClientSecretOAuth2OAuth2 client secret.
AccessTokenOAuth2OAuth2 access token.

Operation Fields

FieldRequiredDescription
ReturnAllOptionalWhen true, automatically pages through all users. Default: false.
LimitOptionalMax users to return per call (1–100). Default: 100.
StartCursorOptionalPagination cursor from a previous call's next_cursor.

Sample Configuration

{
  "resource": "user",
  "operation": "getMany",
  "AuthenticationMethod": "ApiToken",
  "ApiToken": "{{ $credentials.notionApiToken }}",
  "ReturnAll": true
}

Validation Errors

Error CodeCause
NOTION_UNAUTHORIZEDAPI token is invalid or disconnected from workspace.
NOTION_INVALID_CONFIGLimit is outside the valid range (1–100).
NOTION_INVALID_REQUESTStartCursor is not a valid pagination cursor.
NOTION_RATE_LIMITEDRate limit exceeded.

Output

Success Port

FieldTypeDescription
resultsarrayArray of user objects. Each contains id, name, email, avatarUrl, and type ("person" or "bot").
has_morebooleanWhether additional users exist past the current page.
next_cursorstringPagination cursor for the next call. Null when has_more is false.

Error Port

On failure the error port receives errorCode, message, and httpStatus.

Sample Output

{
  "results": [
    {
      "id": "a1b2c3d4-1111-2222-3333-e5f678901234",
      "name": "Sarah Chen",
      "email": "sarah.chen@acmecorp.com",
      "avatarUrl": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/avatars/sarah.jpg",
      "type": "person"
    },
    {
      "id": "b2c3d4e5-2222-3333-4444-f6a789012345",
      "name": "Marcus Johnson",
      "email": "marcus.johnson@acmecorp.com",
      "avatarUrl": null,
      "type": "person"
    },
    {
      "id": "c3d4e5f6-3333-4444-5555-a7b890123456",
      "name": "BizFirstAI Integration",
      "email": null,
      "avatarUrl": null,
      "type": "bot"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Expression Reference

ExpressionTypeUse
{{ $output.getManyUsers.results.length }}numberTotal user count including bots
{{ $output.getManyUsers.results.filter(u => u.type === 'person').length }}numberCount of human users only
{{ $output.getManyUsers.results.find(u => u.name === 'Sarah Chen').id }}stringResolve name to UUID for use in page/update assignee
{{ $output.getManyUsers.results.filter(u => u.type === 'person').map(u => u.email) }}arrayAll person emails for bulk notification
{{ $output.getManyUsers.has_more }}booleanGate manual pagination loop

Node Policies & GuardRails

PolicyDetail
Filter bots before processingThe results include both person and bot accounts. Filter to type === "person" in a Function node before sending emails or building a people picker. Bot accounts do not have email addresses.
Guest user email may be nullGuest users (invited without full workspace membership) may not return an email address. Use null-safe access and handle missing emails before routing notifications.
Cache for long workflowsIf a workflow references many Notion users, call user/getMany once at the start and build a lookup map (id → email). Avoid calling user/get per-user in a loop, which multiplies API calls by the number of assignees.
Use ReturnAll for small workspacesReturnAll: true is efficient for workspaces under 100 users. For larger organizations, use cursor-based pagination to stay within rate limits.
Credentials in Credentials ManagerAlways use {{ $credentials.notionApiToken }} — never hard-code the token.

Workflow Examples

Example 1 — Build User Lookup Map for Bulk Notifications

Load all users once, build a map, then use it to resolve assignee IDs across many pages without additional API calls.

// Step 1: user/getMany (ReturnAll: true)
// Step 2: Function node — build lookup map
const userMap = {};
$output.getManyUsers.results
  .filter(u => u.type === 'person')
  .forEach(u => { userMap[u.id] = { name: u.name, email: u.email }; });
return { userMap };

// Step 3: database/query (all open tasks)
// Step 4: Loop over tasks
// Step 5 per task: lookup assignee from userMap (no extra API call)
const assignee = $vars.userMap[$json.properties.Assignee.people[0]?.id];
if (assignee?.email) {
  // send email to assignee.email
}

Example 2 — HR System Sync Audit

Compare Notion workspace members to the active employee list from an HR system and flag discrepancies.

// Step 1: user/getMany (ReturnAll: true)
// Step 2: Function node — filter person users only
const notionEmails = results.filter(u => u.type === 'person').map(u => u.email).filter(Boolean);
// Step 3: HttpRequest — fetch active employee emails from HR API
// Step 4: Function node — find users in Notion but not in HR
const departed = notionEmails.filter(e => !hrEmails.includes(e));
// Step 5: Slack/postMessage — alert IT/security team

Example 3 — Name-to-UUID Resolution for Page Update

An external form captures a task assignee by name. Resolve to Notion UUID before updating the page property.

// Step 1: FormTrigger — { assigneeName: "Sarah Chen", pageId: "..." }
// Step 2: user/getMany (ReturnAll: true)
// Step 3: Function node
const user = $output.getManyUsers.results.find(u => u.name === $json.assigneeName);
if (!user) throw new Error("User not found: " + $json.assigneeName);
return { userId: user.id };

// Step 4: page/update
{
  "Page": "{{ $json.pageId }}",
  "Properties": {
    "Assignee": { "people": [{ "object": "user", "id": "{{ $json.userId }}" }] }
  }
}