> ## Documentation Index
> Fetch the complete documentation index at: https://docs.riseworks.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Team Management Guide

> Manage teams and users with Rise B2B API using the SDK

Learn how to manage teams and users with the Rise B2B API using the official SDK. The SDK provides methods for team updates, user management, and team invitations.

## Team Management Flow

<Steps>
  <Step title="Initialize SDK">
    Set up the Rise SDK with authentication
  </Step>

  <Step title="Get User Teams">
    Retrieve teams associated with the current user
  </Step>

  <Step title="Update Team Settings">
    Modify team information and settings
  </Step>

  <Step title="Manage Team Members">
    Send invitations and manage team membership
  </Step>
</Steps>

## SDK Installation

First, install the Rise SDK:

```bash theme={null}
npm install @riseworks/riseworks-sdk
# Or: yarn add @riseworks/riseworks-sdk
# Or: pnpm add @riseworks/riseworks-sdk
```

## Getting Started

### Initialize the SDK

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');
require('dotenv').config();

// Initialize with Rise ID and private key (recommended)
const client = new RiseApiClient({
  environment: 'prod',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY
  }
});

// Alternative: Initialize with JWT token
const jwtClient = new RiseApiClient({
  environment: 'prod',
  jwtToken: process.env.JWT_TOKEN
});
```

## Team Management Operations

### Get User's Teams

Retrieve all teams associated with the current user:

```javascript theme={null}
// Get all teams for the current user
const teams = await client.user.getTeams();
console.log('User teams:', teams.data);

// Example response structure
// {
//   "success": true,
//   "data": {
//     "teams": [
//       {
//         "nanoid": "te-abc123def456",
//         "name": "Engineering Team",
//         "description": "Core engineering team",
//         "member_count": 5,
//         "status": "active"
//       }
//     ]
//   }
// }
```

### Update Team Information

Update team settings and information:

```javascript theme={null}
// Update team information
await client.team.update({
  nanoid: 'te-abc123def456',
  name: 'Updated Engineering Team',
  description: 'Updated team description'
});

console.log('Team updated successfully');
```

### Team Invitations

The SDK provides different approaches for sending team invitations depending on the role:

#### Regular Team Invitations

For regular team members (employees, viewers), no signing is required:

```javascript theme={null}
// Send invitation to regular team members (no signing required)
const invitation = await client.invites.send({
  nanoid: 'te-abc123def456',
  invites: [
    {
      email: 'john.doe@example.com',
      role: 'team_employee',
      permissions: ['pay', 'view']
    },
    {
      email: 'jane.smith@example.com',
      role: 'team_viewer',
      permissions: ['view']
    }
  ],
  role: 'team_employee',
  anonymous: false
});

console.log('Invitations sent:', invitation.data);
```

**What the SDK does automatically:**

1. **Validates invitation data** and permissions
2. **Sends invitations** to the specified email addresses
3. **Handles authentication** and JWT token management
4. **Provides error handling** and validation

#### Manager Invitations (Requires Signing)

For manager-level invitations (team\_admin, finance\_admin), signing is required. The SDK must be initialized with a private key for automatic signing:

```javascript theme={null}
// Initialize SDK with private key for automatic signing
const client = new RiseApiClient({
  environment: 'prod',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY  // Required for automatic signing
  }
});

// Send manager invitation with automatic signing
const managerInvite = await client.invites.sendManagerInvite({
  emails: ['manager@example.com'],
  role: 'team_admin',
  nanoid: 'te-abc123def456'
});

console.log('Manager invitation sent:', managerInvite.data);
```

**What the SDK does automatically:**

1. **Generates typed data** for EIP-712 signing
2. **Signs the typed data** using your private key
3. **Submits the signed invitation** to the Rise API
4. **Handles authentication** and JWT token management
5. **Provides error handling** and retry logic

#### Manual Manager Invitations

For more control over manager invitation signing, you can handle the signing manually:

```javascript theme={null}
// Initialize SDK (private key not required for manual flow)
const client = new RiseApiClient({
  environment: 'prod',
  jwtToken: process.env.JWT_TOKEN  // JWT token is sufficient for manual flow
});

