Groups

Replace a group's members

curl -X PUT https://api.subscriby.net/v1/groups/$GROUP_ID/members \
  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"user_ids": ["2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80", "4b8e2f6a-1c3d-4e5f-9a7b-8c9d0e1f2a3b"]}'

This is a sync, not an add. The array replaces the membership entirely: anyone omitted is removed, and [] empties the group. That is deliberate and differs from the permission field above: clearing a group is a legitimate thing to ask for, whereas silently stripping every permission because a field was blank is not.

This is the one write in the identity surface whose tier gate depends on its argument: a sync that only removes people succeeds on any tier, and one that adds anybody needs Growth. Deciding from the route alone would leave a lapsed creator unable to take one person out of a group without deleting the whole group, and deleting is not gated, so the gate would only be pushing them toward the more destructive option.

Every id must already belong to the group's team. A group grants permissions inside one tenant, so an outsider is refused naming the offending ids; the whole call fails rather than partly applying, so you never end up with a membership you did not ask for.

Answers 200 with the group, its permissions and its member_ids. Emits group.members_synced, which carries added_ids and removed_ids as well as the final list, so an access-control mirror does not have to diff two snapshots to work out what moved. A sync that changes nothing emits nothing.

put/v1/groups/{group}/members

Request

  • Base URL: https://api.subscriby.net
  • URL: https://api.subscriby.net/v1/groups/{group}/members
  • Auth: HTTP bearer

Path parameters

groupstring uuid required

The group, resolved by the route binder.

Headers

Idempotency-Keystring uuid required

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Request body

user_idsstring[] required

Every user the group should have afterwards. Must be present; [] empties the group. Each id must already belong to the group's team, or the whole call is refused naming the outsiders.

Response

The group with its permissions and members.

Example response

{
  "data": {
    "id": "1f68d92a-04c5-4e83-97b1-3d6a05e2f847",
    "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",
    "code": "ops",
    "name": "Ops",
    "permissions": [
      "project:view-any"
    ],
    "member_ids": [
      "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80"
    ],
    "created_at": "2026-05-18T10:05:00Z"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.