The setUsers method allows you to bulk create or update users in the Teamwork Graph in a single
API call. This is the recommended approach for bulk user ingestion as it's more efficient than
making individual requests for each user.
1 2setUsers(request: BulkUsersRequest): Promise<BulkUsersResponse>
BulkUsersRequest1 2// BulkUsersRequest object: { users: UserPayload[]; // users: Array of users to ingest (maximum 100 users per request) connectionId?: string; // Optional: Connection identifier for multi-connection scenarios }
The UserPayload type supports comprehensive user information:
1 2type UserPayload = { externalId: string; // Required: Unique external identifier for the user nickname?: string; // Optional: User's nickname displayName?: string; // Optional: Display name for the user photos?: UserPhoto[]; // Optional: User profile photos emails: UserEmail[]; // Required: User email addresses (at least one) extendedProfile?: UserExtendedProfile; // Optional: Additional profile information updateSequenceNumber?: number; // Optional: Sequence number for tracking updates };
1 2type UserPhoto = { value: string; // URL or data URI of the photo type: string; // Type of photo (e.g., 'photo') }; type UserEmail = { value: string; // Email address primary: boolean; // Whether this is the primary email }; type UserExtendedProfile = { jobTitle?: string; // User's job title department?: string; // User's department organization?: string; // User's organization location?: string; // User's location phoneNumbers?: UserPhoneNumber[]; // User's phone numbers }; type UserPhoneNumber = { type?: string; // Type of phone number (e.g., 'mobile', 'work') value: string; // Phone number };
1 2import { graph } from '@forge/teamwork-graph'; const user = { externalId: 'user-123', displayName: 'Test User', nickname: 'tester', photos: [ { value: 'https://example.com/avatar.jpg', type: 'photo' } ], emails: [ { value: 'test@example.com', primary: true }, { value: 'backup@example.com', primary: false } ], extendedProfile: { jobTitle: 'Software Engineer', department: 'Engineering', organization: 'Tech Corp', location: 'San Francisco' } }; const request = { users: [user], connectionId: 'connection-id-123' }; const response = await graph.setUsers(request);
1 2const users = [ { externalId: 'user-1', displayName: 'John Doe', emails: [{ value: 'john@example.com', primary: true }] }, { externalId: 'user-2', displayName: 'Jane Smith', emails: [{ value: 'jane@example.com', primary: true }] } ]; const response = await graph.setUsers({ users, connectionId: 'connection-id-123' });
1 2const minimalUser = { externalId: 'user-123', displayName: 'Simple User', emails: [{ value: 'simple.user@example.com', primary: true }] }; const response = await graph.setUsers({ users: [minimalUser] });
The method validates the following:
users field must be a valid array.users array cannot be empty.| Error message | Description |
|---|---|
users must be an array | The users field is not an array. |
users array cannot be empty | The users array is empty |
Bulk user ingestion supports maximum 100 users. Received X | The number of users per request has exceeded the maximum limit. |
The method returns a promise that resolves to a BulkUsersResponse object.
1 2// BulkUsersResponse { success: boolean; // Indicates if the overall operation was successful results?: { success: Array<{ // Array of users successfully ingested externalId: string; // The external ID that was processed statusCode: number; // 200-299 }>; failures: Array<{ // Array of users not ingested externalId: string; // The external ID that was processed statusCode: number; // non 200-299 error: string; // Error message for this specific user }>; }; error?: string; // Overall error message (if operation failed) originalError?: unknown; // Original error object (if available) }
The SDK provides type-safe request and response objects that ensure compile-time validation:
1 2import { types } from '@forge/teamwork-graph'; // Type-safe user creation const user: types.UserPayload = { externalId: 'user-123', displayName: 'Test User', emails: [{ value: 'test@example.com', primary: true }] }; // Type-safe request creation const request: types.BulkUsersRequest = { users: [user], connectionId: 'connection-id-123' }; // Type-safe response handling const response = await graph.setUsers(request); if (response.success && response.results) { // TypeScript knows results exists here and provides proper typing response.results.success.forEach(result => { // result is properly typed with externalId, success, and statusCode properties console.log(`Successfully created user: ${result.externalId}`); }); response.results.failures.forEach(result => { // result is properly typed with error information console.error(`Failed to create user: ${result.externalId}, Error: ${result.error}`); }); }
The type system ensures:
user object has correct UserPayload structure with proper email and name typesrequest.users must be an array of UserPayload objectsresponse.results has properly typed success and failures arraysRate this page: