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

# Bulk User Removal

> Remove multiple users from your organization at once

<Warning>
  **DEPRECATED:** This endpoint has been replaced by [DELETE /admin/users](/api-reference/admin-api/remove-users-from-organization).

  The new endpoint provides:

  * Cleaner RESTful structure
  * Better separation between users and invitations
  * Consistent response format

  This endpoint will be removed in a future version.
</Warning>

<Note>
  This endpoint requires organization admin privileges. Only users with the `org:admin` role can bulk remove users from their organization.
</Note>

<Warning>
  Users cannot remove themselves from the organization using this endpoint. This prevents accidental lockouts.
</Warning>

### Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication. Must be from a user with `org:admin` role.
</ParamField>

### Body

<ParamField body="userIds" type="array" required>
  Array of Clerk user IDs to remove from the organization (1-50 users per request)
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Whether all users were successfully removed
</ResponseField>

<ResponseField name="total" type="number">
  Total number of users requested to be removed
</ResponseField>

<ResponseField name="successful" type="number">
  Number of users successfully removed
</ResponseField>

<ResponseField name="failed" type="number">
  Number of users that failed to be removed
</ResponseField>

<ResponseField name="results" type="array">
  Array of successful removal results

  <Expandable title="Result Object">
    <ResponseField name="userId" type="string">
      Clerk user ID that was successfully removed
    </ResponseField>

    <ResponseField name="success" type="boolean">
      Whether this specific removal was successful (always true in results array)
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="errors" type="array" optional>
  Array of failed removals (only present if there were failures)

  <Expandable title="Error Object">
    <ResponseField name="userId" type="string">
      Clerk user ID that failed to be removed
    </ResponseField>

    <ResponseField name="success" type="boolean">
      Always false for error objects
    </ResponseField>

    <ResponseField name="error" type="string">
      Description of what went wrong
    </ResponseField>
  </Expandable>
</ResponseField>

### Examples

<CodeGroup>
  ```curl Basic Removal theme={null}
  curl -X POST https://asteragents.com/api/admin/bulkRemove \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "userIds": [
        "user_2ABC123DEF",
        "user_2XYZ789GHI"
      ]
    }'
  ```

  ```python theme={null}
  import requests

  url = "https://asteragents.com/api/admin/bulkRemove"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  data = {
      "userIds": [
          "user_2ABC123DEF",
          "user_2XYZ789GHI",
          "user_2MNO456PQR"
      ]
  }

  response = requests.post(url, headers=headers, json=data)
  result = response.json()
  print(f"Removed {result['successful']} users successfully")
  ```

  ```javascript theme={null}
  const response = await fetch('https://asteragents.com/api/admin/bulkRemove', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      userIds: [
        'user_2ABC123DEF',
        'user_2XYZ789GHI'
      ]
    })
  });

  const result = await response.json();
  console.log(`Removed ${result.successful} users successfully`);
  ```

  ```json Success Response theme={null}
  {
    "success": true,
    "total": 2,
    "successful": 2,
    "failed": 0,
    "results": [
      {
        "userId": "user_2ABC123DEF",
        "success": true
      },
      {
        "userId": "user_2XYZ789GHI", 
        "success": true
      }
    ]
  }
  ```

  ```json Partial Success Response theme={null}
  {
    "success": false,
    "total": 3,
    "successful": 2,
    "failed": 1,
    "results": [
      {
        "userId": "user_2ABC123DEF",
        "success": true
      },
      {
        "userId": "user_2XYZ789GHI",
        "success": true
      }
    ],
    "errors": [
      {
        "userId": "user_2INVALID123",
        "success": false,
        "error": "User not found in organization"
      }
    ]
  }
  ```
</CodeGroup>

### Error Codes

<ResponseField name="400" type="object">
  Bad Request - Invalid request data, validation errors, or attempting to remove yourself
</ResponseField>

<ResponseField name="401" type="object">
  Unauthorized - Invalid or missing authentication
</ResponseField>

<ResponseField name="403" type="object">
  Forbidden - User is not an admin in the organization
</ResponseField>

<ResponseField name="405" type="object">
  Method Not Allowed - Only POST requests are accepted
</ResponseField>

<ResponseField name="207" type="object">
  Multi-Status - Some removals succeeded, others failed (partial success)
</ResponseField>

## Workflow

### Step 1: Get User IDs

First, use the [Get Organization Users](/api-reference/endpoint/get-users-in-org) endpoint to retrieve user IDs:

```javascript theme={null}
// Get all users in organization
const usersResponse = await fetch('/api/admin/getUsersInOrg', {
  headers: { 'Authorization': 'Bearer ' + token }
});
const users = await usersResponse.json();

// Filter users you want to remove (e.g., by department)
// Note: publicMetadata is organization-scoped
const usersToRemove = users
  .filter(user => user.publicMetadata?.department === 'marketing')
  .map(user => user.id);
```

### Step 2: Bulk Remove Users

Then use those IDs to remove users from the organization:

```javascript theme={null}
const removeResponse = await fetch('/api/admin/bulkRemove', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + token,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    userIds: usersToRemove
  })
});
```

## Use Cases

### Department Restructuring

Remove all users from a specific department:

```python theme={null}
# Get all users
users = requests.get('/api/admin/getUsersInOrg', headers=headers).json()

# Filter by department
marketing_users = [
    user['id'] for user in users 
    if user.get('publicMetadata', {}).get('department') == 'marketing'
]

# Remove them
response = requests.post('/api/admin/bulkRemove', 
    headers=headers, json={'userIds': marketing_users})
```

### Inactive User Cleanup

Remove users who haven't signed in recently:

```javascript theme={null}
const cutoffDate = new Date('2023-01-01');
const inactiveUsers = users
  .filter(user => {
    const lastSignIn = user.lastSignInAt ? new Date(user.lastSignInAt) : null;
    return !lastSignIn || lastSignIn < cutoffDate;
  })
  .map(user => user.id);

// Remove inactive users
await fetch('/api/admin/bulkRemove', {
  method: 'POST',
  headers: headers,
  body: JSON.stringify({ userIds: inactiveUsers })
});
```

### Role-Based Removal

Remove users with specific roles or metadata:

```python theme={null}
# Remove all temporary contractors
temp_contractors = [
    user['id'] for user in users 
    if user.get('publicMetadata', {}).get('role') == 'temp_contractor'
]
```

## Features

**Safe Operations**: Built-in protection against self-removal and comprehensive error handling.

* **Self-Protection**: Admins cannot accidentally remove themselves
* **Batch Processing**: Handle up to 50 users per request efficiently
* **Detailed Results**: Know exactly which users were removed and which failed
* **Partial Success**: Continue processing even if some removals fail

## Security Notes

* Only organization admins can remove users
* Removed users lose access to the organization immediately
* **Organization-scoped metadata is deleted** when a user is removed from the organization
* Users can be re-invited after removal (with fresh metadata)
* Action is logged in Clerk audit logs
* Webhooks will fire for `organizationMembership.deleted` events

## Limits

* **Batch Size**: 1-50 user IDs per request
* **User ID Validation**: All user IDs must be valid Clerk user identifiers
* **Rate Limiting**: Subject to Clerk's API rate limits
* **Self-Removal**: Cannot remove your own user ID (will fail with error)

<Tip>
  Use this endpoint in combination with [Get Organization Users](/api-reference/endpoint/get-users-in-org) to build powerful user management workflows.
</Tip>
