Skip to content

Change the group's profile

PATCH
/groups/{groupId}/profile
curl --request PATCH \
--url https://app.grouperly.com/api/v2/groups/example/profile \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{}'

Each field sent replaces what’s stored, and null removes it; fields not sent stay as they are. Only subtype and the fields the group’s vertical’s descriptor declares (profile.fields) can be sent, and they’re checked as Grouperly’s settings page checks them: the subtype is one the vertical has, each field holds its type, text is trimmed.

A value that was already stored is accepted as it is, so a descriptor change never blocks saving something else. Returns the group.

  • appToken
    https://api.grouperly.com/groups.write
groupId
required
string

The credential’s group

Media typeapplication/json

Profile fields to change, e.g. { “unitNumber”: “1232”, “district”: null }

object
key
additional properties
any
Examplegenerated
{}

OK

Media typeapplication/json
object
id
required
string
name
required
string
slug
required

The group’s page address, www.grouperly.com/. It can change: leaders can change it, and the group pages’ rollout replaces one that breaks the address rules (2.26.4). Keep track of a group by its id.

string
type
required
string
description
required
string | null
metadata
required

The group profile: subtype and the fields its vertical’s descriptor declares (profile.fields), e.g. { subtype: “PACK”, unitNumber: “1232” } for a scouting unit. Groups in a vertical are checked against its descriptor when saved; others record anything

object
vertical
required

The vertical the group belongs to, e.g. “scouting” (added in 2.1.0)

string | null
memberCount
required
integer
youthCount
required

Youth entries on the roster (added in 2.3.0). For an app without roster.youth.read it’s all it learns about them: /contacts leaves them out.

integer
subgroupCount
required
integer
createdAt
required
string format: date-time
updatedAt
required
string format: date-time
Examplegenerated
{
"id": "example",
"name": "example",
"slug": "example",
"type": "example",
"description": "example",
"metadata": {},
"vertical": "example",
"memberCount": 1,
"youthCount": 1,
"subgroupCount": 1,
"createdAt": "2026-04-15T12:00:00Z",
"updatedAt": "2026-04-15T12:00:00Z"
}
X-RateLimit-Limit
integer

Requests allowed per minute for this credential

X-RateLimit-Remaining
integer

Requests left in this window

X-RateLimit-Reset
integer

When the window ends (Unix seconds)

The body isn’t a JSON object of at most 16 KB, or a field is unknown, missing or malformed (invalid_body, with parameter), or a value doesn’t fit the descriptor (invalid_profile, with every problem in message)

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}
X-RateLimit-Limit
integer

Requests allowed per minute for this credential

X-RateLimit-Remaining
integer

Requests left in this window

X-RateLimit-Reset
integer

When the window ends (Unix seconds)

Missing, unknown, revoked or expired credential (unauthorized)

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}

A key: wrong group (forbidden), missing scope (insufficient_scope), or its creator no longer leads the group (key_owner_not_leader). An app’s token: missing scope (insufficient_scope), the group hasn’t installed the app (app_not_installed) or allowed the scope (scope_not_allowed, the message has the consent link), the person may not do this in the group (forbidden), Grouperly paused the app (app_suspended), the person hasn’t accepted Grouperly’s current Terms (terms_required: refresh their token, then send them to the hub’s /account/welcome), or it’s a child’s account (child_account)

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}
X-RateLimit-Limit
integer

Requests allowed per minute for this credential

X-RateLimit-Remaining
integer

Requests left in this window

X-RateLimit-Reset
integer

When the window ends (Unix seconds)

Not found (not_found)

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}
X-RateLimit-Limit
integer

Requests allowed per minute for this credential

X-RateLimit-Remaining
integer

Requests left in this window

X-RateLimit-Reset
integer

When the window ends (Unix seconds)

The group’s vertical has no profile, or it has no vertical (no_profile)

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}
X-RateLimit-Limit
integer

Requests allowed per minute for this credential

X-RateLimit-Remaining
integer

Requests left in this window

X-RateLimit-Reset
integer

When the window ends (Unix seconds)

Rate limited (rate_limited)

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}
X-RateLimit-Limit
integer

Requests allowed per minute for this credential

X-RateLimit-Remaining
integer

Requests left in this window

X-RateLimit-Reset
integer

When the window ends (Unix seconds)

Retry-After
integer

Seconds to wait

An app’s token for someone new, while Grouperly’s sign-in can’t be reached (unavailable); try again

Media typeapplication/json
object
error
required
object
code
required

Stable and machine-readable: unauthorized, forbidden, insufficient_scope, key_owner_not_leader, app_not_installed, scope_not_allowed, app_suspended, rate_limited, not_found, invalid_parameter, invalid_body, invalid_profile, invalid_descriptor, no_profile, already_exists, not_a_member, position_inactive, position_full, already_assigned, assignment_ended, version_not_current, nothing_to_pay, payments_not_ready, payload_too_large, first_party_only, terms_required, child_account, assistant_off, not_for_assistant, assistant_failed, not_a_draft, storage_full, unavailable, internal_error. New codes may be added.

string
message
required

For people; wording may change.

string
parameter

The query parameter (invalid_parameter) or body field (invalid_body, not_a_member) at fault.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"parameter": "example"
}
}