// Step 1: Get typed data for signing
const typedDataResponse = await client.invites.getManagerInviteTypedData({
  emails: ['manager@example.com'],
  role: 'team_admin',
  nanoid: 'te-abc123def456'
});

console.log('Typed data received:', typedDataResponse.data);

// Step 2: Sign the typed data (if you want custom signing logic)
const { ethers } = require('ethers');
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
const signature = await wallet.signTypedData(
  typedDataResponse.data.typed_data.domain,
  typedDataResponse.data.typed_data.types,
  typedDataResponse.data.typed_data.typed_data
);

// Step 3: Execute with signature
const executeResponse = await client.invites.executeManagerInviteWithSignedData({
  invites: typedDataResponse.data.invites,
  signer: wallet.address,
  typed_data: typedDataResponse.data.typed_data.typed_data,
  signature: signature
});

console.log('Manager invitation executed:', executeResponse.data);
```

**What the manual flow provides:**

1. **Custom signing logic** - You control when and how to sign
2. **Typed data inspection** - You can examine the data before signing
3. **Signature verification** - You can verify the signature before submission
4. **Error handling control** - Custom error handling for each step
5. **Integration flexibility** - Easier integration with existing signing workflows

## Complete Team Management Example

Here's a complete example using the Rise SDK:

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');
require('dotenv').config();

class RiseTeamManager {
  constructor() {
    this.client = new RiseApiClient({
      environment: 'prod',
      riseIdAuth: {
        riseId: process.env.RISE_ID,
        privateKey: process.env.PRIVATE_KEY
      }
    });
  }

  async getUserTeams() {
    try {
      const teams = await this.client.user.getTeams();
      return teams.data;
    } catch (error) {
      console.error('Failed to get user teams:', error.message);
      throw error;
    }
  }

  async updateTeam(teamNanoid, updates) {
    try {
      await this.client.team.update({
        nanoid: teamNanoid,
        ...updates
      });
      console.log('Team updated successfully');
    } catch (error) {
      console.error('Failed to update team:', error.message);
      throw error;
    }
  }

  async inviteTeamMembers(teamNanoid, members) {
    try {
      const invitation = await this.client.invites.send({
        nanoid: teamNanoid,
        invites: members,
        role: 'team_employee',
        anonymous: false
      });
      
      console.log('Team invitations sent:', invitation.data);
      return invitation.data;
    } catch (error) {
      console.error('Failed to send invitations:', error.message);
      throw error;
    }
  }

  async inviteManager(teamNanoid, email, role = 'team_admin') {
    try {
      const managerInvite = await this.client.invites.sendManagerInvite({
        emails: [email],
        role: role,
        nanoid: teamNanoid
      });
      
      console.log('Manager invitation sent:', managerInvite.data);
      return managerInvite.data;
    } catch (error) {
      console.error('Failed to send manager invitation:', error.message);
      throw error;
    }
  }

  async getTeamInvites(teamNanoid) {
    try {
      const invites = await this.client.invites.get({
        nanoid: teamNanoid
      });
      return invites.data;
    } catch (error) {
      console.error('Failed to get team invites:', error.message);
      throw error;
    }
  }
}

// Usage example
const teamManager = new RiseTeamManager();

async function main() {
  try {
    // Get user's teams
    const teams = await teamManager.getUserTeams();
    console.log('User teams:', teams);

    if (teams.teams && teams.teams.length > 0) {
      const firstTeam = teams.teams[0];

      // Update team information
      await teamManager.updateTeam(firstTeam.nanoid, {
        name: 'Updated Engineering Team',
        description: 'Updated team description'
      });

      // Invite new team members
      const newMembers = [
        {
          email: 'developer1@example.com',
          role: 'team_employee',
          permissions: ['pay', 'view']
        },
        {
          email: 'developer2@example.com',
          role: 'team_employee',
          permissions: ['pay', 'view']
        }
      ];

      await teamManager.inviteTeamMembers(firstTeam.nanoid, newMembers);

      // Invite a manager
      await teamManager.inviteManager(
        firstTeam.nanoid,
        'manager@example.com',
        'team_admin'
      );

      // Get team invitations
      const invites = await teamManager.getTeamInvites(firstTeam.nanoid);
      console.log('Team invitations:', invites);
    }

  } catch (error) {
    console.error('Team management error:', error.message);
  }
}

// Run the example
if (require.main === module) {
  main();
}
```

