The Connector SDK APIs are available through Forge's Early Access Program (EAP).
EAPs are offered to selected users for testing and feedback purposes. APIs and features under EAP are unsupported and subject to change without notice. APIs and features under EAP are not recommended for use in production environments.
To use the Connector SDK, you must be part of the Forge connector EAP. You can express interest in joining this EAP through this form.
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>
BulkUsersRequest
1 2// BulkUsersRequest object: { users: UserPayload[]; // users: Array of users to ingest (maximum 100 users per request) }
The UserPayload
type supports comprehensive user information:
1 2type UserPayload = { externalId: string; // Required: Unique external identifier for the user userName?: string; // Optional: Username for the user name?: UserName; // Optional: Structured name information nickname?: string; // Optional: User's nickname displayName?: string; // Optional: Display name for the user photos?: UserPhoto[]; // Optional: User profile photos emails?: UserEmail[]; // Optional: User email addresses extendedProfile?: UserExtendedProfile; // Optional: Additional profile information };
1 2type UserName = { formatted?: string; // Full formatted name familyName?: string; // Last name givenName?: string; // First name }; type 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', userName: 'testuser', nickname: 'tester', name: { formatted: 'Test User', familyName: 'User', givenName: 'Test' }, 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] }; const response = await graph.setUsers(request);
1 2const users = [ { externalId: 'user-1', displayName: 'John Doe', userName: 'johndoe', emails: [{ value: 'john@example.com', primary: true }] }, { externalId: 'user-2', displayName: 'Jane Smith', userName: 'janesmith', emails: [{ value: 'jane@example.com', primary: true }] } ]; const response = await graph.setUsers({ users });
1 2const minimalUser = { externalId: 'user-123', displayName: 'Simple User' }; 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', userName: 'testuser', emails: [{ value: 'test@example.com', primary: true }] }; // Type-safe request creation const request: types.BulkUsersRequest = { users: [user] }; // 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: