﻿---
name: user-groups
description: >
  Instructs AI agents how to create, read, update, and delete user groups
  in Kyriba, and how to add or remove member users. User groups are used
  for process template access, approval rules, publishing rights, and forum access.
version: 1.0.0
scopes:
  - user-group-scope
authors:
  - kyriba
tags:
  - kyriba
  - platform
  - users
  - api
---

> **Auth** — POST {AUTH_BASE_URL}/oauth/token · Basic base64(CLIENT_ID:CLIENT_SECRET) · no scope.
> Use token_type verbatim — do not hardcode `Bearer`. On 401: retry once with the other scheme (`token` vs `Bearer`). On 429: wait Kyriba-Customer-Rate-Limit-Reset.

# Kyriba API Skill: User Groups

---

## Required Kyriba Permission

```
user-group-scope
```

This is a Kyriba access permission — not an OAuth scope parameter. Do NOT add `scope=` to the token request.

---

## What are User Groups?

Group Kyriba users together for access control purposes. A user group controls:
- Process template filtering and administration rights (`processTemplateFiltering`)
- Approval workflow eligibility (`approvalWorkflow`)
- Publishing task results (`taskPublishing`)
- Intranet / forum access (`intranetAccess`)

---

## Base URL

```
https://api.demo.kyriba.com/api/v1/user-groups
```

---

## Endpoints

`{ref}` accepts either `uuid` or `code`.

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/v1/user-groups` | List user groups |
| `POST` | `/api/v1/user-groups` | Create a user group |
| `GET` | `/api/v1/user-groups/{ref}` | Get a specific group (includes `users[]`) |
| `PUT` | `/api/v1/user-groups/{ref}` | Update a group |
| `DELETE` | `/api/v1/user-groups/{ref}` | Delete a group |
| `POST` | `/api/v1/user-groups/{ref}/members` | Add user(s) to a group |
| `DELETE` | `/api/v1/user-groups/{ref}/members` | Remove user(s) from a group |

---

## Pagination

Uses standard `page.limit` / `page.offset`.

---

## Filterable Fields

```
code, description, ownershipCompany.code, ownershipCompany.uuid
```

---

## Key Fields

| Field | Description |
|---|---|
| `uuid` | System-generated identifier |
| `code` | Unique group code |
| `description` | Group description. **Can be `null`**. |
| `ownershipCompany` | Company that owns this group `{ "code": "...", "uuid": "..." }` |
| `users[]` | Member users - **only present in `GET /{ref}`**, not in list response |
| `processTemplateFiltering` | Allow group for process template access/admin (default: `true`) |
| `approvalWorkflow` | Allow group for approval rules (default: `true`) |
| `taskPublishing` | Allow group for publishing task results (default: `true`) |
| `intranetAccess` | Allow group for forum/intranet access (default: `true`) |

---

## Example Requests

**List all user groups:**
```
GET /api/v1/user-groups?page.limit=100&page.offset=0&sort=code
```

**GET list response:**
```json
{
  "metadata": {
    "pageLimit": 100,
    "pageOffset": 0,
    "pageResults": 2,
    "numberOfTotalResults": 2
  },
  "results": [ ... ]
}
```
> Response key is always `results`. Stop paginating when `len(results) < pageLimit`.

**Filter by ownership company:**
```
GET /api/v1/user-groups?filter=ownershipCompany.code==COMP_FR
```

**Create a user group:**
```http
POST /api/v1/user-groups
Content-Type: application/json

{
  "code": "GRP_TREASURY",
  "description": "Treasury Team",
  "ownershipCompany": { "code": "COMP_FR" },
  "processTemplateFiltering": true,
  "approvalWorkflow": true,
  "taskPublishing": false,
  "intranetAccess": false
}
```

**Create response:** `{ "uuid": "..." }`

**Add users to a group:**
```http
POST /api/v1/user-groups/GRP_TREASURY/members
Content-Type: application/json

[
  { "code": "jsmith" },
  { "code": "mjones" }
]
```

**Remove users from a group:**
```http
DELETE /api/v1/user-groups/GRP_TREASURY/members
Content-Type: application/json

[
  { "code": "mjones" }
]
```

---

##  Common Mistakes

| Wrong field name | Correct field name |
|---|---|
| `useForProcessTemplateAccess` | `processTemplateFiltering` |
| `useForApprovalRules` | `approvalWorkflow` |
| `useForPublishingTaskResults` | `taskPublishing` |
| `useForForumAccess` | `intranetAccess` |
| `members[]` (response key) | `users[]` |

---

## Critical Rules

1. `uuid` is auto-generated - do not include in POST body
2. Member users are in **`users[]`** (not `members[]`) - only present in `GET /{ref}`
3. `description` can be `null` - always handle with a default
4. All 4 boolean flags default to `true` - explicitly set to `false` to restrict usage
5. Add/remove members via `/members` sub-resource - **not** via PUT on the group
6. `DELETE` on a group returns `409` if it is in use

---

## Error Reference

| Status | Meaning |
|---|---|
| `201` | Created - returns `{ "uuid": "..." }` |
| `400` | Invalid request |
| `403` | Required Kyriba permission not configured on your API client |
| `404` | Group or user not found |
| `409` | Code already exists or group is in use |

---

## OpenAPI Spec

- OpenAPI: `https://developer.kyriba.com/static/apis/user-groups/user-groups.yaml`