## Team Roles and Permissions

| Role              | Permissions                       | Description                                    |
| ----------------- | --------------------------------- | ---------------------------------------------- |
| **Team Admin**    | `pay`, `view`, `manage`, `invite` | Full control over team settings and members    |
| **Finance Admin** | `pay`, `view`, `finance`          | Financial management capabilities              |
| **Team Employee** | `pay`, `view`                     | Standard team member with payment capabilities |
| **Team Viewer**   | `view`                            | Read-only access to team information           |

## Error Handling

The SDK provides comprehensive error handling:

```javascript theme={null}
try {
  const teams = await client.user.getTeams();
  console.log('Teams retrieved successfully:', teams.data);
} catch (error) {
  console.error('Team management error:', error.message);
  
  // Handle specific error types based on message content
  if (error.message.includes('401')) {
    console.error('Authentication failed');
  } else if (error.message.includes('403')) {
    console.error('Insufficient permissions for this operation');
  } else if (error.message.includes('404')) {
    console.error('Team not found');
  } else if (error.message.includes('invalid')) {
    console.error('Invalid team data provided');
  } else {
    console.error('Team operation failed:', error.message);
  }
}
```

Common team management errors:

| Error Message       | Description               | Solution                                      |
| ------------------- | ------------------------- | --------------------------------------------- |
| `401`               | Authentication failed     | Check your credentials and JWT token          |
| `403`               | Insufficient permissions  | Verify user has required role and permissions |
| `404`               | Team not found            | Check team nanoid is correct                  |
| `invalid team data` | Invalid team information  | Verify team data format and requirements      |
| `invitation failed` | Failed to send invitation | Check email format and team permissions       |

## Best Practices

<Warning>
  **Always maintain at least one team admin** to prevent losing access to team management capabilities.
</Warning>

### Team Management Best Practices

* **Role Hierarchy**: Use the principle of least privilege when assigning roles
* **Regular Audits**: Periodically review team members and their permissions
* **Documentation**: Keep records of team structure and permission changes
* **Backup Admins**: Always have multiple admins for critical teams
* **Permission Reviews**: Regularly review and update member permissions

### SDK Best Practices

* **Error Handling**: Implement proper error handling for all team operations
* **Authentication**: Use Rise ID authentication for automatic JWT management
* **Environment**: Use staging environment for testing team operations
* **Logging**: Log team management operations for audit purposes

## Testing Team Management

For testing, use the staging environment:

```javascript theme={null}
// Staging configuration for testing
const stagingClient = new RiseApiClient({
  environment: 'stg',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY
  }
});

// Test team operations
const testTeams = await stagingClient.user.getTeams();
console.log('Test teams:', testTeams.data);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Authentication Guide" icon="key" href="/guides/auth-integration">
    Learn how to authenticate with Rise using the SDK
  </Card>

  <Card title="Payment Integration" icon="credit-card" href="/guides/payment-integration">
    Process payments for team members
  </Card>

  <Card title="Web3 Integration" icon="link" href="/guides/web3-integration">
    Advanced blockchain integration features
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/guides/error-handling">
    Comprehensive error handling and troubleshooting
  </Card>
</CardGroup>

<Note>
  **Need help?** See the [Teams](/concepts/teams) page for detailed team management concepts or contact support at [Hello@Riseworks.io](mailto:Hello@Riseworks.io)
</Note>
