For AI agents: markdown of this page — /docs-content-en/entities/workgroups/search.md documentation index — /llms.txt

Search workgroups

POST /v1/workgroups/search

Returns a list of workgroups matching the given filters. The same contract as GET /v1/workgroups, but the conditions are passed in the request body — suitable for long filters and non-Latin values.

Request fields (body)

Field Type Description
filter object Filtering conditions. Field list: GET /v1/workgroups/fields. Syntax: Filtering.
select array List of fields in the response. Names — from GET /v1/workgroups/fields.
sort object Sorting: {"<field>": "ASC"|"DESC"}.
limit number Maximum records. Default 50, maximum 5000.
offset number Offset from the start of the result set. Default 0. Together with a date-range filter wider than 14 days it is rejected — see UNSTABLE_OFFSET_PAGINATION in the "Errors" section.
autoWindow boolean Split the result set into weekly windows when filtering by a date range wider than 14 days. Defaults to true. false disables splitting

For limit > 50 Vibecode automatically paginates the request on the server side. The maximum is 5000 records per call. If more match the filter — meta.hasMore will be true.

Get projects only

A single collection stores both workgroups and projects. The isProject field distinguishes them: true — a project, false — an ordinary workgroup. To select projects, pass "filter": { "isProject": "Y" }.

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/workgroups/search" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "%name": "Marketing", "archived": "N" },
    "select": ["id", "name", "ownerId", "membersCount"],
    "sort": { "dateCreate": "DESC" },
    "limit": 5
  }'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/workgroups/search" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "%name": "Marketing", "archived": "N" },
    "select": ["id", "name", "ownerId", "membersCount"],
    "sort": { "dateCreate": "DESC" },
    "limit": 5
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/workgroups/search', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { '%name': 'Marketing', archived: 'N' },
    select: ['id', 'name', 'ownerId', 'membersCount'],
    sort: { dateCreate: 'DESC' },
    limit: 5,
  }),
})

const { success, data, meta } = await res.json()
console.log(`Found ${meta.total} workgroups`)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/workgroups/search', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { '%name': 'Marketing', archived: 'N' },
    select: ['id', 'name', 'ownerId', 'membersCount'],
    sort: { dateCreate: 'DESC' },
    limit: 5,
  }),
})

const { success, data, meta } = await res.json()

Response fields

Field Type Description
success boolean Always true on success
data array Array of workgroups (all fields — see Workgroup fields)
meta.total number How many records matched the filter
meta.hasMore boolean Whether there is a next page
meta.durationMs number Request duration in milliseconds
meta.autoWindowed boolean true if the result set was split into time windows
meta.windowCount number Number of windows. Present with autoWindowed: true
meta.batchWaves number Number of parallel request waves. Present with autoWindowed: true

The meta fields sit next to data, not inside it. Pages must be walked by meta.hasMore: a data length equal to limit does not rule out the last page.

Response example

JSON
{
  "success": true,
  "data": [
    {
      "id": 85,
      "name": "Marketing 2026",
      "ownerId": 1271,
      "membersCount": 2,
      "dateCreate": "2026-03-20T06:45:10.000Z"
    },
    {
      "id": 83,
      "name": "New product development team",
      "ownerId": 1269,
      "membersCount": 1,
      "dateCreate": "2026-03-20T06:41:07.000Z"
    },
    {
      "id": 81,
      "name": "Regional office launch",
      "ownerId": 1271,
      "membersCount": 1,
      "dateCreate": "2026-03-20T06:29:07.000Z"
    }
  ],
  "meta": {
    "total": 3,
    "hasMore": false
  }
}

With a date-range filter wider than 14 days, meta additionally returns autoWindowed, windowCount, and batchWaves:

JSON
{
  "success": true,
  "data": [ /* ... */ ],
  "meta": {
    "total": 29,
    "hasMore": true,
    "autoWindowed": true,
    "windowCount": 131,
    "batchWaves": 3,
    "durationMs": 4217
  }
}

Error response example

401 — no authorization key was passed:

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_API_KEY",
    "message": "API key required. Pass via X-Api-Key header."
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS The request body does not parse or contains invalid fields
401 MISSING_API_KEY The X-Api-Key header was not passed
401 INVALID_API_KEY The provided key was not recognized
403 SCOPE_DENIED The key is missing the sonet_group scope
400 UNSTABLE_OFFSET_PAGINATION offset greater than zero together with a date-range filter wider than 14 days. Two different retrieval algorithms produce inconsistent results, so the request is rejected. Take everything in a single request with limit up to 5000, or pass autoWindow: false with sorting by id, or split the date range into parts yourself

Full list of common API errors — Errors.

Known specifics

Time-window splitting. A date-range filter wider than 14 days is automatically split into weekly windows executed in parallel waves, so the result set bypasses the ceiling of 5000 records per call. meta then returns autoWindowed: true, the number of windows windowCount, and the number of waves batchWaves. The autoWindow: false parameter disables splitting. While splitting is active, an offset greater than zero is rejected with UNSTABLE_OFFSET_PAGINATION.

Boolean fields in the filter can be passed in two ways. In the POST body both Y / N and native JSON true / false are allowed: "filter": {"active": "Y"} and "filter": {"active": true} produce the same result set. In the response the same fields always come back as true / false.

A % prefix in the field name — substring search. "filter": {"%name": "Marketing"} will find all groups whose name contains "Marketing". Without the prefix the filter requires an exact match.

The sort parameter in the body is sort. An order key in the body is ignored without an error — the result set is returned in the default order. Use "sort": {"dateCreate": "DESC"} or the string form "sort": "dateCreate" (the default direction is ASC).

See also