
## Add user or department

`POST /v1/infra/servers/:id/access`

Adds an access entry to a BLACKHOLE server: a specific Bitrix24 user (with the `NAMED_USERS` policy) or a department (with the `DEPARTMENT` policy). The policy is not changed automatically — switch it separately via [`PATCH /access-policy`](./access-policy.md) if you have not done so yet. Duplicates (the same `userId` or `departmentId` on the same server) return 409 `ALREADY_EXISTS`.

## Parameters

| Parameter | In | Type | Req. | Description |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | yes | BLACKHOLE server ID |

## Request fields (body)

| Field | Type | Req. | Description |
|------|-----|:-----:|----------|
| `type` | string | **yes** | `user` — add a user, `department` — add a department |
| `userId` | string | yes (for `type: "user"`) | Bitrix24 user ID. Search via [`GET /b24-users?search=`](./b24-users.md) |
| `userName` | string | no | User name (up to 255 characters). Optional, but recommended for readability in the UI |
| `departmentId` | string | yes (for `type: "department"`) | Bitrix24 department ID |
| `departmentName` | string | yes (for `type: "department"`) | Department name (up to 255 characters) |

## Examples

### curl — personal key

```bash
# Add a user
curl -X POST https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "user", "userId": "243", "userName": "Kate Smith"}'

# Add a department
curl -X POST https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "department", "departmentId": "5", "departmentName": "Development"}'
```

### curl — OAuth application

```bash
curl -X POST https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type": "user", "userId": "243", "userName": "Kate Smith"}'
```

### JavaScript — personal key

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/access`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      type: 'user',
      userId: '243',
      userName: 'Kate Smith',
    }),
  }
)
if (res.status === 201) {
  const { data } = await res.json()
  console.log(`Added: ${data.userName} (entry ${data.id})`)
}
```

### JavaScript — OAuth application

```javascript
await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/access`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      type: 'department',
      departmentId: '5',
      departmentName: 'Development',
    }),
  }
)
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on successful addition. HTTP status — 201 |
| `data.id` | string (UUID) | ID of the created entry — pass it to [`DELETE /access/:accessId`](./access-delete.md) to delete it |
| `data.serverId` | string (UUID) | Server ID |
| `data.userId` | string | Bitrix24 user ID (only for `type: "user"`) |
| `data.userName` | string \| null | User name (only for `type: "user"`) |
| `data.networkUserId` | string \| null | The user's Network ID. `null` right after creation, filled in asynchronously (only for `type: "user"`) |
| `data.departmentId` | string | Bitrix24 department ID (only for `type: "department"`) |
| `data.departmentName` | string | Department name (only for `type: "department"`) |
| `data.grantedBy` | string (UUID) | ID of the Vibecode user who created the entry |
| `data.createdAt` | string (ISO 8601) | When the entry was added |

## Response example

Adding a user:

```json
{
  "success": true,
  "data": {
    "id": "b3a6f8d1-3c2a-4e17-9f0b-1a7c2d4e5f60",
    "serverId": "e765edfc-ba0a-43de-b8ea-838dd872c522",
    "userId": "243",
    "userName": "Kate Smith",
    "networkUserId": null,
    "grantedBy": "f1d2e3c4-5b6a-4d0e-8f1a-2b3c4d5e6f70",
    "createdAt": "2026-04-22T10:15:00.000Z"
  }
}
```

Adding a department:

```json
{
  "success": true,
  "data": {
    "id": "c7d8e9f0-1a2b-3c4d-5e6f-7a8b9c0d1e2f",
    "serverId": "e765edfc-ba0a-43de-b8ea-838dd872c522",
    "departmentId": "5",
    "departmentName": "Development",
    "grantedBy": "f1d2e3c4-5b6a-4d0e-8f1a-2b3c4d5e6f70",
    "createdAt": "2026-04-22T11:30:00.000Z"
  }
}
```

## Error response example

409 — the entry already exists:

```json
{
  "success": false,
  "error": {
    "code": "ALREADY_EXISTS",
    "message": "Access entry already exists"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | The fields failed validation: invalid `type`, a required field for the chosen type is missing |
| 400 | `BLACKHOLE_ONLY` | The server is in OPEN mode |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not provided |
| 401 | `INVALID_API_KEY` | Invalid or expired API key |
| 404 | `NOT_FOUND` | The server does not exist, was deleted, or belongs to another API key |
| 409 | `ALREADY_EXISTS` | An entry for this `userId`/`departmentId` on this server already exists |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |

The full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **`userName` and `departmentName` are for display only.** Matching during the access check uses `userId`/`departmentId` — the name does not affect authorization. The name is used for display in the list when the Bitrix24 integration is temporarily unavailable.
- **`networkUserId` is filled in asynchronously.** Right after the `POST`, the field is `null`. In the background, the platform calls the Bitrix24 webhook (if available), finds the user's Network ID, and updates the entry. This is needed for matching when the user signs in to Vibecode via Network OAuth (rather than through your Bitrix24 account).
- **Uniqueness — the pair `(serverId, userId)` for users and `(serverId, departmentId)` for departments.** To "update" an entry, first `DELETE`, then `POST`.
- **The policy is not changed automatically.** If the server is in `OWNER_ONLY`, adding an entry will not act as "opening access" — first switch the policy to `NAMED_USERS` (or `DEPARTMENT`) via [`PATCH /access-policy`](./access-policy.md).

## See also

- [Access list](./access-list.md) — verify that the entry was added.
- [Delete entry](./access-delete.md) — `DELETE /v1/infra/servers/:id/access/:accessId`.
- [Access policy](./access-policy.md) — switch `NAMED_USERS` / `DEPARTMENT`.
- [Search Bitrix24 users](./b24-users.md) — find the `userId` before adding.
